cuke_linter 0.11.1 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +5 -1
  3. data/CHANGELOG.md +13 -2
  4. data/LICENSE.txt +1 -1
  5. data/appveyor.yml +19 -0
  6. data/cuke_linter.gemspec +1 -1
  7. data/environments/rspec_env.rb +4 -0
  8. data/lib/cuke_linter.rb +6 -0
  9. data/lib/cuke_linter/linters/element_with_common_tags_linter.rb +41 -0
  10. data/lib/cuke_linter/linters/element_with_duplicate_tags_linter.rb +44 -0
  11. data/lib/cuke_linter/linters/feature_file_with_mismatched_name_linter.rb +26 -0
  12. data/lib/cuke_linter/version.rb +1 -1
  13. data/testing/cucumber/features/command_line.feature +7 -7
  14. data/testing/cucumber/features/default_linters.feature +3 -0
  15. data/testing/cucumber/features/linters/element_with_common_tags.feature +28 -0
  16. data/testing/cucumber/features/linters/element_with_duplicate_tags.feature +71 -0
  17. data/testing/cucumber/features/linters/feature_file_with_mismatched_name.feature +32 -0
  18. data/testing/cucumber/step_definitions/setup_steps.rb +25 -0
  19. data/testing/gemfiles/cuke_modeler1.gemfile +8 -0
  20. data/testing/gemfiles/cuke_modeler2.gemfile +8 -0
  21. data/testing/model_factory.rb +14 -2
  22. data/testing/rspec/spec/integration/cli_integration_spec.rb +8 -7
  23. data/testing/rspec/spec/integration/cuke_linter_integration_spec.rb +5 -0
  24. data/testing/rspec/spec/integration/linters/element_with_common_tags_linter_integration_spec.rb +8 -0
  25. data/testing/rspec/spec/integration/linters/element_with_duplicate_tags_linter_integration_spec.rb +8 -0
  26. data/testing/rspec/spec/integration/linters/feature_file_with_mismatched_name_integration_spec.rb +8 -0
  27. data/testing/rspec/spec/unit/linters/element_with_common_tags_linter_unit_spec.rb +248 -0
  28. data/testing/rspec/spec/unit/linters/element_with_duplicate_tags_linter_unit_spec.rb +203 -0
  29. data/testing/rspec/spec/unit/linters/element_with_too_many_tags_linter_unit_spec.rb +1 -4
  30. data/testing/rspec/spec/unit/linters/feature_file_with_invalid_name_linter_unit_spec.rb +1 -1
  31. data/testing/rspec/spec/unit/linters/feature_file_with_mismatched_name_linter_unit_spec.rb +124 -0
  32. metadata +24 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 05f9639710a8ee90502992efd3bf5a0cd23d989e10f8b2699ca2120c25729c64
4
- data.tar.gz: 6aeae6c4a917210bc09de39b0d751de4c0c15c929478dd362f65c6ac3e88dc70
3
+ metadata.gz: 2f5b4c792db279ecfb0eab3df8591ca772891edfe1f156daae3fd1715d74cda9
4
+ data.tar.gz: 572b6d392046c43da411458e0f3ac23e32ee4bd82bfacadcf98e0268120235a0
5
5
  SHA512:
6
- metadata.gz: 6e11d0529be4f2202de3f98bf2cf7149822fd2378f5ec18de2b4c2a0cbdc56f7b8534614de911ffd570823e4faf0ffb06ceed31df392a37ab7911c1edd1c3715
7
- data.tar.gz: c5152f78a6092267fe7050445c72864807cd70ce61af044292c5af3be5a91e180d236680ca3e3622795417d08e1c47ada1bbfcaf8cb99a7607df8a22f91e5885
6
+ metadata.gz: ff8ed351d8fe31419a1cc922e3430eda5a84e88d8bda09838095c1cd647bf56826a121f0eb335527a03b2ccb35a6e399d3a4f34e09dcef998860228a2fcd9a14
7
+ data.tar.gz: f0739486ca0c93b175e5bd34c0b7334c360331bd8e2e9472055bd53a2ed4acde21b7db9f5f53b70a3f852c2d093e39f4193aa473a45e869e23ecda086019fa0f
@@ -8,12 +8,16 @@ dist: trusty
8
8
 
9
9
  language: ruby
10
10
  rvm:
11
- - 2.3.3
12
11
  - 2.4.0
13
12
  - 2.5.1
14
13
  - 2.6.0
15
14
  - jruby-9.1.7.0
16
15
 
16
+
17
+ gemfile:
18
+ - testing/gemfiles/cuke_modeler1.gemfile
19
+ - testing/gemfiles/cuke_modeler2.gemfile
20
+
17
21
  before_install: gem install bundler -v 1.16.2
18
22
 
19
23
  script: bundle exec rake cuke_linter:ci_build
@@ -6,7 +6,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
- Nothing yet... *(see development branch)*
9
+ Nothing yet...
10
+
11
+ ## [0.12.0] - 2020-02-13
12
+
13
+ ### Added
14
+ - New linters
15
+ - ElementWithCommonTagsLinter
16
+ - ElementWithDuplicateTagsLinter
17
+ - FeatureFileWithMismatchedNameLinter
18
+
19
+ - Now compatible with CukeModeler 2.x
10
20
 
11
21
 
12
22
  ## [0.11.1] - 2019-11-07
@@ -119,7 +129,8 @@ Nothing yet... *(see development branch)*
119
129
  - Custom linters, formatters, and command line usability
120
130
 
121
131
 
122
- [Unreleased]: https://github.com/enkessler/cuke_linter/compare/v0.11.1...HEAD
132
+ [Unreleased]: https://github.com/enkessler/cuke_linter/compare/v0.12.0...HEAD
133
+ [0.12.0]: https://github.com/enkessler/cuke_linter/compare/v0.11.1...v0.12.0
123
134
  [0.11.1]: https://github.com/enkessler/cuke_linter/compare/v0.11.0...v0.11.1
124
135
  [0.11.0]: https://github.com/enkessler/cuke_linter/compare/v0.10.0...v0.11.0
125
136
  [0.10.0]: https://github.com/enkessler/cuke_linter/compare/v0.9.0...v0.10.0
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2018-2019 Eric Kessler
3
+ Copyright (c) 2018-2020 Eric Kessler
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -3,11 +3,30 @@ version: '1.0.{build}'
3
3
  environment:
4
4
  matrix:
5
5
  - RUBY_VERSION: 23
6
+ BUNDLE_GEMFILE: testing/gemfiles/cuke_modeler1.gemfile
6
7
  - RUBY_VERSION: 23-x64
8
+ BUNDLE_GEMFILE: testing/gemfiles/cuke_modeler1.gemfile
7
9
  - RUBY_VERSION: 24
10
+ BUNDLE_GEMFILE: testing/gemfiles/cuke_modeler1.gemfile
8
11
  - RUBY_VERSION: 24-x64
12
+ BUNDLE_GEMFILE: testing/gemfiles/cuke_modeler1.gemfile
9
13
  - RUBY_VERSION: 25
14
+ BUNDLE_GEMFILE: testing/gemfiles/cuke_modeler1.gemfile
10
15
  - RUBY_VERSION: 25-x64
16
+ BUNDLE_GEMFILE: testing/gemfiles/cuke_modeler1.gemfile
17
+
18
+ - RUBY_VERSION: 23
19
+ BUNDLE_GEMFILE: testing/gemfiles/cuke_modeler2.gemfile
20
+ - RUBY_VERSION: 23-x64
21
+ BUNDLE_GEMFILE: testing/gemfiles/cuke_modeler2.gemfile
22
+ - RUBY_VERSION: 24
23
+ BUNDLE_GEMFILE: testing/gemfiles/cuke_modeler2.gemfile
24
+ - RUBY_VERSION: 24-x64
25
+ BUNDLE_GEMFILE: testing/gemfiles/cuke_modeler2.gemfile
26
+ - RUBY_VERSION: 25
27
+ BUNDLE_GEMFILE: testing/gemfiles/cuke_modeler2.gemfile
28
+ - RUBY_VERSION: 25-x64
29
+ BUNDLE_GEMFILE: testing/gemfiles/cuke_modeler2.gemfile
11
30
 
12
31
  install:
13
32
  - set PATH=C:\Ruby%RUBY_VERSION%\bin;%PATH%
@@ -26,7 +26,7 @@ Gem::Specification.new do |spec|
26
26
 
27
27
  spec.required_ruby_version = '~> 2.0'
28
28
 
29
- spec.add_runtime_dependency 'cuke_modeler', '~> 1.5'
29
+ spec.add_runtime_dependency 'cuke_modeler', '>= 1.5', '< 3.0'
30
30
 
31
31
  spec.add_development_dependency "bundler", "< 3.0"
32
32
  spec.add_development_dependency "cucumber", "~> 3.0"
@@ -12,6 +12,10 @@ require_relative '../testing/rspec/spec/unit/linters/linter_unit_specs'
12
12
  require_relative '../testing/rspec/spec/integration/formatters/formatter_integration_specs'
13
13
  require_relative '../testing/rspec/spec/integration/linters/linter_integration_specs'
14
14
 
15
+ # Convenient constants, just in case what kinds of elements are taggable ever changes
16
+ TAGGABLE_ELEMENTS = ['feature', 'scenario', 'outline', 'example']
17
+ ELEMENTS_WITH_TAGGABLE_CHILDREN = ['feature', 'outline']
18
+
15
19
  RSpec.configure do |config|
16
20
  # Enable flags like --only-failures and --next-failure
17
21
  config.example_status_persistence_file_path = ".rspec_status"
@@ -5,9 +5,12 @@ 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'
8
+ require 'cuke_linter/linters/element_with_common_tags_linter'
9
+ require 'cuke_linter/linters/element_with_duplicate_tags_linter'
8
10
  require 'cuke_linter/linters/element_with_too_many_tags_linter'
9
11
  require 'cuke_linter/linters/example_without_name_linter'
10
12
  require 'cuke_linter/linters/feature_file_with_invalid_name_linter'
13
+ require 'cuke_linter/linters/feature_file_with_mismatched_name_linter'
11
14
  require 'cuke_linter/linters/feature_with_too_many_different_tags_linter'
12
15
  require 'cuke_linter/linters/feature_without_name_linter'
13
16
  require 'cuke_linter/linters/feature_without_description_linter'
@@ -33,9 +36,12 @@ require 'cuke_linter/linters/test_with_too_many_steps_linter'
33
36
  module CukeLinter
34
37
 
35
38
  @original_linters = { 'BackgroundDoesMoreThanSetupLinter' => BackgroundDoesMoreThanSetupLinter.new,
39
+ 'ElementWithCommonTagsLinter' => ElementWithCommonTagsLinter.new,
40
+ 'ElementWithDuplicateTagsLinter' => ElementWithDuplicateTagsLinter.new,
36
41
  'ElementWithTooManyTagsLinter' => ElementWithTooManyTagsLinter.new,
37
42
  'ExampleWithoutNameLinter' => ExampleWithoutNameLinter.new,
38
43
  'FeatureFileWithInvalidNameLinter' => FeatureFileWithInvalidNameLinter.new,
44
+ 'FeatureFileWithMismatchedNameLinter' => FeatureFileWithMismatchedNameLinter.new,
39
45
  'FeatureWithTooManyDifferentTagsLinter' => FeatureWithTooManyDifferentTagsLinter.new,
40
46
  'FeatureWithoutDescriptionLinter' => FeatureWithoutDescriptionLinter.new,
41
47
  'FeatureWithoutNameLinter' => FeatureWithoutNameLinter.new,
@@ -0,0 +1,41 @@
1
+ module CukeLinter
2
+
3
+ # A linter that detects Gherkin elements that have the same tag on all of their taggable child elements
4
+
5
+ class ElementWithCommonTagsLinter < 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) || model.is_a?(CukeModeler::Outline)
10
+
11
+ @linted_model_class = model.class
12
+
13
+ child_accessor_method = model.is_a?(CukeModeler::Feature) ? :tests : :examples
14
+ child_models = model.send(child_accessor_method) || []
15
+
16
+ tag_sets = child_models.collect { |child_model| child_model.tags || [] }
17
+ tag_name_sets = tag_sets.collect { |tags| tags.map(&:name) }
18
+
19
+ return false if tag_name_sets.count < 2
20
+
21
+ @common_tag = tag_name_sets.reduce(:&).first
22
+
23
+ !@common_tag.nil?
24
+ end
25
+
26
+ # The message used to describe the problem that has been found
27
+ def message
28
+ class_name = @linted_model_class.name.split('::').last
29
+
30
+ case class_name
31
+ when 'Feature'
32
+ "All tests in #{class_name} have tag '#{@common_tag}'. Move tag to #{class_name} level."
33
+ when 'Outline'
34
+ "All Examples in #{class_name} have tag '#{@common_tag}'. Move tag to #{class_name} level."
35
+ else
36
+ raise("Linted an unexpected model type '#{class_name}'!")
37
+ end
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,44 @@
1
+ module CukeLinter
2
+
3
+ # A linter that detects taggable Gherkin elements that have duplicate tags
4
+
5
+ class ElementWithDuplicateTagsLinter < Linter
6
+
7
+ # Changes the linting settings on the linter using the provided configuration
8
+ def configure(options)
9
+ @tag_inheritance = options['IncludeInheritedTags']
10
+ end
11
+
12
+ # The rule used to determine if a model has a problem
13
+ def rule(model)
14
+ return false unless model.is_a?(CukeModeler::Feature) ||
15
+ model.is_a?(CukeModeler::Scenario) ||
16
+ model.is_a?(CukeModeler::Outline) ||
17
+ model.is_a?(CukeModeler::Example)
18
+
19
+
20
+ @linted_model_class = model.class
21
+
22
+ if @tag_inheritance
23
+ relevant_tags = model.all_tags
24
+ else
25
+ relevant_tags = model.tags || []
26
+ end
27
+
28
+
29
+ tag_names = relevant_tags.map(&:name)
30
+
31
+ @duplicate_tag = tag_names.find { |tag| tag_names.count(tag) > 1 }
32
+
33
+ !@duplicate_tag.nil?
34
+ end
35
+
36
+ # The message used to describe the problem that has been found
37
+ def message
38
+ class_name = @linted_model_class.name.split('::').last
39
+
40
+ "#{class_name} has duplicate tag '#{@duplicate_tag}'."
41
+ end
42
+
43
+ end
44
+ end
@@ -0,0 +1,26 @@
1
+ module CukeLinter
2
+
3
+ # A linter that detects mismatched feature file names
4
+
5
+ class FeatureFileWithMismatchedNameLinter < 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::FeatureFile)
10
+
11
+ file_name = File.basename(model.path, '.feature')
12
+ feature_name = model.feature.name
13
+
14
+ normalized_file_name = file_name.downcase.delete('_ -')
15
+ normalized_feature_name = feature_name.downcase.delete('_ -')
16
+
17
+ normalized_file_name != normalized_feature_name
18
+ end
19
+
20
+ # The message used to describe the problem that has been found
21
+ def message
22
+ 'Feature file name does not match feature name.'
23
+ end
24
+
25
+ end
26
+ end
@@ -1,4 +1,4 @@
1
1
  module CukeLinter
2
2
  # The release version of this gem
3
- VERSION = '0.11.1'
3
+ VERSION = '0.12.0'
4
4
  end
@@ -57,14 +57,14 @@ Feature: Using cuke_linter on the command line
57
57
  """
58
58
 
59
59
  Scenario: Specifying directories and files to lint
60
- Given the following feature file "some.feature":
60
+ Given the following feature file "some_feature.feature":
61
61
  """
62
62
  Feature: Some feature
63
63
  Scenario: A scenario
64
64
  When a step
65
65
  Then a step
66
66
  """
67
- And the following feature file "a_directory/with_a.feature":
67
+ And the following feature file "a_directory/with/some_feature.feature":
68
68
  """
69
69
  Feature: Some feature
70
70
  Scenario: A scenario
@@ -73,14 +73,14 @@ Feature: Using cuke_linter on the command line
73
73
  """
74
74
  When the following command is executed:
75
75
  """
76
- cuke_linter -p <path_to>/some.feature -p <path_to>/a_directory
76
+ cuke_linter -p <path_to>/some_feature.feature -p <path_to>/a_directory
77
77
  """
78
78
  Then the resulting output is the following:
79
79
  """
80
80
  FeatureWithoutDescriptionLinter
81
81
  Feature has no description
82
- <path_to>/a_directory/with_a.feature:1
83
- <path_to>/some.feature:1
82
+ <path_to>/a_directory/with/some_feature.feature:1
83
+ <path_to>/some_feature.feature:1
84
84
 
85
85
  2 issues found
86
86
  """
@@ -173,8 +173,8 @@ Feature: Using cuke_linter on the command line
173
173
 
174
174
  Given the following feature file "has_no_scenarios.feature":
175
175
  """
176
- Feature: This feature
177
- has no scenarios
176
+ Feature: Has no scenarios
177
+ Not a single one
178
178
  """
179
179
  And the following configuration file "my_config.file":
180
180
  """
@@ -9,9 +9,12 @@ Feature: Default Linters
9
9
  Given no other linters have been registered or unregistered
10
10
  Then the following linters are registered by default
11
11
  | BackgroundDoesMoreThanSetupLinter |
12
+ | ElementWithCommonTagsLinter |
13
+ | ElementWithDuplicateTagsLinter |
12
14
  | ElementWithTooManyTagsLinter |
13
15
  | ExampleWithoutNameLinter |
14
16
  | FeatureFileWithInvalidNameLinter |
17
+ | FeatureFileWithMismatchedNameLinter |
15
18
  | FeatureWithTooManyDifferentTagsLinter |
16
19
  | FeatureWithoutDescriptionLinter |
17
20
  | FeatureWithoutNameLinter |
@@ -0,0 +1,28 @@
1
+ Feature: Element with common tags linter
2
+
3
+ As a writer of documentation
4
+ I want taggable elements to not needlessly have the same tags
5
+ So that redundancy is minimized
6
+
7
+
8
+ Scenario: Linting
9
+
10
+ Note: Also works on outlines that have common tags on their examples
11
+
12
+ Given a linter for elements with common tags
13
+ And the following feature:
14
+ """
15
+ Feature:
16
+
17
+ @same_tag
18
+ Scenario:
19
+ * a step
20
+
21
+ @same_tag
22
+ Scenario:
23
+ * a step
24
+ """
25
+ When it is linted
26
+ Then an error is reported:
27
+ | linter | problem | location |
28
+ | ElementWithCommonTagsLinter | All tests in Feature have tag '@same_tag'. Move tag to Feature level. | <path_to_file>:1 |
@@ -0,0 +1,71 @@
1
+ Feature: Element with duplicate tags linter
2
+
3
+ As a writer of documentation
4
+ I want taggable elements to not have duplicate of tags
5
+ So that redundancy is minimized
6
+
7
+
8
+ Scenario: Linting
9
+
10
+ Note: Also works on outlines, features, and examples
11
+
12
+ Given a linter for elements with duplicate tags
13
+ And the following feature:
14
+ """
15
+ Feature:
16
+
17
+ @same_tag @a_different_tag @same_tag
18
+ Scenario:
19
+ * a step
20
+ """
21
+ When it is linted
22
+ Then an error is reported:
23
+ | linter | problem | location |
24
+ | ElementWithDuplicateTagsLinter | Scenario has duplicate tag '@same_tag'. | <path_to_file>:4 |
25
+
26
+
27
+ Scenario: Configuration of indirect tag inclusion (turned off)
28
+
29
+ Note: Tags inherited from other elements are not included by default
30
+
31
+ Given a linter for elements with duplicate tags has been registered
32
+ And the following configuration file:
33
+ """
34
+ ElementWithDuplicateTagsLinter:
35
+ IncludeInheritedTags: false
36
+ """
37
+ And the following feature:
38
+ """
39
+ @same_tag
40
+ Feature:
41
+
42
+ @same_tag
43
+ Scenario:
44
+ * a step
45
+ """
46
+ When the configuration file is loaded
47
+ And it is linted
48
+ Then no error is reported
49
+
50
+
51
+ Scenario: Configuration of indirect tag inclusion (turned on)
52
+ Given a linter for elements with duplicate tags has been registered
53
+ And the following configuration file:
54
+ """
55
+ ElementWithDuplicateTagsLinter:
56
+ IncludeInheritedTags: true
57
+ """
58
+ And the following feature:
59
+ """
60
+ @same_tag
61
+ Feature:
62
+
63
+ @same_tag
64
+ Scenario:
65
+ * a step
66
+ """
67
+ When the configuration file is loaded
68
+ And it is linted
69
+ Then an error is reported:
70
+ | linter | problem | location |
71
+ | ElementWithDuplicateTagsLinter | Scenario has duplicate tag '@same_tag'. | <path_to_file>:5 |
@@ -0,0 +1,32 @@
1
+ Feature: Feature file with mismatched name linter
2
+
3
+ As a reader of documentation
4
+ I want file names to match their features
5
+ so that I can tell what a file is about by reading the name
6
+
7
+ Scenario: Linting files with mismatched names
8
+ Given a feature file model based on the file "some_name" with the following text:
9
+ """
10
+ Feature: Some different name
11
+ """
12
+ And a linter for features with mismatched file names
13
+ When it is linted
14
+ Then an error is reported:
15
+ | linter | problem | location |
16
+ | FeatureFileWithMismatchedNameLinter | Feature file name does not match feature name. | <path_to_file> |
17
+
18
+ Scenario Outline: Linting files with matching names
19
+ Given a feature file model based on the file "<file name>" with the following text:
20
+ """
21
+ Feature: <feature name>
22
+ """
23
+ And a linter for features with mismatched file names
24
+ When it is linted
25
+ Then no error is reported
26
+
27
+ Examples:
28
+ | file name | feature name |
29
+ | name_with_underscores | Name with_underscores |
30
+ | name with spaces | Name with spaces |
31
+ | NameWithCaps | Name with Caps |
32
+ | name-with-hyphens | Name with-hyphens |