cuke_linter 0.13.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -1
  3. data/README.md +4 -4
  4. data/cuke_linter.gemspec +3 -3
  5. data/lib/cuke_linter.rb +5 -3
  6. data/lib/cuke_linter/version.rb +1 -1
  7. metadata +2 -86
  8. data/.gitignore +0 -19
  9. data/.simplecov +0 -8
  10. data/.travis.yml +0 -33
  11. data/CONTRIBUTING.md +0 -26
  12. data/Gemfile +0 -6
  13. data/Rakefile +0 -63
  14. data/appveyor.yml +0 -43
  15. data/bin/console +0 -14
  16. data/bin/setup +0 -8
  17. data/environments/common_env.rb +0 -12
  18. data/environments/cucumber_env.rb +0 -22
  19. data/environments/rspec_env.rb +0 -50
  20. data/testing/cucumber/step_definitions/action_steps.rb +0 -84
  21. data/testing/cucumber/step_definitions/setup_steps.rb +0 -258
  22. data/testing/cucumber/step_definitions/verification_steps.rb +0 -94
  23. data/testing/file_helper.rb +0 -41
  24. data/testing/formatter_factory.rb +0 -15
  25. data/testing/gemfiles/cuke_modeler1.gemfile +0 -8
  26. data/testing/gemfiles/cuke_modeler2.gemfile +0 -8
  27. data/testing/linter_factory.rb +0 -60
  28. data/testing/model_factory.rb +0 -109
  29. data/testing/rspec/spec/integration/cli_integration_spec.rb +0 -556
  30. data/testing/rspec/spec/integration/configuration_spec.rb +0 -811
  31. data/testing/rspec/spec/integration/cuke_linter_integration_spec.rb +0 -243
  32. data/testing/rspec/spec/integration/formatters/formatter_integration_specs.rb +0 -5
  33. data/testing/rspec/spec/integration/formatters/pretty_formatter_integration_spec.rb +0 -8
  34. data/testing/rspec/spec/integration/linters/background_does_more_than_setup_linter_integration_spec.rb +0 -8
  35. data/testing/rspec/spec/integration/linters/element_with_common_tags_linter_integration_spec.rb +0 -8
  36. data/testing/rspec/spec/integration/linters/element_with_duplicate_tags_linter_integration_spec.rb +0 -8
  37. data/testing/rspec/spec/integration/linters/element_with_too_many_tags_linter_integration_spec.rb +0 -8
  38. data/testing/rspec/spec/integration/linters/example_without_name_linter_integration_spec.rb +0 -8
  39. data/testing/rspec/spec/integration/linters/feature_file_with_invalid_name_integration_spec.rb +0 -8
  40. data/testing/rspec/spec/integration/linters/feature_file_with_mismatched_name_integration_spec.rb +0 -8
  41. data/testing/rspec/spec/integration/linters/feature_with_too_many_different_tags_linter_integration_spec.rb +0 -8
  42. data/testing/rspec/spec/integration/linters/feature_without_description_linter_integration_spec.rb +0 -8
  43. data/testing/rspec/spec/integration/linters/feature_without_name_linter_integration_spec.rb +0 -8
  44. data/testing/rspec/spec/integration/linters/feature_without_scenarios_linter_integration_spec.rb +0 -8
  45. data/testing/rspec/spec/integration/linters/linter_integration_spec.rb +0 -8
  46. data/testing/rspec/spec/integration/linters/linter_integration_specs.rb +0 -7
  47. data/testing/rspec/spec/integration/linters/outline_with_single_example_row_linter_integration_spec.rb +0 -8
  48. data/testing/rspec/spec/integration/linters/single_test_background_linter_integration_spec.rb +0 -8
  49. data/testing/rspec/spec/integration/linters/step_with_end_period_linter_integration_spec.rb +0 -8
  50. data/testing/rspec/spec/integration/linters/step_with_too_many_characters_linter_integration_spec.rb +0 -8
  51. data/testing/rspec/spec/integration/linters/test_should_use_background_linter_integration_spec.rb +0 -8
  52. data/testing/rspec/spec/integration/linters/test_with_action_step_as_final_step_linter_integration_spec.rb +0 -8
  53. data/testing/rspec/spec/integration/linters/test_with_bad_name_integration_spec.rb +0 -8
  54. data/testing/rspec/spec/integration/linters/test_with_no_action_step_integration_spec.rb +0 -8
  55. data/testing/rspec/spec/integration/linters/test_with_no_name_integration_spec.rb +0 -8
  56. data/testing/rspec/spec/integration/linters/test_with_no_verification_step_integration_spec.rb +0 -8
  57. data/testing/rspec/spec/integration/linters/test_with_setup_step_after_action_step_linter_integration_spec.rb +0 -8
  58. data/testing/rspec/spec/integration/linters/test_with_setup_step_after_verification_step_linter_integration_spec.rb +0 -8
  59. data/testing/rspec/spec/integration/linters/test_with_setup_step_as_final_step_linter_integration_spec.rb +0 -8
  60. data/testing/rspec/spec/integration/linters/test_with_too_many_steps_linter_integration_spec.rb +0 -8
  61. data/testing/rspec/spec/unit/cuke_linter_unit_spec.rb +0 -114
  62. data/testing/rspec/spec/unit/formatters/formatter_unit_specs.rb +0 -11
  63. data/testing/rspec/spec/unit/formatters/pretty_formatter_unit_spec.rb +0 -115
  64. data/testing/rspec/spec/unit/linters/background_does_more_than_setup_linter_unit_spec.rb +0 -186
  65. data/testing/rspec/spec/unit/linters/configurable_linter_unit_specs.rb +0 -11
  66. data/testing/rspec/spec/unit/linters/element_with_common_tags_linter_unit_spec.rb +0 -248
  67. data/testing/rspec/spec/unit/linters/element_with_duplicate_tags_linter_unit_spec.rb +0 -203
  68. data/testing/rspec/spec/unit/linters/element_with_too_many_tags_linter_unit_spec.rb +0 -296
  69. data/testing/rspec/spec/unit/linters/example_without_name_linter_unit_spec.rb +0 -81
  70. data/testing/rspec/spec/unit/linters/feature_file_with_invalid_name_linter_unit_spec.rb +0 -106
  71. data/testing/rspec/spec/unit/linters/feature_file_with_mismatched_name_linter_unit_spec.rb +0 -124
  72. data/testing/rspec/spec/unit/linters/feature_with_too_many_different_tags_linter_unit_spec.rb +0 -293
  73. data/testing/rspec/spec/unit/linters/feature_without_description_linter_unit_spec.rb +0 -80
  74. data/testing/rspec/spec/unit/linters/feature_without_name_linter_unit_spec.rb +0 -84
  75. data/testing/rspec/spec/unit/linters/feature_without_scenarios_linter_unit_spec.rb +0 -102
  76. data/testing/rspec/spec/unit/linters/linter_unit_spec.rb +0 -197
  77. data/testing/rspec/spec/unit/linters/linter_unit_specs.rb +0 -57
  78. data/testing/rspec/spec/unit/linters/outline_with_single_example_row_linter_unit_spec.rb +0 -184
  79. data/testing/rspec/spec/unit/linters/single_test_background_linter_unit_spec.rb +0 -89
  80. data/testing/rspec/spec/unit/linters/step_with_end_period_linter_unit_spec.rb +0 -54
  81. data/testing/rspec/spec/unit/linters/step_with_too_many_characters_linter_unit_spec.rb +0 -155
  82. data/testing/rspec/spec/unit/linters/test_should_use_background_linter_unit_spec.rb +0 -464
  83. data/testing/rspec/spec/unit/linters/test_with_action_step_as_final_step_linter_unit_spec.rb +0 -165
  84. data/testing/rspec/spec/unit/linters/test_with_bad_name_linter_unit_spec.rb +0 -81
  85. data/testing/rspec/spec/unit/linters/test_with_no_action_step_linter_unit_spec.rb +0 -244
  86. data/testing/rspec/spec/unit/linters/test_with_no_name_linter_unit_spec.rb +0 -88
  87. data/testing/rspec/spec/unit/linters/test_with_no_verification_step_linter_unit_spec.rb +0 -246
  88. data/testing/rspec/spec/unit/linters/test_with_setup_step_after_action_step_linter_unit_spec.rb +0 -233
  89. data/testing/rspec/spec/unit/linters/test_with_setup_step_after_verification_step_linter_unit_spec.rb +0 -233
  90. data/testing/rspec/spec/unit/linters/test_with_setup_step_as_final_step_linter_unit_spec.rb +0 -164
  91. data/testing/rspec/spec/unit/linters/test_with_too_many_steps_linter_unit_spec.rb +0 -192
@@ -1,41 +0,0 @@
1
- require 'tmpdir'
2
-
3
-
4
- module CukeLinter
5
- module FileHelper
6
-
7
- class << self
8
-
9
- def created_directories
10
- @created_directories ||= []
11
- end
12
-
13
- def create_directory(options = {})
14
- options[:name] ||= 'test_directory'
15
- options[:directory] ||= Dir.mktmpdir
16
-
17
- path = "#{options[:directory]}/#{options[:name]}"
18
-
19
- Dir::mkdir(path)
20
- created_directories << options[:directory]
21
-
22
- path
23
- end
24
-
25
- def create_file(options = {})
26
- options[:text] ||= ''
27
- options[:name] ||= 'test_file'
28
- options[:extension] ||= '.txt'
29
- options[:directory] ||= create_directory
30
-
31
- file_path = "#{options[:directory]}/#{options[:name]}#{options[:extension]}"
32
- FileUtils.mkdir_p(File.dirname(file_path)) # Ensuring that the target directory already exists
33
- File.write(file_path, options[:text])
34
-
35
- file_path
36
- end
37
-
38
- end
39
-
40
- end
41
- end
@@ -1,15 +0,0 @@
1
- module CukeLinter
2
- module FormatterFactory
3
-
4
- def self.generate_fake_formatter(name: 'FakeFormater')
5
- formatter = Object.new
6
-
7
- formatter.define_singleton_method('format') do |data|
8
- data.reduce("#{name}: ") { |final, lint_error| final << "#{lint_error[:problem]}: #{lint_error[:location]}\n" }
9
- end
10
-
11
- formatter
12
- end
13
-
14
- end
15
- end
@@ -1,8 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
-
5
- # Specify your gem's dependencies in cuke_linter.gemspec
6
- gemspec :path => "../../"
7
-
8
- gem 'cuke_modeler', '~> 1.0'
@@ -1,8 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
-
5
- # Specify your gem's dependencies in cuke_linter.gemspec
6
- gemspec :path => "../../"
7
-
8
- gem 'cuke_modeler', '~> 2.0'
@@ -1,60 +0,0 @@
1
- module CukeLinter
2
- module LinterFactory
3
-
4
- def self.generate_fake_linter(name: 'FakeLinter', finds_problems: true)
5
- linter = Object.new
6
-
7
- linter.define_singleton_method('lint') do |model|
8
- location = model.respond_to?(:source_line) ? "#{model.get_ancestor(:feature_file).path}:#{model.source_line}" : model.path
9
- problem = @problem || "#{name} problem"
10
-
11
- if finds_problems
12
- { problem: problem,
13
- location: location }
14
- else
15
- nil
16
- end
17
- end
18
-
19
- linter.define_singleton_method('name') do
20
- name
21
- end
22
-
23
- linter.define_singleton_method('configure') do |options|
24
- @problem = options['Problem'] if options['Problem']
25
- end
26
-
27
-
28
- linter
29
- end
30
-
31
- def self.generate_fake_linter_class(module_name: nil, class_name: 'FakeLinter', name: 'Some Name', finds_problems: true)
32
-
33
- if module_name
34
- parent_module = Kernel.const_defined?(module_name) ? Kernel.const_get(module_name) : Kernel.const_set(module_name, Module.new)
35
- end
36
-
37
- (parent_module || Kernel).const_set(class_name, Class.new do
38
-
39
- define_method('lint') do |model|
40
- location = model.respond_to?(:source_line) ? "#{model.get_ancestor(:feature_file).path}:#{model.source_line}" : model.path
41
- problem = @problem || "#{name} problem"
42
-
43
- if finds_problems
44
- { problem: problem,
45
- location: location }
46
- else
47
- nil
48
- end
49
- end
50
-
51
- define_method('name') do
52
- name
53
- end
54
-
55
- end)
56
-
57
- end
58
-
59
- end
60
- end
@@ -1,109 +0,0 @@
1
- module CukeLinter
2
-
3
- # A simple model used for testing
4
-
5
- class TestModel < CukeModeler::Model
6
-
7
- include CukeModeler::Sourceable
8
- include CukeModeler::Taggable
9
-
10
- def initialize
11
- super
12
-
13
- @tags = []
14
- end
15
-
16
- end
17
- end
18
-
19
-
20
- module CukeLinter
21
-
22
- # A helper module that generates various models for use in testing
23
-
24
- module ModelFactory
25
-
26
- def self.generate_feature_model(source_text: 'Feature:', parent_file_path: 'path_to_file')
27
- fake_parent_model = CukeModeler::FeatureFile.new
28
- fake_parent_model.path = parent_file_path
29
-
30
- model = CukeModeler::Feature.new(source_text)
31
- model.parent_model = fake_parent_model
32
-
33
- fake_parent_model.feature = model
34
-
35
- model
36
- end
37
-
38
- def self.generate_feature_file_model
39
- model = CukeModeler::FeatureFile.new
40
-
41
- model
42
- end
43
-
44
- def self.generate_example_model(source_text: 'Examples:', parent_file_path: 'path_to_file')
45
- fake_parent_model = generate_outline_model(parent_file_path: parent_file_path)
46
-
47
- model = CukeModeler::Example.new(source_text)
48
- model.parent_model = fake_parent_model
49
-
50
- model
51
- end
52
-
53
- def self.generate_outline_model(source_text: "Scenario Outline:", parent_file_path: 'path_to_file')
54
- fake_parent_model = generate_feature_model(parent_file_path: parent_file_path)
55
-
56
- model = CukeModeler::Outline.new(source_text)
57
- model.parent_model = fake_parent_model
58
-
59
- model
60
- end
61
-
62
- def self.generate_scenario_model(source_text: 'Scenario:', parent_file_path: 'path_to_file')
63
- fake_parent_model = generate_feature_model(parent_file_path: parent_file_path)
64
-
65
- model = CukeModeler::Scenario.new(source_text)
66
- model.parent_model = fake_parent_model
67
-
68
- model
69
- end
70
-
71
- def self.generate_background_model(source_text: "Background:\n* a step", parent_file_path: 'path_to_file')
72
- fake_parent_model = generate_feature_model(parent_file_path: parent_file_path)
73
-
74
- model = CukeModeler::Background.new(source_text)
75
- model.parent_model = fake_parent_model
76
-
77
- model
78
- end
79
-
80
- def self.generate_step_model(source_text: '* a step', parent_file_path: 'path_to_file')
81
- fake_parent_model = generate_scenario_model(parent_file_path: parent_file_path)
82
-
83
- model = CukeModeler::Step.new(source_text)
84
- model.parent_model = fake_parent_model
85
-
86
- model
87
- end
88
-
89
- def self.generate_tag_model(source_text: '@a_tag')
90
- CukeModeler::Tag.new(source_text)
91
- end
92
-
93
- def self.generate_lintable_model(parent_file_path: 'path_to_file', source_line: 1, children: [])
94
- fake_file_model = CukeModeler::FeatureFile.new
95
- fake_file_model.path = parent_file_path
96
-
97
- model = CukeLinter::TestModel.new
98
- model.parent_model = fake_file_model
99
- model.source_line = source_line
100
-
101
- model.define_singleton_method('children') do
102
- children
103
- end
104
-
105
- model
106
- end
107
-
108
- end
109
- end
@@ -1,556 +0,0 @@
1
- require_relative '../../../../environments/rspec_env'
2
- require 'open3'
3
-
4
-
5
- RSpec.describe 'the Command Line Interface' do
6
-
7
- # Exit codes that are expected during normal use of the CLI
8
- let(:normal_exit_codes) { [0, 1] }
9
-
10
- # A minimal fake test suite that should be available for every spec
11
- let!(:test_directory) { CukeLinter::FileHelper.create_directory }
12
- let!(:linted_file) { CukeLinter::FileHelper.create_file(directory: test_directory,
13
- name: 'lacking_a_description',
14
- extension: '.feature',
15
- text: 'Feature:
16
- Scenario: A scenario
17
- When a step
18
- Then a step') }
19
-
20
- # Stuff that is not always needed and so can be lazy instantiated
21
- let(:executable_directory) { "#{PROJECT_ROOT}/exe" }
22
- let(:executable_name) { 'cuke_linter' }
23
- let(:executable_path) { "#{executable_directory}/#{executable_name}" }
24
- let(:command) { "bundle exec ruby #{executable_path}" }
25
- let(:results) { std_out, std_err, status = [nil, nil, nil]
26
-
27
- Dir.chdir(test_directory) do
28
- std_out, std_err, status = Open3.capture3(command)
29
- end
30
-
31
- { std_out: std_out, std_err: std_err, status: status } }
32
- let(:expected_help_text) { ['Usage: cuke_linter [options]',
33
- ' -p, --path PATH The file path that should be linted. Can be a file or directory.',
34
- ' This option can be specified multiple times in order to lint',
35
- ' multiple, unconnected locations.',
36
- ' -f, --formatter FORMATTER The formatter used for generating linting output. This option',
37
- ' can be specified multiple times in order to use more than one',
38
- ' formatter. Formatters must be specified using their fully',
39
- ' qualified class name (e.g CukeLinter::PrettyFormatter). Uses',
40
- ' the default formatter if none are specified.',
41
- ' -o, --out OUT The file path to which linting results are output. Can be specified',
42
- ' multiple times. Specified files are matched to formatters in the',
43
- ' same order that the formatters are specified. Any formatter without',
44
- ' a corresponding file path will output to STDOUT instead.',
45
- ' -r, --require FILEPATH A file that will be required before further processing. Likely',
46
- ' needed when using custom linters or formatters in order to ensure',
47
- ' that the specified classes have been read into memory. This option',
48
- ' can be specified multiple times in order to load more than one file.',
49
- ' -c, --config FILEPATH The configuration file that will be used. Will use the default',
50
- ' configuration file (if present) if this option is not specified.',
51
- ' -h, --help Display the help that you are reading now.',
52
- ' -v, --version Display the version of the gem being used.',
53
- ''].join("\n") }
54
-
55
- context 'with no additional arguments' do
56
-
57
- let(:command) { "bundle exec ruby #{executable_path}" }
58
-
59
- it 'can run cleanly by default' do
60
- expect(normal_exit_codes).to include(results[:status].exitstatus)
61
- end
62
-
63
- context 'when the default configuration file exists' do
64
-
65
- before(:each) do
66
- CukeLinter::FileHelper.create_file(directory: test_directory,
67
- name: '.cuke_linter',
68
- extension: '',
69
- text: 'AllLinters:
70
- Enabled: false')
71
- end
72
-
73
- it 'uses the default configuration file by default' do
74
- expect(results[:std_out]).to include("0 issues found\n")
75
- end
76
-
77
- end
78
-
79
- context 'when the default configuration file does not exist' do
80
-
81
- before(:each) do
82
- Dir.chdir(test_directory) do
83
- FileUtils.rm('./.cuke_linter') if File.exist?('./.cuke_linter')
84
- end
85
- end
86
-
87
- it 'can still run cleanly' do
88
- expect(normal_exit_codes).to include(results[:status].exitstatus)
89
- end
90
-
91
- end
92
-
93
- end
94
-
95
- describe 'exit codes' do
96
-
97
- context 'when no problems are found' do
98
- # This file does not have any problems with the current linter set
99
- let!(:linted_file) { CukeLinter::FileHelper.create_file(directory: test_directory,
100
- name: 'nothing_wrong',
101
- extension: '.feature',
102
- text: 'Feature: Nothing wrong
103
- A description
104
- Scenario: A scenario
105
- When a step
106
- Then a step') }
107
-
108
- it 'returns a zero exit code' do
109
- expect(results[:status].exitstatus).to eq(0)
110
- end
111
-
112
- end
113
-
114
- context 'when linting problems are found' do
115
- # This should be a problematic feature file
116
- let!(:linted_file) { CukeLinter::FileHelper.create_file(directory: test_directory,
117
- name: 'pretty_empty',
118
- extension: '.feature',
119
- text: 'Feature: ') }
120
-
121
- it 'returns a non-zero exit code' do
122
- expect(results[:status].exitstatus).to eq(1)
123
- end
124
-
125
- end
126
-
127
- context 'when something else goes wrong' do
128
-
129
- # Bad CLI usage due to missing required flag arguments
130
- let(:command) { "bundle exec ruby #{executable_path} -r" }
131
-
132
- it 'returns a different non-zero exit code' do
133
- expect(results[:status].exitstatus).to eq(2)
134
- end
135
-
136
- end
137
- end
138
-
139
-
140
- describe 'option flags' do
141
-
142
- context 'with a path flag' do
143
- ['-p', '--path'].each do |path_flag|
144
-
145
- context "using the '#{path_flag}' form" do
146
-
147
- let(:flag) { path_flag }
148
-
149
- context 'with path arguments' do
150
- let(:file_1) { CukeLinter::FileHelper.create_file(directory: test_directory,
151
- name: 'some_feature',
152
- extension: '.feature',
153
- text: 'Feature: Some feature
154
- Scenario: A scenario
155
- When a step
156
- Then a step') }
157
- let(:file_2) { CukeLinter::FileHelper.create_file(directory: test_directory,
158
- name: 'a_directory/with/some_feature',
159
- extension: '.feature',
160
- text: 'Feature: Some feature
161
- Scenario: A scenario
162
- When a step
163
- Then a step') }
164
- let(:file_1_path) { file_1 }
165
- let(:file_2_directory) { File.dirname(file_2) }
166
- let(:command) { "bundle exec ruby #{executable_path} #{flag} #{file_1_path} #{flag} #{file_2_directory}" }
167
-
168
- # TODO: add a negative test that makes sure that non-included paths aren't linted when paths are explicitly included
169
-
170
- it "lints that locations specified by '#{path_flag}'" do
171
- expect(results[:std_out]).to eq(['FeatureWithoutDescriptionLinter',
172
- ' Feature has no description',
173
- ' <path_to>/a_directory/with/some_feature.feature:1',
174
- ' <path_to>/some_feature.feature:1',
175
- '',
176
- '2 issues found',
177
- ''].join("\n").gsub('<path_to>', test_directory))
178
- end
179
-
180
- end
181
-
182
- context 'without path arguments' do
183
-
184
- let(:command) { "bundle exec ruby #{executable_path} #{flag}" }
185
-
186
-
187
- it 'complains about the missing argument' do
188
- expect(results[:std_out]).to include("missing argument: #{flag}")
189
- end
190
-
191
- it 'displays the help text' do
192
- expect(results[:std_out]).to include(expected_help_text)
193
- end
194
-
195
- it 'exits with an error' do
196
- expect(results[:status].exitstatus).to eq(2)
197
- end
198
-
199
- end
200
-
201
- end
202
- end
203
- end
204
-
205
- context 'with a formatter flag' do
206
- ['-f', '--formatter'].each do |formatter_flag|
207
-
208
- context "using the '#{formatter_flag}' form" do
209
-
210
- let(:flag) { formatter_flag }
211
-
212
- context 'with formatter arguments' do
213
- let(:linted_file) { CukeLinter::FileHelper.create_file(name: 'some_feature',
214
- extension: '.feature',
215
- text: 'Feature: Some feature
216
- Scenario: A scenario
217
- When a step
218
- Then a step') }
219
- let(:formatter_class) { 'AFakeFormatter' }
220
- let(:formatter_class_in_module) { 'CukeLinter::AnotherFakeFormatter' }
221
- let(:formatter_class_file) { CukeLinter::FileHelper.create_file(extension: '.rb',
222
- text: 'class AFakeFormatter
223
- def format(data)
224
- data.reduce("#{self.class}: ") { |final, lint_error| final << "#{lint_error[:problem]}: #{lint_error[:location]}\n" }
225
- end
226
- end') }
227
- let(:formatter_class_in_module_file) { CukeLinter::FileHelper.create_file(extension: '.rb',
228
- text: 'module CukeLinter
229
- class AnotherFakeFormatter
230
- def format(data)
231
- data.reduce("#{self.class}: ") { |final, lint_error| final << "#{lint_error[:problem]}: #{lint_error[:location]}\n" }
232
- end
233
- end
234
- end') }
235
- let(:command) { "bundle exec ruby #{executable_path} #{flag} #{formatter_class} #{flag} #{formatter_class_in_module} -p #{linted_file} -r #{formatter_class_file} -r #{formatter_class_in_module_file}" }
236
-
237
-
238
- it "uses the formatters specified by '#{formatter_flag}'" do
239
- expect(results[:std_out]).to eq(['AFakeFormatter: Feature has no description: <path_to_file>:1',
240
- 'CukeLinter::AnotherFakeFormatter: Feature has no description: <path_to_file>:1',
241
- ''].join("\n").gsub('<path_to_file>', linted_file))
242
- end
243
-
244
- end
245
-
246
- context 'without formatter arguments' do
247
-
248
- let(:command) { "bundle exec ruby #{executable_path} #{flag}" }
249
-
250
-
251
- it 'complains about the missing argument' do
252
- expect(results[:std_out]).to include("missing argument: #{flag}")
253
- end
254
-
255
- it 'displays the help text' do
256
- expect(results[:std_out]).to include(expected_help_text)
257
- end
258
-
259
- it 'exits with an error' do
260
- expect(results[:status].exitstatus).to eq(2)
261
- end
262
-
263
- end
264
-
265
- end
266
- end
267
- end
268
-
269
- context 'with an output flag' do
270
- ['-o', '--out'].each do |output_flag|
271
-
272
- context "using the '#{output_flag}' form" do
273
-
274
- let(:flag) { output_flag }
275
-
276
- context 'with output arguments' do
277
- let(:output_location) { "#{CukeLinter::FileHelper.create_directory}/output.txt" }
278
- let(:other_output_location) { "#{CukeLinter::FileHelper.create_directory}/other_output.txt" }
279
- let(:linted_file) { CukeLinter::FileHelper.create_file(name: 'some_feature',
280
- extension: '.feature',
281
- text: 'Feature: Some feature
282
- Scenario: A scenario
283
- When a step
284
- Then a step') }
285
- let(:formatter_class_1) { 'AFakeFormatter' }
286
- let(:formatter_class_2) { 'AnotherFakeFormatter' }
287
- let(:formatter_class_file) { CukeLinter::FileHelper.create_file(extension: '.rb',
288
- text: 'class AFakeFormatter
289
- def format(data)
290
- "Formatting done by #{self.class}"
291
- end
292
- end
293
-
294
- class AnotherFakeFormatter
295
- def format(data)
296
- "Formatting done by #{self.class}"
297
- end
298
- end') }
299
- let(:command) { "bundle exec ruby #{executable_path} -f #{formatter_class_1} -f #{formatter_class_2} #{flag} #{output_location} #{flag} #{other_output_location} -p #{linted_file} -r #{formatter_class_file}" }
300
-
301
-
302
- it 'matches output locations to formatters in the same order that they are specified' do
303
- # Have to trigger the command
304
- results
305
-
306
- expect(File.read(output_location)).to eq('Formatting done by AFakeFormatter')
307
- expect(File.read(other_output_location)).to eq('Formatting done by AnotherFakeFormatter')
308
- end
309
-
310
-
311
- context 'with unmatched output arguments' do
312
- let(:command) { "bundle exec ruby #{executable_path} #{flag} #{output_location} -p #{linted_file}" }
313
-
314
-
315
- it "outputs to the location specified by '#{output_flag}'" do
316
- # Have to trigger the command
317
- results
318
-
319
- expect(File.read(output_location)).to eq(['FeatureWithoutDescriptionLinter',
320
- ' Feature has no description',
321
- ' <path_to_file>:1',
322
- '',
323
- '1 issues found'].join("\n").gsub('<path_to_file>', linted_file))
324
- end
325
-
326
- it 'does not output to STDOUT' do
327
- expect(results[:std_out]).to eq('')
328
- end
329
-
330
- it 'uses the default formatter' do
331
- # Have to trigger the command
332
- results
333
-
334
- expect(File.read(output_location)).to eq(['FeatureWithoutDescriptionLinter',
335
- ' Feature has no description',
336
- ' <path_to_file>:1',
337
- '',
338
- '1 issues found'].join("\n").gsub('<path_to_file>', linted_file))
339
- end
340
-
341
- end
342
-
343
- context 'with unmatched formatter arguments' do
344
- let(:command) { "bundle exec ruby #{executable_path} #{flag} #{output_location} -f #{formatter_class_1} -f #{formatter_class_2} -p #{linted_file} -r #{formatter_class_file}" }
345
-
346
-
347
- it "outputs to the location specified by '#{output_flag}' for the matched formatters" do
348
- # Have to trigger the command
349
- results
350
-
351
- expect(File.read(output_location)).to eq("Formatting done by #{formatter_class_1}")
352
- end
353
-
354
- it 'outputs to STDOUT for the unmatched formatters' do
355
- expect(results[:std_out]).to eq("Formatting done by #{formatter_class_2}\n")
356
- end
357
-
358
- end
359
-
360
- end
361
-
362
-
363
- context 'without output arguments' do
364
-
365
- let(:command) { "bundle exec ruby #{executable_path} #{flag}" }
366
-
367
-
368
- it 'complains about the missing argument' do
369
- expect(results[:std_out]).to include("missing argument: #{flag}")
370
- end
371
-
372
- it 'displays the help text' do
373
- expect(results[:std_out]).to include(expected_help_text)
374
- end
375
-
376
- it 'exits with an error' do
377
- expect(results[:status].exitstatus).to eq(2)
378
- end
379
-
380
- end
381
-
382
- end
383
- end
384
- end
385
-
386
- context 'with a require flag' do
387
- ['-r', '--require'].each do |require_flag|
388
-
389
- context "using the '#{require_flag}' form" do
390
-
391
- let(:flag) { require_flag }
392
-
393
- context 'with require arguments' do
394
- let(:file_1) { CukeLinter::FileHelper.create_file(extension: '.rb',
395
- text: "puts 'This file was loaded'") }
396
- let(:file_1_path) { file_1 }
397
- let(:file_2) { CukeLinter::FileHelper.create_file(extension: '.rb',
398
- text: "puts 'This file was also loaded'") }
399
- let(:file_2_path) { file_2 }
400
- let(:command) { "bundle exec ruby #{executable_path} #{flag} #{file_1_path} #{flag} #{file_2_path}" }
401
-
402
-
403
- it "require the files specified by '#{require_flag}' before linting" do
404
- expect(results[:std_out]).to include('This file was loaded')
405
- expect(results[:std_out]).to include('This file was also loaded')
406
- end
407
-
408
- end
409
-
410
- context 'without require arguments' do
411
-
412
- let(:command) { "bundle exec ruby #{executable_path} #{flag}" }
413
-
414
-
415
- it 'complains about the missing argument' do
416
- expect(results[:std_out]).to include("missing argument: #{flag}")
417
- end
418
-
419
- it 'displays the help text' do
420
- expect(results[:std_out]).to include(expected_help_text)
421
- end
422
-
423
- it 'exits with an error' do
424
- expect(results[:status].exitstatus).to eq(2)
425
- end
426
-
427
- end
428
-
429
- end
430
- end
431
- end
432
-
433
- context 'with a config flag' do
434
- ['-c', '--config'].each do |config_flag|
435
-
436
- context "using the '#{config_flag}' form" do
437
-
438
- let(:flag) { config_flag }
439
-
440
- context 'with a single config argument' do
441
-
442
- let(:config_file) { CukeLinter::FileHelper.create_file(name: 'my_config_file',
443
- extension: '.yml',
444
- text: 'AllLinters:
445
- Enabled: false') }
446
- let(:command) { "bundle exec ruby #{executable_path} #{flag} #{config_file}" }
447
-
448
- it "uses the configuration file specified by '#{config_flag}'" do
449
- expect(results[:std_out]).to include("0 issues found\n")
450
- end
451
-
452
- end
453
-
454
- context 'with multiple config arguments' do
455
-
456
- let(:command) { "bundle exec ruby #{executable_path} #{flag} foo #{flag} bar" }
457
-
458
- it 'complains that more than one configuration file is specified' do
459
- expect(results[:std_out]).to eq("Cannot specify more than one configuration file!\n")
460
- end
461
-
462
- it 'exits with an error' do
463
- expect(results[:status].exitstatus).to eq(2)
464
- end
465
-
466
- end
467
-
468
- context 'without config arguments' do
469
-
470
- let(:command) { "bundle exec ruby #{executable_path} #{flag}" }
471
-
472
-
473
- it 'complains about the missing argument' do
474
- expect(results[:std_out]).to include("missing argument: #{flag}")
475
- end
476
-
477
- it 'displays the help text' do
478
- expect(results[:std_out]).to include(expected_help_text)
479
- end
480
-
481
- it 'exits with an error' do
482
- expect(results[:status].exitstatus).to eq(2)
483
- end
484
-
485
- end
486
-
487
- end
488
- end
489
- end
490
-
491
- context 'with a help flag' do
492
-
493
- let(:command) { "bundle exec ruby #{executable_path} #{flag}" }
494
-
495
- ['-h', '--help'].each do |help_flag|
496
-
497
- context "using the '#{help_flag}' form" do
498
-
499
- let(:flag) { help_flag }
500
-
501
- it "'#{help_flag}' displays the help text" do
502
- expect(results[:std_out]).to eq(expected_help_text)
503
- end
504
-
505
- it 'exits cleanly' do
506
- expect(results[:status].exitstatus).to eq(0)
507
- end
508
-
509
- end
510
- end
511
- end
512
-
513
- context 'with a version flag' do
514
-
515
- let(:command) { "bundle exec ruby #{executable_path} #{flag}" }
516
-
517
- ['-v', '--version'].each do |version_flag|
518
-
519
- context "using the '#{version_flag}' form" do
520
-
521
- let(:flag) { version_flag }
522
-
523
- it "'#{version_flag}' displays the version being used" do
524
- expect(results[:std_out]).to eq("#{CukeLinter::VERSION}\n")
525
- end
526
-
527
- it 'exits cleanly' do
528
- expect(results[:status].exitstatus).to eq(0)
529
- end
530
-
531
- end
532
- end
533
- end
534
-
535
- context 'with an invalid flag' do
536
-
537
- let(:command) { "bundle exec ruby #{executable_path} #{flag}" }
538
- let(:flag) { '--not_a_real_flag' }
539
-
540
- it 'complains about the invalid flag' do
541
- expect(results[:std_out]).to include("invalid option: #{flag}")
542
- end
543
-
544
- it 'displays the help text' do
545
- expect(results[:std_out]).to include(expected_help_text)
546
- end
547
-
548
- it 'exits with an error' do
549
- expect(results[:status].exitstatus).to eq(2)
550
- end
551
-
552
- end
553
-
554
- end
555
-
556
- end