sandi_meter 1.1.8 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 54a3a95954d2e42aaf57f24b88a0988b793015b2
4
- data.tar.gz: 0b71ff002bb37ceee3e65b2d70ba3ebd8ff1db35
3
+ metadata.gz: 9a83923b441f198ed909f5cc7e0b3933b4b0b2ad
4
+ data.tar.gz: 5f0d9b05649988b2c7e2094ee81490212be49444
5
5
  SHA512:
6
- metadata.gz: bfbf7a4c4374cdc0f78ef62faf90500fcf2e85895fb2f52d26da3ed66b6c9507b9fb8c0a72350fa1e50dfd54e3f1865a255217f4e2a99bbed43b871b45efcc7c
7
- data.tar.gz: 7e7158e10271549a4c5fad4004874bacb629e6dc77efd8d9db36c8f35f42dfbe9019c63ab459d9175843cb1c7ff9f98d249d0b1b83d8ea7d01974d50afb0dc3d
6
+ metadata.gz: 7b35f03467396393d3ce937b5850c3cd1e6d1ac83becbc137feac43d7bb1b904e1fc21f3f195150b98dd7daa8c917406e30ad06bd7490bfc02a7fd71e51e69f5
7
+ data.tar.gz: 047facafdc3447ea5c37ed7e11260504fe6e7fb2e42f980b65e04f3a673d1bcaabc54328a9b33471cca1e4cabbbc14b7c5e095fccdd96da73cfcdbcfd6eced64
data/README.md CHANGED
@@ -7,7 +7,7 @@ Static analysis tool for checking your Ruby code for [Sandi Metz' four rules](ht
7
7
  * 100 lines per class
8
8
  * 5 lines per method
9
9
  * 4 params per method call (and don't even try cheating with hash params)
10
- * 1 instance variables per controller' action
10
+ * 1 instance variable per controller action
11
11
 
12
12
  ## CLI mode
13
13
 
@@ -19,8 +19,12 @@ sandi_meter --help
19
19
  -g, --graph HTML mode. Create folder, log data and output stats to HTML file.
20
20
  --json Output as JSON
21
21
  -l, --log Show syntax error and indentation log output
22
- -p, --path PATH Path to folder or file to analyze (default is ".")
22
+ -o, --output-path PATH Path for storing generated output files (default: ./sandi_meter/)
23
+ -p, --path PATH Path to folder or file to analyze
24
+ -q, --quiet Do not open HTML report for graph option in browser.
25
+ -t, --thresholds THRESHOLD Thresholds for each rule (default: "90,90,90,90" or in config.yml)
23
26
  -r, --rules Show rules
27
+ -v, --version Gem version
24
28
  -h, --help Help
25
29
 
26
30
  cd ~/your/ruby/or/rails/project
@@ -21,6 +21,11 @@ module SandiMeter
21
21
  description: "Path to folder or file to analyze",
22
22
  default: "."
23
23
 
24
+ option :output_path,
25
+ short: "-o PATH",
26
+ long: "--output-path PATH",
27
+ description: "Path for storing generated output files (default: ./sandi_meter/)"
28
+
24
29
  option :log,
25
30
  short: "-l",
26
31
  long: "--log",
@@ -70,6 +75,12 @@ module SandiMeter
70
75
  long: "--json",
71
76
  description: "Output as JSON",
72
77
  boolean: false
78
+
79
+ option :rule_thresholds,
80
+ short: "-t THRESHOLD",
81
+ long: "--thresholds THRESHOLD",
82
+ description: "Thresholds for each rule (default: 90,90,90,90) or in config.yml",
83
+ default: "90,90,90,90"
73
84
  end
74
85
 
75
86
  class CLI
@@ -78,12 +89,15 @@ module SandiMeter
78
89
  cli = CommandParser.new
79
90
  cli.parse_options
80
91
 
92
+ cli.config[:output_path] ||= File.expand_path(File.join(cli.config[:path], 'sandi_meter'))
93
+
94
+ cli.config[:rule_thresholds] = cli.config[:rule_thresholds].split(",").map(&:to_i)
95
+
81
96
  if cli.config[:graph]
82
- log_dir_path = File.join(cli.config[:path], 'sandi_meter')
83
- FileUtils.mkdir(log_dir_path) unless Dir.exists?(log_dir_path)
97
+ FileUtils.mkdir_p(cli.config[:output_path]) unless Dir.exists?(cli.config[:output_path])
84
98
 
85
- create_config_file(cli.config[:path], 'sandi_meter/.sandi_meter', %w(db vendor).join("\n"))
86
- create_config_file(cli.config[:path], 'sandi_meter/config.yml', YAML.dump({ threshold: 90 }))
99
+ create_config_file(cli.config[:output_path], '.sandi_meter', %w(db vendor).join("\n"))
100
+ create_config_file(cli.config[:output_path], 'config.yml', YAML.dump({ thresholds: [90, 90, 90, 90] }))
87
101
  end
88
102
 
89
103
  if cli.config[:version]
@@ -108,16 +122,16 @@ module SandiMeter
108
122
  formatter.print_data(data)
109
123
 
110
124
  if cli.config[:graph]
111
- if File.directory?(cli.config[:path])
125
+ if File.directory?(cli.config[:output_path])
112
126
  logger = SandiMeter::Logger.new(data)
113
- logger.log!(cli.config[:path])
127
+ logger.log!(cli.config[:output_path])
114
128
 
115
129
  html_generator = SandiMeter::HtmlGenerator.new
116
- html_generator.copy_assets!(cli.config[:path])
117
- html_generator.generate_data!(cli.config[:path])
118
- html_generator.generate_details!(cli.config[:path], data)
130
+ html_generator.copy_assets!(cli.config[:output_path])
131
+ html_generator.generate_data!(cli.config[:output_path])
132
+ html_generator.generate_details!(cli.config[:output_path], data)
119
133
 
120
- index_html_path = File.join(cli.config[:path], 'sandi_meter/index.html')
134
+ index_html_path = File.join(cli.config[:output_path], 'index.html')
121
135
  unless cli.config[:quiet]
122
136
  open_in_browser(index_html_path)
123
137
  end
@@ -126,11 +140,11 @@ module SandiMeter
126
140
  end
127
141
  end
128
142
 
129
- config_file_path = File.join(cli.config[:path], 'sandi_meter', 'config.yml')
143
+ config_file_path = File.join(cli.config[:output_path], 'config.yml')
130
144
  config = if File.exists?(config_file_path)
131
145
  YAML.load(File.read(config_file_path))
132
146
  else
133
- { threshold: 90 }
147
+ { thresholds: cli.config[:rule_thresholds] }
134
148
  end
135
149
 
136
150
  if RulesChecker.new(data, config).ok?
@@ -4,19 +4,19 @@ require 'json'
4
4
  module SandiMeter
5
5
  class HtmlGenerator
6
6
  def copy_assets!(path)
7
- asset_dir_path = File.join(path, 'sandi_meter/assets')
7
+ asset_dir_path = File.join(path, 'assets')
8
8
  FileUtils.mkdir(asset_dir_path) unless Dir.exists?(asset_dir_path)
9
+ html_dir = File.expand_path('../../html', File.dirname(__FILE__))
9
10
 
10
-
11
- Dir[File.join(File.dirname(__FILE__), "../../html/*.{js,css,png}")].each do |file|
11
+ Dir[File.join(html_dir, "*.{js,css,png}")].each do |file|
12
12
  FileUtils.cp file, File.join(asset_dir_path, File.basename(file))
13
13
  end
14
14
 
15
- FileUtils.cp File.join(File.dirname(__FILE__), "../../html", "index.html"), File.join(path, 'sandi_meter', 'index.html')
15
+ FileUtils.cp File.join(html_dir, 'index.html'), File.join(path, 'index.html')
16
16
  end
17
17
 
18
18
  def generate_data!(path)
19
- raw_data = File.read(File.join(path, 'sandi_meter', 'sandi_meter.log')).split("\n")
19
+ raw_data = File.read(File.join(path, 'sandi_meter.log')).split("\n")
20
20
  raw_data.map! { |row| row.split(';').map(&:to_i) }
21
21
 
22
22
  data = []
@@ -31,7 +31,7 @@ module SandiMeter
31
31
  data << hash
32
32
  end
33
33
 
34
- index_file = File.join(path, 'sandi_meter', 'index.html')
34
+ index_file = File.join(path, 'index.html')
35
35
  index = File.read(index_file)
36
36
  index.gsub!('<% plot_data %>', data.to_json)
37
37
 
@@ -91,7 +91,7 @@ module SandiMeter
91
91
  )
92
92
  end
93
93
 
94
- index_file = File.join(path, 'sandi_meter', 'index.html')
94
+ index_file = File.join(path, 'index.html')
95
95
  index = File.read(index_file)
96
96
  index.gsub!('<% details %>', details)
97
97
 
@@ -3,7 +3,7 @@ require 'fileutils'
3
3
  module SandiMeter
4
4
  class Logger < Struct.new(:data)
5
5
  def log!(path)
6
- File.open(File.join(path, 'sandi_meter', 'sandi_meter.log'), 'a') do |file|
6
+ File.open(File.join(path, 'sandi_meter.log'), 'a') do |file|
7
7
  file.puts(log_line)
8
8
  end
9
9
  end
@@ -10,12 +10,18 @@ module SandiMeter
10
10
  end
11
11
 
12
12
  def ok?
13
- @rules.reduce(:+) / 4 > @config[:threshold]
13
+ if @config[:threshold]
14
+ puts "DEPRECATION WARNING: sandi_meter threshold will be deprecated. Set thresholds for each rule in sandi_meter config.yml"
15
+
16
+ @rules.reduce(:+) / 4 > @config[:threshold]
17
+ elsif @config[:thresholds]
18
+ @rules.each_with_index.map { |percentage, index| percentage >= @config[:thresholds][index].to_f }.reduce(:&)
19
+ end
14
20
  end
15
21
 
16
22
  private
17
23
  def percentage(amount, total)
18
- total > 0 ? (amount / total.to_f)*100 : 100
24
+ total > 0 ? (amount / total.to_f) * 100 : 100
19
25
  end
20
26
  end
21
27
  end
@@ -1,3 +1,3 @@
1
1
  module SandiMeter
2
- VERSION = "1.1.8"
2
+ VERSION = "1.2.0"
3
3
  end
@@ -21,7 +21,7 @@ module SandiMeter
21
21
 
22
22
  private
23
23
  def validate(source)
24
- Open3.capture3('ruby -wc', stdin_data: source)
24
+ Open3.capture3("#{RUBY_ENGINE} -wc", stdin_data: source)
25
25
  end
26
26
 
27
27
  def check_syntax(status)
@@ -14,7 +14,7 @@ describe SandiMeter::Analyzer do
14
14
  it 'finds indentation warnings for method' do
15
15
  klass = analyzer.classes.find { |c| c.name == "TestClass" }
16
16
 
17
- klass.should have_attributes(
17
+ expect(klass).to have_attributes(
18
18
  first_line: 1,
19
19
  last_line: 5,
20
20
  path: test_file_path(3)
@@ -24,7 +24,7 @@ describe SandiMeter::Analyzer do
24
24
  it 'finds methods' do
25
25
  method = analyzer.methods["TestClass"].find { |m| m.name == "blah" }
26
26
 
27
- method.should have_attributes(
27
+ expect(method).to have_attributes(
28
28
  first_line: 2,
29
29
  last_line: 4,
30
30
  number_of_arguments: 0,
@@ -35,7 +35,7 @@ describe SandiMeter::Analyzer do
35
35
  it 'finds method calls that brakes third rule' do
36
36
  method_call = analyzer.method_calls.first
37
37
 
38
- method_call.should have_attributes(
38
+ expect(method_call).to have_attributes(
39
39
  first_line: 3,
40
40
  number_of_arguments: 5,
41
41
  path: test_file_path(3)
@@ -53,7 +53,7 @@ describe SandiMeter::Analyzer do
53
53
  it 'finds indentation warnings for method' do
54
54
  klass = analyzer.classes.find { |c| c.name == "MyApp::TestClass" }
55
55
 
56
- klass.should have_attributes(
56
+ expect(klass).to have_attributes(
57
57
  first_line: 2,
58
58
  last_line: nil,
59
59
  path: test_file_path(1)
@@ -63,7 +63,7 @@ describe SandiMeter::Analyzer do
63
63
  it 'finds methods' do
64
64
  method = analyzer.methods["MyApp::TestClass"].find { |m| m.name == "blah" }
65
65
 
66
- method.should have_attributes(
66
+ expect(method).to have_attributes(
67
67
  first_line: 3,
68
68
  last_line: nil,
69
69
  number_of_arguments: 0,
@@ -82,7 +82,7 @@ describe SandiMeter::Analyzer do
82
82
  it 'finds classes' do
83
83
  klass = analyzer.classes.find { |c| c.name == "FirstTestClass" }
84
84
 
85
- klass.should have_attributes(
85
+ expect(klass).to have_attributes(
86
86
  first_line: 1,
87
87
  last_line: 4,
88
88
  path: test_file_path(4)
@@ -90,7 +90,7 @@ describe SandiMeter::Analyzer do
90
90
 
91
91
  klass = analyzer.classes.find { |c| c.name == "SecondTestClass" }
92
92
 
93
- klass.should have_attributes(
93
+ expect(klass).to have_attributes(
94
94
  first_line: 6,
95
95
  last_line: 9,
96
96
  path: test_file_path(4)
@@ -100,7 +100,7 @@ describe SandiMeter::Analyzer do
100
100
  it 'finds methods' do
101
101
  method = analyzer.methods["FirstTestClass"].find { |m| m.name == "first_meth" }
102
102
 
103
- method.should have_attributes(
103
+ expect(method).to have_attributes(
104
104
  first_line: 2,
105
105
  last_line: 3,
106
106
  number_of_arguments: 1,
@@ -109,7 +109,7 @@ describe SandiMeter::Analyzer do
109
109
 
110
110
  method = analyzer.methods["SecondTestClass"].find { |m| m.name == "second_meth" }
111
111
 
112
- method.should have_attributes(
112
+ expect(method).to have_attributes(
113
113
  first_line: 7,
114
114
  last_line: 8,
115
115
  number_of_arguments: 1,
@@ -128,7 +128,7 @@ describe SandiMeter::Analyzer do
128
128
  it 'finds classes' do
129
129
  klass = analyzer.classes.find { |c| c.name == "OneLinerClass" }
130
130
 
131
- klass.should have_attributes(
131
+ expect(klass).to have_attributes(
132
132
  first_line: 1,
133
133
  last_line: nil,
134
134
  path: test_file_path(5)
@@ -136,7 +136,7 @@ describe SandiMeter::Analyzer do
136
136
  end
137
137
 
138
138
  it 'finds methods' do
139
- analyzer.methods.should be_empty
139
+ expect(analyzer.methods).to be_empty
140
140
  end
141
141
  end
142
142
 
@@ -149,14 +149,14 @@ describe SandiMeter::Analyzer do
149
149
 
150
150
  it 'finds class and subclass' do
151
151
  klass = analyzer.classes.find { |c| c.name == "MyApp::Blah::User" }
152
- klass.should have_attributes(
152
+ expect(klass).to have_attributes(
153
153
  first_line: 5,
154
154
  last_line: 13,
155
155
  path: test_file_path(7)
156
156
  )
157
157
 
158
158
  klass = analyzer.classes.find { |c| c.name == "MyApp::Blah::User::SubUser" }
159
- klass.should have_attributes(
159
+ expect(klass).to have_attributes(
160
160
  first_line: 9,
161
161
  last_line: 12,
162
162
  path: test_file_path(7)
@@ -165,7 +165,7 @@ describe SandiMeter::Analyzer do
165
165
 
166
166
  it 'finds methods' do
167
167
  method = analyzer.methods["MyApp::Blah"].find { |m| m.name == "module_meth" }
168
- method.should have_attributes(
168
+ expect(method).to have_attributes(
169
169
  first_line: 2,
170
170
  last_line: 3,
171
171
  number_of_arguments: 0,
@@ -173,7 +173,7 @@ describe SandiMeter::Analyzer do
173
173
  )
174
174
 
175
175
  method = analyzer.methods["MyApp::Blah::User"].find { |m| m.name == "class_meth" }
176
- method.should have_attributes(
176
+ expect(method).to have_attributes(
177
177
  first_line: 6,
178
178
  last_line: 7,
179
179
  number_of_arguments: 0,
@@ -181,7 +181,7 @@ describe SandiMeter::Analyzer do
181
181
  )
182
182
 
183
183
  method = analyzer.methods["MyApp::Blah::User::SubUser"].find { |m| m.name == "sub_meth" }
184
- method.should have_attributes(
184
+ expect(method).to have_attributes(
185
185
  first_line: 10,
186
186
  last_line: 11,
187
187
  number_of_arguments: 0,
@@ -199,7 +199,7 @@ describe SandiMeter::Analyzer do
199
199
 
200
200
  it 'finds class and subclass' do
201
201
  klass = analyzer.classes.find { |c| c.name == "RailsController" }
202
- klass.should have_attributes(
202
+ expect(klass).to have_attributes(
203
203
  first_line: 1,
204
204
  last_line: 12,
205
205
  path: test_file_path(8)
@@ -208,7 +208,7 @@ describe SandiMeter::Analyzer do
208
208
 
209
209
  it 'finds methods' do
210
210
  method = analyzer.methods["RailsController"].find { |m| m.name == "index" }
211
- method.should have_attributes(
211
+ expect(method).to have_attributes(
212
212
  first_line: 2,
213
213
  last_line: 3,
214
214
  number_of_arguments: 0,
@@ -216,7 +216,7 @@ describe SandiMeter::Analyzer do
216
216
  )
217
217
 
218
218
  method = analyzer.methods["RailsController"].find { |m| m.name == "destroy" }
219
- method.should have_attributes(
219
+ expect(method).to have_attributes(
220
220
  first_line: 5,
221
221
  last_line: 6,
222
222
  number_of_arguments: 0,
@@ -224,7 +224,7 @@ describe SandiMeter::Analyzer do
224
224
  )
225
225
 
226
226
  method = analyzer.methods["RailsController"].find { |m| m.name == "private_meth" }
227
- method.should be_nil
227
+ expect(method).to be_nil
228
228
  end
229
229
  end
230
230
 
@@ -238,7 +238,7 @@ describe SandiMeter::Analyzer do
238
238
 
239
239
  it 'finds instance variable' do
240
240
  method = analyzer.methods["UsersController"].find { |m| m.name == "index" }
241
- method.ivars.should eq(["@users"])
241
+ expect(method.ivars).to eq(["@users"])
242
242
  end
243
243
  end
244
244
 
@@ -251,7 +251,7 @@ describe SandiMeter::Analyzer do
251
251
 
252
252
  it 'does not find instance variables' do
253
253
  method = analyzer.methods["GuestController"].find { |m| m.name == "create_guest_user" }
254
- method.ivars.should be_empty
254
+ expect(method.ivars).to be_empty
255
255
  end
256
256
  end
257
257
 
@@ -264,10 +264,10 @@ describe SandiMeter::Analyzer do
264
264
 
265
265
  it 'does not find instance variable' do
266
266
  method = analyzer.methods["User"].find { |m| m.name == "initialize" }
267
- method.ivars.should be_empty
267
+ expect(method.ivars).to be_empty
268
268
 
269
269
  method = analyzer.methods["User"].find { |m| m.name == "hi" }
270
- method.ivars.should be_empty
270
+ expect(method.ivars).to be_empty
271
271
  end
272
272
  end
273
273
 
@@ -280,22 +280,22 @@ describe SandiMeter::Analyzer do
280
280
 
281
281
  it 'finds method defined after public keyword' do
282
282
  method = analyzer.methods["UsersController"].find { |m| m.name == "create" }
283
- method.ivars.should eq(["@user"])
283
+ expect(method.ivars).to eq(["@user"])
284
284
  end
285
285
 
286
286
  it 'omits actions without instance variables' do
287
287
  method = analyzer.methods["UsersController"].find { |m| m.name == "show" }
288
- method.ivars.should be_empty
288
+ expect(method.ivars).to be_empty
289
289
  end
290
290
 
291
291
  it 'omits private methods' do
292
292
  method = analyzer.methods["UsersController"].find { |m| m.name == "find_user" }
293
- method.should be_nil
293
+ expect(method).to be_nil
294
294
  end
295
295
 
296
296
  it 'omits protected methods' do
297
297
  method = analyzer.methods["UsersController"].find { |m| m.name == "protected_find_user" }
298
- method.should be_nil
298
+ expect(method).to be_nil
299
299
  end
300
300
  end
301
301
  end
@@ -310,7 +310,7 @@ describe SandiMeter::Analyzer do
310
310
  it 'counts arguments' do
311
311
  method_call = analyzer.method_calls.first
312
312
 
313
- method_call.should have_attributes(
313
+ expect(method_call).to have_attributes(
314
314
  first_line: 3,
315
315
  number_of_arguments: 5,
316
316
  path: test_file_path(11)
@@ -328,7 +328,7 @@ describe SandiMeter::Analyzer do
328
328
  it 'are count for class definition' do
329
329
  klass = analyzer.classes.find { |c| c.name == "Valera" }
330
330
 
331
- klass.should have_attributes(
331
+ expect(klass).to have_attributes(
332
332
  first_line: 1,
333
333
  last_line: 109,
334
334
  path: test_file_path(12)
@@ -338,7 +338,7 @@ describe SandiMeter::Analyzer do
338
338
  it 'are count for method definition' do
339
339
  method = analyzer.methods["Valera"].find { |m| m.name == "doodle" }
340
340
 
341
- method.should have_attributes(
341
+ expect(method).to have_attributes(
342
342
  first_line: 2,
343
343
  last_line: 9,
344
344
  number_of_arguments: 0,
@@ -355,7 +355,7 @@ describe SandiMeter::Analyzer do
355
355
  end
356
356
 
357
357
  it 'is not scanned' do
358
- analyzer.method_calls.should be_empty
358
+ expect(analyzer.method_calls).to be_empty
359
359
  end
360
360
  end
361
361
 
@@ -370,7 +370,7 @@ describe SandiMeter::Analyzer do
370
370
  it 'mark 4line methods good' do
371
371
  method = analyzer.methods["TestClass"].find { |m| m.name == "render4" }
372
372
 
373
- method.should have_attributes(
373
+ expect(method).to have_attributes(
374
374
  first_line: 2,
375
375
  last_line: 7,
376
376
  number_of_arguments: 0,
@@ -381,7 +381,7 @@ describe SandiMeter::Analyzer do
381
381
  it 'mark 5line methods good' do
382
382
  method = analyzer.methods["TestClass"].find { |m| m.name == "render5" }
383
383
 
384
- method.should have_attributes(
384
+ expect(method).to have_attributes(
385
385
  first_line: 9,
386
386
  last_line: 15,
387
387
  number_of_arguments: 0,
@@ -392,7 +392,7 @@ describe SandiMeter::Analyzer do
392
392
  it 'mark 6line methods bad' do
393
393
  method = analyzer.methods["TestClass"].find { |m| m.name == "render6" }
394
394
 
395
- method.should have_attributes(
395
+ expect(method).to have_attributes(
396
396
  first_line: 17,
397
397
  last_line: 24,
398
398
  number_of_arguments: 0,
@@ -17,13 +17,13 @@ describe SandiMeter::Calculator do
17
17
  it 'counts class lines' do
18
18
  output = calculator.calculate!(true)
19
19
  klass = output[:first_rule][:log][:classes].find { |params| params.first == "User" }
20
- klass[1].should eq(109)
20
+ expect(klass[1]).to eq(109)
21
21
  end
22
22
 
23
23
  it 'counts method lines' do
24
24
  output = calculator.calculate!(true)
25
25
  method_params = output[:second_rule][:log][:methods].find { |method| method[1] == "create" }
26
- method_params[2].should eq(6)
26
+ expect(method_params[2]).to eq(6)
27
27
  end
28
28
  end
29
29
 
@@ -69,12 +69,12 @@ describe SandiMeter::Calculator do
69
69
  describe 'no matching ruby files found' do
70
70
  it 'counts class lines' do
71
71
  output = calculator.calculate!(false)
72
- output[:first_rule][:total_classes_amount].should eql(0)
72
+ expect(output[:first_rule][:total_classes_amount]).to eql(0)
73
73
  end
74
74
 
75
75
  it 'counts method lines' do
76
76
  output = calculator.calculate!(true)
77
- output[:second_rule][:total_methods_amount].should eql(0)
77
+ expect(output[:second_rule][:total_methods_amount]).to eq(0)
78
78
  end
79
79
  end
80
80
  end
@@ -2,25 +2,37 @@ require 'test_helper'
2
2
  require_relative '../lib/sandi_meter/cli'
3
3
 
4
4
  describe SandiMeter::CLI do
5
+ include FakeFS::SpecHelpers
6
+
5
7
  let(:cli) { SandiMeter::CLI }
6
-
7
- describe '#execute' do
8
- before do
8
+ let(:gem_root) { File.expand_path('../', File.dirname(__FILE__)) }
9
+
10
+ before do
11
+ FakeFS.activate!
12
+
13
+ FakeFS::FileSystem.clone(gem_root)
14
+ end
15
+
16
+ after do
17
+ FakeFS.deactivate!
18
+ end
19
+
20
+ describe '#execute', silent_cli: true do
21
+ before do
9
22
  @original_argv = ARGV
10
23
  ARGV.clear
11
24
  end
12
-
13
- after do
25
+
26
+ after do
14
27
  ARGV.clear
15
28
  ARGV.concat(@original_argv)
16
29
  end
17
-
30
+
18
31
  context 'with the graph flag passed in' do
19
32
  before { ARGV.push('-g') }
20
- after { ARGV.pop }
21
-
33
+
22
34
  it 'opens the graph in a web browser' do
23
- cli.should_receive(:open_in_browser)
35
+ expect(cli).to receive(:open_in_browser)
24
36
  expect { cli.execute }.to raise_error(SystemExit)
25
37
  end
26
38
  end
@@ -30,15 +42,64 @@ describe SandiMeter::CLI do
30
42
  ARGV.push('-q')
31
43
  ARGV.push('-g')
32
44
  end
33
- after do
34
- ARGV.pop
35
- ARGV.pop
36
- end
37
-
45
+
38
46
  it 'does not open the browser' do
39
- cli.should_not_receive(:open_in_browser)
47
+ expect(cli).to_not receive(:open_in_browser)
40
48
  expect { cli.execute }.to raise_error(SystemExit)
41
49
  end
42
50
  end
51
+
52
+ context 'output path passed in' do
53
+ let(:test_path) { '/test_out_dir/test2' }
54
+ before do
55
+ ARGV.push('-q')
56
+ ARGV.push('-g')
57
+ ARGV.push('-o')
58
+ ARGV.push(test_path)
59
+ end
60
+
61
+ it 'saves output files to specified output path' do
62
+ expect { cli.execute }.to raise_error(SystemExit)
63
+ expect(File.directory?(test_path)).to eq(true)
64
+ end
65
+ end
66
+
67
+ context 'output path not specified' do
68
+ before do
69
+ ARGV.push('-q')
70
+ ARGV.push('-g')
71
+ ARGV.push('-p')
72
+ ARGV.push('/')
73
+ end
74
+
75
+ it 'saves output files in sandi_meter folder relative to scanned path' do
76
+ expect { cli.execute }.to raise_error(SystemExit)
77
+ expect(File.directory?(File.expand_path('/sandi_meter'))).to eq(true)
78
+ end
79
+ end
80
+
81
+ context 'makes account for rules thresholds' do
82
+ context 'for low thresholds' do
83
+ before do
84
+ ARGV.push('-t')
85
+ ARGV.push("1,1,1,1")
86
+ end
87
+
88
+ it 'terminates with 0 code' do
89
+ expect { cli.execute }.to terminate.with_code(0)
90
+ end
91
+ end
92
+
93
+ context 'for high thresholds' do
94
+ before do
95
+ ARGV.push('-t')
96
+ ARGV.push("99,99,99,99")
97
+ end
98
+
99
+ it 'terminates with 1 code' do
100
+ expect { cli.execute }.to terminate.with_code(1)
101
+ end
102
+ end
103
+ end
43
104
  end
44
105
  end
@@ -8,24 +8,24 @@ describe SandiMeter::LOCChecker do
8
8
  context 'for short code' do
9
9
  before do
10
10
  stub_const('SandiMeter::LOCChecker::MAX_LOC', { 'blah' => 10 })
11
- checker.stub(:locs_size).and_return(rand(0..10))
11
+ allow(checker).to receive(:locs_size).and_return(rand(0..10))
12
12
  end
13
13
 
14
14
  # REFACTOR
15
15
  # avoid passing dumb arguments to tested methods
16
16
  it 'passes the check' do
17
- checker.check([1,2,3], 'blah').should be_true
17
+ expect(checker.check([1,2,3], 'blah')).to eq true
18
18
  end
19
19
  end
20
20
 
21
21
  context 'for large code' do
22
22
  before do
23
23
  stub_const('SandiMeter::LOCChecker::MAX_LOC', { 'blah' => 10 })
24
- checker.stub(:locs_size).and_return(rand(11..100))
24
+ allow(checker).to receive(:locs_size).and_return(rand(11..100))
25
25
  end
26
26
 
27
27
  it 'does not pass the check' do
28
- checker.check([1,2,3], 'blah').should be_false
28
+ expect(checker.check([1,2,3], 'blah')).to eq false
29
29
  end
30
30
  end
31
31
  end
@@ -10,8 +10,8 @@ describe SandiMeter::MethodArgumentsCounter do
10
10
  let(:args_add_block_2) { load_args_block('blah(arg1, arg2)')}
11
11
 
12
12
  it 'counts arguments' do
13
- analyzer.count(args_add_block_1).should eq([2, 1])
14
- analyzer.count(args_add_block_2).should eq([2, 1])
13
+ expect(analyzer.count(args_add_block_1)).to eq([2, 1])
14
+ expect(analyzer.count(args_add_block_2)).to eq([2, 1])
15
15
  end
16
16
  end
17
17
 
@@ -23,10 +23,10 @@ describe SandiMeter::MethodArgumentsCounter do
23
23
  let(:args_add_block_4) { load_args_block('blah(k1: :v1, k2: :v2)') }
24
24
 
25
25
  it 'counts arguments' do
26
- analyzer.count(args_add_block_1).should eq([1, 1])
27
- analyzer.count(args_add_block_2).should eq([1, 1])
28
- analyzer.count(args_add_block_3).should eq([2, 1])
29
- analyzer.count(args_add_block_4).should eq([2, 1])
26
+ expect(analyzer.count(args_add_block_1)).to eq([1, 1])
27
+ expect(analyzer.count(args_add_block_2)).to eq([1, 1])
28
+ expect(analyzer.count(args_add_block_3)).to eq([2, 1])
29
+ expect(analyzer.count(args_add_block_4)).to eq([2, 1])
30
30
  end
31
31
  end
32
32
 
@@ -37,13 +37,13 @@ describe SandiMeter::MethodArgumentsCounter do
37
37
  let(:code_4) { load_args_block('blah(arg_1, arg_2, k1: :v1, k2: :v2)') }
38
38
 
39
39
  it 'counts arguments' do
40
- analyzer.count(code_1).should eq([3, 1])
41
- analyzer.count(code_2).should eq([3, 1])
40
+ expect(analyzer.count(code_1)).to eq([3, 1])
41
+ expect(analyzer.count(code_2)).to eq([3, 1])
42
42
  end
43
43
 
44
44
  it 'counts hash keys as argumets' do
45
- analyzer.count(code_3).should eq([4, 1])
46
- analyzer.count(code_4).should eq([4, 1])
45
+ expect(analyzer.count(code_3)).to eq([4, 1])
46
+ expect(analyzer.count(code_4)).to eq([4, 1])
47
47
  end
48
48
  end
49
49
 
@@ -52,8 +52,8 @@ describe SandiMeter::MethodArgumentsCounter do
52
52
  let(:code_2) { load_args_block('blah(arg_1 = "blah")') }
53
53
 
54
54
  it 'counts arguments' do
55
- analyzer.count(code_1).should eq([1, 1])
56
- analyzer.count(code_2).should eq([1, 1])
55
+ expect(analyzer.count(code_1)).to eq([1, 1])
56
+ expect(analyzer.count(code_2)).to eq([1, 1])
57
57
  end
58
58
  end
59
59
  end
@@ -13,11 +13,11 @@ describe SandiMeter::RulesChecker do
13
13
 
14
14
  describe "#ok?" do
15
15
  it "returns false with 100 threshold" do
16
- expect(SandiMeter::RulesChecker.new(conditions, {threshold: 100})).to_not be_ok
16
+ expect(SandiMeter::RulesChecker.new(conditions, {thresholds: [100, 100, 100, 100]})).to_not be_ok
17
17
  end
18
18
 
19
19
  it "returns true with threshold less than 100" do
20
- expect(SandiMeter::RulesChecker.new(conditions, {threshold: 50})).to be_ok
20
+ expect(SandiMeter::RulesChecker.new(conditions, {thresholds: [50, 100, 100, 100]})).to be_ok
21
21
  end
22
22
  end
23
23
  end
@@ -10,7 +10,7 @@ RSpec::Matchers.define :have_attributes do |expected|
10
10
  result
11
11
  end
12
12
 
13
- failure_message_for_should do |actual|
13
+ failure_message do |actual|
14
14
  wrong_fields = {}
15
15
  expected.each do |key, value|
16
16
  wrong_fields[key] = {
@@ -0,0 +1,39 @@
1
+ #https://gist.github.com/mmasashi/58bd7e2668836a387856
2
+
3
+ RSpec::Matchers.define :terminate do |code|
4
+ actual = nil
5
+
6
+ def supports_block_expectations?
7
+ true
8
+ end
9
+
10
+ match do |block|
11
+ begin
12
+ block.call
13
+ rescue SystemExit => e
14
+ actual = e.status
15
+ end
16
+ actual and actual == status_code
17
+ end
18
+
19
+ chain :with_code do |status_code|
20
+ @status_code = status_code
21
+ end
22
+
23
+ failure_message do |block|
24
+ "expected block to call exit(#{status_code}) but exit" +
25
+ (actual.nil? ? " not called" : "(#{actual}) was called")
26
+ end
27
+
28
+ failure_message_when_negated do |block|
29
+ "expected block not to call exit(#{status_code})"
30
+ end
31
+
32
+ description do
33
+ "expect block to call exit(#{status_code})"
34
+ end
35
+
36
+ def status_code
37
+ @status_code ||= 0
38
+ end
39
+ end
@@ -1,4 +1,22 @@
1
- require 'rspec/autorun'
1
+ require 'pry'
2
2
  require 'ripper'
3
+ require 'fakefs/spec_helpers'
4
+
5
+ # silence CLI output
6
+ RSpec.configure do |config|
7
+ original_stderr = $stderr
8
+ original_stdout = $stdout
9
+
10
+ config.before silent_cli: true do
11
+ # Redirect stderr and stdout
12
+ $stderr = File.open(File::NULL, "w")
13
+ $stdout = File.open(File::NULL, "w")
14
+ end
15
+
16
+ config.after silent_cli: true do
17
+ $stderr = original_stderr
18
+ $stdout = original_stdout
19
+ end
20
+ end
3
21
 
4
22
  Dir["#{Dir.pwd}/spec/support/**/*.rb"].each { |f| require f }
@@ -12,15 +12,15 @@ describe SandiMeter::WarningScanner do
12
12
  end
13
13
 
14
14
  it 'finds indentation warnings for method' do
15
- scanner.indentation_warnings['def'].should eq([[3, 4]])
15
+ expect(scanner.indentation_warnings['def']).to eq([[3, 4]])
16
16
  end
17
17
 
18
18
  it 'finds indentation warnings for class' do
19
- scanner.indentation_warnings['class'].should eq([[2, 5]])
19
+ expect(scanner.indentation_warnings['class']).to eq([[2, 5]])
20
20
  end
21
21
 
22
22
  it 'finds indentation warnings for module' do
23
- scanner.indentation_warnings['module'].should eq([[1, 6]])
23
+ expect(scanner.indentation_warnings['module']).to eq([[1, 6]])
24
24
  end
25
25
  end
26
26
 
metadata CHANGED
@@ -1,97 +1,97 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sandi_meter
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.8
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anatoli Makarevich
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-02 00:00:00.000000000 Z
11
+ date: 2015-05-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.3'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.3'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ~>
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
47
  version: '2.13'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ~>
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '2.13'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: mixlib-cli
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '>='
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '>='
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: json
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - '>='
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - '>='
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: launchy
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - '>='
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0'
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - '>='
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  description: Sandi Metz rules checker
@@ -105,7 +105,7 @@ files:
105
105
  - LICENSE
106
106
  - README.md
107
107
  - Rakefile
108
- - sandi_meter.gemspec
108
+ - bin/sandi_meter
109
109
  - html/_detail_block.html
110
110
  - html/chart.js
111
111
  - html/forkme.png
@@ -131,7 +131,7 @@ files:
131
131
  - lib/sandi_meter/sandi_meter/method_call.rb
132
132
  - lib/sandi_meter/version.rb
133
133
  - lib/sandi_meter/warning_scanner.rb
134
- - bin/sandi_meter
134
+ - sandi_meter.gemspec
135
135
  - spec/analyzer_spec.rb
136
136
  - spec/calculator_spec.rb
137
137
  - spec/cli_spec.rb
@@ -141,6 +141,7 @@ files:
141
141
  - spec/support/args_loader.rb
142
142
  - spec/support/attr_matcher.rb
143
143
  - spec/support/helper_methods.rb
144
+ - spec/support/terminate_matcher.rb
144
145
  - spec/test_classes/1.rb
145
146
  - spec/test_classes/10.rb
146
147
  - spec/test_classes/10_controller.rb
@@ -171,17 +172,17 @@ require_paths:
171
172
  - lib
172
173
  required_ruby_version: !ruby/object:Gem::Requirement
173
174
  requirements:
174
- - - '>='
175
+ - - ">="
175
176
  - !ruby/object:Gem::Version
176
177
  version: 1.9.0
177
178
  required_rubygems_version: !ruby/object:Gem::Requirement
178
179
  requirements:
179
- - - '>='
180
+ - - ">="
180
181
  - !ruby/object:Gem::Version
181
182
  version: '0'
182
183
  requirements: []
183
184
  rubyforge_project:
184
- rubygems_version: 2.0.5
185
+ rubygems_version: 2.4.5
185
186
  signing_key:
186
187
  specification_version: 4
187
188
  summary: Sandi Metz rules checker