cucumber_lint 0.0.4 → 0.1.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/.ruby-version +1 -0
- data/Gemfile +2 -1
- data/Gemfile.lock +48 -30
- data/README.md +41 -24
- data/Rakefile +1 -1
- data/circle.yml +3 -0
- data/config/default.yml +27 -0
- data/cucumber_lint.gemspec +4 -4
- data/features/cucumber_lint/consistent_empty_lines/between_description_and_scenario.feature +39 -0
- data/features/cucumber_lint/consistent_empty_lines/between_elements/ending_with_docstring.feature +47 -0
- data/features/cucumber_lint/consistent_empty_lines/between_elements/ending_with_examples.feature +49 -0
- data/features/cucumber_lint/consistent_empty_lines/between_elements/ending_with_step.feature +41 -0
- data/features/cucumber_lint/consistent_empty_lines/between_elements/ending_with_table.feature +43 -0
- data/features/cucumber_lint/consistent_empty_lines/between_feature_and_description.feature +33 -0
- data/features/cucumber_lint/consistent_empty_lines/between_feature_and_scenario.feature +33 -0
- data/features/cucumber_lint/consistent_table_headers/examples_table.feature +74 -0
- data/features/cucumber_lint/consistent_table_headers/step_table.feature +64 -0
- data/features/cucumber_lint/consistent_table_headers/unsupported_style.feature +20 -0
- data/features/cucumber_lint/consistent_table_whitespace/examples_table.feature +46 -0
- data/features/cucumber_lint/consistent_table_whitespace/step_table.feature +42 -0
- data/features/cucumber_lint/no_empty_features.feature +20 -0
- data/features/cucumber_lint/no_files.feature +6 -0
- data/features/cucumber_lint/no_repeating_keywords.feature +44 -0
- data/features/cucumber_lint/unsupported_options.feature +11 -0
- data/features/step_definitions/cli_steps.rb +47 -10
- data/features/step_definitions/env.rb +5 -9
- data/features/step_definitions/fixtures/config/disabled.yml +18 -0
- data/features/step_definitions/support/file_helpers.rb +20 -0
- data/lib/core_ext/array.rb +8 -0
- data/lib/core_ext/basic_object.rb +8 -0
- data/lib/core_ext/hash.rb +3 -18
- data/lib/core_ext/string.rb +7 -0
- data/lib/cucumber_lint/cli.rb +60 -31
- data/lib/cucumber_lint/config.rb +55 -0
- data/lib/cucumber_lint/errors/unsupported_style.rb +10 -0
- data/lib/cucumber_lint/linted_file.rb +77 -0
- data/lib/cucumber_lint/linter/feature_empty_lines_linter.rb +125 -0
- data/lib/cucumber_lint/linter/feature_linter.rb +33 -30
- data/lib/cucumber_lint/linter/scenario_outline_linter.rb +17 -8
- data/lib/cucumber_lint/linter/steps_linter.rb +9 -8
- data/lib/cucumber_lint/linter/table_linter.rb +26 -15
- data/lib/cucumber_lint/linter.rb +10 -10
- data/lib/cucumber_lint/version.rb +1 -1
- data/lib/cucumber_lint.rb +4 -1
- metadata +35 -36
- data/.travis.yml +0 -9
- data/features/cucumber_lint/fix/nothing.feature +0 -12
- data/features/cucumber_lint/fix/repeating_steps.feature +0 -25
- data/features/cucumber_lint/fix/table_whitespace.feature +0 -25
- data/features/cucumber_lint/fix/uppercase_table_headers.feature +0 -25
- data/features/cucumber_lint/lint/nothing.feature +0 -12
- data/features/cucumber_lint/lint/repeating_steps.feature +0 -31
- data/features/cucumber_lint/lint/table_whitespace.feature +0 -27
- data/features/cucumber_lint/lint/uppercase_table_headers.feature +0 -30
- data/features/step_definitions/feature_formatter_steps.rb +0 -15
- data/features/step_definitions/fixtures/repeating_steps/bad.feature.example +0 -12
- data/features/step_definitions/fixtures/repeating_steps/good.feature.example +0 -12
- data/features/step_definitions/fixtures/table_whitespace/bad.feature.example +0 -20
- data/features/step_definitions/fixtures/table_whitespace/good.feature.example +0 -20
- data/features/step_definitions/fixtures/uppercase_table_headers/bad.feature.example +0 -20
- data/features/step_definitions/fixtures/uppercase_table_headers/good.feature.example +0 -20
- data/lib/cucumber_lint/fix_list.rb +0 -37
@@ -0,0 +1,64 @@
|
|
1
|
+
Feature: consistent_table_headers for a step table
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given I have a feature with content
|
5
|
+
"""
|
6
|
+
Feature: Test Feature
|
7
|
+
|
8
|
+
Scenario: Test Scenario
|
9
|
+
Given a table
|
10
|
+
| VEGETABLE | fruit | Code Name |
|
11
|
+
| Asparagus | Apple | Alpha |
|
12
|
+
| Broccoli | Banana | Bravo |
|
13
|
+
| Carrot | Cherry | Charlie |
|
14
|
+
Then my tests pass
|
15
|
+
"""
|
16
|
+
|
17
|
+
Scenario: disabled
|
18
|
+
Given I have "consistent_table_headers" disabled
|
19
|
+
When I run `cucumber_lint`
|
20
|
+
Then it passes
|
21
|
+
|
22
|
+
Scenario: uppercase - lint and fix
|
23
|
+
Given I have "consistent_table_headers" enabled with "enforced_style" as "uppercase"
|
24
|
+
When I run `cucumber_lint`
|
25
|
+
Then it fails with
|
26
|
+
| LINE | MESSAGE |
|
27
|
+
| 5 | uppercase table headers |
|
28
|
+
When I run `cucumber_lint --fix`
|
29
|
+
Then my feature now has content
|
30
|
+
"""
|
31
|
+
Feature: Test Feature
|
32
|
+
|
33
|
+
Scenario: Test Scenario
|
34
|
+
Given a table
|
35
|
+
| VEGETABLE | FRUIT | CODE NAME |
|
36
|
+
| Asparagus | Apple | Alpha |
|
37
|
+
| Broccoli | Banana | Bravo |
|
38
|
+
| Carrot | Cherry | Charlie |
|
39
|
+
Then my tests pass
|
40
|
+
"""
|
41
|
+
When I run `cucumber_lint`
|
42
|
+
Then it passes
|
43
|
+
|
44
|
+
Scenario: lowercase - lint and fix
|
45
|
+
Given I have "consistent_table_headers" enabled with "enforced_style" as "lowercase"
|
46
|
+
When I run `cucumber_lint`
|
47
|
+
Then it fails with
|
48
|
+
| LINE | MESSAGE |
|
49
|
+
| 5 | lowercase table headers |
|
50
|
+
When I run `cucumber_lint --fix`
|
51
|
+
Then my feature now has content
|
52
|
+
"""
|
53
|
+
Feature: Test Feature
|
54
|
+
|
55
|
+
Scenario: Test Scenario
|
56
|
+
Given a table
|
57
|
+
| vegetable | fruit | code name |
|
58
|
+
| Asparagus | Apple | Alpha |
|
59
|
+
| Broccoli | Banana | Bravo |
|
60
|
+
| Carrot | Cherry | Charlie |
|
61
|
+
Then my tests pass
|
62
|
+
"""
|
63
|
+
When I run `cucumber_lint`
|
64
|
+
Then it passes
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Feature: consistent_table_headers enforcing an unsupported style
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given I have "consistent_table_headers" enabled with "enforced_style" as "invalid"
|
5
|
+
|
6
|
+
Scenario: lint
|
7
|
+
When I run `cucumber_lint`
|
8
|
+
Then I see the output
|
9
|
+
"""
|
10
|
+
consistent_table_headers does not support invalid. Supported: lowercase, uppercase
|
11
|
+
"""
|
12
|
+
And it exits with status 1
|
13
|
+
|
14
|
+
Scenario: fix
|
15
|
+
When I run `cucumber_lint --fix`
|
16
|
+
Then I see the output
|
17
|
+
"""
|
18
|
+
consistent_table_headers does not support invalid. Supported: lowercase, uppercase
|
19
|
+
"""
|
20
|
+
And it exits with status 1
|
@@ -0,0 +1,46 @@
|
|
1
|
+
Feature: consistent_table_whitespace for an examples table
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given I have a feature with content
|
5
|
+
"""
|
6
|
+
Feature: Test Feature
|
7
|
+
|
8
|
+
Scenario Outline: Test Scenario Outline
|
9
|
+
Given <VEGETABLE> and <FRUIT>
|
10
|
+
Then I expect <CODENAME>
|
11
|
+
|
12
|
+
Examples:
|
13
|
+
|VEGETABLE| FRUIT | CODENAME |
|
14
|
+
|Asparagus | Apple | Alpha |
|
15
|
+
|Broccoli | Banana | Bravo |
|
16
|
+
| Carrot| Cherry | Charlie |
|
17
|
+
"""
|
18
|
+
|
19
|
+
Scenario: disabled
|
20
|
+
Given I have "consistent_table_whitespace" enabled
|
21
|
+
When I run `cucumber_lint --fix`
|
22
|
+
Then it passes
|
23
|
+
|
24
|
+
Scenario: lint and fix
|
25
|
+
Given I have "consistent_table_whitespace" enabled
|
26
|
+
When I run `cucumber_lint`
|
27
|
+
Then it fails with
|
28
|
+
| LINE | MESSAGE |
|
29
|
+
| 8 | Fix table whitespace |
|
30
|
+
When I run `cucumber_lint --fix`
|
31
|
+
Then my feature now has content
|
32
|
+
"""
|
33
|
+
Feature: Test Feature
|
34
|
+
|
35
|
+
Scenario Outline: Test Scenario Outline
|
36
|
+
Given <VEGETABLE> and <FRUIT>
|
37
|
+
Then I expect <CODENAME>
|
38
|
+
|
39
|
+
Examples:
|
40
|
+
| VEGETABLE | FRUIT | CODENAME |
|
41
|
+
| Asparagus | Apple | Alpha |
|
42
|
+
| Broccoli | Banana | Bravo |
|
43
|
+
| Carrot | Cherry | Charlie |
|
44
|
+
"""
|
45
|
+
When I run `cucumber_lint`
|
46
|
+
Then it passes
|
@@ -0,0 +1,42 @@
|
|
1
|
+
Feature: consistent_table_whitespace for a step table
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given I have a feature with content
|
5
|
+
"""
|
6
|
+
Feature: Test Feature
|
7
|
+
|
8
|
+
Scenario: Test Scenario
|
9
|
+
Given a table
|
10
|
+
|VEGETABLE|CODENAME|
|
11
|
+
|Asparagus|Alpha|
|
12
|
+
|Broccoli|Bravo|
|
13
|
+
|Carrot|Charlie|
|
14
|
+
Then my tests pass
|
15
|
+
"""
|
16
|
+
|
17
|
+
Scenario: disabled
|
18
|
+
Given I have "consistent_table_whitespace" disabled
|
19
|
+
When I run `cucumber_lint`
|
20
|
+
Then it passes
|
21
|
+
|
22
|
+
Scenario: lint and fix
|
23
|
+
Given I have "consistent_table_whitespace" enabled
|
24
|
+
When I run `cucumber_lint`
|
25
|
+
Then it fails with
|
26
|
+
| LINE | MESSAGE |
|
27
|
+
| 5 | Fix table whitespace |
|
28
|
+
When I run `cucumber_lint --fix`
|
29
|
+
Then my feature now has content
|
30
|
+
"""
|
31
|
+
Feature: Test Feature
|
32
|
+
|
33
|
+
Scenario: Test Scenario
|
34
|
+
Given a table
|
35
|
+
| VEGETABLE | CODENAME |
|
36
|
+
| Asparagus | Alpha |
|
37
|
+
| Broccoli | Bravo |
|
38
|
+
| Carrot | Charlie |
|
39
|
+
Then my tests pass
|
40
|
+
"""
|
41
|
+
When I run `cucumber_lint`
|
42
|
+
Then it passes
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Feature: no_empty_features
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given I have a file without a feature
|
5
|
+
|
6
|
+
Scenario: disabled
|
7
|
+
Given I have "no_empty_features" disabled
|
8
|
+
When I run `cucumber_lint`
|
9
|
+
Then it passes
|
10
|
+
|
11
|
+
Scenario: lint and fix
|
12
|
+
Given I have "no_empty_features" enabled
|
13
|
+
When I run `cucumber_lint`
|
14
|
+
Then it fails with
|
15
|
+
| MESSAGE |
|
16
|
+
| Remove file with no feature |
|
17
|
+
When I run `cucumber_lint --fix`
|
18
|
+
Then the file has been deleted
|
19
|
+
When I run `cucumber_lint`
|
20
|
+
Then it passes
|
@@ -0,0 +1,44 @@
|
|
1
|
+
Feature: no_repeating_keywords enabled
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given I have a feature with content
|
5
|
+
"""
|
6
|
+
Feature: Test Feature
|
7
|
+
|
8
|
+
Scenario: Test Scenario
|
9
|
+
Given A
|
10
|
+
Given B
|
11
|
+
When C
|
12
|
+
When D
|
13
|
+
Then E
|
14
|
+
Then F
|
15
|
+
"""
|
16
|
+
|
17
|
+
Scenario: disabled
|
18
|
+
Given I have "no_repeating_keywords" disabled
|
19
|
+
When I run `cucumber_lint`
|
20
|
+
Then it passes
|
21
|
+
|
22
|
+
Scenario: lint and fix
|
23
|
+
Given I have "no_repeating_keywords" enabled
|
24
|
+
When I run `cucumber_lint`
|
25
|
+
Then it fails with
|
26
|
+
| LINE | MESSAGE |
|
27
|
+
| 5 | Use "And" instead of repeating "Given" |
|
28
|
+
| 7 | Use "And" instead of repeating "When" |
|
29
|
+
| 9 | Use "And" instead of repeating "Then" |
|
30
|
+
When I run `cucumber_lint --fix`
|
31
|
+
Then my feature now has content
|
32
|
+
"""
|
33
|
+
Feature: Test Feature
|
34
|
+
|
35
|
+
Scenario: Test Scenario
|
36
|
+
Given A
|
37
|
+
And B
|
38
|
+
When C
|
39
|
+
And D
|
40
|
+
Then E
|
41
|
+
And F
|
42
|
+
"""
|
43
|
+
When I run `cucumber_lint`
|
44
|
+
Then it passes
|
@@ -0,0 +1,11 @@
|
|
1
|
+
Feature: unsupported option
|
2
|
+
|
3
|
+
Scenario: passing an unsupported option
|
4
|
+
When I run `cucumber_lint --invalid`
|
5
|
+
Then I see the output
|
6
|
+
"""
|
7
|
+
error: unsupported option(s): --invalid
|
8
|
+
usage: cucumber_lint
|
9
|
+
or: cucumber_lint --fix
|
10
|
+
"""
|
11
|
+
And it exits with status 1
|
@@ -1,21 +1,54 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
|
1
4
|
Given(/^I have no files$/) do
|
2
5
|
# Empty step for readability
|
3
6
|
end
|
4
7
|
|
5
8
|
|
6
|
-
Given(/^I have
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
Given(/^I have "(.+?)" (enabled|disabled)$/) do |key, value|
|
10
|
+
update_config(key => { enabled: value == 'enabled' })
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
Given(/^I have "(.+?)" enabled with "(.+?)" as "(.+?)"$/) do |key, config_key, config_value|
|
15
|
+
config_value = config_value.to_i if config_value.match(/^\d*$/)
|
16
|
+
update_config(key => { enabled: true, config_key => config_value })
|
11
17
|
end
|
12
18
|
|
13
19
|
|
20
|
+
Given(/^I have a file without a feature$/) do
|
21
|
+
write_feature ''
|
22
|
+
end
|
23
|
+
|
24
|
+
Given(/^I have a feature with content$/) do |content|
|
25
|
+
write_feature content.to_s
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
|
14
31
|
When(/^I run `(.+?)`$/) do |command|
|
15
32
|
@last_run = run command
|
16
33
|
end
|
17
34
|
|
18
35
|
|
36
|
+
Then(/^it passes$/) do
|
37
|
+
expect(@last_run.exit_status).to eql(0), @last_run.out.uncolorize
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
Then(/^it fails with$/) do |failureTable|
|
42
|
+
expected_text = failureTable.hashes.map do |row|
|
43
|
+
identifer = './features/test.feature'
|
44
|
+
identifer += ":#{row['LINE']}" if row['LINE']
|
45
|
+
"#{identifer}: #{row['MESSAGE']}"
|
46
|
+
end.join "\n"
|
47
|
+
expect(@last_run.out.uncolorize).to include expected_text
|
48
|
+
expect(@last_run.exit_status).to eql 1
|
49
|
+
end
|
50
|
+
|
51
|
+
|
19
52
|
Then(/^I see the output$/) do |output|
|
20
53
|
expect(@last_run.out.uncolorize).to eql "#{output}\n"
|
21
54
|
end
|
@@ -26,9 +59,13 @@ Then(/^it exits with status (\d+)$/) do |status|
|
|
26
59
|
end
|
27
60
|
|
28
61
|
|
29
|
-
Then(/^
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
62
|
+
Then(/^my feature now has content$/) do |content|
|
63
|
+
actual = IO.read feature_path
|
64
|
+
expect(actual).to eql content.to_s
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
Then(/^the file has been deleted$/) do
|
69
|
+
exists = File.exist? feature_path
|
70
|
+
expect(exists).to be_falsy
|
34
71
|
end
|
@@ -1,20 +1,16 @@
|
|
1
|
+
require 'active_support/core_ext/hash/deep_merge.rb'
|
1
2
|
require 'cucumber_lint'
|
2
3
|
require 'open4'
|
3
4
|
require 'rspec'
|
4
5
|
|
5
6
|
|
6
7
|
BIN_PATH = "#{File.dirname(__FILE__)}/../../bin"
|
7
|
-
|
8
|
-
TMP_DIR = '/tmp'
|
8
|
+
CONFIG_PATH = "#{File.dirname(__FILE__)}/fixtures/config/disabled.yml"
|
9
9
|
|
10
10
|
|
11
11
|
Before do
|
12
|
-
Dir.
|
13
|
-
|
12
|
+
@tmp_dir = Dir.mktmpdir
|
13
|
+
Dir.chdir @tmp_dir
|
14
|
+
IO.write 'cucumber_lint.yml', IO.read(CONFIG_PATH)
|
14
15
|
Dir.mkdir 'features'
|
15
16
|
end
|
16
|
-
|
17
|
-
|
18
|
-
at_exit do
|
19
|
-
FileUtils.rm_rf TMP_DIR
|
20
|
-
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
def config_path
|
2
|
+
"#{@tmp_dir}/cucumber_lint.yml"
|
3
|
+
end
|
4
|
+
|
5
|
+
|
6
|
+
def feature_path
|
7
|
+
"#{@tmp_dir}/features/test.feature"
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
def update_config updates
|
12
|
+
config = YAML.load IO.read config_path
|
13
|
+
updated_config = config.deep_merge updates
|
14
|
+
IO.write config_path, updated_config.to_yaml
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
def write_feature content
|
19
|
+
IO.write feature_path, content
|
20
|
+
end
|
data/lib/core_ext/hash.rb
CHANGED
@@ -3,27 +3,12 @@ class Hash
|
|
3
3
|
|
4
4
|
def to_open_struct
|
5
5
|
out = OpenStruct.new self
|
6
|
-
out.each_pair { |k, v| out[k] = object_to_open_struct v }
|
7
|
-
out
|
8
|
-
end
|
9
|
-
|
10
|
-
|
11
|
-
private
|
12
6
|
|
13
|
-
|
14
|
-
|
15
|
-
if object.is_a? Hash
|
16
|
-
object.to_open_struct
|
17
|
-
elsif object.is_a? Array
|
18
|
-
array_to_open_struct object
|
19
|
-
else
|
20
|
-
object
|
7
|
+
out.each_pair do |k, v|
|
8
|
+
out[k] = v.to_open_struct
|
21
9
|
end
|
22
|
-
end
|
23
10
|
|
24
|
-
|
25
|
-
def array_to_open_struct array
|
26
|
-
array.map { |element| object_to_open_struct element }
|
11
|
+
out
|
27
12
|
end
|
28
13
|
|
29
14
|
end
|
data/lib/cucumber_lint/cli.rb
CHANGED
@@ -13,8 +13,10 @@ module CucumberLint
|
|
13
13
|
|
14
14
|
def initialize args, out: STDOUT
|
15
15
|
@out = out
|
16
|
-
|
17
|
-
|
16
|
+
|
17
|
+
opts = extract_args args
|
18
|
+
@config = load_config fix: opts[:fix]
|
19
|
+
@results = OpenStruct.new(total: 0, passed: 0, failed: 0, written: 0, deleted: 0, errors: [])
|
18
20
|
end
|
19
21
|
|
20
22
|
|
@@ -27,29 +29,56 @@ module CucumberLint
|
|
27
29
|
exit 1 unless @results.errors.empty?
|
28
30
|
end
|
29
31
|
|
32
|
+
|
30
33
|
private
|
31
34
|
|
35
|
+
|
36
|
+
def add_result status, errors
|
37
|
+
@results.total += 1
|
38
|
+
@results[status] += 1
|
39
|
+
@results.errors += errors
|
40
|
+
@out.print output_for_status(status)
|
41
|
+
end
|
42
|
+
|
43
|
+
|
32
44
|
def lint_feature filename
|
33
|
-
|
45
|
+
linted_file = LintedFile.new filename
|
46
|
+
|
47
|
+
linter = FeatureLinter.new config: @config, linted_file: linted_file
|
34
48
|
linter.lint
|
35
49
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
50
|
+
add_result linted_file.resolve, linted_file.errors
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
def load_config fix:
|
55
|
+
Config.new dir: Pathname.new('.').realpath, fix: fix
|
56
|
+
rescue UnsupportedStyle => e
|
57
|
+
@out.puts e.message.red
|
58
|
+
exit 1
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
def extract_args args
|
63
|
+
valid_args = ['--fix']
|
64
|
+
|
65
|
+
if (args - valid_args).empty?
|
66
|
+
{ fix: args.count == 1 }
|
41
67
|
else
|
42
|
-
|
68
|
+
@out.puts "error: unsupported option(s): #{args.join(' ')}".red
|
69
|
+
@out.puts 'usage: cucumber_lint'
|
70
|
+
@out.puts ' or: cucumber_lint --fix'
|
71
|
+
exit 1
|
43
72
|
end
|
44
|
-
|
45
|
-
linter.write if linter.can_fix?
|
46
73
|
end
|
47
74
|
|
75
|
+
|
48
76
|
def file_counts
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
77
|
+
[:passed, :written, :deleted, :failed].map do |status|
|
78
|
+
if status == :passed || @results[status] > 0
|
79
|
+
"#{@results[status]} #{status}".colorize(output_color_for status)
|
80
|
+
end
|
81
|
+
end.compact.join(', ')
|
53
82
|
end
|
54
83
|
|
55
84
|
|
@@ -62,7 +91,7 @@ module CucumberLint
|
|
62
91
|
def output_counts
|
63
92
|
@out.print "\n\n"
|
64
93
|
@out.print "#{@results.total} file#{'s' if @results.total != 1} inspected"
|
65
|
-
@out.print " #{file_counts}" if @results.total > 0
|
94
|
+
@out.print " (#{file_counts})" if @results.total > 0
|
66
95
|
@out.print "\n"
|
67
96
|
end
|
68
97
|
|
@@ -72,25 +101,25 @@ module CucumberLint
|
|
72
101
|
output_counts
|
73
102
|
end
|
74
103
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
104
|
+
def output_color_for status
|
105
|
+
case status
|
106
|
+
when :passed then :green
|
107
|
+
when :failed then :red
|
108
|
+
else :yellow
|
109
|
+
end
|
80
110
|
end
|
81
111
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
112
|
+
def output_letter_for status
|
113
|
+
case status
|
114
|
+
when :passed then '.'
|
115
|
+
when :failed then 'F'
|
116
|
+
when :written then 'W'
|
117
|
+
when :deleted then 'D'
|
118
|
+
end
|
87
119
|
end
|
88
120
|
|
89
|
-
|
90
|
-
|
91
|
-
@results.total += 1
|
92
|
-
@results.written += 1
|
93
|
-
@out.print 'W'.yellow
|
121
|
+
def output_for_status status
|
122
|
+
output_letter_for(status).colorize output_color_for(status)
|
94
123
|
end
|
95
124
|
|
96
125
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module CucumberLint
|
4
|
+
# A configuration for executing cucumber_lint
|
5
|
+
class Config
|
6
|
+
|
7
|
+
attr_reader :fix
|
8
|
+
|
9
|
+
def initialize dir:, fix:
|
10
|
+
@dir = dir
|
11
|
+
@fix = fix
|
12
|
+
@options = parse_config
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
def method_missing method
|
17
|
+
@options.send(method)
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
# rubocop:disable Metrics/MethodLength
|
24
|
+
def parse_config
|
25
|
+
defaults = load_default_config
|
26
|
+
overrides = load_config "#{@dir}/cucumber_lint.yml"
|
27
|
+
|
28
|
+
overrides.each_pair do |style, style_overrides|
|
29
|
+
style_overrides.each_pair do |key, value|
|
30
|
+
if key == 'enforced_style'
|
31
|
+
supported = defaults[style]['supported_styles']
|
32
|
+
fail UnsupportedStyle.new style, supported, value unless supported.include?(value)
|
33
|
+
end
|
34
|
+
|
35
|
+
defaults[style][key] = value
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
defaults.to_open_struct
|
40
|
+
end
|
41
|
+
# rubocop:enable Metrics/MethodLength
|
42
|
+
|
43
|
+
|
44
|
+
def load_config path
|
45
|
+
return {} unless File.exist? path
|
46
|
+
YAML.load File.read path
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
def load_default_config
|
51
|
+
load_config "#{File.dirname(__FILE__)}/../../config/default.yml"
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module CucumberLint
|
2
|
+
# A class representing a user configuration that tries to use an unsupported style
|
3
|
+
class UnsupportedStyle < StandardError
|
4
|
+
|
5
|
+
def initialize style, supported_styles, override
|
6
|
+
super("#{style} does not support #{override}. Supported: #{supported_styles.join(', ')}")
|
7
|
+
end
|
8
|
+
|
9
|
+
end
|
10
|
+
end
|