cucumber_lint 0.0.4 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|