rails_stats 2.0.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +23 -15
- data/CHANGELOG.md +18 -3
- data/Gemfile +2 -2
- data/README.md +224 -232
- data/bin/rails-stats +27 -0
- data/lib/rails_stats/all.rb +8 -0
- data/lib/rails_stats/app_statistics.rb +1 -1
- data/lib/rails_stats/code_statistics_calculator.rb +18 -0
- data/lib/rails_stats/console_formatter.rb +60 -12
- data/lib/rails_stats/cucumber_statistics.rb +1 -1
- data/lib/rails_stats/gem_statistics.rb +1 -1
- data/lib/rails_stats/json_formatter.rb +59 -6
- data/lib/rails_stats/pack_finder.rb +67 -0
- data/lib/rails_stats/root_statistics.rb +1 -1
- data/lib/rails_stats/spec_statistics.rb +1 -1
- data/lib/rails_stats/stats_calculator.rb +135 -5
- data/lib/rails_stats/stats_formatter.rb +1 -0
- data/lib/rails_stats/tasks.rb +4 -1
- data/lib/rails_stats/test_statistics.rb +1 -1
- data/lib/rails_stats/util.rb +10 -2
- data/lib/rails_stats/version.rb +1 -1
- data/rails_stats.gemspec +4 -3
- data/test/dummy/app/javascript/dummy.jsx +1 -0
- data/test/dummy/app/javascript/dummy.tsx +0 -0
- data/test/dummy/app/javascript/index.ts +0 -0
- data/test/dummy/app/models/comment.rb +3 -0
- data/test/dummy/app/models/pet.rb +2 -0
- data/test/dummy/app/models/user.rb +2 -0
- data/test/dummy/db/schema.rb +10 -0
- data/test/fixtures/console-output.txt +8 -24
- data/test/fixtures/packwerk_app/app/controllers/core_controller.rb +4 -0
- data/test/fixtures/packwerk_app/app/models/core_model.rb +5 -0
- data/test/fixtures/packwerk_app/components/billing/app/models/billing_model.rb +4 -0
- data/test/fixtures/packwerk_app/components/billing/lib/billing.rb +2 -0
- data/test/fixtures/packwerk_app/lib/core_lib.rb +3 -0
- data/test/fixtures/packwerk_app/package.yml +1 -0
- data/test/fixtures/packwerk_app/packs/pack1/app/controllers/pack1_controller.rb +4 -0
- data/test/fixtures/packwerk_app/packs/pack1/app/models/pack1_model.rb +6 -0
- data/test/fixtures/packwerk_app/packs/pack1/lib/pack1_lib.rb +2 -0
- data/test/fixtures/packwerk_app/packs/pack1/package.yml +3 -0
- data/test/fixtures/packwerk_app/packs/pack1/spec/models/pack1_model_spec.rb +4 -0
- data/test/fixtures/packwerk_app/packs/pack2/app/models/pack2_model.rb +4 -0
- data/test/fixtures/packwerk_app/packs/pack2/test/models/pack2_model_test.rb +4 -0
- data/test/lib/rails_stats/code_statistics_test.rb +5 -5
- data/test/lib/rails_stats/console_formatter_test.rb +48 -0
- data/test/lib/rails_stats/json_formatter_test.rb +70 -127
- data/test/lib/rails_stats/pack_finder_test.rb +29 -0
- data/test/lib/rails_stats/stats_calculator_test.rb +64 -0
- data/test/lib/rails_stats/util_test.rb +49 -0
- metadata +56 -3
|
@@ -1,22 +1,3 @@
|
|
|
1
|
-
+-----------------------|------------|----------------+
|
|
2
|
-
| Name | Total Deps | 1st Level Deps |
|
|
3
|
-
+-----------------------|------------|----------------+
|
|
4
|
-
| simplecov-console | 7 | 3 |
|
|
5
|
-
| codecov | 5 | 2 |
|
|
6
|
-
| rails_stats | 4 | 2 |
|
|
7
|
-
| simplecov | 3 | 3 |
|
|
8
|
-
| minitest-around | 1 | 1 |
|
|
9
|
-
| bundler | 0 | 0 |
|
|
10
|
-
| byebug | 0 | 0 |
|
|
11
|
-
| minitest | 0 | 0 |
|
|
12
|
-
| minitest-spec-context | 0 | 0 |
|
|
13
|
-
+-----------------------|------------|----------------+
|
|
14
|
-
|
|
15
|
-
Declared Gems 9
|
|
16
|
-
Total Gems 18
|
|
17
|
-
Unpinned Versions 8
|
|
18
|
-
Github Refs 0
|
|
19
|
-
|
|
20
1
|
+----------------------+---------+---------+---------+---------+---------+-----+-------+
|
|
21
2
|
| Name | Files | Lines | LOC | Classes | Methods | M/C | LOC/M |
|
|
22
3
|
+----------------------+---------+---------+---------+---------+---------+-----+-------+
|
|
@@ -24,17 +5,20 @@
|
|
|
24
5
|
| Configuration | 19 | 417 | 111 | 1 | 0 | 0 | 0 |
|
|
25
6
|
| Controllers | 1 | 7 | 6 | 1 | 1 | 1 | 4 |
|
|
26
7
|
| Helpers | 1 | 3 | 3 | 0 | 0 | 0 | 0 |
|
|
27
|
-
| Javascripts |
|
|
8
|
+
| Javascripts | 6 | 28 | 7 | 0 | 0 | 0 | 0 |
|
|
28
9
|
| Jobs | 1 | 7 | 2 | 1 | 0 | 0 | 0 |
|
|
29
10
|
| Libraries | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
|
|
30
11
|
| Mailers | 1 | 4 | 4 | 1 | 0 | 0 | 0 |
|
|
31
12
|
| Model Tests | 2 | 5 | 4 | 2 | 0 | 0 | 0 |
|
|
32
|
-
| Models |
|
|
13
|
+
| Models | 4 | 10 | 10 | 4 | 0 | 0 | 0 |
|
|
33
14
|
| Spec Support | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
|
|
34
15
|
| Test Support | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
|
|
35
16
|
+----------------------+---------+---------+---------+---------+---------+-----+-------+
|
|
36
|
-
| Code |
|
|
17
|
+
| Code | 36 | 485 | 152 | 10 | 1 | 0 | 150 |
|
|
37
18
|
| Tests | 4 | 7 | 6 | 2 | 0 | 0 | 0 |
|
|
38
|
-
| Total |
|
|
19
|
+
| Total | 40 | 492 | 158 | 12 | 1 | 0 | 156 |
|
|
39
20
|
+----------------------+---------+---------+---------+---------+---------+-----+-------+
|
|
40
|
-
Code LOC:
|
|
21
|
+
Code LOC: 152 Test LOC: 6 Code to Test Ratio: 1:0.0 Files: 40
|
|
22
|
+
|
|
23
|
+
Polymorphic models count: 1 polymorphic associations
|
|
24
|
+
Schema Stats: 2 `create_table` calls in schema.rb
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
enforce_dependencies: true
|
|
@@ -8,13 +8,13 @@ describe RailsStats::CodeStatistics do
|
|
|
8
8
|
describe "#to_s" do
|
|
9
9
|
it "outputs useful stats for a Rails project" do
|
|
10
10
|
root_directory = File.expand_path('../../../test/dummy', File.dirname(__FILE__))
|
|
11
|
-
|
|
11
|
+
expected_table = File.read(File.expand_path('../../../fixtures/console-output.txt', __FILE__))
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
RailsStats::CodeStatistics.new(root_directory).to_s
|
|
15
|
-
end
|
|
13
|
+
expected_bundler_table, _ = capture_io { Bundler::Stats::CLI.start }
|
|
16
14
|
|
|
17
|
-
|
|
15
|
+
output, _ = capture_io { RailsStats::CodeStatistics.new(root_directory).to_s }
|
|
16
|
+
|
|
17
|
+
assert_equal([expected_bundler_table, expected_table].join, output)
|
|
18
18
|
end
|
|
19
19
|
end
|
|
20
20
|
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'test_helper'
|
|
4
|
+
|
|
5
|
+
describe RailsStats::ConsoleFormatter do
|
|
6
|
+
describe '#to_s' do
|
|
7
|
+
it 'invokes Bundler::Stats::CLI with text format' do
|
|
8
|
+
root_directory = File.absolute_path('./test/dummy')
|
|
9
|
+
calculator = RailsStats::StatsCalculator.new(root_directory)
|
|
10
|
+
formatter = RailsStats::ConsoleFormatter.new(calculator)
|
|
11
|
+
|
|
12
|
+
received_args = nil
|
|
13
|
+
original = Bundler::Stats::CLI.method(:start)
|
|
14
|
+
Bundler::Stats::CLI.define_singleton_method(:start) { |args = []| received_args = args }
|
|
15
|
+
|
|
16
|
+
begin
|
|
17
|
+
capture_io { formatter.to_s }
|
|
18
|
+
ensure
|
|
19
|
+
Bundler::Stats::CLI.singleton_class.remove_method(:start)
|
|
20
|
+
Bundler::Stats::CLI.define_singleton_method(:start, original)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
assert_equal ['--format', 'text'], received_args
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'prints a section per pack plus a Core and a grand total for packwerk apps' do
|
|
27
|
+
root_directory = File.absolute_path('./test/fixtures/packwerk_app')
|
|
28
|
+
calculator = RailsStats::StatsCalculator.new(root_directory)
|
|
29
|
+
formatter = RailsStats::ConsoleFormatter.new(calculator)
|
|
30
|
+
|
|
31
|
+
original = Bundler::Stats::CLI.method(:start)
|
|
32
|
+
Bundler::Stats::CLI.define_singleton_method(:start) { |args = []| nil }
|
|
33
|
+
|
|
34
|
+
begin
|
|
35
|
+
output, _ = capture_io { formatter.to_s }
|
|
36
|
+
ensure
|
|
37
|
+
Bundler::Stats::CLI.singleton_class.remove_method(:start)
|
|
38
|
+
Bundler::Stats::CLI.define_singleton_method(:start, original)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
assert_includes output, '== Core Application =='
|
|
42
|
+
assert_includes output, '== Pack: packs/pack1 =='
|
|
43
|
+
assert_includes output, '== Pack: packs/pack2 =='
|
|
44
|
+
assert_includes output, '== Pack: components/billing =='
|
|
45
|
+
assert_includes output, '== Total (all packs) =='
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -4,141 +4,84 @@ require "test_helper"
|
|
|
4
4
|
|
|
5
5
|
describe RailsStats::JSONFormatter do
|
|
6
6
|
describe "#result" do
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
"classes": "1",
|
|
23
|
-
"methods": "0",
|
|
24
|
-
"m_over_c": "0",
|
|
25
|
-
"loc_over_m": "0"
|
|
26
|
-
}, {
|
|
27
|
-
"name": "Model Tests",
|
|
28
|
-
"files": "2",
|
|
29
|
-
"lines": "5",
|
|
30
|
-
"loc": "4",
|
|
31
|
-
"classes": "2",
|
|
32
|
-
"methods": "0",
|
|
33
|
-
"m_over_c": "0",
|
|
34
|
-
"loc_over_m": "0"
|
|
35
|
-
}, {
|
|
36
|
-
"name": "Models",
|
|
37
|
-
"files": "1",
|
|
38
|
-
"lines": "3",
|
|
39
|
-
"loc": "3",
|
|
40
|
-
"classes": "1",
|
|
41
|
-
"methods": "0",
|
|
42
|
-
"m_over_c": "0",
|
|
43
|
-
"loc_over_m": "0"
|
|
44
|
-
}, {
|
|
45
|
-
"name": "Javascripts",
|
|
46
|
-
"files": "3",
|
|
47
|
-
"lines": "27",
|
|
48
|
-
"loc": "7",
|
|
49
|
-
"classes": "0",
|
|
50
|
-
"methods": "0",
|
|
51
|
-
"m_over_c": "0",
|
|
52
|
-
"loc_over_m": "0"
|
|
53
|
-
}, {
|
|
54
|
-
"name": "Jobs",
|
|
55
|
-
"files": "1",
|
|
56
|
-
"lines": "7",
|
|
57
|
-
"loc": "2",
|
|
58
|
-
"classes": "1",
|
|
59
|
-
"methods": "0",
|
|
60
|
-
"m_over_c": "0",
|
|
61
|
-
"loc_over_m": "0"
|
|
62
|
-
}, {
|
|
63
|
-
"name": "Controllers",
|
|
64
|
-
"files": "1",
|
|
65
|
-
"lines": "7",
|
|
66
|
-
"loc": "6",
|
|
67
|
-
"classes": "1",
|
|
68
|
-
"methods": "1",
|
|
69
|
-
"m_over_c": "1",
|
|
70
|
-
"loc_over_m": "4"
|
|
71
|
-
}, {
|
|
72
|
-
"name": "Helpers",
|
|
73
|
-
"files": "1",
|
|
74
|
-
"lines": "3",
|
|
75
|
-
"loc": "3",
|
|
76
|
-
"classes": "0",
|
|
77
|
-
"methods": "0",
|
|
78
|
-
"m_over_c": "0",
|
|
79
|
-
"loc_over_m": "0"
|
|
80
|
-
}, {
|
|
81
|
-
"name": "Channels",
|
|
82
|
-
"files": "2",
|
|
83
|
-
"lines": "8",
|
|
84
|
-
"loc": "8",
|
|
85
|
-
"classes": "2",
|
|
86
|
-
"methods": "0",
|
|
87
|
-
"m_over_c": "0",
|
|
88
|
-
"loc_over_m": "0"
|
|
89
|
-
}, {
|
|
90
|
-
"name": "Configuration",
|
|
91
|
-
"files": "19",
|
|
92
|
-
"lines": "417",
|
|
93
|
-
"loc": "111",
|
|
94
|
-
"classes": "1",
|
|
95
|
-
"methods": "0",
|
|
96
|
-
"m_over_c": "0",
|
|
97
|
-
"loc_over_m": "0"
|
|
98
|
-
}, {
|
|
99
|
-
"name": "Spec Support",
|
|
100
|
-
"files": "1",
|
|
101
|
-
"lines": "1",
|
|
102
|
-
"loc": "1",
|
|
103
|
-
"classes": "0",
|
|
104
|
-
"methods": "0",
|
|
105
|
-
"m_over_c": "0",
|
|
106
|
-
"loc_over_m": "0"
|
|
107
|
-
}, {
|
|
108
|
-
"name": "Test Support",
|
|
109
|
-
"files": "1",
|
|
110
|
-
"lines": "1",
|
|
111
|
-
"loc": "1",
|
|
112
|
-
"classes": "0",
|
|
113
|
-
"methods": "0",
|
|
114
|
-
"m_over_c": "0",
|
|
115
|
-
"loc_over_m": "0"
|
|
116
|
-
}, {
|
|
117
|
-
"name": "Total",
|
|
118
|
-
"files": "34",
|
|
119
|
-
"lines": "484",
|
|
120
|
-
"loc": "151",
|
|
121
|
-
"classes": "9",
|
|
122
|
-
"methods": "1",
|
|
123
|
-
"m_over_c": "0",
|
|
124
|
-
"loc_over_m": "149",
|
|
125
|
-
"code_to_test_ratio": "0.0",
|
|
126
|
-
"total": true
|
|
127
|
-
}]
|
|
128
|
-
EOS
|
|
7
|
+
def code_stat(name, files:, lines:, loc:, classes:, methods: "0", m_over_c: "0", loc_over_m: "0")
|
|
8
|
+
{"name"=>name, "files"=>files, "lines"=>lines, "loc"=>loc,
|
|
9
|
+
"classes"=>classes, "methods"=>methods, "m_over_c"=>m_over_c, "loc_over_m"=>loc_over_m}
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def total_stat(name, files:, lines:, loc:, classes:, methods: "0", m_over_c: "0", loc_over_m: "0", code_to_test_ratio: "0.0")
|
|
13
|
+
code_stat(name, files: files, lines: lines, loc: loc, classes: classes,
|
|
14
|
+
methods: methods, m_over_c: m_over_c, loc_over_m: loc_over_m)
|
|
15
|
+
.merge("code_to_test_ratio" => code_to_test_ratio, "total" => true)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
EXPECTED_GEM_NAMES = %w[
|
|
19
|
+
simplecov-console codecov rails_stats simplecov minitest-around
|
|
20
|
+
bundler byebug minitest minitest-spec-context
|
|
21
|
+
].freeze
|
|
129
22
|
|
|
130
23
|
it "outputs useful stats for a Rails project" do
|
|
131
24
|
root_directory = File.absolute_path("./test/dummy")
|
|
132
25
|
|
|
133
26
|
calculator = RailsStats::StatsCalculator.new(root_directory)
|
|
134
27
|
formatter = RailsStats::JSONFormatter.new(calculator)
|
|
28
|
+
result = formatter.result
|
|
29
|
+
|
|
30
|
+
# Verify bundler-stats structure (without asserting on version-specific values)
|
|
31
|
+
gems_section = result.find { |h| h["gems"] }
|
|
32
|
+
assert gems_section, "Expected a gems section in the result"
|
|
33
|
+
assert gems_section["summary"], "Expected a summary in the gems section"
|
|
34
|
+
%w[declared unpinned total github].each do |key|
|
|
35
|
+
assert gems_section["summary"].key?(key), "Expected summary to have '#{key}'"
|
|
36
|
+
end
|
|
135
37
|
|
|
136
|
-
|
|
137
|
-
|
|
38
|
+
gem_names = gems_section["gems"].map { |g| g["name"] }
|
|
39
|
+
assert_equal EXPECTED_GEM_NAMES.sort, gem_names.sort
|
|
138
40
|
|
|
139
|
-
|
|
140
|
-
|
|
41
|
+
gems_section["gems"].each do |gem|
|
|
42
|
+
%w[name total_dependencies first_level_dependencies top_level_dependencies transitive_dependencies].each do |key|
|
|
43
|
+
assert gem.key?(key), "Expected gem '#{gem["name"]}' to have '#{key}'"
|
|
44
|
+
end
|
|
141
45
|
end
|
|
46
|
+
|
|
47
|
+
# Verify code stats (these are stable across Ruby versions)
|
|
48
|
+
expected_code_stats = [
|
|
49
|
+
code_stat("Mailers", files: "1", lines: "4", loc: "4", classes: "1"),
|
|
50
|
+
code_stat("Models", files: "4", lines: "10", loc: "10", classes: "4"),
|
|
51
|
+
code_stat("Controllers", files: "1", lines: "7", loc: "6", classes: "1", methods: "1", m_over_c: "1", loc_over_m: "4"),
|
|
52
|
+
code_stat("Helpers", files: "1", lines: "3", loc: "3", classes: "0"),
|
|
53
|
+
code_stat("Jobs", files: "1", lines: "7", loc: "2", classes: "1"),
|
|
54
|
+
code_stat("Channels", files: "2", lines: "8", loc: "8", classes: "2"),
|
|
55
|
+
code_stat("Javascripts", files: "6", lines: "28", loc: "7", classes: "0"),
|
|
56
|
+
code_stat("Libraries", files: "1", lines: "1", loc: "1", classes: "0"),
|
|
57
|
+
code_stat("Configuration", files: "19", lines: "417", loc: "111", classes: "1"),
|
|
58
|
+
code_stat("Model Tests", files: "2", lines: "5", loc: "4", classes: "2"),
|
|
59
|
+
code_stat("Spec Support", files: "1", lines: "1", loc: "1", classes: "0"),
|
|
60
|
+
code_stat("Test Support", files: "1", lines: "1", loc: "1", classes: "0"),
|
|
61
|
+
]
|
|
62
|
+
|
|
63
|
+
code_stats = result.select { |h| h["name"] && !h["total"] }
|
|
64
|
+
assert_equal expected_code_stats.sort_by { |h| h["name"] }, code_stats.sort_by { |h| h["name"] }
|
|
65
|
+
|
|
66
|
+
# Verify totals
|
|
67
|
+
expected_totals = [
|
|
68
|
+
total_stat("Code", files: "36", lines: "485", loc: "152", classes: "10", methods: "1", loc_over_m: "150"),
|
|
69
|
+
total_stat("Tests", files: "4", lines: "7", loc: "6", classes: "2"),
|
|
70
|
+
total_stat("Total", files: "40", lines: "492", loc: "158", classes: "12", methods: "1", loc_over_m: "156"),
|
|
71
|
+
]
|
|
72
|
+
|
|
73
|
+
totals = result.select { |h| h["total"] }
|
|
74
|
+
assert_equal expected_totals.sort_by { |h| h["name"] }, totals.sort_by { |h| h["name"] }
|
|
75
|
+
|
|
76
|
+
# Verify schema and polymorphic stats
|
|
77
|
+
schema_stats = result.find { |h| h["schema_stats"] }
|
|
78
|
+
assert schema_stats, "Expected schema_stats in result"
|
|
79
|
+
assert_equal "#{Dir.pwd}/test/dummy/db/schema.rb", schema_stats["schema_stats"]["schema_path"]
|
|
80
|
+
assert_equal 2, schema_stats["schema_stats"]["create_table calls count"]
|
|
81
|
+
|
|
82
|
+
polymorphic_stats = result.find { |h| h["polymorphic_stats"] }
|
|
83
|
+
assert polymorphic_stats, "Expected polymorphic_stats in result"
|
|
84
|
+
assert_equal 1, polymorphic_stats["polymorphic_stats"]["polymorphic_models_count"]
|
|
142
85
|
end
|
|
143
86
|
end
|
|
144
|
-
end
|
|
87
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "test_helper"
|
|
4
|
+
|
|
5
|
+
describe RailsStats::PackFinder do
|
|
6
|
+
describe ".find" do
|
|
7
|
+
it "detects packwerk packs and component-based components" do
|
|
8
|
+
root = File.absolute_path("./test/fixtures/packwerk_app")
|
|
9
|
+
|
|
10
|
+
packs = RailsStats::PackFinder.find(root).map { |path| path.sub("#{root}/", "") }
|
|
11
|
+
|
|
12
|
+
assert_equal ["components/billing", "packs/pack1", "packs/pack2"], packs.sort
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "does not treat the root package.yml as a pack" do
|
|
16
|
+
root = File.absolute_path("./test/fixtures/packwerk_app")
|
|
17
|
+
|
|
18
|
+
packs = RailsStats::PackFinder.find(root)
|
|
19
|
+
|
|
20
|
+
refute_includes packs, root
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "returns an empty list for a plain Rails app" do
|
|
24
|
+
root = File.absolute_path("./test/dummy")
|
|
25
|
+
|
|
26
|
+
assert_empty RailsStats::PackFinder.find(root)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "test_helper"
|
|
4
|
+
|
|
5
|
+
describe RailsStats::StatsCalculator do
|
|
6
|
+
describe "#statistics_by_group" do
|
|
7
|
+
before do
|
|
8
|
+
root = File.absolute_path("./test/fixtures/packwerk_app")
|
|
9
|
+
@calculator = RailsStats::StatsCalculator.new(root)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "reports that the app is split into packs" do
|
|
13
|
+
assert @calculator.packs?
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "groups statistics per pack/component with Core first" do
|
|
17
|
+
groups = @calculator.statistics_by_group.keys
|
|
18
|
+
|
|
19
|
+
assert_equal "Core", groups.first
|
|
20
|
+
assert_equal ["Core", "components/billing", "packs/pack1", "packs/pack2"], groups
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "attributes each pack's files to its own group" do
|
|
24
|
+
by_group = @calculator.statistics_by_group
|
|
25
|
+
|
|
26
|
+
assert_equal 1, by_group["packs/pack1"]["Models"].files_total
|
|
27
|
+
assert_equal 1, by_group["packs/pack1"]["Controllers"].files_total
|
|
28
|
+
assert_equal 1, by_group["packs/pack1"]["Model Tests"].files_total
|
|
29
|
+
assert_equal 1, by_group["packs/pack2"]["Models"].files_total
|
|
30
|
+
assert_equal 1, by_group["components/billing"]["Models"].files_total
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "keeps core files in the Core group" do
|
|
34
|
+
core = @calculator.statistics_by_group["Core"]
|
|
35
|
+
|
|
36
|
+
assert_equal 1, core["Models"].files_total
|
|
37
|
+
assert_equal 1, core["Controllers"].files_total
|
|
38
|
+
assert_equal 1, core["Libraries"].files_total
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "includes pack lib directories that are not gems" do
|
|
42
|
+
assert_equal 1, @calculator.statistics_by_group["packs/pack1"]["Libraries"].files_total
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "has a grand total that matches the sum of every group" do
|
|
46
|
+
_code, _tests, grand = @calculator.totals_for(@calculator.statistics)
|
|
47
|
+
|
|
48
|
+
per_group_files = @calculator.statistics_by_group.sum do |_group, stats|
|
|
49
|
+
_c, _t, group_grand = @calculator.totals_for(stats)
|
|
50
|
+
group_grand.files_total
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
assert_equal grand.files_total, per_group_files
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
describe "#packs?" do
|
|
58
|
+
it "is false for a plain Rails app" do
|
|
59
|
+
calculator = RailsStats::StatsCalculator.new(File.absolute_path("./test/dummy"))
|
|
60
|
+
|
|
61
|
+
refute calculator.packs?
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "test_helper"
|
|
4
|
+
require "tmpdir"
|
|
5
|
+
require "fileutils"
|
|
6
|
+
|
|
7
|
+
describe RailsStats::Util do
|
|
8
|
+
describe ".calculate_directory_statistics" do
|
|
9
|
+
it "ignores vendored directories and never counts a directory that looks like a source file" do
|
|
10
|
+
Dir.mktmpdir do |dir|
|
|
11
|
+
# A real source file that should be counted.
|
|
12
|
+
File.write(File.join(dir, "real.rb"), "class Real\nend\n")
|
|
13
|
+
|
|
14
|
+
# A directory whose name matches the source-file pattern. It must be
|
|
15
|
+
# walked (its contents counted) but never opened as a file itself,
|
|
16
|
+
# which previously raised Errno::EISDIR.
|
|
17
|
+
weird = File.join(dir, "weird.rb")
|
|
18
|
+
FileUtils.mkdir_p(weird)
|
|
19
|
+
File.write(File.join(weird, "inner.rb"), "class Inner\nend\n")
|
|
20
|
+
|
|
21
|
+
# A vendored tree that must be skipped entirely, including a directory
|
|
22
|
+
# named like a JS file (e.g. node_modules/popper.js), the exact case
|
|
23
|
+
# that crashed on a packs app.
|
|
24
|
+
popper = File.join(dir, "node_modules", "popper.js")
|
|
25
|
+
FileUtils.mkdir_p(popper)
|
|
26
|
+
File.write(File.join(popper, "index.js"), "function noop() {}\n")
|
|
27
|
+
|
|
28
|
+
stats = RailsStats::Util.calculate_directory_statistics(dir)
|
|
29
|
+
|
|
30
|
+
# real.rb + weird.rb/inner.rb, nothing under node_modules.
|
|
31
|
+
assert_equal 2, stats.files_total
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "skips every ignored directory name" do
|
|
36
|
+
RailsStats::IGNORED_DIRS.each do |ignored|
|
|
37
|
+
Dir.mktmpdir do |dir|
|
|
38
|
+
vendored = File.join(dir, ignored)
|
|
39
|
+
FileUtils.mkdir_p(vendored)
|
|
40
|
+
File.write(File.join(vendored, "ignored.rb"), "class Ignored\nend\n")
|
|
41
|
+
|
|
42
|
+
stats = RailsStats::Util.calculate_directory_statistics(dir)
|
|
43
|
+
|
|
44
|
+
assert_equal 0, stats.files_total, "expected #{ignored}/ to be skipped"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|