diff --git a/test/fixtures/console-output.txt b/test/fixtures/console-output.txt index ffdca26..7c07a1f 100644 --- a/test/fixtures/console-output.txt +++ b/test/fixtures/console-output.txt @@ -1,22 +1,3 @@ -+-----------------------|------------|----------------+ -| Name | Total Deps | 1st Level Deps | -+-----------------------|------------|----------------+ -| simplecov-console | 8 | 3 | -| codecov | 4 | 1 | -| rails_stats | 4 | 2 | -| simplecov | 3 | 3 | -| minitest-around | 1 | 1 | -| bundler | 0 | 0 | -| byebug | 0 | 0 | -| minitest | 0 | 0 | -| minitest-spec-context | 0 | 0 | -+-----------------------|------------|----------------+ - - Declared Gems 9 - Total Gems 18 - Unpinned Versions 6 - Github Refs 0 - +----------------------+---------+---------+---------+---------+---------+-----+-------+ | Name | Files | Lines | LOC | Classes | Methods | M/C | LOC/M | +----------------------+---------+---------+---------+---------+---------+-----+-------+ diff --git a/test/lib/rails_stats/code_statistics_test.rb b/test/lib/rails_stats/code_statistics_test.rb index 2af4d7c..a2769a4 100644 --- a/test/lib/rails_stats/code_statistics_test.rb +++ b/test/lib/rails_stats/code_statistics_test.rb @@ -8,16 +8,13 @@ describe "#to_s" do it "outputs useful stats for a Rails project" do root_directory = File.expand_path('../../../test/dummy', File.dirname(__FILE__)) - table = File.read(File.expand_path('../../../fixtures/console-output.txt', __FILE__)) + expected_table = File.read(File.expand_path('../../../fixtures/console-output.txt', __FILE__)) - out, err = capture_io do - RailsStats::CodeStatistics.new(root_directory).to_s - end + expected_bundler_table, _ = capture_io { Bundler::Stats::CLI.start } - assert_equal( - table.lines.map(&:rstrip).join, - out.lines.map(&:rstrip).join - ) + output, _ = capture_io { RailsStats::CodeStatistics.new(root_directory).to_s } + + assert_equal([expected_bundler_table, expected_table].join, output) end end end diff --git a/test/lib/rails_stats/json_formatter_test.rb b/test/lib/rails_stats/json_formatter_test.rb index 8bce6ba..7a7c9cd 100644 --- a/test/lib/rails_stats/json_formatter_test.rb +++ b/test/lib/rails_stats/json_formatter_test.rb @@ -4,290 +4,84 @@ describe RailsStats::JSONFormatter do describe "#result" do - JSON_STRING = <<~EOS - [{ - "summary": { - "declared": 9, - "unpinned": 6, - "total": 18, - "github": 0 - }, - "gems": [ - { - "name": "simplecov-console", - "total_dependencies": 8, - "first_level_dependencies": 3, - "top_level_dependencies": {}, - "transitive_dependencies": [ - "ansi (>= 0)", - "simplecov (>= 0)", - "terminal-table (>= 0)", - "docile (~> 1.1)", - "simplecov-html (~> 0.11)", - "simplecov_json_formatter (~> 0.1)", - "unicode-display_width (>= 1.1.1, < 4)", - "unicode-emoji (~> 4.0, >= 4.0.4)" - ] - }, - { - "name": "codecov", - "total_dependencies": 4, - "first_level_dependencies": 1, - "top_level_dependencies": {}, - "transitive_dependencies": [ - "simplecov (>= 0.15, < 0.22)", - "docile (~> 1.1)", - "simplecov-html (~> 0.11)", - "simplecov_json_formatter (~> 0.1)" - ] - }, - { - "name": "rails_stats", - "total_dependencies": 4, - "first_level_dependencies": 2, - "top_level_dependencies": {}, - "transitive_dependencies": [ - "bundler-stats (>= 2.1)", - "rake (>= 0)", - "bundler (>= 1.9, < 3)", - "thor (>= 0.19.0, < 2.0)" - ] - }, - { - "name": "simplecov", - "total_dependencies": 3, - "first_level_dependencies": 3, - "top_level_dependencies": { - "codecov": "codecov (0.6.0)", - "simplecov-console": "simplecov-console (0.9.3)" - }, - "transitive_dependencies": [ - "docile (~> 1.1)", - "simplecov-html (~> 0.11)", - "simplecov_json_formatter (~> 0.1)" - ] - }, - { - "name": "minitest-around", - "total_dependencies": 1, - "first_level_dependencies": 1, - "top_level_dependencies": {}, - "transitive_dependencies": [ - "minitest (~> 5.0)" - ] - }, - { - "name": "bundler", - "total_dependencies": 0, - "first_level_dependencies": 0, - "top_level_dependencies": { - "bundler-stats": "bundler-stats (2.4.0)", - "rails_stats": "rails_stats (2.0.1)" - }, - "transitive_dependencies": [] - }, - { - "name": "byebug", - "total_dependencies": 0, - "first_level_dependencies": 0, - "top_level_dependencies": {}, - "transitive_dependencies": [] - }, - { - "name": "minitest", - "total_dependencies": 0, - "first_level_dependencies": 0, - "top_level_dependencies": { - "minitest-around": "minitest-around (0.5.0)" - }, - "transitive_dependencies": [] - }, - { - "name": "minitest-spec-context", - "total_dependencies": 0, - "first_level_dependencies": 0, - "top_level_dependencies": {}, - "transitive_dependencies": [] - } - ] - },{ - "name": "Mailers", - "files": "1", - "lines": "4", - "loc": "4", - "classes": "1", - "methods": "0", - "m_over_c": "0", - "loc_over_m": "0" - }, { - "name": "Helpers", - "files": "1", - "lines": "3", - "loc": "3", - "classes": "0", - "methods": "0", - "m_over_c": "0", - "loc_over_m": "0" - }, { - "name": "Jobs", - "files": "1", - "lines": "7", - "loc": "2", - "classes": "1", - "methods": "0", - "m_over_c": "0", - "loc_over_m": "0" - }, { - "name": "Controllers", - "files": "1", - "lines": "7", - "loc": "6", - "classes": "1", - "methods": "1", - "m_over_c": "1", - "loc_over_m": "4" - }, { - "name": "Models", - "files": "4", - "lines": "10", - "loc": "10", - "classes": "4", - "methods": "0", - "m_over_c": "0", - "loc_over_m": "0" - }, { - "name": "Channels", - "files": "2", - "lines": "8", - "loc": "8", - "classes": "2", - "methods": "0", - "m_over_c": "0", - "loc_over_m": "0" - }, { - "name": "Javascripts", - "files": "6", - "lines": "28", - "loc": "7", - "classes": "0", - "methods": "0", - "m_over_c": "0", - "loc_over_m": "0" - }, { - "name": "Libraries", - "files": "1", - "lines": "1", - "loc": "1", - "classes": "0", - "methods": "0", - "m_over_c": "0", - "loc_over_m": "0" - }, { - "name": "Configuration", - "files": "19", - "lines": "417", - "loc": "111", - "classes": "1", - "methods": "0", - "m_over_c": "0", - "loc_over_m": "0" - }, { - "name": "Model Tests", - "files": "2", - "lines": "5", - "loc": "4", - "classes": "2", - "methods": "0", - "m_over_c": "0", - "loc_over_m": "0" - }, { - "name": "Spec Support", - "files": "1", - "lines": "1", - "loc": "1", - "classes": "0", - "methods": "0", - "m_over_c": "0", - "loc_over_m": "0" - }, { - "name": "Test Support", - "files": "1", - "lines": "1", - "loc": "1", - "classes": "0", - "methods": "0", - "m_over_c": "0", - "loc_over_m": "0" - }, { - "name": "Code", - "files": "36", - "lines": "485", - "loc": "152", - "classes": "10", - "methods": "1", - "m_over_c": "0", - "loc_over_m": "150", - "code_to_test_ratio": "0.0", - "total": true - }, { - "name": "Tests", - "files": "4", - "lines": "7", - "loc": "6", - "classes": "2", - "methods": "0", - "m_over_c": "0", - "loc_over_m": "0", - "code_to_test_ratio": "0.0", - "total": true - }, { - "name": "Total", - "files": "40", - "lines": "492", - "loc": "158", - "classes": "12", - "methods": "1", - "m_over_c": "0", - "loc_over_m": "156", - "code_to_test_ratio": "0.0", - "total": true}, - {"schema_stats": - {"schema_path": - "#{Dir.pwd}/test/dummy/db/schema.rb", - "create_table calls count": 2}}, - {"polymorphic_stats": {"polymorphic_models_count": 1} - } - ] - EOS + def code_stat(name, files:, lines:, loc:, classes:, methods: "0", m_over_c: "0", loc_over_m: "0") + {"name"=>name, "files"=>files, "lines"=>lines, "loc"=>loc, + "classes"=>classes, "methods"=>methods, "m_over_c"=>m_over_c, "loc_over_m"=>loc_over_m} + end + + def total_stat(name, files:, lines:, loc:, classes:, methods: "0", m_over_c: "0", loc_over_m: "0", code_to_test_ratio: "0.0") + code_stat(name, files: files, lines: lines, loc: loc, classes: classes, + methods: methods, m_over_c: m_over_c, loc_over_m: loc_over_m) + .merge("code_to_test_ratio" => code_to_test_ratio, "total" => true) + end + + EXPECTED_GEM_NAMES = %w[ + simplecov-console codecov rails_stats simplecov minitest-around + bundler byebug minitest minitest-spec-context + ].freeze it "outputs useful stats for a Rails project" do root_directory = File.absolute_path("./test/dummy") calculator = RailsStats::StatsCalculator.new(root_directory) formatter = RailsStats::JSONFormatter.new(calculator) - - expectation = JSON.parse(JSON_STRING) result = formatter.result - [expectation, result].each do |data| - data.each do |hash| - next unless hash["gems"] - - hash["gems"].each do |gem| - next unless gem["transitive_dependencies"] + # Verify bundler-stats structure (without asserting on version-specific values) + gems_section = result.find { |h| h["gems"] } + assert gems_section, "Expected a gems section in the result" + assert gems_section["summary"], "Expected a summary in the gems section" + %w[declared unpinned total github].each do |key| + assert gems_section["summary"].key?(key), "Expected summary to have '#{key}'" + end - gem["transitive_dependencies"].map! do |dep| - name, constraints = dep.split(/[()]/) - next dep unless constraints + gem_names = gems_section["gems"].map { |g| g["name"] } + assert_equal EXPECTED_GEM_NAMES.sort, gem_names.sort - normalized_constraints = constraints.split(/,\s*/).sort.join(', ') - "#{name}(#{normalized_constraints})" - end.sort! - end + gems_section["gems"].each do |gem| + %w[name total_dependencies first_level_dependencies top_level_dependencies transitive_dependencies].each do |key| + assert gem.key?(key), "Expected gem '#{gem["name"]}' to have '#{key}'" end end - assert_equal expectation, result + # Verify code stats (these are stable across Ruby versions) + expected_code_stats = [ + code_stat("Mailers", files: "1", lines: "4", loc: "4", classes: "1"), + code_stat("Models", files: "4", lines: "10", loc: "10", classes: "4"), + code_stat("Controllers", files: "1", lines: "7", loc: "6", classes: "1", methods: "1", m_over_c: "1", loc_over_m: "4"), + code_stat("Helpers", files: "1", lines: "3", loc: "3", classes: "0"), + code_stat("Jobs", files: "1", lines: "7", loc: "2", classes: "1"), + code_stat("Channels", files: "2", lines: "8", loc: "8", classes: "2"), + code_stat("Javascripts", files: "6", lines: "28", loc: "7", classes: "0"), + code_stat("Libraries", files: "1", lines: "1", loc: "1", classes: "0"), + code_stat("Configuration", files: "19", lines: "417", loc: "111", classes: "1"), + code_stat("Model Tests", files: "2", lines: "5", loc: "4", classes: "2"), + code_stat("Spec Support", files: "1", lines: "1", loc: "1", classes: "0"), + code_stat("Test Support", files: "1", lines: "1", loc: "1", classes: "0"), + ] + + code_stats = result.select { |h| h["name"] && !h["total"] } + assert_equal expected_code_stats.sort_by { |h| h["name"] }, code_stats.sort_by { |h| h["name"] } + + # Verify totals + expected_totals = [ + total_stat("Code", files: "36", lines: "485", loc: "152", classes: "10", methods: "1", loc_over_m: "150"), + total_stat("Tests", files: "4", lines: "7", loc: "6", classes: "2"), + total_stat("Total", files: "40", lines: "492", loc: "158", classes: "12", methods: "1", loc_over_m: "156"), + ] + + totals = result.select { |h| h["total"] } + assert_equal expected_totals.sort_by { |h| h["name"] }, totals.sort_by { |h| h["name"] } + + # Verify schema and polymorphic stats + schema_stats = result.find { |h| h["schema_stats"] } + assert schema_stats, "Expected schema_stats in result" + assert_equal "#{Dir.pwd}/test/dummy/db/schema.rb", schema_stats["schema_stats"]["schema_path"] + assert_equal 2, schema_stats["schema_stats"]["create_table calls count"] + + polymorphic_stats = result.find { |h| h["polymorphic_stats"] } + assert polymorphic_stats, "Expected polymorphic_stats in result" + assert_equal 1, polymorphic_stats["polymorphic_stats"]["polymorphic_models_count"] end end end