diff --git a/CHANGELOG.md b/CHANGELOG.md index e39a04e..e144329 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ * [BUGFIX: Fix JSON output missing Code and Tests total count](https://github.com/fastruby/rails_stats/pull/40) * Update README examples +* [FEATURE: Output number of tables created from schema.rb or structure.sql, add polymorphic models count](https://github.com/fastruby/rails_stats/pull/37) # v2.0.1 ([commits](https://github.com/fastruby/rails_stats/compare/v2.0.0...v2.0.1)) diff --git a/lib/rails_stats/console_formatter.rb b/lib/rails_stats/console_formatter.rb index 990b726..e12fae1 100644 --- a/lib/rails_stats/console_formatter.rb +++ b/lib/rails_stats/console_formatter.rb @@ -18,6 +18,8 @@ def to_s end print_code_test_stats + print_polymorphic_stats + print_schema_stats end private @@ -53,5 +55,19 @@ def print_code_test_stats puts " Code LOC: #{code} Test LOC: #{tests} Code to Test Ratio: 1:#{sprintf("%.1f", tests.to_f/code)} Files: #{calculator.files_total}" puts "" end + + def print_polymorphic_stats + puts " Polymorphic models count: #{calculator.polymorphic} polymorphic associations" + end + + def print_schema_stats + if File.exist?(calculator.schema_path) + puts " Schema Stats: #{calculator.schema} `create_table` calls in schema.rb" + elsif File.exist?(calculator.structure_path) + puts " Schema Stats: #{calculator.schema} `CREATE TABLE` calls in structure.sql" + else + puts " Schema Stats: No schema.rb or structure.sql file found" + end + end end end \ No newline at end of file diff --git a/lib/rails_stats/json_formatter.rb b/lib/rails_stats/json_formatter.rb index a0ad8b0..cb1f1d2 100644 --- a/lib/rails_stats/json_formatter.rb +++ b/lib/rails_stats/json_formatter.rb @@ -17,6 +17,9 @@ def result @result << stat_hash("Tests", @tests_total).merge(code_test_hash) if @tests_total @result << stat_hash("Total", @grand_total).merge(code_test_hash) if @grand_total + @result << { "schema_stats" => schema_info } + @result << { "polymorphic_stats" => print_polymorphic_stats } + @result end @@ -50,5 +53,29 @@ def stat_hash(name, statistics) "loc_over_m" => loc_over_m.to_s } end + + def print_polymorphic_stats + if calculator.polymorphic + { + "polymorphic_models_count" => calculator.polymorphic, + } + end + end + + def schema_info + if File.exist?(calculator.schema_path) + { + "schema_path" => calculator.schema_path, + "create_table calls count" => calculator.schema, + } + elsif File.exist?(calculator.structure_path) + { + "structure_path" => calculator.structure_path, + "create_table calls count" => calculator.schema + } + else + { "schema_stats" => "No schema.rb or structure.sql file found" } + end + end end -end \ No newline at end of file +end diff --git a/lib/rails_stats/stats_calculator.rb b/lib/rails_stats/stats_calculator.rb index 773ec14..f8c283e 100644 --- a/lib/rails_stats/stats_calculator.rb +++ b/lib/rails_stats/stats_calculator.rb @@ -9,15 +9,19 @@ class StatsCalculator def initialize(root_directory) @root_directory = root_directory + @schema_path = File.join(@root_directory, "db", "schema.rb") + @structure_path = File.join(@root_directory, "db", "structure.sql") @key_concepts = calculate_key_concepts @projects = calculate_projects @statistics = calculate_statistics @code_loc = calculate_code @test_loc = calculate_tests + @schema = calculate_create_table_calls + @polymorphic = calculate_polymorphic @files_total, @code_total, @tests_total, @grand_total = calculate_totals end - attr_reader :code_loc, :code_total, :files_total, :grand_total, :statistics, :test_loc, :tests_total + attr_reader :code_loc, :code_total, :files_total, :grand_total, :statistics, :test_loc, :tests_total, :schema, :schema_path, :structure_path, :polymorphic private @@ -46,7 +50,6 @@ def calculate_projects out end - def app_projects @app_projects ||= calculate_app_projects end @@ -79,7 +82,6 @@ def calculate_test_projects end end - def calculate_root_projects [RootStatistics.new(@root_directory)] end @@ -133,5 +135,35 @@ def calculate_tests @statistics.each { |k, v| @test_loc += v.code_lines if v.test } @test_loc end + + def calculate_create_table_calls + if @schema_path && File.exist?(@schema_path) + count_create_table_calls(schema_path, "create_table") + elsif @structure_path && File.exist?(@structure_path) + count_create_table_calls(structure_path, "CREATE TABLE") + else + 0 + end + end + + def count_create_table_calls(file_path, keyword) + create_table_count = 0 + File.foreach(file_path) do |line| + create_table_count += 1 if line.strip.start_with?(keyword) + end + create_table_count + end + + def calculate_polymorphic + polymorphic_count = 0 + Dir.glob(File.join(@root_directory, "app", "models", "*.rb")).each do |file| + File.foreach(file) do |line| + if line =~ /belongs_to\s+:\w+,\s+polymorphic:\s+true/ + polymorphic_count += 1 + end + end + end + polymorphic_count + end end end \ No newline at end of file diff --git a/test/dummy/app/models/comment.rb b/test/dummy/app/models/comment.rb new file mode 100644 index 0000000..46abe97 --- /dev/null +++ b/test/dummy/app/models/comment.rb @@ -0,0 +1,3 @@ +class Comments < ApplicationRecord + belongs_to :commentable, polymorphic: true +end diff --git a/test/dummy/app/models/pet.rb b/test/dummy/app/models/pet.rb new file mode 100644 index 0000000..667f211 --- /dev/null +++ b/test/dummy/app/models/pet.rb @@ -0,0 +1,2 @@ +class Pets < User +end diff --git a/test/dummy/app/models/user.rb b/test/dummy/app/models/user.rb new file mode 100644 index 0000000..6537292 --- /dev/null +++ b/test/dummy/app/models/user.rb @@ -0,0 +1,2 @@ +class Users < ApplicationRecord +end diff --git a/test/dummy/db/schema.rb b/test/dummy/db/schema.rb new file mode 100644 index 0000000..e61cdad --- /dev/null +++ b/test/dummy/db/schema.rb @@ -0,0 +1,10 @@ + +ActiveRecord::Schema[7.0].define(version: 2023_04_25_154701) do + create_table "users", force: :cascade do |t| + t.string "email" + end + create_table "comments", force: :cascade do |t| + t.bigint :commentable_id + t.string :commentable_type + end +end diff --git a/test/fixtures/console-output.txt b/test/fixtures/console-output.txt index 5069d28..cda0301 100644 --- a/test/fixtures/console-output.txt +++ b/test/fixtures/console-output.txt @@ -21,7 +21,7 @@ | Name | Files | Lines | LOC | Classes | Methods | M/C | LOC/M | +----------------------+---------+---------+---------+---------+---------+-----+-------+ | Channels | 2 | 8 | 8 | 2 | 0 | 0 | 0 | -| Configuration | 19 | 417 | 111 | 1 | 0 | 0 | 0 | +| Configuration | 19 | 417 | 111 | 1 | 0 | 0 | 0 | | Controllers | 1 | 7 | 6 | 1 | 1 | 1 | 4 | | Helpers | 1 | 3 | 3 | 0 | 0 | 0 | 0 | | Javascripts | 3 | 27 | 7 | 0 | 0 | 0 | 0 | @@ -29,12 +29,15 @@ | Libraries | 1 | 1 | 1 | 0 | 0 | 0 | 0 | | Mailers | 1 | 4 | 4 | 1 | 0 | 0 | 0 | | Model Tests | 2 | 5 | 4 | 2 | 0 | 0 | 0 | -| Models | 1 | 3 | 3 | 1 | 0 | 0 | 0 | +| Models | 4 | 10 | 10 | 4 | 0 | 0 | 0 | | Spec Support | 1 | 1 | 1 | 0 | 0 | 0 | 0 | | Test Support | 1 | 1 | 1 | 0 | 0 | 0 | 0 | +----------------------+---------+---------+---------+---------+---------+-----+-------+ -| Code | 30 | 477 | 145 | 7 | 1 | 0 | 143 | +| Code | 33 | 484 | 152 | 10 | 1 | 0 | 150 | | Tests | 4 | 7 | 6 | 2 | 0 | 0 | 0 | -| Total | 34 | 484 | 151 | 9 | 1 | 0 | 149 | +| Total | 37 | 491 | 158 | 12 | 1 | 0 | 156 | +----------------------+---------+---------+---------+---------+---------+-----+-------+ - Code LOC: 145 Test LOC: 6 Code to Test Ratio: 1:0.0 Files: 34 \ No newline at end of file + Code LOC: 152 Test LOC: 6 Code to Test Ratio: 1:0.0 Files: 37 + + Polymorphic models count: 1 polymorphic associations + Schema Stats: 2 `create_table` calls in schema.rb diff --git a/test/lib/rails_stats/code_statistics_test.rb b/test/lib/rails_stats/code_statistics_test.rb index bb50052..2af4d7c 100644 --- a/test/lib/rails_stats/code_statistics_test.rb +++ b/test/lib/rails_stats/code_statistics_test.rb @@ -14,7 +14,10 @@ RailsStats::CodeStatistics.new(root_directory).to_s end - assert_equal table, out + assert_equal( + table.lines.map(&:rstrip).join, + out.lines.map(&:rstrip).join + ) end end end diff --git a/test/lib/rails_stats/json_formatter_test.rb b/test/lib/rails_stats/json_formatter_test.rb index f47e228..0f5b0f6 100644 --- a/test/lib/rails_stats/json_formatter_test.rb +++ b/test/lib/rails_stats/json_formatter_test.rb @@ -110,148 +110,154 @@ "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": "1", - "lines": "3", - "loc": "3", - "classes": "1", - "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": "3", - "lines": "27", - "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": "30", - "lines": "477", - "loc": "145", - "classes": "7", - "methods": "1", - "m_over_c": "0", - "loc_over_m": "143", - "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": "34", - "lines": "484", - "loc": "151", - "classes": "9", - "methods": "1", - "m_over_c": "0", - "loc_over_m": "149", - "code_to_test_ratio": "0.0", - "total": true - }] + },{ + "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": "3", + "lines": "27", + "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": "33", + "lines": "484", + "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": "37", + "lines": "491", + "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 it "outputs useful stats for a Rails project" do @@ -284,4 +290,4 @@ assert_equal expectation, result end end -end \ No newline at end of file +end