cuke_linter 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +19 -16
  3. data/CHANGELOG.md +12 -1
  4. data/lib/cuke_linter/linters/background_does_more_than_setup_linter.rb +20 -0
  5. data/lib/cuke_linter/linters/feature_without_description_linter.rb +20 -0
  6. data/lib/cuke_linter/linters/single_test_background_linter.rb +20 -0
  7. data/lib/cuke_linter/linters/step_with_end_period_linter.rb +20 -0
  8. data/lib/cuke_linter/linters/step_with_too_many_characters_linter.rb +39 -0
  9. data/lib/cuke_linter/version.rb +1 -1
  10. data/lib/cuke_linter.rb +13 -2
  11. data/testing/cucumber/features/linters/background_does_more_than_setup_linter.feature +50 -0
  12. data/testing/cucumber/features/linters/default_linters.feature +7 -0
  13. data/testing/cucumber/features/linters/feature_without_description.feature +17 -0
  14. data/testing/cucumber/features/linters/single_test_background_linter.feature +24 -0
  15. data/testing/cucumber/features/linters/step_too_long.feature +43 -0
  16. data/testing/cucumber/features/linters/step_with_end_period.feature +21 -0
  17. data/testing/cucumber/step_definitions/setup_steps.rb +24 -0
  18. data/testing/model_factory.rb +18 -0
  19. data/testing/rspec/spec/integration/cuke_linter_integration_spec.rb +12 -2
  20. data/testing/rspec/spec/integration/linters/background_does_more_than_setup_linter_integration_spec.rb +8 -0
  21. data/testing/rspec/spec/integration/linters/feature_without_description_linter_integration_spec.rb +8 -0
  22. data/testing/rspec/spec/integration/linters/single_test_background_linter_integration_spec.rb +8 -0
  23. data/testing/rspec/spec/integration/linters/step_with_end_period_linter_integration_spec.rb +8 -0
  24. data/testing/rspec/spec/integration/linters/step_with_too_many_characters_linter_integration_spec.rb +8 -0
  25. data/testing/rspec/spec/unit/linters/background_does_more_than_setup_linter_unit_spec.rb +114 -0
  26. data/testing/rspec/spec/unit/linters/feature_without_description_linter_unit_spec.rb +97 -0
  27. data/testing/rspec/spec/unit/linters/single_test_background_linter_unit_spec.rb +116 -0
  28. data/testing/rspec/spec/unit/linters/step_with_end_period_linter_unit_spec.rb +73 -0
  29. data/testing/rspec/spec/unit/linters/step_with_too_many_characters_linter_unit_spec.rb +180 -0
  30. data/testing/rspec/spec/unit/linters/test_with_too_many_steps_linter_unit_spec.rb +8 -5
  31. metadata +22 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 232cb6cefe917fc75ea2c3b21da060298a4b4f1d4c392dd0853ee2cef91bb80d
4
- data.tar.gz: b8365e3d6b4b82bb494a9af552ee06db6467dac7e73d144a5c7dcc4df8d7b59c
3
+ metadata.gz: 6d4a41e4f1d37dde72387b44003228f891855230312e1da57ffe227fa7f1f853
4
+ data.tar.gz: ec0842ceccb4025aad332923ae0df4d921250f58f5f2a97f82818b0d7d0717c4
5
5
  SHA512:
6
- metadata.gz: e2ad543a81bd093b5856e82fe7fb2bcf74447dcd96f1816adc47dcb220253d4a5e581e2e7fa7414cbb595b34815e217f431fb658f4ce70f4a779f8ff1bbc603c
7
- data.tar.gz: b721820908884a39d786de81e8b87ff3c77daa4ff77037ad87384e301f3391f005328c0147aae9b093aea40552cf35a030db62c563c893838bef275f61dd44f9
6
+ metadata.gz: c8c38a81b0d6fe47db0f46eaefbc61a8c00305f90273d752fc81e7eb364278f2dc36cc7bf09b487bb183543a27b3380fe219eb7049d934e54fb2f117bc1a31a9
7
+ data.tar.gz: 8f8a924840f5ce979fe6037e85dca647eb70f91b1f7b2a1a3ee9e31716af04475a9b54095769d703cb796b41c6089366e1dd6d0a61652fd4cc430330fb774df7
data/.gitignore CHANGED
@@ -1,16 +1,19 @@
1
- /.bundle/
2
- /.yardoc
3
- /_yardoc/
4
- /coverage/
5
- /doc/
6
- /pkg/
7
- /spec/reports/
8
- /tmp/
9
-
10
- # rspec failure tracking
11
- .rspec_status
12
-
13
- # JetBrains IDE metadata folders
14
- /.idea
15
-
16
- Gemfile.lock
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
12
+
13
+ # JetBrains IDE metadata folders
14
+ /.idea
15
+
16
+ # Mac metadata directories
17
+ .DS_Store
18
+
19
+ Gemfile.lock
data/CHANGELOG.md CHANGED
@@ -8,6 +8,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8
8
 
9
9
  Nothing yet...
10
10
 
11
+ ## [0.5.0] - 2019-05-25
12
+
13
+ ### Added
14
+ - New linters
15
+ - BackgroundDoesMoreThanSetupLinter
16
+ - FeatureWithoutDescriptionLinter
17
+ - SingleTestBackgroundLinter
18
+ - StepWithEndPeriodLinter
19
+ - StepWithTooManyCharactersLinter
20
+
11
21
  ## [0.4.0] - 2019-05-11
12
22
 
13
23
  ### Added
@@ -41,7 +51,8 @@ Nothing yet...
41
51
  - Custom linters, formatters, and command line usability
42
52
 
43
53
 
44
- [Unreleased]: https://github.com/enkessler/cuke_linter/compare/v0.4.0...HEAD
54
+ [Unreleased]: https://github.com/enkessler/cuke_linter/compare/v0.5.0...HEAD
55
+ [0.5.0]: https://github.com/enkessler/cuke_linter/compare/v0.4.0...v0.5.0
45
56
  [0.4.0]: https://github.com/enkessler/cuke_linter/compare/v0.3.1...v0.4.0
46
57
  [0.3.1]: https://github.com/enkessler/cuke_linter/compare/v0.3.0...v0.3.1
47
58
  [0.3.0]: https://github.com/enkessler/cuke_linter/compare/v0.2.0...v0.3.0
@@ -0,0 +1,20 @@
1
+ module CukeLinter
2
+
3
+ # A linter that detects backgrounds that have non-setup steps
4
+
5
+ class BackgroundDoesMoreThanSetupLinter < Linter
6
+
7
+ # The rule used to determine if a model has a problem
8
+ def rule(model)
9
+ return false unless model.is_a?(CukeModeler::Background)
10
+
11
+ model.steps.collect(&:keyword).any? { |keyword| (keyword == 'When') || (keyword == 'Then') }
12
+ end
13
+
14
+ # The message used to describe the problem that has been found
15
+ def message
16
+ 'Background has non-setup steps'
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ module CukeLinter
2
+
3
+ # A linter that detects features that don't have a description
4
+
5
+ class FeatureWithoutDescriptionLinter < Linter
6
+
7
+ # The rule used to determine if a model has a problem
8
+ def rule(model)
9
+ return false unless model.is_a?(CukeModeler::Feature)
10
+
11
+ model.description.nil? || model.description.empty?
12
+ end
13
+
14
+ # The message used to describe the problem that has been found
15
+ def message
16
+ "Feature has no description"
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ module CukeLinter
2
+
3
+ # A linter that detects backgrounds that apply to only one test
4
+
5
+ class SingleTestBackgroundLinter < Linter
6
+
7
+ # The rule used to determine if a model has a problem
8
+ def rule(model)
9
+ return false unless model.is_a?(CukeModeler::Background)
10
+
11
+ model.parent_model.tests.count == 1
12
+ end
13
+
14
+ # The message used to describe the problem that has been found
15
+ def message
16
+ 'Background used with only one test'
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ module CukeLinter
2
+
3
+ # A linter that detects steps that end in a period
4
+
5
+ class StepWithEndPeriodLinter < Linter
6
+
7
+ # The rule used to determine if a model has a problem
8
+ def rule(model)
9
+ return false unless model.is_a?(CukeModeler::Step)
10
+
11
+ model.text.end_with?('.')
12
+ end
13
+
14
+ # The message used to describe the problem that has been found
15
+ def message
16
+ 'Step ends with a period'
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,39 @@
1
+ module CukeLinter
2
+
3
+ # A linter that detects steps that are too long
4
+
5
+ class StepWithTooManyCharactersLinter < Linter
6
+
7
+ # The threshold used if not otherwise configured
8
+ DEFAULT_STEP_LENGTH_THRESHOLD = 80
9
+
10
+ # Changes the linting settings on the linter using the provided configuration
11
+ def configure(options)
12
+ @step_length_threshold = options['StepLengthThreshold'] if options['StepLengthThreshold']
13
+ end
14
+
15
+ # The rule used to determine if a model has a problem
16
+ def rule(model)
17
+ return false unless model.is_a?(CukeModeler::Step)
18
+
19
+ @linted_step_length = model.text&.length || 0
20
+
21
+ @linted_step_length > step_length_threshold
22
+ end
23
+
24
+ # The message used to describe the problem that has been found
25
+ def message
26
+ "Step is too long. #{@linted_step_length} characters found (max #{step_length_threshold})"
27
+ end
28
+
29
+
30
+ private
31
+
32
+
33
+ # The maximum length allowable of a step
34
+ def step_length_threshold
35
+ @step_length_threshold || DEFAULT_STEP_LENGTH_THRESHOLD
36
+ end
37
+
38
+ end
39
+ end
@@ -1,4 +1,4 @@
1
1
  module CukeLinter
2
2
  # The release version of this gem
3
- VERSION = "0.4.0"
3
+ VERSION = "0.5.0"
4
4
  end
data/lib/cuke_linter.rb CHANGED
@@ -3,9 +3,14 @@ require 'cuke_modeler'
3
3
  require "cuke_linter/version"
4
4
  require 'cuke_linter/formatters/pretty_formatter'
5
5
  require 'cuke_linter/linters/linter'
6
+ require 'cuke_linter/linters/background_does_more_than_setup_linter'
6
7
  require 'cuke_linter/linters/example_without_name_linter'
8
+ require 'cuke_linter/linters/feature_without_description_linter'
7
9
  require 'cuke_linter/linters/feature_without_scenarios_linter'
8
10
  require 'cuke_linter/linters/outline_with_single_example_row_linter'
11
+ require 'cuke_linter/linters/single_test_background_linter'
12
+ require 'cuke_linter/linters/step_with_end_period_linter'
13
+ require 'cuke_linter/linters/step_with_too_many_characters_linter'
9
14
  require 'cuke_linter/linters/test_with_too_many_steps_linter'
10
15
 
11
16
 
@@ -13,10 +18,16 @@ require 'cuke_linter/linters/test_with_too_many_steps_linter'
13
18
 
14
19
  module CukeLinter
15
20
 
16
- @original_linters = { 'FeatureWithoutScenariosLinter' => FeatureWithoutScenariosLinter.new,
21
+ @original_linters = { 'BackgroundDoesMoreThanSetupLinter' => BackgroundDoesMoreThanSetupLinter.new,
17
22
  'ExampleWithoutNameLinter' => ExampleWithoutNameLinter.new,
23
+ 'FeatureWithoutDescriptionLinter' => FeatureWithoutDescriptionLinter.new,
24
+ 'FeatureWithoutScenariosLinter' => FeatureWithoutScenariosLinter.new,
18
25
  'OutlineWithSingleExampleRowLinter' => OutlineWithSingleExampleRowLinter.new,
26
+ 'SingleTestBackgroundLinter' => SingleTestBackgroundLinter.new,
27
+ 'StepWithEndPeriodLinter' => StepWithEndPeriodLinter.new,
28
+ 'StepWithTooManyCharactersLinter' => StepWithTooManyCharactersLinter.new,
19
29
  'TestWithTooManyStepsLinter' => TestWithTooManyStepsLinter.new }
30
+
20
31
 
21
32
  # Configures linters based on the given options
22
33
  def self.load_configuration(config_file_path: nil, config: nil)
@@ -28,7 +39,7 @@ module CukeLinter
28
39
  end
29
40
 
30
41
  config = config || YAML.load_file(config_file_path)
31
-
42
+
32
43
  config.each_pair do |linter_name, options|
33
44
  unregister_linter(linter_name) if options.key?('Enabled') && !options['Enabled']
34
45
 
@@ -0,0 +1,50 @@
1
+ Feature: Background does more than setup linter
2
+
3
+ As a reader of documentation
4
+ I want to backgrounds to not contain actions or verifications
5
+ So that what is being demonstrated in individual use cases is clear
6
+
7
+
8
+ Scenario: Linting backgrounds with action steps
9
+ Given a linter for backgrounds that do more than setup
10
+ And the following feature:
11
+ """
12
+ Feature:
13
+
14
+ Background:
15
+ Given some setup
16
+ When some action
17
+ """
18
+ When it is linted
19
+ Then an error is reported
20
+ | linter | problem | location |
21
+ | BackgroundDoesMoreThanSetupLinter | Background has non-setup steps | <path_to_file>:3 |
22
+
23
+ Scenario: Linting backgrounds with verification steps
24
+ Given a linter for backgrounds that do more than setup
25
+ And the following feature:
26
+ """
27
+ Feature:
28
+
29
+ Background:
30
+ Given some setup
31
+ Then some verification
32
+ """
33
+ When it is linted
34
+ Then an error is reported
35
+ | linter | problem | location |
36
+ | BackgroundDoesMoreThanSetupLinter | Background has non-setup steps | <path_to_file>:3 |
37
+
38
+ Scenario: Linting backgrounds with only setup steps
39
+ Given a linter for backgrounds that do more than setup
40
+ And the following feature:
41
+ """
42
+ Feature:
43
+
44
+ Background:
45
+ Given some setup
46
+ And some more setup
47
+ * this is also setup
48
+ """
49
+ When it is linted
50
+ Then no error is reported
@@ -8,11 +8,18 @@ Feature: Default Linters
8
8
  Scenario: Using the default linters
9
9
  Given no other linters have been registered or unregistered
10
10
  Then the following linters are registered by default
11
+ | BackgroundDoesMoreThanSetupLinter |
11
12
  | ExampleWithoutNameLinter |
13
+ | FeatureWithoutDescriptionLinter |
12
14
  | FeatureWithoutScenariosLinter |
13
15
  | OutlineWithSingleExampleRowLinter |
16
+ | SingleTestBackgroundLinter |
17
+ | StepWithEndPeriodLinter |
18
+ | StepWithTooManyCharactersLinter |
14
19
  | TestWithTooManyStepsLinter |
15
20
 
21
+
22
+
16
23
  Scenario: Registering new linters
17
24
  Given no linters are currently registered
18
25
  When the following code is used:
@@ -0,0 +1,17 @@
1
+ Feature: Feature without description linter
2
+
3
+ As a writer of documentation
4
+ I want features to have a description
5
+ So that I do not have incomplete documentation
6
+
7
+
8
+ Scenario: Linting
9
+ Given a linter for features without a description
10
+ And the following feature:
11
+ """
12
+ Feature: Features must have a description
13
+ """
14
+ When it is linted
15
+ Then an error is reported
16
+ | linter | problem | location |
17
+ | FeatureWithoutDescriptionLinter | Feature has no description | <path_to_file>:1 |
@@ -0,0 +1,24 @@
1
+ Feature: Single test background linter
2
+
3
+
4
+ As a writer of documentation
5
+ I want backgrounds to apply to at least two tests
6
+ So that I am not needlessly using a background instead of adding the background steps directly to the test
7
+
8
+
9
+ Scenario: Linting
10
+ Given a linter for backgrounds applied to only one test
11
+ And the following feature:
12
+ """
13
+ Feature:
14
+
15
+ Background:
16
+ * a step
17
+
18
+ Scenario:
19
+ * a step
20
+ """
21
+ When it is linted
22
+ Then an error is reported
23
+ | linter | problem | location |
24
+ | SingleTestBackgroundLinter | Background used with only one test | <path_to_file>:3 |
@@ -0,0 +1,43 @@
1
+ Feature: Test step with too many characters
2
+
3
+ As a reader of documentation
4
+ I want test steps not to be unduly long
5
+ So that I can easily understand its purpose
6
+
7
+
8
+ Scenario: Linting
9
+
10
+ Given a linter for test steps with too many characters
11
+ And the following feature:
12
+ """
13
+ Feature:
14
+
15
+ Scenario:
16
+ * tea exists and teapots exist and so do cups and saucers and there might be milk in the milk jug together with sugar cubes
17
+ """
18
+ When it is linted
19
+ Then an error is reported
20
+ | linter | problem | location |
21
+ | StepWithTooManyCharactersLinter | Step is too long. 121 characters found (max 80) | <path_to_file>:4 |
22
+
23
+
24
+ Scenario: Configuration of step count threshold
25
+
26
+ Given a linter for test steps with too many characters has been registered
27
+ And the following configuration file:
28
+ """
29
+ StepWithTooManyCharactersLinter:
30
+ StepLengthThreshold: 55
31
+ """
32
+ And the following feature:
33
+ """
34
+ Feature:
35
+
36
+ Scenario:
37
+ Given that a rose by any other name would still smell as sweet
38
+ """
39
+ When the configuration file is loaded
40
+ And the feature is linted
41
+ Then an error is reported
42
+ | linter | problem | location |
43
+ | StepWithTooManyCharactersLinter | Step is too long. 56 characters found (max 55) | <path_to_file>:4 |
@@ -0,0 +1,21 @@
1
+ Feature: Step that ends with a period linter
2
+
3
+ As a writer of documentation
4
+ I want to avoid periods at the end of steps
5
+ So that readability is not impacted when they are used elsewhere
6
+
7
+
8
+ Scenario: Linting
9
+ Given a linter for steps the end with a period
10
+ And the following feature:
11
+ """
12
+ Feature:
13
+
14
+ Scenario:
15
+ * an okay step
16
+ * a bad step.
17
+ """
18
+ When it is linted
19
+ Then an error is reported
20
+ | linter | problem | location |
21
+ | StepWithEndPeriodLinter | Step ends with a period | <path_to_file>:5 |
@@ -41,10 +41,34 @@ Given(/^a linter for tests with too many steps$/) do
41
41
  @linter = CukeLinter::TestWithTooManyStepsLinter.new
42
42
  end
43
43
 
44
+ Given(/^a linter for steps the end with a period$/) do
45
+ @linter = CukeLinter::StepWithEndPeriodLinter.new
46
+ end
47
+
48
+ Given(/^a linter for backgrounds applied to only one test$/) do
49
+ @linter = CukeLinter::SingleTestBackgroundLinter.new
50
+ end
51
+
52
+ Given(/^a linter for backgrounds that do more than setup$/) do
53
+ @linter = CukeLinter::BackgroundDoesMoreThanSetupLinter.new
54
+ end
55
+
56
+ Given("a linter for test steps with too many characters") do
57
+ @linter = CukeLinter::StepWithTooManyCharactersLinter.new
58
+ end
59
+
44
60
  Given(/^a linter for tests with too many steps has been registered$/) do
45
61
  CukeLinter.register_linter(linter: CukeLinter::TestWithTooManyStepsLinter.new, name: 'TestWithTooManyStepsLinter')
46
62
  end
47
63
 
64
+ Given("a linter for features without a description") do
65
+ @linter = CukeLinter::FeatureWithoutDescriptionLinter.new
66
+ end
67
+
68
+ Given(/^a linter for test steps with too many characters has been registered$/) do
69
+ CukeLinter.register_linter(linter: CukeLinter::StepWithTooManyCharactersLinter.new, name: 'StepWithTooManyCharactersLinter')
70
+ end
71
+
48
72
  Given(/^the following configuration file(?: "([^"]*)")?:$/) do |file_name, text|
49
73
  file_name ||= '.cuke_linter'
50
74
 
@@ -53,6 +53,24 @@ module CukeLinter
53
53
  model
54
54
  end
55
55
 
56
+ def self.generate_background_model(source_text: "Background:\n* a step", parent_file_path: 'path_to_file')
57
+ fake_parent_model = generate_feature_model(parent_file_path: parent_file_path)
58
+
59
+ model = CukeModeler::Background.new(source_text)
60
+ model.parent_model = fake_parent_model
61
+
62
+ model
63
+ end
64
+
65
+ def self.generate_step_model(source_text: '* a step', parent_file_path: 'path_to_file')
66
+ fake_parent_model = generate_scenario_model(parent_file_path: parent_file_path)
67
+
68
+ model = CukeModeler::Step.new(source_text)
69
+ model.parent_model = fake_parent_model
70
+
71
+ model
72
+ end
73
+
56
74
  def self.generate_lintable_model(parent_file_path: 'path_to_file', source_line: '1', children: [])
57
75
  fake_file_model = CukeModeler::FeatureFile.new
58
76
  fake_file_model.path = parent_file_path
@@ -110,12 +110,22 @@ RSpec.describe CukeLinter do
110
110
  end
111
111
 
112
112
  it 'has a default set of registered linters' do
113
- expect(subject.registered_linters.keys).to include('FeatureWithoutScenariosLinter')
114
- expect(subject.registered_linters['FeatureWithoutScenariosLinter']).to be_a(CukeLinter::FeatureWithoutScenariosLinter)
113
+ expect(subject.registered_linters.keys).to include('BackgroundDoesMoreThanSetupLinter')
114
+ expect(subject.registered_linters['BackgroundDoesMoreThanSetupLinter']).to be_a(CukeLinter::BackgroundDoesMoreThanSetupLinter)
115
115
  expect(subject.registered_linters.keys).to include('ExampleWithoutNameLinter')
116
116
  expect(subject.registered_linters['ExampleWithoutNameLinter']).to be_a(CukeLinter::ExampleWithoutNameLinter)
117
+ expect(subject.registered_linters.keys).to include('FeatureWithoutDescriptionLinter')
118
+ expect(subject.registered_linters['FeatureWithoutDescriptionLinter']).to be_a(CukeLinter::FeatureWithoutDescriptionLinter)
119
+ expect(subject.registered_linters.keys).to include('FeatureWithoutScenariosLinter')
120
+ expect(subject.registered_linters['FeatureWithoutScenariosLinter']).to be_a(CukeLinter::FeatureWithoutScenariosLinter)
117
121
  expect(subject.registered_linters.keys).to include('OutlineWithSingleExampleRowLinter')
118
122
  expect(subject.registered_linters['OutlineWithSingleExampleRowLinter']).to be_a(CukeLinter::OutlineWithSingleExampleRowLinter)
123
+ expect(subject.registered_linters.keys).to include('SingleTestBackgroundLinter')
124
+ expect(subject.registered_linters['SingleTestBackgroundLinter']).to be_a(CukeLinter::SingleTestBackgroundLinter)
125
+ expect(subject.registered_linters.keys).to include('StepWithEndPeriodLinter')
126
+ expect(subject.registered_linters['StepWithEndPeriodLinter']).to be_a(CukeLinter::StepWithEndPeriodLinter)
127
+ expect(subject.registered_linters.keys).to include('StepWithTooManyCharactersLinter')
128
+ expect(subject.registered_linters['StepWithTooManyCharactersLinter']).to be_a(CukeLinter::StepWithTooManyCharactersLinter)
119
129
  expect(subject.registered_linters.keys).to include('TestWithTooManyStepsLinter')
120
130
  expect(subject.registered_linters['TestWithTooManyStepsLinter']).to be_a(CukeLinter::TestWithTooManyStepsLinter)
121
131
  end
@@ -0,0 +1,8 @@
1
+ require_relative '../../../../../environments/rspec_env'
2
+
3
+
4
+ RSpec.describe CukeLinter::BackgroundDoesMoreThanSetupLinter do
5
+
6
+ it_should_behave_like 'a linter at the integration level'
7
+
8
+ end
@@ -0,0 +1,8 @@
1
+ require_relative '../../../../../environments/rspec_env'
2
+
3
+
4
+ RSpec.describe CukeLinter::FeatureWithoutDescriptionLinter do
5
+
6
+ it_should_behave_like 'a linter at the integration level'
7
+
8
+ end
@@ -0,0 +1,8 @@
1
+ require_relative '../../../../../environments/rspec_env'
2
+
3
+
4
+ RSpec.describe CukeLinter::SingleTestBackgroundLinter do
5
+
6
+ it_should_behave_like 'a linter at the integration level'
7
+
8
+ end
@@ -0,0 +1,8 @@
1
+ require_relative '../../../../../environments/rspec_env'
2
+
3
+
4
+ RSpec.describe CukeLinter::StepWithEndPeriodLinter do
5
+
6
+ it_should_behave_like 'a linter at the integration level'
7
+
8
+ end
@@ -0,0 +1,8 @@
1
+ require_relative '../../../../../environments/rspec_env'
2
+
3
+
4
+ RSpec.describe CukeLinter::StepWithTooManyCharactersLinter do
5
+
6
+ it_should_behave_like 'a linter at the integration level'
7
+
8
+ end
@@ -0,0 +1,114 @@
1
+ require_relative '../../../../../environments/rspec_env'
2
+
3
+
4
+ RSpec.describe CukeLinter::BackgroundDoesMoreThanSetupLinter do
5
+
6
+ let(:good_data) do
7
+ CukeLinter::ModelFactory.generate_background_model(source_text: 'Background:
8
+ Given something')
9
+ end
10
+
11
+ let(:bad_data) do
12
+ CukeLinter::ModelFactory.generate_background_model(source_text: 'Background:
13
+ When something')
14
+ end
15
+
16
+
17
+ it_should_behave_like 'a linter at the unit level'
18
+
19
+
20
+ it 'has a name' do
21
+ expect(subject.name).to eq('BackgroundDoesMoreThanSetupLinter')
22
+ end
23
+
24
+ describe 'linting' do
25
+
26
+ context 'a background with action steps' do
27
+
28
+ let(:test_model) do
29
+ CukeLinter::ModelFactory.generate_background_model(source_text: 'Background:
30
+ When something')
31
+ end
32
+
33
+ it 'records a problem' do
34
+ result = subject.lint(test_model)
35
+
36
+ expect(result[:problem]).to eq('Background has non-setup steps')
37
+ end
38
+
39
+ it 'records the location of the problem' do
40
+ model = CukeLinter::ModelFactory.generate_background_model(parent_file_path: 'path_to_file',
41
+ source_text: 'Background:
42
+ When something')
43
+
44
+ model.source_line = 1
45
+ result = subject.lint(model)
46
+ expect(result[:location]).to eq('path_to_file:1')
47
+
48
+ model.source_line = 3
49
+ result = subject.lint(model)
50
+ expect(result[:location]).to eq('path_to_file:3')
51
+ end
52
+
53
+ end
54
+
55
+ context 'a background with verification steps' do
56
+
57
+ let(:test_model) do
58
+ CukeLinter::ModelFactory.generate_background_model(source_text: 'Background:
59
+ Then something')
60
+ end
61
+
62
+ it 'records a problem' do
63
+ result = subject.lint(test_model)
64
+
65
+ expect(result[:problem]).to eq('Background has non-setup steps')
66
+ end
67
+
68
+ it 'records the location of the problem' do
69
+ model = CukeLinter::ModelFactory.generate_background_model(parent_file_path: 'path_to_file',
70
+ source_text: 'Background:
71
+ Then something')
72
+
73
+ model.source_line = 1
74
+ result = subject.lint(model)
75
+ expect(result[:location]).to eq('path_to_file:1')
76
+
77
+ model.source_line = 3
78
+ result = subject.lint(model)
79
+ expect(result[:location]).to eq('path_to_file:3')
80
+ end
81
+
82
+ end
83
+
84
+ context 'a background with only setup steps' do
85
+
86
+ context 'with a scenario' do
87
+
88
+ let(:test_model) do
89
+ gherkin = 'Background:
90
+ Given something
91
+ * (plus something)'
92
+
93
+ CukeLinter::ModelFactory.generate_background_model(source_text: gherkin)
94
+ end
95
+
96
+ it 'does not record a problem' do
97
+ expect(subject.lint(test_model)).to eq(nil)
98
+ end
99
+
100
+ end
101
+
102
+ end
103
+
104
+ context 'a non-background model' do
105
+
106
+ it 'returns no result' do
107
+ result = subject.lint(CukeModeler::Model.new)
108
+
109
+ expect(result).to eq(nil)
110
+ end
111
+
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,97 @@
1
+ require_relative '../../../../../environments/rspec_env'
2
+
3
+
4
+ RSpec.describe CukeLinter::FeatureWithoutDescriptionLinter do
5
+
6
+ let(:good_data) do
7
+ feature_text = 'Feature:
8
+ with a description'
9
+
10
+ CukeLinter::ModelFactory.generate_feature_model(source_text: feature_text)
11
+ end
12
+
13
+ let(:bad_data) do
14
+ feature_text = 'Feature: without a description'
15
+
16
+ CukeLinter::ModelFactory.generate_feature_model(source_text: feature_text)
17
+ end
18
+
19
+ it_should_behave_like 'a linter at the unit level'
20
+
21
+
22
+ it 'has a name' do
23
+ expect(subject.name).to eq('FeatureWithoutDescriptionLinter')
24
+ end
25
+
26
+ describe 'linting' do
27
+
28
+ context 'a feature with no description' do
29
+
30
+ context 'because the description is empty' do
31
+
32
+ let(:feature_with_no_description) do
33
+ model = CukeLinter::ModelFactory.generate_feature_model(parent_file_path: 'path_to_file')
34
+ model.description = ''
35
+
36
+ model
37
+ end
38
+
39
+
40
+ it 'records a problem' do
41
+ result = subject.lint(feature_with_no_description)
42
+ expect(result[:problem]).to eq('Feature has no description')
43
+ end
44
+
45
+ it 'records the location of the problem' do
46
+ result = subject.lint(feature_with_no_description)
47
+ expect(result[:location]).to eq('path_to_file:1')
48
+ end
49
+ end
50
+
51
+ context 'because the description is nil' do
52
+
53
+ let(:feature_with_no_description) do
54
+ model = CukeLinter::ModelFactory.generate_feature_model(parent_file_path: 'path_to_file')
55
+ model.description = nil
56
+
57
+ model
58
+ end
59
+
60
+ it 'records a problem' do
61
+ result = subject.lint(feature_with_no_description)
62
+ expect(result[:problem]).to eq('Feature has no description')
63
+ end
64
+
65
+ it 'records the location of the problem' do
66
+ result = subject.lint(feature_with_no_description)
67
+ expect(result[:location]).to eq('path_to_file:1')
68
+ end
69
+
70
+ end
71
+ end
72
+
73
+ context 'a feature with a description' do
74
+
75
+ let(:feature_with_a_description) do
76
+ model_source = "Feature:\n This feature has a description"
77
+ CukeLinter::ModelFactory.generate_feature_model(source_text: model_source,
78
+ parent_file_path: 'path_to_file')
79
+ end
80
+
81
+ it 'does not record a problem' do
82
+ result = subject.lint(feature_with_a_description)
83
+ expect(result).to eq(nil)
84
+ end
85
+ end
86
+
87
+ context 'a non-feature model' do
88
+
89
+ it 'returns no results' do
90
+ result = subject.lint(CukeModeler::Model.new)
91
+
92
+ expect(result).to eq(nil)
93
+ end
94
+ end
95
+
96
+ end
97
+ end
@@ -0,0 +1,116 @@
1
+ require_relative '../../../../../environments/rspec_env'
2
+
3
+
4
+ RSpec.describe CukeLinter::SingleTestBackgroundLinter do
5
+
6
+ let(:good_data) do
7
+ CukeLinter::ModelFactory.generate_feature_model(source_text: 'Feature:
8
+ Background:
9
+ * a step
10
+ Scenario:
11
+ Scenario:').background
12
+ end
13
+
14
+ let(:bad_data) do
15
+ CukeLinter::ModelFactory.generate_feature_model(source_text: 'Feature:
16
+ Background:
17
+ * a step
18
+ Scenario:').background
19
+ end
20
+
21
+
22
+ it_should_behave_like 'a linter at the unit level'
23
+
24
+
25
+ it 'has a name' do
26
+ expect(subject.name).to eq('SingleTestBackgroundLinter')
27
+ end
28
+
29
+ describe 'linting' do
30
+
31
+ context 'with a background that affects only one test' do
32
+
33
+ ['scenario', 'outline'].each do |model_type|
34
+
35
+ context "and that test is a #{model_type}" do
36
+
37
+ let(:test_model) do
38
+ background_model = CukeLinter::ModelFactory.generate_feature_model(source_text: 'Feature:
39
+ Background:
40
+ * a step').background
41
+
42
+ background_model.parent_model.tests.clear
43
+ background_model.parent_model.tests << CukeLinter::ModelFactory.send("generate_#{model_type}_model")
44
+
45
+ background_model
46
+ end
47
+
48
+ it 'records a problem' do
49
+ result = subject.lint(test_model)
50
+
51
+ expect(result[:problem]).to match('Background used with only one test')
52
+ end
53
+
54
+ it 'records the location of the problem' do
55
+ test_model.source_line = 1
56
+ result = subject.lint(test_model)
57
+ expect(result[:location]).to eq('path_to_file:1')
58
+
59
+ test_model.source_line = 3
60
+ result = subject.lint(test_model)
61
+ expect(result[:location]).to eq('path_to_file:3')
62
+ end
63
+
64
+ end
65
+
66
+ end
67
+
68
+ end
69
+
70
+ context 'with a background that affects multiple tests' do
71
+
72
+ let(:test_model) do
73
+ CukeLinter::ModelFactory.generate_feature_model(source_text: 'Feature:
74
+ Background:
75
+ * a step
76
+ Scenario:
77
+ Scenario Outline:
78
+ * a step
79
+ Examples:
80
+ |param|
81
+ |value|').background
82
+ end
83
+
84
+ it 'does not record a problem' do
85
+ expect(subject.lint(test_model)).to eq(nil)
86
+ end
87
+
88
+ end
89
+
90
+ context 'with a background that affects no tests' do
91
+
92
+ let(:test_model) do
93
+ CukeLinter::ModelFactory.generate_feature_model(source_text: 'Feature:
94
+ Background:
95
+ * a step').background
96
+ end
97
+
98
+ it 'does not record a problem' do
99
+ expect(subject.lint(test_model)).to eq(nil)
100
+ end
101
+
102
+ end
103
+
104
+ context 'with a non-background model' do
105
+
106
+ let(:test_model) { CukeModeler::Model.new }
107
+
108
+ it 'returns no result' do
109
+ result = subject.lint(test_model)
110
+
111
+ expect(result).to eq(nil)
112
+ end
113
+
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,73 @@
1
+ require_relative '../../../../../environments/rspec_env'
2
+
3
+
4
+ RSpec.describe CukeLinter::StepWithEndPeriodLinter do
5
+
6
+ let(:good_data) do
7
+ CukeLinter::ModelFactory.generate_step_model(source_text: '* without a period')
8
+ end
9
+
10
+ let(:bad_data) do
11
+ CukeLinter::ModelFactory.generate_step_model(source_text: '* with a period.')
12
+ end
13
+
14
+
15
+ it_should_behave_like 'a linter at the unit level'
16
+
17
+
18
+ it 'has a name' do
19
+ expect(subject.name).to eq('StepWithEndPeriodLinter')
20
+ end
21
+
22
+ describe 'linting' do
23
+
24
+ context "with a step that ends with a period" do
25
+
26
+ let(:test_model) do
27
+ CukeLinter::ModelFactory.generate_step_model(source_text: '* with a period.')
28
+ end
29
+
30
+ it 'records a problem' do
31
+ result = subject.lint(test_model)
32
+
33
+ expect(result[:problem]).to match('Step ends with a period')
34
+ end
35
+
36
+ it 'records the location of the problem' do
37
+ test_model.source_line = 1
38
+ result = subject.lint(test_model)
39
+ expect(result[:location]).to eq('path_to_file:1')
40
+
41
+ test_model.source_line = 3
42
+ result = subject.lint(test_model)
43
+ expect(result[:location]).to eq('path_to_file:3')
44
+ end
45
+
46
+ end
47
+
48
+ context "with a step that does not end with a period" do
49
+
50
+
51
+ let(:test_model) do
52
+ CukeLinter::ModelFactory.generate_step_model(source_text: '* without a period')
53
+ end
54
+
55
+ it 'does not record a problem' do
56
+ expect(subject.lint(test_model)).to eq(nil)
57
+ end
58
+
59
+ end
60
+
61
+ context 'with a non-step model' do
62
+
63
+ let(:test_model) { CukeModeler::Model.new }
64
+
65
+ it 'returns no result' do
66
+ result = subject.lint(test_model)
67
+
68
+ expect(result).to eq(nil)
69
+ end
70
+
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,180 @@
1
+ require_relative '../../../../../environments/rspec_env'
2
+
3
+
4
+ RSpec.describe CukeLinter::StepWithTooManyCharactersLinter do
5
+
6
+ let(:good_data) do
7
+ CukeLinter::ModelFactory.generate_step_model(source_text: '* a short step')
8
+ end
9
+
10
+ let(:bad_data) do
11
+ long_step = <<~EOL.delete("\n")
12
+ * this is a very long string which will violate the linter
13
+ rule which expects step rules to have fewer than one hundred
14
+ and twenty characters
15
+ EOL
16
+ CukeLinter::ModelFactory.generate_step_model(source_text: long_step)
17
+ end
18
+
19
+ it_should_behave_like 'a linter at the unit level'
20
+ it_should_behave_like 'a configurable linter at the unit level'
21
+
22
+
23
+ it 'has a name' do
24
+ expect(subject.name).to eq('StepWithTooManyCharactersLinter')
25
+ end
26
+
27
+ describe 'linting' do
28
+
29
+ let(:default_character_threshold) { 80 }
30
+
31
+ context 'when the step is too long' do
32
+
33
+ let(:step_too_long_model) do
34
+ step = 'x' * (default_character_threshold + 1)
35
+ CukeLinter::ModelFactory.generate_step_model(source_text: "* #{step}")
36
+ end
37
+
38
+ it 'reports a problem' do
39
+ result = subject.lint(step_too_long_model)
40
+
41
+ expect(result[:problem]).to match(/^Step is too long. \d+ characters found \(max 80\)/)
42
+ end
43
+
44
+ it 'records the location of the problem' do
45
+ result = subject.lint(step_too_long_model)
46
+
47
+ expect(result[:location]).to eq('path_to_file:4')
48
+ end
49
+
50
+ it 'includes the number of characters found in the problem record' do
51
+ character_count = step_too_long_model.text.length
52
+ result = subject.lint(step_too_long_model)
53
+ expect(result[:problem]).to eq("Step is too long. #{character_count} characters found (max 80)")
54
+
55
+ step_too_long_model.text += 'x'
56
+ result = subject.lint(step_too_long_model)
57
+ expect(result[:problem]).to eq("Step is too long. #{character_count + 1} characters found (max 80)")
58
+ end
59
+
60
+ end
61
+
62
+ context 'when the step is the maximum length' do
63
+
64
+ let(:step_mex_length_model) do
65
+ step = 'x' * default_character_threshold
66
+ CukeLinter::ModelFactory.generate_step_model(source_text: "* #{step}")
67
+ end
68
+
69
+ it 'does not record a problem' do
70
+ result = subject.lint(step_mex_length_model)
71
+ expect(result).to eq(nil)
72
+ end
73
+
74
+ end
75
+
76
+ context 'when the step is below the maximum length' do
77
+
78
+ let(:step_below_length_model) do
79
+ step = 'x' * (default_character_threshold - 1)
80
+ CukeLinter::ModelFactory.generate_step_model(source_text: "* #{step}")
81
+ end
82
+
83
+ it 'does not record a problem' do
84
+ result = subject.lint(step_below_length_model)
85
+ expect(result).to eq(nil)
86
+ end
87
+
88
+ end
89
+
90
+ context 'when the step has no text' do
91
+
92
+ let(:step_with_nil_text_model) do
93
+ model = CukeLinter::ModelFactory.generate_step_model
94
+ model.text = nil
95
+
96
+ model
97
+ end
98
+
99
+ it 'does not record a problem' do
100
+ result = subject.lint(step_with_nil_text_model)
101
+ expect(result).to eq(nil)
102
+ end
103
+
104
+ end
105
+
106
+ end
107
+
108
+ describe 'configuration' do
109
+
110
+ context 'with no configuration' do
111
+
112
+ let(:default_character_threshold) { 80 }
113
+
114
+ context 'because configuration never happened' do
115
+
116
+ let(:default_model) do
117
+ step = 'x' * (default_character_threshold + 1)
118
+ CukeLinter::ModelFactory.generate_step_model(source_text: "* #{step}")
119
+ end
120
+
121
+ it 'defaults to a maximum of 80 characters' do
122
+ result = subject.lint(default_model)
123
+
124
+ expect( result[:problem]).to match(/^Step is too long. \d+ characters found \(max 80\)/)
125
+ end
126
+
127
+ end
128
+
129
+ context 'because configuration did not set a step threshold' do
130
+ let(:configuration) { {} }
131
+ let(:configured_model) do
132
+ subject.configure(configuration)
133
+ step = 'x' * (default_character_threshold + 1)
134
+ CukeLinter::ModelFactory.generate_step_model(source_text: "* #{step}")
135
+ end
136
+
137
+ it 'defaults to a maximum of 80 characters' do
138
+ result = subject.lint(configured_model)
139
+
140
+ expect( result[:problem]).to match(/^Step is too long. \d+ characters found \(max 80\)/)
141
+ end
142
+
143
+ end
144
+
145
+ end
146
+
147
+ context 'when configured' do
148
+ let(:character_threshold) { 10 }
149
+ let(:configuration) { {'StepLengthThreshold' => character_threshold} }
150
+
151
+ subject { linter = CukeLinter::StepWithTooManyCharactersLinter.new
152
+ linter.configure(configuration)
153
+ linter }
154
+
155
+ let(:test_model) do
156
+ step = 'x' * (character_threshold + 1)
157
+ CukeLinter::ModelFactory.generate_step_model(source_text: "* #{step}")
158
+ end
159
+
160
+ it 'uses the maximum character length provided by configuration' do
161
+ result = subject.lint(test_model)
162
+
163
+ expect( result[:problem]).to match(/^Step is too long. \d+ characters found \(max 10\)/)
164
+ end
165
+
166
+ end
167
+
168
+ context 'a non-step model' do
169
+
170
+ let(:test_model) { CukeModeler::Model.new }
171
+
172
+ it 'returns no result' do
173
+ result = subject.lint(test_model)
174
+
175
+ expect(result).to eq(nil)
176
+ end
177
+
178
+ end
179
+ end
180
+ end
@@ -192,20 +192,23 @@ RSpec.describe CukeLinter::TestWithTooManyStepsLinter do
192
192
 
193
193
  let(:step_threshhold) { 3 }
194
194
  let(:configuration) { { 'StepThreshold' => step_threshhold } }
195
- let(:configured_test_model) do
195
+
196
+ subject { linter = CukeLinter::TestWithTooManyStepsLinter.new
197
+ linter.configure(configuration)
198
+ linter }
199
+
200
+ let(:test_model) do
196
201
  model = CukeLinter::ModelFactory.send("generate_#{model_type}_model")
197
202
  model.steps = []
198
203
  (step_threshhold + 1).times { model.steps << :a_step }
199
204
 
200
- subject.configure(configuration)
201
-
202
205
  model
203
206
  end
204
207
 
205
208
  it 'the step threshold used is the configured value' do
206
- result = subject.lint(configured_test_model)
209
+ result = subject.lint(test_model)
207
210
 
208
- expect(result[:problem]).to match(/^Test has too many steps. #{configured_test_model.steps.count} steps found \(max #{step_threshhold}\)/)
211
+ expect(result[:problem]).to match(/^Test has too many steps. #{test_model.steps.count} steps found \(max #{step_threshhold}\)/)
209
212
  end
210
213
 
211
214
  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.4.0
4
+ version: 0.5.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-11 00:00:00.000000000 Z
11
+ date: 2019-05-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cuke_modeler
@@ -176,21 +176,31 @@ files:
176
176
  - exe/cuke_linter
177
177
  - lib/cuke_linter.rb
178
178
  - lib/cuke_linter/formatters/pretty_formatter.rb
179
+ - lib/cuke_linter/linters/background_does_more_than_setup_linter.rb
179
180
  - lib/cuke_linter/linters/example_without_name_linter.rb
181
+ - lib/cuke_linter/linters/feature_without_description_linter.rb
180
182
  - lib/cuke_linter/linters/feature_without_scenarios_linter.rb
181
183
  - lib/cuke_linter/linters/linter.rb
182
184
  - lib/cuke_linter/linters/outline_with_single_example_row_linter.rb
185
+ - lib/cuke_linter/linters/single_test_background_linter.rb
186
+ - lib/cuke_linter/linters/step_with_end_period_linter.rb
187
+ - lib/cuke_linter/linters/step_with_too_many_characters_linter.rb
183
188
  - lib/cuke_linter/linters/test_with_too_many_steps_linter.rb
184
189
  - lib/cuke_linter/version.rb
185
190
  - testing/cucumber/features/command_line.feature
186
191
  - testing/cucumber/features/configuration/configuring_linters.feature
187
192
  - testing/cucumber/features/configuration/using_configurations.feature
188
193
  - testing/cucumber/features/formatters/pretty_formatter.feature
194
+ - testing/cucumber/features/linters/background_does_more_than_setup_linter.feature
189
195
  - testing/cucumber/features/linters/custom_linters.feature
190
196
  - testing/cucumber/features/linters/default_linters.feature
191
197
  - testing/cucumber/features/linters/example_without_name.feature
198
+ - testing/cucumber/features/linters/feature_without_description.feature
192
199
  - testing/cucumber/features/linters/feature_without_scenarios.feature
193
200
  - testing/cucumber/features/linters/outline_with_single_example_row.feature
201
+ - testing/cucumber/features/linters/single_test_background_linter.feature
202
+ - testing/cucumber/features/linters/step_too_long.feature
203
+ - testing/cucumber/features/linters/step_with_end_period.feature
194
204
  - testing/cucumber/features/linters/test_with_too_many_steps.feature
195
205
  - testing/cucumber/step_definitions/action_steps.rb
196
206
  - testing/cucumber/step_definitions/setup_steps.rb
@@ -202,21 +212,31 @@ files:
202
212
  - testing/rspec/spec/integration/cuke_linter_integration_spec.rb
203
213
  - testing/rspec/spec/integration/formatters/formatter_integration_specs.rb
204
214
  - testing/rspec/spec/integration/formatters/pretty_formatter_integration_spec.rb
215
+ - testing/rspec/spec/integration/linters/background_does_more_than_setup_linter_integration_spec.rb
205
216
  - testing/rspec/spec/integration/linters/example_without_name_linter_integration_spec.rb
217
+ - testing/rspec/spec/integration/linters/feature_without_description_linter_integration_spec.rb
206
218
  - testing/rspec/spec/integration/linters/feature_without_scenarios_linter_integration_spec.rb
207
219
  - testing/rspec/spec/integration/linters/linter_integration_spec.rb
208
220
  - testing/rspec/spec/integration/linters/linter_integration_specs.rb
209
221
  - testing/rspec/spec/integration/linters/outline_with_single_example_row_linter_integration_spec.rb
222
+ - testing/rspec/spec/integration/linters/single_test_background_linter_integration_spec.rb
223
+ - testing/rspec/spec/integration/linters/step_with_end_period_linter_integration_spec.rb
224
+ - testing/rspec/spec/integration/linters/step_with_too_many_characters_linter_integration_spec.rb
210
225
  - testing/rspec/spec/integration/linters/test_with_too_many_steps_linter_integration_spec.rb
211
226
  - testing/rspec/spec/unit/cuke_linter_unit_spec.rb
212
227
  - testing/rspec/spec/unit/formatters/formatter_unit_specs.rb
213
228
  - testing/rspec/spec/unit/formatters/pretty_formatter_unit_spec.rb
229
+ - testing/rspec/spec/unit/linters/background_does_more_than_setup_linter_unit_spec.rb
214
230
  - testing/rspec/spec/unit/linters/configurable_linter_unit_specs.rb
215
231
  - testing/rspec/spec/unit/linters/example_without_name_linter_unit_spec.rb
232
+ - testing/rspec/spec/unit/linters/feature_without_description_linter_unit_spec.rb
216
233
  - testing/rspec/spec/unit/linters/feature_without_scenarios_linter_unit_spec.rb
217
234
  - testing/rspec/spec/unit/linters/linter_unit_spec.rb
218
235
  - testing/rspec/spec/unit/linters/linter_unit_specs.rb
219
236
  - testing/rspec/spec/unit/linters/outline_with_single_example_row_linter_unit_spec.rb
237
+ - testing/rspec/spec/unit/linters/single_test_background_linter_unit_spec.rb
238
+ - testing/rspec/spec/unit/linters/step_with_end_period_linter_unit_spec.rb
239
+ - testing/rspec/spec/unit/linters/step_with_too_many_characters_linter_unit_spec.rb
220
240
  - testing/rspec/spec/unit/linters/test_with_too_many_steps_linter_unit_spec.rb
221
241
  homepage: https://github.com/enkessler/cuke_linter
222
242
  licenses: