Skip to content

Commit

Permalink
Merge pull request #88 from etagwerker/fixes-86-json-support
Browse files Browse the repository at this point in the history
JSON Output Support
  • Loading branch information
danmayer authored Mar 17, 2024
2 parents d21db69 + 7c04103 commit b76db8e
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 26 deletions.
34 changes: 8 additions & 26 deletions bin/churn
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ bin_file = Pathname.new(__FILE__).realpath
$:.unshift File.expand_path("../../lib", bin_file)

require 'churn/calculator'
require 'churn/reporter'
require 'churn/version'
require 'main'
require 'yaml'
Expand All @@ -24,6 +25,11 @@ Main do
default false
end

option('json', 'j') do
cast :boolean
default false
end

option('ignore_files', 'i') do
cast :string
argument :optional
Expand Down Expand Up @@ -80,33 +86,9 @@ Main do
default false
end

def report_churn(output_string)
options = {
minimum_churn_count: params['minimum_churn_count'].value,
ignore_files: params['ignore_files'].value,
start_date: params['start_date'].value,
data_directory: params['data_directory'].value,
history: params['past_history'].value,
report: params['report'].value,
name: params['name'].value,
file_extension: params['extension'].value,
file_prefix: params['prefix'].value,
}
if params['version'].value
puts Churn::VERSION
return
end

result = Churn::ChurnCalculator.new(options).report(output_string)
if output_string
result
else
YAML::dump(result)
end
end

def run
report = report_churn(!params['yaml'].value)
reporter = Churn::ChurnReporter.new(params)
report = reporter.report_churn
puts report
end
end
57 changes: 57 additions & 0 deletions lib/churn/reporter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
require 'json'

require_relative 'calculator'
require_relative 'version'

module Churn

# The reporter of churn results. Knows how to report churn
# in different formats:
#
# - Console (stdout)
# - YAML
# - JSON
class ChurnReporter
attr_accessor :calculator, :options, :params

def initialize(_params)
self.params = _params
self.options = {
minimum_churn_count: params['minimum_churn_count'].value,
ignore_files: params['ignore_files'].value,
start_date: params['start_date'].value,
data_directory: params['data_directory'].value,
history: params['past_history'].value,
report: params['report'].value,
name: params['name'].value,
file_extension: params['extension'].value,
file_prefix: params['prefix'].value,
json: params['json'].value,
yaml: params['yaml'].value,
}
self.calculator = Churn::ChurnCalculator.new(options)
end

# Knows how to return a churn result in different formats.
#
# @return [String]
def report_churn
print_output = !options[:json] && !options[:yaml]

if params['version'].value
puts Churn::VERSION
return
end

result = calculator.report(print_output)

if options[:json]
JSON::dump(result)
elsif options[:yaml]
YAML::dump(result)
else
result
end
end
end
end
73 changes: 73 additions & 0 deletions test/unit/reporter_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
require 'minitest/autorun'
require_relative '../../lib/churn/reporter'

class ChurnReporterTest < Minitest::Test
StructOption = Struct.new(:value)

def setup
@params = {
'minimum_churn_count' => StructOption.new(3),
'ignore_files' => StructOption.new('file.rb'),
'start_date' => StructOption.new('2022-01-01'),
'data_directory' => StructOption.new('/data'),
'past_history' => StructOption.new(true),
'report' => StructOption.new('summary'),
'name' => StructOption.new('churn_report'),
'extension' => StructOption.new('.rb'),
'prefix' => StructOption.new('churn_'),
'json' => StructOption.new(false),
'yaml' => StructOption.new(false),
'version' => StructOption.new(false)
}
churn_calculator = Churn::ChurnCalculator.new({:minimum_churn_count => 3})

churn_calculator.stubs(:parse_log_for_changes).returns([['file.rb', 4],['less.rb',1]])
churn_calculator.stubs(:parse_log_for_revision_changes).returns(['revision'])
churn_calculator.stubs(:analyze)
@churn_reporter = Churn::ChurnReporter.new(@params)
@churn_reporter.calculator = churn_calculator
end

test "initialize sets the params as an instance variable" do
assert_equal @params, @churn_reporter.params
end

test "report churn prints version when version param is true" do
@params['version'].value = true

expected_output = "#{Churn::VERSION}\n"

assert_output(expected_output) { @churn_reporter.report_churn }
end

test "report churn returns result as json when json param is true" do
@churn_reporter.options[:json] = true

result = "{\"churn\":{\"changes\":[[\"file.rb\",4]],\"class_churn\":{},\"method_churn\":{}}}"

assert_equal result, @churn_reporter.report_churn
end

test "report churn returns result as yaml when yaml param is true" do
@churn_reporter.options[:yaml] = true

result =<<~EOS
---
:churn:
:changes:
- - file.rb
- 4
:class_churn: {}
:method_churn: {}
EOS

assert_equal result, @churn_reporter.report_churn
end

test "report churn returns result when neither json nor yaml param is true" do
output = @churn_reporter.report_churn

assert_match /Revision Changes/, output
assert_match /Project Churn/, output
end
end

0 comments on commit b76db8e

Please sign in to comment.