Skip to content

Commit

Permalink
Refactor reporter class out of the bin/churn file
Browse files Browse the repository at this point in the history
This also adds support for a JSON format output.
  • Loading branch information
etagwerker committed Mar 16, 2024
1 parent 2192345 commit 7c04103
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 0 deletions.
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 7c04103

Please sign in to comment.