cuke_linter 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,7 +5,7 @@ RSpec.describe CukeLinter do
5
5
  let(:test_model_tree) { CukeLinter::ModelFactory.generate_lintable_model }
6
6
  let(:test_linters) { [CukeLinter::LinterFactory.generate_fake_linter] }
7
7
  let(:test_formatters) { [[CukeLinter::FormatterFactory.generate_fake_formatter, "#{CukeLinter::FileHelper::create_directory}/junk_output_file.txt"]] }
8
- let(:linting_options) { { model_tree: test_model_tree, linters: test_linters, formatters: test_formatters } }
8
+ let(:linting_options) { { model_trees: [test_model_tree], linters: test_linters, formatters: test_formatters } }
9
9
 
10
10
 
11
11
  it 'returns the un-formatted linting data when linting' do
@@ -14,7 +14,7 @@ RSpec.describe CukeLinter do
14
14
  expect(results).to eq([{ linter: 'FakeLinter', location: 'path_to_file:1', problem: 'FakeLinter problem' }])
15
15
  end
16
16
 
17
- it 'uses evey formatter provided' do
17
+ it 'uses every formatter provided' do
18
18
  linting_options[:formatters] = [[CukeLinter::FormatterFactory.generate_fake_formatter(name: 'Formatter1')],
19
19
  [CukeLinter::FormatterFactory.generate_fake_formatter(name: 'Formatter2')]]
20
20
 
@@ -47,28 +47,92 @@ RSpec.describe CukeLinter do
47
47
  expect { subject.lint(linting_options) }.to output("Formatter1: FakeLinter problem: path_to_file:1\n").to_stdout
48
48
  end
49
49
 
50
- it 'lints every model in the model tree' do
51
- child_model = CukeLinter::ModelFactory.generate_lintable_model(source_line: 3)
52
- parent_model = CukeLinter::ModelFactory.generate_lintable_model(source_line: 5, children: [child_model])
53
- linting_options[:model_tree] = parent_model
50
+ context 'with only model trees' do
54
51
 
55
- results = subject.lint(linting_options)
52
+ before(:each) do
53
+ child_model = CukeLinter::ModelFactory.generate_lintable_model(source_line: 3)
54
+ parent_model = CukeLinter::ModelFactory.generate_lintable_model(source_line: 5, children: [child_model])
55
+ multi_node_tree = parent_model
56
+ single_node_tree = CukeLinter::ModelFactory.generate_lintable_model(source_line: 7)
57
+
58
+ linting_options[:model_trees] = [single_node_tree, multi_node_tree]
59
+ linting_options.delete(:file_paths)
60
+ end
61
+
62
+ it 'lints every model in each model tree' do
63
+ results = subject.lint(linting_options)
64
+
65
+ expect(results).to match_array([{ linter: 'FakeLinter', location: 'path_to_file:3', problem: 'FakeLinter problem' },
66
+ { linter: 'FakeLinter', location: 'path_to_file:5', problem: 'FakeLinter problem' },
67
+ { linter: 'FakeLinter', location: 'path_to_file:7', problem: 'FakeLinter problem' }])
68
+ end
69
+
70
+ end
71
+
72
+ context 'with only file paths' do
73
+
74
+ before(:each) do
75
+ @a_feature_file = CukeLinter::FileHelper::create_file(text: "\nFeature:", extension: '.feature')
76
+ a_non_feature_file = CukeLinter::FileHelper::create_file(text: 'Some text', extension: '.foo')
77
+ @a_directory = CukeLinter::FileHelper::create_directory
78
+ File.write("#{@a_directory}/test_feature.feature", "Feature:")
79
+
80
+ linting_options[:file_paths] = [@a_feature_file, a_non_feature_file, @a_directory]
81
+ linting_options.delete(:model_trees)
82
+ end
83
+
84
+ it 'lints every model in each path' do
85
+ results = subject.lint(linting_options)
86
+
87
+ expect(results).to match_array([{ linter: 'FakeLinter', location: @a_directory, problem: 'FakeLinter problem' },
88
+ { linter: 'FakeLinter', location: "#{@a_directory}/test_feature.feature", problem: 'FakeLinter problem' },
89
+ { linter: 'FakeLinter', location: "#{@a_directory}/test_feature.feature:1", problem: 'FakeLinter problem' },
90
+ { linter: 'FakeLinter', location: @a_feature_file, problem: 'FakeLinter problem' },
91
+ { linter: 'FakeLinter', location: "#{@a_feature_file}:2", problem: 'FakeLinter problem' }])
92
+ end
56
93
 
57
- expect(results).to match_array([{ linter: 'FakeLinter', location: 'path_to_file:3', problem: 'FakeLinter problem' },
58
- { linter: 'FakeLinter', location: 'path_to_file:5', problem: 'FakeLinter problem' }])
59
94
  end
60
95
 
61
- it 'models the current directory if a model tree is not provided' do
62
- test_dir = CukeLinter::FileHelper::create_directory
63
- File.write("#{test_dir}/test_feature.feature", "Feature:")
64
- linting_options.delete(:model_tree)
96
+ context 'with both model trees and file paths' do
97
+
98
+ before(:each) do
99
+ a_model = CukeLinter::ModelFactory.generate_lintable_model(source_line: 3)
100
+ @a_feature_file = CukeLinter::FileHelper::create_file(text: 'Feature:', extension: '.feature')
65
101
 
66
- Dir.chdir(test_dir) do
67
- @results = subject.lint(linting_options)
102
+ linting_options[:model_trees] = [a_model]
103
+ linting_options[:file_paths] = [@a_feature_file]
104
+ end
105
+
106
+
107
+ it 'lints every model in each model tree and file path' do
108
+ results = subject.lint(linting_options)
109
+
110
+ expect(results).to match_array([{ linter: 'FakeLinter', location: 'path_to_file:3', problem: 'FakeLinter problem' },
111
+ { linter: 'FakeLinter', location: @a_feature_file, problem: 'FakeLinter problem' },
112
+ { linter: 'FakeLinter', location: "#{@a_feature_file}:1", problem: 'FakeLinter problem' }])
113
+ end
114
+
115
+ end
116
+
117
+ context 'with neither model trees or file paths' do
118
+
119
+ before(:each) do
120
+ linting_options.delete(:model_trees)
121
+ linting_options.delete(:file_paths)
122
+ end
123
+
124
+ it 'models the current directory' do
125
+ test_dir = CukeLinter::FileHelper::create_directory
126
+ File.write("#{test_dir}/test_feature.feature", "Feature:")
127
+
128
+ Dir.chdir(test_dir) do
129
+ @results = subject.lint(linting_options)
130
+ end
131
+
132
+ # There should be 3 models to lint: the directory, the feature file, and the feature
133
+ expect(@results.count).to eq(3)
68
134
  end
69
135
 
70
- # There should be 3 models to lint: the directory, the file, and the feature
71
- expect(@results.count).to eq(3)
72
136
  end
73
137
 
74
138
  it 'uses evey linter provided' do
@@ -172,6 +236,20 @@ RSpec.describe CukeLinter do
172
236
  expect(subject.registered_linters['FakeLinter1']).to be nil
173
237
  end
174
238
 
239
+ it 'even unregisters non-configurable disabled linters' do
240
+ config = { 'FakeLinter' => { 'Enabled' => false } }
241
+ configuration_file = CukeLinter::FileHelper.create_file(name: '.cuke_linter', extension: '', text: config.to_yaml)
242
+ non_configurable_linter = CukeLinter::LinterFactory.generate_fake_linter(name: 'FakeLinter')
243
+ non_configurable_linter.instance_eval('undef :configure')
244
+
245
+ CukeLinter.register_linter(linter: non_configurable_linter, name: 'FakeLinter')
246
+ expect(subject.registered_linters['FakeLinter']).to_not be nil
247
+
248
+ subject.load_configuration(config_file_path: configuration_file)
249
+
250
+ expect(subject.registered_linters['FakeLinter']).to be nil
251
+ end
252
+
175
253
  it 'uses the default configuration file in the current directory if no configuration file is provided' do
176
254
  config = { 'FakeLinter1' => { 'Enabled' => false } }
177
255
  configuration_file = CukeLinter::FileHelper.create_file(name: '.cuke_linter', extension: '', text: config.to_yaml)
@@ -209,6 +287,21 @@ RSpec.describe CukeLinter do
209
287
  { linter: 'FakeLinter2', location: 'path_to_file:1', problem: 'My custom message for FakeLinter2' }])
210
288
  end
211
289
 
290
+ it "does not try to configure linters that don't know how to be configured" do
291
+ config = { 'FakeLinter' => { 'Problem' => 'My custom message for FakeLinter' } }
292
+ non_configurable_linter = CukeLinter::LinterFactory.generate_fake_linter(name: 'FakeLinter')
293
+ non_configurable_linter.instance_eval('undef :configure')
294
+
295
+ CukeLinter.clear_registered_linters
296
+ CukeLinter.register_linter(linter: non_configurable_linter, name: 'FakeLinter')
297
+ linting_options.delete(:linters)
298
+
299
+ subject.load_configuration(config: config)
300
+ results = subject.lint(linting_options)
301
+
302
+ expect(results).to match_array([{ linter: 'FakeLinter', location: 'path_to_file:1', problem: 'FakeLinter problem' }])
303
+ end
304
+
212
305
  end
213
306
 
214
307
  end
@@ -29,11 +29,12 @@ RSpec.describe CukeLinter do
29
29
  expect(CukeLinter).to respond_to(:lint)
30
30
  end
31
31
 
32
- it 'lints the (optionally) given model tree using the (optionally) provided set of linters and formats the output with the (optionally) provided formatters' do
32
+ it 'lints the (optionally) given model trees and (optionally) file paths using the (optionally) provided set of linters and formats the output with the (optionally) provided formatters' do
33
33
  expect(CukeLinter.method(:lint).arity).to eq(-1)
34
- expect(CukeLinter.method(:lint).parameters).to match_array([[:key, :model_tree],
34
+ expect(CukeLinter.method(:lint).parameters).to match_array([[:key, :model_trees],
35
35
  [:key, :linters],
36
- [:key, :formatters]])
36
+ [:key, :formatters],
37
+ [:key, :file_paths]])
37
38
  end
38
39
 
39
40
  it 'can register a linter' do
@@ -50,16 +50,41 @@ RSpec.describe CukeLinter::PrettyFormatter do
50
50
  '3 issues found'].join("\n"))
51
51
  end
52
52
 
53
- it 'orders violations by line number' do
53
+ it 'orders violations within the same category by file path' do
54
54
  linting_data = [{ linter: 'SomeLinter',
55
55
  problem: 'Some problem',
56
- location: 'path/to/the_file:2' },
56
+ location: 'path/to/the_file:1' },
57
57
  { linter: 'SomeLinter',
58
58
  problem: 'Some problem',
59
59
  location: 'path/to/the_file:3' },
60
+ { linter: 'SomeLinter',
61
+ problem: 'Some problem',
62
+ location: 'path/to/a_different_file:2' }]
63
+
64
+ results = subject.format(linting_data)
65
+
66
+ expect(results).to eq(['SomeLinter',
67
+ ' Some problem',
68
+ ' path/to/a_different_file:2',
69
+ ' path/to/the_file:1',
70
+ ' path/to/the_file:3',
71
+ '',
72
+ '3 issues found'].join("\n"))
73
+ end
74
+
75
+ it 'orders violations in the same file by line number' do
76
+ linting_data = [{ linter: 'SomeLinter',
77
+ problem: 'Some problem',
78
+ location: 'path/to/the_file:2' },
60
79
  { linter: 'SomeLinter',
61
80
  problem: 'Some problem',
62
81
  location: 'path/to/the_file:3' },
82
+ { linter: 'SomeLinter',
83
+ problem: 'Some problem',
84
+ location: 'path/to/the_file:11' }, # larger number that is alphabetically lower
85
+ { linter: 'SomeLinter',
86
+ problem: 'Some problem',
87
+ location: 'path/to/the_file:3' }, # duplicate number
63
88
  { linter: 'SomeLinter',
64
89
  problem: 'Some problem',
65
90
  location: 'path/to/the_file:1' }]
@@ -72,8 +97,9 @@ RSpec.describe CukeLinter::PrettyFormatter do
72
97
  ' path/to/the_file:2',
73
98
  ' path/to/the_file:3',
74
99
  ' path/to/the_file:3',
100
+ ' path/to/the_file:11',
75
101
  '',
76
- '4 issues found'].join("\n"))
102
+ '5 issues found'].join("\n"))
77
103
  end
78
104
 
79
105
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cuke_linter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Kessler
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-05-25 00:00:00.000000000 Z
11
+ date: 2019-06-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cuke_modeler
@@ -209,6 +209,7 @@ files:
209
209
  - testing/formatter_factory.rb
210
210
  - testing/linter_factory.rb
211
211
  - testing/model_factory.rb
212
+ - testing/rspec/spec/integration/cli_integration_spec.rb
212
213
  - testing/rspec/spec/integration/cuke_linter_integration_spec.rb
213
214
  - testing/rspec/spec/integration/formatters/formatter_integration_specs.rb
214
215
  - testing/rspec/spec/integration/formatters/pretty_formatter_integration_spec.rb