cuke_linter 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +217 -211
- data/LICENSE.txt +21 -21
- data/README.md +160 -160
- data/cuke_linter.gemspec +59 -58
- data/exe/cuke_linter +112 -112
- data/lib/cuke_linter/configuration.rb +45 -45
- data/lib/cuke_linter/default_linters.rb +32 -32
- data/lib/cuke_linter/formatters/pretty_formatter.rb +84 -84
- data/lib/cuke_linter/gherkin.rb +10 -10
- data/lib/cuke_linter/linter_registration.rb +32 -32
- data/lib/cuke_linter/linters/background_does_more_than_setup_linter.rb +35 -35
- data/lib/cuke_linter/linters/element_with_common_tags_linter.rb +49 -49
- data/lib/cuke_linter/linters/element_with_duplicate_tags_linter.rb +48 -48
- data/lib/cuke_linter/linters/element_with_too_many_tags_linter.rb +46 -46
- data/lib/cuke_linter/linters/example_without_name_linter.rb +19 -19
- data/lib/cuke_linter/linters/feature_file_with_invalid_name_linter.rb +20 -20
- data/lib/cuke_linter/linters/feature_file_with_mismatched_name_linter.rb +25 -25
- data/lib/cuke_linter/linters/feature_with_too_many_different_tags_linter.rb +35 -35
- data/lib/cuke_linter/linters/feature_without_description_linter.rb +19 -19
- data/lib/cuke_linter/linters/feature_without_name_linter.rb +19 -19
- data/lib/cuke_linter/linters/feature_without_scenarios_linter.rb +23 -23
- data/lib/cuke_linter/linters/linter.rb +42 -42
- data/lib/cuke_linter/linters/outline_with_single_example_row_linter.rb +22 -22
- data/lib/cuke_linter/linters/single_test_background_linter.rb +19 -19
- data/lib/cuke_linter/linters/step_with_end_period_linter.rb +19 -19
- data/lib/cuke_linter/linters/step_with_too_many_characters_linter.rb +38 -38
- data/lib/cuke_linter/linters/test_name_with_too_many_characters_linter.rb +38 -38
- data/lib/cuke_linter/linters/test_should_use_background_linter.rb +80 -80
- data/lib/cuke_linter/linters/test_with_action_step_as_final_step_linter.rb +33 -33
- data/lib/cuke_linter/linters/test_with_bad_name_linter.rb +23 -23
- data/lib/cuke_linter/linters/test_with_no_action_step_linter.rb +33 -33
- data/lib/cuke_linter/linters/test_with_no_name_linter.rb +19 -19
- data/lib/cuke_linter/linters/test_with_no_verification_step_linter.rb +33 -33
- data/lib/cuke_linter/linters/test_with_setup_step_after_action_step_linter.rb +46 -46
- data/lib/cuke_linter/linters/test_with_setup_step_after_verification_step_linter.rb +46 -46
- data/lib/cuke_linter/linters/test_with_setup_step_as_final_step_linter.rb +33 -33
- data/lib/cuke_linter/linters/test_with_too_many_steps_linter.rb +27 -27
- data/lib/cuke_linter/version.rb +4 -4
- data/lib/cuke_linter.rb +196 -196
- data/testing/cucumber/features/command_line.feature +202 -202
- data/testing/cucumber/features/configuration/configuring_linters.feature +58 -58
- data/testing/cucumber/features/configuration/locally_scoping_linters.feature +55 -55
- data/testing/cucumber/features/configuration/using_configurations.feature +41 -41
- data/testing/cucumber/features/custom_linters.feature +56 -56
- data/testing/cucumber/features/default_linters.feature +57 -57
- data/testing/cucumber/features/formatters/pretty_formatter.feature +26 -26
- data/testing/cucumber/features/linters/background_does_more_than_setup.feature +84 -84
- data/testing/cucumber/features/linters/element_with_common_tags.feature +28 -28
- data/testing/cucumber/features/linters/element_with_duplicate_tags.feature +71 -71
- data/testing/cucumber/features/linters/element_with_too_many_tags.feature +70 -70
- data/testing/cucumber/features/linters/example_without_name.feature +34 -34
- data/testing/cucumber/features/linters/feature_file_with_invalid_name.feature +20 -20
- data/testing/cucumber/features/linters/feature_file_with_mismatched_name.feature +32 -32
- data/testing/cucumber/features/linters/feature_with_too_many_different_tags.feature +56 -56
- data/testing/cucumber/features/linters/feature_without_description.feature +17 -17
- data/testing/cucumber/features/linters/feature_without_name.feature +18 -18
- data/testing/cucumber/features/linters/feature_without_scenarios.feature +39 -39
- data/testing/cucumber/features/linters/outline_with_single_example_row.feature +23 -23
- data/testing/cucumber/features/linters/single_test_background.feature +24 -24
- data/testing/cucumber/features/linters/step_too_long.feature +43 -43
- data/testing/cucumber/features/linters/step_with_end_period.feature +21 -21
- data/testing/cucumber/features/linters/test_name_too_long.feature +41 -41
- data/testing/cucumber/features/linters/test_should_use_background.feature +29 -29
- data/testing/cucumber/features/linters/test_with_action_as_final_step.feature +50 -50
- data/testing/cucumber/features/linters/test_with_bad_name.feature +29 -29
- data/testing/cucumber/features/linters/test_with_no_action_step.feature +56 -56
- data/testing/cucumber/features/linters/test_with_no_name.feature +23 -23
- data/testing/cucumber/features/linters/test_with_no_verification_step.feature +58 -58
- data/testing/cucumber/features/linters/test_with_setup_step_after_action_step.feature +57 -57
- data/testing/cucumber/features/linters/test_with_setup_step_after_verification_step.feature +57 -57
- data/testing/cucumber/features/linters/test_with_setup_step_as_final_step.feature +50 -50
- data/testing/cucumber/features/linters/test_with_too_many_steps.feature +61 -61
- metadata +21 -25
- data/testing/cucumber/features/linters/rule_without_name.feature +0 -18
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
module CukeLinter
|
|
2
|
-
|
|
3
|
-
# A linter that detects empty features
|
|
4
|
-
class FeatureWithoutScenariosLinter < Linter
|
|
5
|
-
|
|
6
|
-
# The rule used to determine if a model has a problem
|
|
7
|
-
def rule(model) # rubocop:disable Metrics/CyclomaticComplexity
|
|
8
|
-
return false unless model.is_a?(CukeModeler::Feature)
|
|
9
|
-
|
|
10
|
-
feature_tests = model.tests && model.tests.any?
|
|
11
|
-
rule_tests = model.respond_to?(:rules) && # Earlier versions of CukeModeler did not have Rule models
|
|
12
|
-
model.rules && model.rules.any? { |rule| rule.tests && rule.tests.any? }
|
|
13
|
-
|
|
14
|
-
!(feature_tests || rule_tests)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
# The message used to describe the problem that has been found
|
|
18
|
-
def message
|
|
19
|
-
'Feature has no scenarios'
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
end
|
|
23
|
-
end
|
|
1
|
+
module CukeLinter
|
|
2
|
+
|
|
3
|
+
# A linter that detects empty features
|
|
4
|
+
class FeatureWithoutScenariosLinter < Linter
|
|
5
|
+
|
|
6
|
+
# The rule used to determine if a model has a problem
|
|
7
|
+
def rule(model) # rubocop:disable Metrics/CyclomaticComplexity -- It's good enough
|
|
8
|
+
return false unless model.is_a?(CukeModeler::Feature)
|
|
9
|
+
|
|
10
|
+
feature_tests = model.tests && model.tests.any?
|
|
11
|
+
rule_tests = model.respond_to?(:rules) && # Earlier versions of CukeModeler did not have Rule models
|
|
12
|
+
model.rules && model.rules.any? { |rule| rule.tests && rule.tests.any? }
|
|
13
|
+
|
|
14
|
+
!(feature_tests || rule_tests)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# The message used to describe the problem that has been found
|
|
18
|
+
def message
|
|
19
|
+
'Feature has no scenarios'
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
module CukeLinter
|
|
2
|
-
|
|
3
|
-
# A generic linter that can be used to make arbitrary linting rules
|
|
4
|
-
class Linter
|
|
5
|
-
|
|
6
|
-
# Returns the name of the linter
|
|
7
|
-
attr_reader :name
|
|
8
|
-
|
|
9
|
-
# Creates a new linter object
|
|
10
|
-
def initialize(name: nil, message: nil, rule: nil)
|
|
11
|
-
@name = name || self.class.name.split('::').last
|
|
12
|
-
@message = message || "#{self.name} problem detected"
|
|
13
|
-
@rule = rule
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
# Lints the given model and returns linting data about said model
|
|
17
|
-
def lint(model)
|
|
18
|
-
raise 'No linting rule provided!' unless @rule || respond_to?(:rule)
|
|
19
|
-
|
|
20
|
-
problem_found = respond_to?(:rule) ? rule(model) : @rule.call(model)
|
|
21
|
-
|
|
22
|
-
return nil unless problem_found
|
|
23
|
-
|
|
24
|
-
build_problem(model)
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
private
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
def build_problem(model)
|
|
32
|
-
problem_message = respond_to?(:message) ? message : @message
|
|
33
|
-
|
|
34
|
-
if model.is_a?(CukeModeler::FeatureFile)
|
|
35
|
-
{ problem: problem_message, location: model.path }
|
|
36
|
-
else
|
|
37
|
-
{ problem: problem_message, location: "#{model.get_ancestor(:feature_file).path}:#{model.source_line}" }
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
end
|
|
42
|
-
end
|
|
1
|
+
module CukeLinter
|
|
2
|
+
|
|
3
|
+
# A generic linter that can be used to make arbitrary linting rules
|
|
4
|
+
class Linter
|
|
5
|
+
|
|
6
|
+
# Returns the name of the linter
|
|
7
|
+
attr_reader :name
|
|
8
|
+
|
|
9
|
+
# Creates a new linter object
|
|
10
|
+
def initialize(name: nil, message: nil, rule: nil)
|
|
11
|
+
@name = name || self.class.name.split('::').last
|
|
12
|
+
@message = message || "#{self.name} problem detected"
|
|
13
|
+
@rule = rule
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Lints the given model and returns linting data about said model
|
|
17
|
+
def lint(model)
|
|
18
|
+
raise 'No linting rule provided!' unless @rule || respond_to?(:rule)
|
|
19
|
+
|
|
20
|
+
problem_found = respond_to?(:rule) ? rule(model) : @rule.call(model)
|
|
21
|
+
|
|
22
|
+
return nil unless problem_found
|
|
23
|
+
|
|
24
|
+
build_problem(model)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def build_problem(model)
|
|
32
|
+
problem_message = respond_to?(:message) ? message : @message
|
|
33
|
+
|
|
34
|
+
if model.is_a?(CukeModeler::FeatureFile)
|
|
35
|
+
{ problem: problem_message, location: model.path }
|
|
36
|
+
else
|
|
37
|
+
{ problem: problem_message, location: "#{model.get_ancestor(:feature_file).path}:#{model.source_line}" }
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
module CukeLinter
|
|
2
|
-
|
|
3
|
-
# A linter that detects outlines that don't have multiple example rows
|
|
4
|
-
class OutlineWithSingleExampleRowLinter < Linter
|
|
5
|
-
|
|
6
|
-
# The rule used to determine if a model has a problem
|
|
7
|
-
def rule(model)
|
|
8
|
-
return false unless model.is_a?(CukeModeler::Outline)
|
|
9
|
-
return false if model.examples.nil?
|
|
10
|
-
|
|
11
|
-
examples_rows = model.examples.collect(&:argument_rows).flatten
|
|
12
|
-
|
|
13
|
-
examples_rows.
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
# The message used to describe the problem that has been found
|
|
17
|
-
def message
|
|
18
|
-
'Outline has only one example row'
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
end
|
|
22
|
-
end
|
|
1
|
+
module CukeLinter
|
|
2
|
+
|
|
3
|
+
# A linter that detects outlines that don't have multiple example rows
|
|
4
|
+
class OutlineWithSingleExampleRowLinter < Linter
|
|
5
|
+
|
|
6
|
+
# The rule used to determine if a model has a problem
|
|
7
|
+
def rule(model)
|
|
8
|
+
return false unless model.is_a?(CukeModeler::Outline)
|
|
9
|
+
return false if model.examples.nil?
|
|
10
|
+
|
|
11
|
+
examples_rows = model.examples.collect(&:argument_rows).flatten
|
|
12
|
+
|
|
13
|
+
examples_rows.one?
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# The message used to describe the problem that has been found
|
|
17
|
+
def message
|
|
18
|
+
'Outline has only one example row'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
module CukeLinter
|
|
2
|
-
|
|
3
|
-
# A linter that detects backgrounds that apply to only one test
|
|
4
|
-
class SingleTestBackgroundLinter < Linter
|
|
5
|
-
|
|
6
|
-
# The rule used to determine if a model has a problem
|
|
7
|
-
def rule(model)
|
|
8
|
-
return false unless model.is_a?(CukeModeler::Background)
|
|
9
|
-
|
|
10
|
-
model.parent_model.tests.
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
# The message used to describe the problem that has been found
|
|
14
|
-
def message
|
|
15
|
-
'Background used with only one test'
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
end
|
|
19
|
-
end
|
|
1
|
+
module CukeLinter
|
|
2
|
+
|
|
3
|
+
# A linter that detects backgrounds that apply to only one test
|
|
4
|
+
class SingleTestBackgroundLinter < Linter
|
|
5
|
+
|
|
6
|
+
# The rule used to determine if a model has a problem
|
|
7
|
+
def rule(model)
|
|
8
|
+
return false unless model.is_a?(CukeModeler::Background)
|
|
9
|
+
|
|
10
|
+
model.parent_model.tests.one?
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# The message used to describe the problem that has been found
|
|
14
|
+
def message
|
|
15
|
+
'Background used with only one test'
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
module CukeLinter
|
|
2
|
-
|
|
3
|
-
# A linter that detects steps that end in a period
|
|
4
|
-
class StepWithEndPeriodLinter < Linter
|
|
5
|
-
|
|
6
|
-
# The rule used to determine if a model has a problem
|
|
7
|
-
def rule(model)
|
|
8
|
-
return false unless model.is_a?(CukeModeler::Step)
|
|
9
|
-
|
|
10
|
-
model.text.end_with?('.')
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
# The message used to describe the problem that has been found
|
|
14
|
-
def message
|
|
15
|
-
'Step ends with a period'
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
end
|
|
19
|
-
end
|
|
1
|
+
module CukeLinter
|
|
2
|
+
|
|
3
|
+
# A linter that detects steps that end in a period
|
|
4
|
+
class StepWithEndPeriodLinter < Linter
|
|
5
|
+
|
|
6
|
+
# The rule used to determine if a model has a problem
|
|
7
|
+
def rule(model)
|
|
8
|
+
return false unless model.is_a?(CukeModeler::Step)
|
|
9
|
+
|
|
10
|
+
model.text.end_with?('.')
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# The message used to describe the problem that has been found
|
|
14
|
+
def message
|
|
15
|
+
'Step ends with a period'
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
module CukeLinter
|
|
2
|
-
|
|
3
|
-
# A linter that detects steps that are too long
|
|
4
|
-
class StepWithTooManyCharactersLinter < Linter
|
|
5
|
-
|
|
6
|
-
# The threshold used if not otherwise configured
|
|
7
|
-
DEFAULT_STEP_LENGTH_THRESHOLD = 80
|
|
8
|
-
|
|
9
|
-
# Changes the linting settings on the linter using the provided configuration
|
|
10
|
-
def configure(options)
|
|
11
|
-
@step_length_threshold = options['StepLengthThreshold'] if options['StepLengthThreshold']
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
# The rule used to determine if a model has a problem
|
|
15
|
-
def rule(model)
|
|
16
|
-
return false unless model.is_a?(CukeModeler::Step)
|
|
17
|
-
|
|
18
|
-
@linted_step_length = model.text.nil? ? 0 : model.text.length
|
|
19
|
-
|
|
20
|
-
@linted_step_length > step_length_threshold
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
# The message used to describe the problem that has been found
|
|
24
|
-
def message
|
|
25
|
-
"Step is too long. #{@linted_step_length} characters found (max #{step_length_threshold})"
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
private
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
# The maximum length allowable of a step
|
|
33
|
-
def step_length_threshold
|
|
34
|
-
@step_length_threshold || DEFAULT_STEP_LENGTH_THRESHOLD
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
end
|
|
38
|
-
end
|
|
1
|
+
module CukeLinter
|
|
2
|
+
|
|
3
|
+
# A linter that detects steps that are too long
|
|
4
|
+
class StepWithTooManyCharactersLinter < Linter
|
|
5
|
+
|
|
6
|
+
# The threshold used if not otherwise configured
|
|
7
|
+
DEFAULT_STEP_LENGTH_THRESHOLD = 80
|
|
8
|
+
|
|
9
|
+
# Changes the linting settings on the linter using the provided configuration
|
|
10
|
+
def configure(options)
|
|
11
|
+
@step_length_threshold = options['StepLengthThreshold'] if options['StepLengthThreshold']
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# The rule used to determine if a model has a problem
|
|
15
|
+
def rule(model)
|
|
16
|
+
return false unless model.is_a?(CukeModeler::Step)
|
|
17
|
+
|
|
18
|
+
@linted_step_length = model.text.nil? ? 0 : model.text.length
|
|
19
|
+
|
|
20
|
+
@linted_step_length > step_length_threshold
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# The message used to describe the problem that has been found
|
|
24
|
+
def message
|
|
25
|
+
"Step is too long. #{@linted_step_length} characters found (max #{step_length_threshold})"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# The maximum length allowable of a step
|
|
33
|
+
def step_length_threshold
|
|
34
|
+
@step_length_threshold || DEFAULT_STEP_LENGTH_THRESHOLD
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
module CukeLinter
|
|
2
|
-
|
|
3
|
-
# A linter that detects test names that are too long
|
|
4
|
-
class TestNameWithTooManyCharactersLinter < Linter
|
|
5
|
-
|
|
6
|
-
# The threshold used if not otherwise configured
|
|
7
|
-
DEFAULT_TEST_NAME_LENGTH_THRESHOLD = 80
|
|
8
|
-
|
|
9
|
-
# Changes the linting settings on the linter using the provided configuration
|
|
10
|
-
def configure(options)
|
|
11
|
-
@test_name_length_threshold = options['TestNameLengthThreshold'] if options['TestNameLengthThreshold']
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
# The rule used to determine if a model has a problem
|
|
15
|
-
def rule(model)
|
|
16
|
-
return false unless model.is_a?(CukeModeler::Scenario) || model.is_a?(CukeModeler::Outline)
|
|
17
|
-
|
|
18
|
-
@linted_test_name_length = model.name.nil? ? 0 : model.name.length
|
|
19
|
-
|
|
20
|
-
@linted_test_name_length > test_name_length_threshold
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
# The message used to describe the problem that has been found
|
|
24
|
-
def message
|
|
25
|
-
"Scenario name is too long. #{@linted_test_name_length} characters found (max #{test_name_length_threshold})"
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
private
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
# The maximum length allowable of a scenario name
|
|
33
|
-
def test_name_length_threshold
|
|
34
|
-
@test_name_length_threshold || DEFAULT_TEST_NAME_LENGTH_THRESHOLD
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
end
|
|
38
|
-
end
|
|
1
|
+
module CukeLinter
|
|
2
|
+
|
|
3
|
+
# A linter that detects test names that are too long
|
|
4
|
+
class TestNameWithTooManyCharactersLinter < Linter
|
|
5
|
+
|
|
6
|
+
# The threshold used if not otherwise configured
|
|
7
|
+
DEFAULT_TEST_NAME_LENGTH_THRESHOLD = 80
|
|
8
|
+
|
|
9
|
+
# Changes the linting settings on the linter using the provided configuration
|
|
10
|
+
def configure(options)
|
|
11
|
+
@test_name_length_threshold = options['TestNameLengthThreshold'] if options['TestNameLengthThreshold']
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# The rule used to determine if a model has a problem
|
|
15
|
+
def rule(model)
|
|
16
|
+
return false unless model.is_a?(CukeModeler::Scenario) || model.is_a?(CukeModeler::Outline)
|
|
17
|
+
|
|
18
|
+
@linted_test_name_length = model.name.nil? ? 0 : model.name.length
|
|
19
|
+
|
|
20
|
+
@linted_test_name_length > test_name_length_threshold
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# The message used to describe the problem that has been found
|
|
24
|
+
def message
|
|
25
|
+
"Scenario name is too long. #{@linted_test_name_length} characters found (max #{test_name_length_threshold})"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# The maximum length allowable of a scenario name
|
|
33
|
+
def test_name_length_threshold
|
|
34
|
+
@test_name_length_threshold || DEFAULT_TEST_NAME_LENGTH_THRESHOLD
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -1,80 +1,80 @@
|
|
|
1
|
-
# TODO: Make a new class that it is from the POV of a Feature model instead
|
|
2
|
-
|
|
3
|
-
module CukeLinter
|
|
4
|
-
|
|
5
|
-
# A linter that detects scenarios and outlines within a feature that all share common beginning steps
|
|
6
|
-
class TestShouldUseBackgroundLinter < Linter
|
|
7
|
-
|
|
8
|
-
# The rule used to determine if a model has a problem
|
|
9
|
-
def rule(model)
|
|
10
|
-
return false unless model.is_a?(CukeModeler::Scenario) || model.is_a?(CukeModeler::Outline)
|
|
11
|
-
|
|
12
|
-
model_steps = model.steps || []
|
|
13
|
-
parent_feature_model = model.get_ancestor(:feature)
|
|
14
|
-
|
|
15
|
-
return false unless parent_feature_model.tests.count > 1
|
|
16
|
-
|
|
17
|
-
matching_steps = all_first_steps_match?(parent_feature_model, model_steps)
|
|
18
|
-
none_parameterized = no_parameterized_steps?(parent_feature_model)
|
|
19
|
-
|
|
20
|
-
matching_steps && none_parameterized
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
# The message used to describe the problem that has been found
|
|
24
|
-
def message
|
|
25
|
-
'Test shares steps with all other tests in feature. Use a background.'
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
private
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
def all_first_steps_match?(feature_model, model_steps)
|
|
33
|
-
feature_model.tests.all? do |test|
|
|
34
|
-
test_steps = test.steps || []
|
|
35
|
-
test_steps.first == model_steps.first
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def no_parameterized_steps?(feature_model)
|
|
40
|
-
feature_model.tests.none? do |test|
|
|
41
|
-
next false if test.is_a?(CukeModeler::Scenario)
|
|
42
|
-
|
|
43
|
-
test_steps = test.steps || []
|
|
44
|
-
params_used_by_test = test.examples.map(&:parameters).flatten.uniq
|
|
45
|
-
|
|
46
|
-
next false unless test_steps.any?
|
|
47
|
-
|
|
48
|
-
parameterized_step?(test_steps.first, parameters: params_used_by_test)
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def parameterized_step?(step_model, parameters:)
|
|
53
|
-
parameters.any? do |parameter|
|
|
54
|
-
parameter_string = "<#{parameter}>"
|
|
55
|
-
|
|
56
|
-
parameterized_text?(step_model, parameter_string) ||
|
|
57
|
-
parameterized_doc_string?(step_model, parameter_string) ||
|
|
58
|
-
parameterized_table?(step_model, parameter_string)
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def parameterized_text?(step_model, parameter)
|
|
63
|
-
step_model.text.include?(parameter)
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def parameterized_doc_string?(step_model, parameter)
|
|
67
|
-
return false unless step_model.block.is_a?(CukeModeler::DocString)
|
|
68
|
-
|
|
69
|
-
step_model.block.content.include?(parameter)
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
def parameterized_table?(step_model, parameter)
|
|
73
|
-
return false unless step_model.block.is_a?(CukeModeler::Table)
|
|
74
|
-
|
|
75
|
-
step_model.block.rows.map(&:cells).flatten.map(&:value).any? { |cell_text| cell_text.include?(parameter) }
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
end
|
|
1
|
+
# TODO: Make a new class that it is from the POV of a Feature model instead
|
|
2
|
+
|
|
3
|
+
module CukeLinter
|
|
4
|
+
|
|
5
|
+
# A linter that detects scenarios and outlines within a feature that all share common beginning steps
|
|
6
|
+
class TestShouldUseBackgroundLinter < Linter
|
|
7
|
+
|
|
8
|
+
# The rule used to determine if a model has a problem
|
|
9
|
+
def rule(model)
|
|
10
|
+
return false unless model.is_a?(CukeModeler::Scenario) || model.is_a?(CukeModeler::Outline)
|
|
11
|
+
|
|
12
|
+
model_steps = model.steps || []
|
|
13
|
+
parent_feature_model = model.get_ancestor(:feature)
|
|
14
|
+
|
|
15
|
+
return false unless parent_feature_model.tests.count > 1
|
|
16
|
+
|
|
17
|
+
matching_steps = all_first_steps_match?(parent_feature_model, model_steps)
|
|
18
|
+
none_parameterized = no_parameterized_steps?(parent_feature_model)
|
|
19
|
+
|
|
20
|
+
matching_steps && none_parameterized
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# The message used to describe the problem that has been found
|
|
24
|
+
def message
|
|
25
|
+
'Test shares steps with all other tests in feature. Use a background.'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def all_first_steps_match?(feature_model, model_steps)
|
|
33
|
+
feature_model.tests.all? do |test|
|
|
34
|
+
test_steps = test.steps || []
|
|
35
|
+
test_steps.first == model_steps.first
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def no_parameterized_steps?(feature_model)
|
|
40
|
+
feature_model.tests.none? do |test|
|
|
41
|
+
next false if test.is_a?(CukeModeler::Scenario)
|
|
42
|
+
|
|
43
|
+
test_steps = test.steps || []
|
|
44
|
+
params_used_by_test = test.examples.map(&:parameters).flatten.uniq
|
|
45
|
+
|
|
46
|
+
next false unless test_steps.any?
|
|
47
|
+
|
|
48
|
+
parameterized_step?(test_steps.first, parameters: params_used_by_test)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def parameterized_step?(step_model, parameters:)
|
|
53
|
+
parameters.any? do |parameter|
|
|
54
|
+
parameter_string = "<#{parameter}>"
|
|
55
|
+
|
|
56
|
+
parameterized_text?(step_model, parameter_string) ||
|
|
57
|
+
parameterized_doc_string?(step_model, parameter_string) ||
|
|
58
|
+
parameterized_table?(step_model, parameter_string)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def parameterized_text?(step_model, parameter)
|
|
63
|
+
step_model.text.include?(parameter)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def parameterized_doc_string?(step_model, parameter)
|
|
67
|
+
return false unless step_model.block.is_a?(CukeModeler::DocString)
|
|
68
|
+
|
|
69
|
+
step_model.block.content.include?(parameter)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def parameterized_table?(step_model, parameter)
|
|
73
|
+
return false unless step_model.block.is_a?(CukeModeler::Table)
|
|
74
|
+
|
|
75
|
+
step_model.block.rows.map(&:cells).flatten.map(&:value).any? { |cell_text| cell_text.include?(parameter) }
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
end
|
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
module CukeLinter
|
|
2
|
-
|
|
3
|
-
# A linter that detects scenarios and outlines that have an action step as their final step
|
|
4
|
-
class TestWithActionStepAsFinalStepLinter < Linter
|
|
5
|
-
|
|
6
|
-
# Changes the linting settings on the linter using the provided configuration
|
|
7
|
-
def configure(options)
|
|
8
|
-
@when_keywords = options['When']
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
# The rule used to determine if a model has a problem
|
|
12
|
-
def rule(model)
|
|
13
|
-
return false unless model.is_a?(CukeModeler::Scenario) || model.is_a?(CukeModeler::Outline)
|
|
14
|
-
|
|
15
|
-
model_steps = model.steps || []
|
|
16
|
-
return false unless model_steps.last
|
|
17
|
-
|
|
18
|
-
when_keywords.include?(model_steps.last.keyword)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
# The message used to describe the problem that has been found
|
|
22
|
-
def message
|
|
23
|
-
"Test has 'When' as the final step."
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
private
|
|
27
|
-
|
|
28
|
-
def when_keywords
|
|
29
|
-
@when_keywords || [DEFAULT_WHEN_KEYWORD]
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
end
|
|
33
|
-
end
|
|
1
|
+
module CukeLinter
|
|
2
|
+
|
|
3
|
+
# A linter that detects scenarios and outlines that have an action step as their final step
|
|
4
|
+
class TestWithActionStepAsFinalStepLinter < Linter
|
|
5
|
+
|
|
6
|
+
# Changes the linting settings on the linter using the provided configuration
|
|
7
|
+
def configure(options)
|
|
8
|
+
@when_keywords = options['When']
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# The rule used to determine if a model has a problem
|
|
12
|
+
def rule(model)
|
|
13
|
+
return false unless model.is_a?(CukeModeler::Scenario) || model.is_a?(CukeModeler::Outline)
|
|
14
|
+
|
|
15
|
+
model_steps = model.steps || []
|
|
16
|
+
return false unless model_steps.last
|
|
17
|
+
|
|
18
|
+
when_keywords.include?(model_steps.last.keyword)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# The message used to describe the problem that has been found
|
|
22
|
+
def message
|
|
23
|
+
"Test has 'When' as the final step."
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def when_keywords
|
|
29
|
+
@when_keywords || [DEFAULT_WHEN_KEYWORD]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end
|
|
33
|
+
end
|