cuke_linter 1.0.0 → 1.0.1

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
  SHA256:
3
- metadata.gz: ae22f6f11409b8b44b14680f1b4134e2deda49a8deca6a92ac78798f33588cd1
4
- data.tar.gz: 443760f17fa6d22ba14c5264e0a26b3f71661afbb703505e9ca257cb3d677cfe
3
+ metadata.gz: cda526ecd0ab5cab7e5a1a588c5052cc9b15ca0779239289b043b5b0aa7160fa
4
+ data.tar.gz: 2a1b1eb4ad68db07f1b8deee8bee8614e1b5fb1048971ae6580e08d544c88424
5
5
  SHA512:
6
- metadata.gz: 72af3e32ba1ee0a0c4b7b6dd939293b708f4e726e1858d43651d14aa3da8ba0266a4d8d0e6b1b6edd213c24a291c5adc601c736134cf6d1537811276ac29a67d
7
- data.tar.gz: 583835b3d2f300f9d960711135aef2c5039062328bb5ba218cad1d37fae71c5dcdce5cc1394f6771281e09fbe740683822b98a5aecdd46c3ce843f12bc9d48dc
6
+ metadata.gz: be54da9ed9d7571302954de93506194b13b605790bcd140c421f00f70af02070b01e6c9af4cf1d51ceaa3b699b967ad60327fb06c85c6bf6cd2b993a26400381
7
+ data.tar.gz: b004e3c98632a9d510b828a238de24460c76201dc659ef780e98606225749b9feeb1568546ed1e9eda218a63e17873594bef8c2301cfa2886b03ddf733e6e855
@@ -8,6 +8,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8
8
 
9
9
  Nothing yet...
10
10
 
11
+ ## [1.0.1] - 2020-05-06
12
+
13
+ ### Fixed
14
+ - Replaced some code that was not valid with earlier versions of Ruby 2.x, with which this gem is specified as being compatible.
15
+
11
16
 
12
17
  ## [1.0.0] - 2020-03-09
13
18
 
@@ -154,7 +159,8 @@ Nothing yet...
154
159
  - Custom linters, formatters, and command line usability
155
160
 
156
161
 
157
- [Unreleased]: https://github.com/enkessler/cuke_linter/compare/v1.0.0...HEAD
162
+ [Unreleased]: https://github.com/enkessler/cuke_linter/compare/v1.0.1...HEAD
163
+ [1.0.1]: https://github.com/enkessler/cuke_linter/compare/v1.0.0...v1.0.1
158
164
  [1.0.0]: https://github.com/enkessler/cuke_linter/compare/v0.13.0...v1.0.0
159
165
  [0.13.0]: https://github.com/enkessler/cuke_linter/compare/v0.12.1...v0.13.0
160
166
  [0.12.1]: https://github.com/enkessler/cuke_linter/compare/v0.12.0...v0.12.1
data/README.md CHANGED
@@ -104,7 +104,8 @@ class MyCustomLinter
104
104
  return nil unless model.is_a?(CukeModeler::Scenario)
105
105
 
106
106
  if model.name.empty?
107
- { problem: 'Scenario has no name', location: "#{model.get_ancestor(:feature_file).path}:#{model.source_line}" }
107
+ { problem: 'Scenario has no name',
108
+ location: "#{model.get_ancestor(:feature_file).path}:#{model.source_line}" }
108
109
  else
109
110
  nil
110
111
  end
@@ -134,13 +135,16 @@ output_path = "#{__dir__}/my_report.txt"
134
135
  model_tree_root = CukeModeler::Directory.new(Dir.pwd)
135
136
  additional_file_path = 'path/to/some.feature'
136
137
 
137
- # Providing the formatter twice so that it also is printed to the console
138
- CukeLinter.lint(linters: [linter], formatters: [[formatter], [formatter, output_path]], model_trees: [model_tree_root], file_paths: [additional_file_path])
138
+ # Providing the formatter twice so that output also is printed to the console
139
+ CukeLinter.lint(linters: [linter],
140
+ formatters: [[formatter], [formatter, output_path]],
141
+ model_trees: [model_tree_root],
142
+ file_paths: [additional_file_path])
139
143
  ```
140
144
 
141
145
  ### Configuration
142
146
 
143
- Rather than using the default linters or providing a custom set of of modified linters every time linting occurs, which linters to use and any linter specific modifications can be configured in a more static manner via a configuration file or setting the configuration directly in code. See [documentation](#documentation) for specifics.
147
+ Rather than using the default linters or providing a custom set of of modified linters every time linting occurs, which linters to use and any linter specific modifications (such as choosing a non-default dialect) can be configured in a more static manner via a configuration file or setting the configuration directly in code. See [documentation](#documentation) for specifics.
144
148
 
145
149
 
146
150
  ### <a id="documentation"></a>Everything Else
@@ -1,40 +1,44 @@
1
-
2
- lib = File.expand_path("../lib", __FILE__)
1
+ lib = File.expand_path('lib', __dir__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require "cuke_linter/version"
3
+ require 'cuke_linter/version'
5
4
 
6
5
  Gem::Specification.new do |spec|
7
- spec.name = "cuke_linter"
6
+ spec.name = 'cuke_linter'
8
7
  spec.version = CukeLinter::VERSION
9
- spec.authors = ["Eric Kessler"]
10
- spec.email = ["morrow748@gmail.com"]
8
+ spec.authors = ['Eric Kessler']
9
+ spec.email = ['morrow748@gmail.com']
11
10
 
12
- spec.summary = %q{Lints feature files used by Cucumber and other similar frameworks.}
11
+ spec.summary = 'Lints feature files used by Cucumber and other similar frameworks.'
13
12
  spec.homepage = 'https://github.com/enkessler/cuke_linter'
14
- spec.license = "MIT"
13
+ spec.license = 'MIT'
15
14
 
16
15
 
17
16
  # Specify which files should be added to the gem when it is released.
18
17
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
19
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
18
+ spec.files = Dir.chdir(File.expand_path('', __dir__)) do
20
19
  source_controlled_files = `git ls-files -z`.split("\x0")
21
- source_controlled_files.keep_if { |file| file =~ %r{^(lib|exe|testing/cucumber/features)} } + ['README.md', 'LICENSE.txt', 'CHANGELOG.md', 'cuke_linter.gemspec']
20
+ source_controlled_files.keep_if { |file| file =~ %r{^(lib|exe|testing/cucumber/features)} }
21
+ source_controlled_files + ['README.md', 'LICENSE.txt', 'CHANGELOG.md', 'cuke_linter.gemspec']
22
22
  end
23
- spec.bindir = "exe"
23
+ spec.bindir = 'exe'
24
24
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
- spec.require_paths = ["lib"]
25
+ spec.require_paths = ['lib']
26
26
 
27
27
  spec.required_ruby_version = '~> 2.0'
28
28
 
29
29
  spec.add_runtime_dependency 'cuke_modeler', '>= 1.5', '< 3.0'
30
30
 
31
- spec.add_development_dependency "bundler", "< 3.0"
32
- spec.add_development_dependency "cucumber", "~> 3.0"
33
- spec.add_development_dependency "racatt", "~> 1.0"
34
- spec.add_development_dependency "rake", "~> 12.0"
35
- spec.add_development_dependency "require_all", "~> 2.0"
36
- spec.add_development_dependency "rspec", "~> 3.0"
37
- spec.add_development_dependency 'simplecov', '< 1.0.0'
31
+ spec.add_development_dependency 'bundler', '< 3.0'
32
+ spec.add_development_dependency 'childprocess', '~> 3.0'
38
33
  spec.add_development_dependency 'coveralls', '< 1.0.0'
34
+ spec.add_development_dependency 'cucumber', '~> 3.0'
35
+ spec.add_development_dependency 'cuke_slicer', '>= 2.0.2', '< 3.0'
36
+ spec.add_development_dependency 'ffi', '~> 1.0'
37
+ spec.add_development_dependency 'parallel', '~> 1.0'
39
38
  spec.add_development_dependency 'rainbow', '< 4.0.0'
39
+ spec.add_development_dependency 'rake', '~> 12.0'
40
+ spec.add_development_dependency 'require_all', '~> 2.0'
41
+ spec.add_development_dependency 'rspec', '~> 3.0'
42
+ spec.add_development_dependency 'rubocop', '< 1.0.0'
43
+ spec.add_development_dependency 'simplecov', '< 1.0.0'
40
44
  end
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "cuke_linter"
3
+ require 'cuke_linter'
4
4
  require 'optparse'
5
5
 
6
6
  params = {}
@@ -9,6 +9,7 @@ params[:formatters] = []
9
9
  params[:outs] = []
10
10
  params[:requires] = []
11
11
 
12
+ # rubocop:disable Metrics/BlockLength
12
13
  parser = OptionParser.new do |options|
13
14
 
14
15
  options.set_summary_width(30)
@@ -68,6 +69,7 @@ parser = OptionParser.new do |options|
68
69
  end
69
70
 
70
71
  end
72
+ # rubocop:enable Metrics/BlockLength
71
73
 
72
74
  begin
73
75
  parser.parse!
@@ -1,7 +1,7 @@
1
1
  require 'yaml'
2
2
  require 'cuke_modeler'
3
3
 
4
- require "cuke_linter/version"
4
+ require 'cuke_linter/version'
5
5
  require 'cuke_linter/formatters/pretty_formatter'
6
6
  require 'cuke_linter/linters/linter'
7
7
  require 'cuke_linter/linters/background_does_more_than_setup_linter'
@@ -29,233 +29,170 @@ require 'cuke_linter/linters/test_with_setup_step_after_action_step_linter'
29
29
  require 'cuke_linter/linters/test_with_setup_step_after_verification_step_linter'
30
30
  require 'cuke_linter/linters/test_with_setup_step_as_final_step_linter'
31
31
  require 'cuke_linter/linters/test_with_too_many_steps_linter'
32
+ require 'cuke_linter/configuration'
33
+ require 'cuke_linter/default_linters'
34
+ require 'cuke_linter/gherkin'
35
+ require 'cuke_linter/linter_registration'
32
36
 
33
37
 
34
38
  # The top level namespace used by this gem
35
-
36
39
  module CukeLinter
37
40
 
38
- # The default keyword that is considered a 'Given' keyword
39
- DEFAULT_GIVEN_KEYWORD = 'Given'.freeze
40
- # The default keyword that is considered a 'When' keyword
41
- DEFAULT_WHEN_KEYWORD = 'When'.freeze
42
- # The default keyword that is considered a 'Then' keyword
43
- DEFAULT_THEN_KEYWORD = 'Then'.freeze
44
-
45
- @original_linters = { 'BackgroundDoesMoreThanSetupLinter' => BackgroundDoesMoreThanSetupLinter.new,
46
- 'ElementWithCommonTagsLinter' => ElementWithCommonTagsLinter.new,
47
- 'ElementWithDuplicateTagsLinter' => ElementWithDuplicateTagsLinter.new,
48
- 'ElementWithTooManyTagsLinter' => ElementWithTooManyTagsLinter.new,
49
- 'ExampleWithoutNameLinter' => ExampleWithoutNameLinter.new,
50
- 'FeatureFileWithInvalidNameLinter' => FeatureFileWithInvalidNameLinter.new,
51
- 'FeatureFileWithMismatchedNameLinter' => FeatureFileWithMismatchedNameLinter.new,
52
- 'FeatureWithTooManyDifferentTagsLinter' => FeatureWithTooManyDifferentTagsLinter.new,
53
- 'FeatureWithoutDescriptionLinter' => FeatureWithoutDescriptionLinter.new,
54
- 'FeatureWithoutNameLinter' => FeatureWithoutNameLinter.new,
55
- 'FeatureWithoutScenariosLinter' => FeatureWithoutScenariosLinter.new,
56
- 'OutlineWithSingleExampleRowLinter' => OutlineWithSingleExampleRowLinter.new,
57
- 'SingleTestBackgroundLinter' => SingleTestBackgroundLinter.new,
58
- 'StepWithEndPeriodLinter' => StepWithEndPeriodLinter.new,
59
- 'StepWithTooManyCharactersLinter' => StepWithTooManyCharactersLinter.new,
60
- 'TestShouldUseBackgroundLinter' => TestShouldUseBackgroundLinter.new,
61
- 'TestWithActionStepAsFinalStepLinter' => TestWithActionStepAsFinalStepLinter.new,
62
- 'TestWithBadNameLinter' => TestWithBadNameLinter.new,
63
- 'TestWithNoActionStepLinter' => TestWithNoActionStepLinter.new,
64
- 'TestWithNoNameLinter' => TestWithNoNameLinter.new,
65
- 'TestWithNoVerificationStepLinter' => TestWithNoVerificationStepLinter.new,
66
- 'TestWithSetupStepAfterActionStepLinter' => TestWithSetupStepAfterActionStepLinter.new,
67
- 'TestWithSetupStepAfterVerificationStepLinter' => TestWithSetupStepAfterVerificationStepLinter.new,
68
- 'TestWithSetupStepAsFinalStepLinter' => TestWithSetupStepAsFinalStepLinter.new,
69
- 'TestWithTooManyStepsLinter' => TestWithTooManyStepsLinter.new }
70
-
71
-
72
- # Configures linters based on the given options
73
- def self.load_configuration(config_file_path: nil, config: nil)
74
- # TODO: define what happens if both a configuration file and a configuration are provided. Merge them or have direct config take precedence? Both?
75
-
76
- unless config || config_file_path
77
- config_file_path = "#{Dir.pwd}/.cuke_linter"
78
- raise 'No configuration or configuration file given and no .cuke_linter file found' unless File.exist?(config_file_path)
79
- end
80
-
81
- config = config || YAML.load_file(config_file_path)
41
+ extend CukeLinter::Configuration
42
+ extend CukeLinter::LinterRegistration
82
43
 
83
- common_config = config['AllLinters'] || {}
84
- to_delete = []
44
+ class << self
85
45
 
86
- registered_linters.each_pair do |name, linter|
87
- linter_config = config[name] || {}
88
- final_config = common_config.merge(linter_config)
46
+ # Lints the given model trees and file paths using the given linting objects and formatting
47
+ # the results with the given formatters and their respective output locations
48
+ def lint(file_paths: [], model_trees: [], linters: registered_linters.values, formatters: [[CukeLinter::PrettyFormatter.new]]) # rubocop:disable Metrics/LineLength
49
+ # TODO: Test this?
50
+ # Because directive memoization is based on a model's `#object_id` and Ruby reuses object IDs over the
51
+ # life of a program as objects are garbage collected, it is not safe to remember the IDs forever. However,
52
+ # models shouldn't get GC'd in the middle of the linting process and so the start of the linting process is
53
+ # a good time to reset things
54
+ @directives_for_feature_file = {}
89
55
 
90
- disabled = (final_config.key?('Enabled') && !final_config['Enabled'])
56
+ model_trees = [CukeModeler::Directory.new(Dir.pwd)] if model_trees.empty? && file_paths.empty?
57
+ file_path_models = collect_file_path_models(file_paths)
58
+ model_sets = model_trees + file_path_models
91
59
 
92
- # Just save it for afterwards because modifying a collection while iterating through it is not a good idea
93
- to_delete << name if disabled
60
+ linting_data = lint_models(model_sets, linters)
61
+ format_data(formatters, linting_data)
94
62
 
95
- linter.configure(final_config) if linter.respond_to?(:configure)
63
+ linting_data
96
64
  end
97
65
 
98
- to_delete.each { |linter_name| unregister_linter(linter_name) }
99
- end
100
-
101
- # Returns the registered linters to their default state
102
- def self.reset_linters
103
- @registered_linters = nil
104
- end
105
-
106
- # Registers for linting use the given linter object, tracked by the given name
107
- def self.register_linter(linter:, name:)
108
- self.registered_linters[name] = linter
109
- end
110
-
111
- # Unregisters the linter object tracked by the given name so that it is not used for linting
112
- def self.unregister_linter(name)
113
- self.registered_linters.delete(name)
114
- end
115
66
 
116
- # Lists the names of the currently registered linting objects
117
- def self.registered_linters
118
- @registered_linters ||= Marshal.load(Marshal.dump(@original_linters))
119
- end
67
+ private
120
68
 
121
- # Unregisters all currently registered linting objects
122
- def self.clear_registered_linters
123
- self.registered_linters.clear
124
- end
125
69
 
126
- # Lints the given model trees and file paths using the given linting objects and formatting the results with the given formatters and their respective output locations
127
- def self.lint(file_paths: [], model_trees: [], linters: self.registered_linters.values, formatters: [[CukeLinter::PrettyFormatter.new]])
128
-
129
- # TODO: Test this?
130
- # Because directive memoization is based on a model's `#object_id` and Ruby reuses object IDs over the
131
- # life of a program as objects are garbage collected, it is not safe to remember the IDs forever. However,
132
- # models shouldn't get GC'd in the middle of the linting process and so the start of the linting process is
133
- # a good time to reset things
134
- @directives_for_feature_file = {}
135
-
136
- model_trees = [CukeModeler::Directory.new(Dir.pwd)] if model_trees.empty? && file_paths.empty?
137
- file_path_models = file_paths.collect do |file_path|
138
- # TODO: raise exception unless path exists?
139
- case
140
- when File.directory?(file_path)
70
+ def collect_file_path_models(file_paths)
71
+ file_paths.collect do |file_path|
72
+ # TODO: raise exception unless path exists?
73
+ if File.directory?(file_path)
141
74
  CukeModeler::Directory.new(file_path)
142
- when File.file?(file_path) && File.extname(file_path) == '.feature'
75
+ elsif File.file?(file_path) && File.extname(file_path) == '.feature'
143
76
  CukeModeler::FeatureFile.new(file_path)
144
- else
145
- # Non-feature files are not modeled
146
- end
147
- end.compact # Compacting in order to get rid of any `nil` values left over from non-feature files
148
-
149
- linting_data = []
150
- model_sets = model_trees + file_path_models
151
-
152
- model_sets.each do |model_tree|
153
- model_tree.each_model do |model|
154
- applicable_linters = relevant_linters_for_model(linters, model)
155
- applicable_linters.each do |linter|
156
- # TODO: have linters lint only certain types of models?
157
- # linting_data.concat(linter.lint(model)) if relevant_model?(linter, model)
158
-
159
- result = linter.lint(model)
160
-
161
- if result
162
- result[:linter] = linter.name
163
- linting_data << result
164
- end
165
77
  end
166
- end
78
+ end.compact # Compacting in order to get rid of any `nil` values left over from non-feature files
167
79
  end
168
80
 
169
- formatters.each do |formatter_output_pair|
170
- formatter = formatter_output_pair[0]
171
- location = formatter_output_pair[1]
172
-
173
- formatted_data = formatter.format(linting_data)
174
-
175
- if location
176
- File.write(location, formatted_data)
177
- else
178
- puts formatted_data
81
+ def lint_models(model_sets, linters)
82
+ [].tap do |linting_data|
83
+ model_sets.each do |model_tree|
84
+ model_tree.each_model do |model|
85
+ applicable_linters = relevant_linters_for_model(linters, model)
86
+ applicable_linters.each do |linter|
87
+ # TODO: have linters lint only certain types of models?
88
+ # linting_data.concat(linter.lint(model)) if relevant_model?(linter, model)
89
+
90
+ result = linter.lint(model)
91
+
92
+ if result
93
+ result[:linter] = linter.name
94
+ linting_data << result
95
+ end
96
+ end
97
+ end
98
+ end
179
99
  end
180
100
  end
181
101
 
182
- linting_data
183
- end
102
+ def relevant_linters_for_model(base_linters, model)
103
+ feature_file_model = model.get_ancestor(:feature_file)
184
104
 
105
+ # Linter directives are not applicable for directory and feature file models. Every other
106
+ # model type should have a feature file ancestor from which to grab linter directive comments.
107
+ return base_linters if feature_file_model.nil?
185
108
 
186
- def self.relevant_linters_for_model(base_linters, model)
187
- feature_file_model = model.get_ancestor(:feature_file)
109
+ linter_modifications_for_model = {}
188
110
 
189
- # Linter directives are not applicable for directory and feature file models. Every other model type should have a feature file ancestor from which to grab linter directive comments.
190
- return base_linters if feature_file_model.nil?
111
+ linter_directives_for_feature_file(feature_file_model).each do |directive|
112
+ # Assuming that the directives are in the same order that they appear in the file
113
+ break if directive[:source_line] > model.source_line
191
114
 
192
- linter_modifications_for_model = {}
115
+ linter_modifications_for_model[directive[:linter_class]] = directive[:enabled_status]
116
+ end
193
117
 
194
- linter_directives_for_feature_file(feature_file_model).each do |directive|
195
- # Assuming that the directives are in the same order that they appear in the file
196
- break if directive[:source_line] > model.source_line
118
+ disabled_linter_classes = linter_modifications_for_model.reject { |_name, status| status }.keys
119
+ enabled_linter_classes = linter_modifications_for_model.select { |_name, status| status }.keys
197
120
 
198
- linter_modifications_for_model[directive[:linter_class]] = directive[:enabled_status]
121
+ determine_final_linters(base_linters, disabled_linter_classes, enabled_linter_classes)
199
122
  end
200
123
 
201
- disabled_linter_classes = linter_modifications_for_model.reject { |_name, status| status }.keys
202
- enabled_linter_classes = linter_modifications_for_model.select { |_name, status| status }.keys
124
+ def determine_final_linters(base_linters, disabled_linter_classes, enabled_linter_classes)
125
+ final_linters = base_linters.reject { |linter| disabled_linter_classes.include?(linter.class) }
203
126
 
204
- final_linters = base_linters.reject { |linter| disabled_linter_classes.include?(linter.class) }
205
- enabled_linter_classes.each do |clazz|
206
- final_linters << dynamic_linters[clazz] unless final_linters.map(&:class).include?(clazz)
207
- end
208
-
209
- final_linters
210
- end
127
+ enabled_linter_classes.each do |clazz|
128
+ final_linters << dynamic_linters[clazz] unless final_linters.map(&:class).include?(clazz)
129
+ end
211
130
 
212
- private_class_method(:relevant_linters_for_model)
131
+ final_linters
132
+ end
213
133
 
134
+ def linter_directives_for_feature_file(feature_file_model)
135
+ # IMPORTANT ASSUMPTION: Models never change during the life of a linting, so data only has to be gathered once
136
+ existing_directives = @directives_for_feature_file[feature_file_model.object_id]
214
137
 
215
- def self.linter_directives_for_feature_file(feature_file_model)
216
- # IMPORTANT ASSUMPTION: Models never change during the life of a linting, so data only has to be gathered once
217
- return @directives_for_feature_file[feature_file_model.object_id] if @directives_for_feature_file[feature_file_model.object_id]
138
+ return existing_directives if existing_directives
218
139
 
140
+ directives = gather_directives_in_feature(feature_file_model)
219
141
 
220
- @directives_for_feature_file[feature_file_model.object_id] = []
142
+ # Make sure that the directives are in the same order as they appear in the source file
143
+ directives = directives.sort_by { |a| a[:source_line] }
221
144
 
222
- feature_file_model.comments.each do |comment|
223
- pieces = comment.text.match(/#\s*cuke_linter:(disable|enable)\s+(.*)/)
224
- next unless pieces # Skipping non-directive file comments
145
+ @directives_for_feature_file[feature_file_model.object_id] = directives
146
+ end
225
147
 
226
- linter_classes = pieces[2].gsub(',', ' ').split(' ')
227
- linter_classes.each do |clazz|
228
- @directives_for_feature_file[feature_file_model.object_id] << { linter_class: Kernel.const_get(clazz),
229
- enabled_status: pieces[1] != 'disable',
230
- source_line: comment.source_line }
148
+ def gather_directives_in_feature(feature_file_model)
149
+ [].tap do |directives|
150
+ feature_file_model.comments.each do |comment|
151
+ pieces = comment.text.match(/#\s*cuke_linter:(disable|enable)\s+(.*)/)
152
+ next unless pieces # Skipping non-directive file comments
153
+
154
+ linter_classes = pieces[2].tr(',', ' ').split(' ')
155
+ linter_classes.each do |clazz|
156
+ directives << { linter_class: Kernel.const_get(clazz),
157
+ enabled_status: pieces[1] != 'disable',
158
+ source_line: comment.source_line }
159
+ end
160
+ end
231
161
  end
232
162
  end
233
163
 
234
- # Make sure that the directives are in the same order as they appear in the source file
235
- @directives_for_feature_file[feature_file_model.object_id] = @directives_for_feature_file[feature_file_model.object_id].sort { |a, b| a[:source_line] <=> b[:source_line] }
164
+ def dynamic_linters
165
+ # No need to keep making new ones over and over...
166
+ @dynamic_linters ||= Hash.new { |hash, key| hash[key] = key.new }
167
+ # return @dynamic_linters if @dynamic_linters
168
+ #
169
+ # @dynamic_linters = {}
170
+ end
236
171
 
172
+ def format_data(formatters, linting_data)
173
+ formatters.each do |formatter_output_pair|
174
+ formatter = formatter_output_pair[0]
175
+ location = formatter_output_pair[1]
237
176
 
238
- @directives_for_feature_file[feature_file_model.object_id]
239
- end
177
+ formatted_data = formatter.format(linting_data)
240
178
 
241
- private_class_method(:linter_directives_for_feature_file)
179
+ if location
180
+ File.write(location, formatted_data)
181
+ else
182
+ puts formatted_data
183
+ end
184
+ end
185
+ end
242
186
 
243
- def self.dynamic_linters
244
- # No need to keep making new ones over and over...
245
- @dynamic_linters ||= Hash.new { |hash, key| hash[key] = key.new }
246
- # return @dynamic_linters if @dynamic_linters
187
+ # Not linting unused code
188
+ # rubocop:disable Metrics/LineLength
189
+ # def self.relevant_model?(linter, model)
190
+ # model_classes = linter.class.target_model_types.map { |type| CukeModeler.const_get(type.to_s.capitalize.chop) }
191
+ # model_classes.any? { |clazz| model.is_a?(clazz) }
192
+ # end
247
193
  #
248
- # @dynamic_linters = {}
249
- end
250
-
251
- private_class_method(:dynamic_linters)
252
-
253
-
254
- # # def self.relevant_model?(linter, model)
255
- # # model_classes = linter.class.target_model_types.map { |type| CukeModeler.const_get(type.to_s.capitalize.chop) }
256
- # # model_classes.any? { |clazz| model.is_a?(clazz) }
257
- # # end
258
- # #
259
- # # private_class_method(:relevant_model?)
194
+ # private_class_method(:relevant_model?)
195
+ # rubocop:enable Metrics/LineLength
260
196
 
197
+ end
261
198
  end