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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -0
  3. data/Gemfile +2 -1
  4. data/Gemfile.lock +48 -30
  5. data/README.md +41 -24
  6. data/Rakefile +1 -1
  7. data/circle.yml +3 -0
  8. data/config/default.yml +27 -0
  9. data/cucumber_lint.gemspec +4 -4
  10. data/features/cucumber_lint/consistent_empty_lines/between_description_and_scenario.feature +39 -0
  11. data/features/cucumber_lint/consistent_empty_lines/between_elements/ending_with_docstring.feature +47 -0
  12. data/features/cucumber_lint/consistent_empty_lines/between_elements/ending_with_examples.feature +49 -0
  13. data/features/cucumber_lint/consistent_empty_lines/between_elements/ending_with_step.feature +41 -0
  14. data/features/cucumber_lint/consistent_empty_lines/between_elements/ending_with_table.feature +43 -0
  15. data/features/cucumber_lint/consistent_empty_lines/between_feature_and_description.feature +33 -0
  16. data/features/cucumber_lint/consistent_empty_lines/between_feature_and_scenario.feature +33 -0
  17. data/features/cucumber_lint/consistent_table_headers/examples_table.feature +74 -0
  18. data/features/cucumber_lint/consistent_table_headers/step_table.feature +64 -0
  19. data/features/cucumber_lint/consistent_table_headers/unsupported_style.feature +20 -0
  20. data/features/cucumber_lint/consistent_table_whitespace/examples_table.feature +46 -0
  21. data/features/cucumber_lint/consistent_table_whitespace/step_table.feature +42 -0
  22. data/features/cucumber_lint/no_empty_features.feature +20 -0
  23. data/features/cucumber_lint/no_files.feature +6 -0
  24. data/features/cucumber_lint/no_repeating_keywords.feature +44 -0
  25. data/features/cucumber_lint/unsupported_options.feature +11 -0
  26. data/features/step_definitions/cli_steps.rb +47 -10
  27. data/features/step_definitions/env.rb +5 -9
  28. data/features/step_definitions/fixtures/config/disabled.yml +18 -0
  29. data/features/step_definitions/support/file_helpers.rb +20 -0
  30. data/lib/core_ext/array.rb +8 -0
  31. data/lib/core_ext/basic_object.rb +8 -0
  32. data/lib/core_ext/hash.rb +3 -18
  33. data/lib/core_ext/string.rb +7 -0
  34. data/lib/cucumber_lint/cli.rb +60 -31
  35. data/lib/cucumber_lint/config.rb +55 -0
  36. data/lib/cucumber_lint/errors/unsupported_style.rb +10 -0
  37. data/lib/cucumber_lint/linted_file.rb +77 -0
  38. data/lib/cucumber_lint/linter/feature_empty_lines_linter.rb +125 -0
  39. data/lib/cucumber_lint/linter/feature_linter.rb +33 -30
  40. data/lib/cucumber_lint/linter/scenario_outline_linter.rb +17 -8
  41. data/lib/cucumber_lint/linter/steps_linter.rb +9 -8
  42. data/lib/cucumber_lint/linter/table_linter.rb +26 -15
  43. data/lib/cucumber_lint/linter.rb +10 -10
  44. data/lib/cucumber_lint/version.rb +1 -1
  45. data/lib/cucumber_lint.rb +4 -1
  46. metadata +35 -36
  47. data/.travis.yml +0 -9
  48. data/features/cucumber_lint/fix/nothing.feature +0 -12
  49. data/features/cucumber_lint/fix/repeating_steps.feature +0 -25
  50. data/features/cucumber_lint/fix/table_whitespace.feature +0 -25
  51. data/features/cucumber_lint/fix/uppercase_table_headers.feature +0 -25
  52. data/features/cucumber_lint/lint/nothing.feature +0 -12
  53. data/features/cucumber_lint/lint/repeating_steps.feature +0 -31
  54. data/features/cucumber_lint/lint/table_whitespace.feature +0 -27
  55. data/features/cucumber_lint/lint/uppercase_table_headers.feature +0 -30
  56. data/features/step_definitions/feature_formatter_steps.rb +0 -15
  57. data/features/step_definitions/fixtures/repeating_steps/bad.feature.example +0 -12
  58. data/features/step_definitions/fixtures/repeating_steps/good.feature.example +0 -12
  59. data/features/step_definitions/fixtures/table_whitespace/bad.feature.example +0 -20
  60. data/features/step_definitions/fixtures/table_whitespace/good.feature.example +0 -20
  61. data/features/step_definitions/fixtures/uppercase_table_headers/bad.feature.example +0 -20
  62. data/features/step_definitions/fixtures/uppercase_table_headers/good.feature.example +0 -20
  63. 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,6 @@
1
+ Feature: no files
2
+
3
+ Scenario: lint
4
+ Given I have no files
5
+ When I run `cucumber_lint`
6
+ 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 a feature with (unformatted|formatted) (.+?)$/) do |format, type|
7
- feature_name = format == 'formatted' ? 'good' : 'bad'
8
- feature_type = type.gsub(' ', '_')
9
- content = IO.read("#{FIXTURES_PATH}/#{feature_type}/#{feature_name}.feature.example")
10
- IO.write "#{TMP_DIR}/features/#{feature_type}.feature", content
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(/^I now have a feature with formatted (.+?)$/) do |type|
30
- feature_type = type.gsub(' ', '_')
31
- expected = IO.read("#{FIXTURES_PATH}/#{feature_type}/good.feature.example")
32
- actual = IO.read "#{TMP_DIR}/features/#{feature_type}.feature"
33
- expect(actual).to eql expected
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
- FIXTURES_PATH = "#{File.dirname(__FILE__)}/fixtures"
8
- TMP_DIR = '/tmp'
8
+ CONFIG_PATH = "#{File.dirname(__FILE__)}/fixtures/config/disabled.yml"
9
9
 
10
10
 
11
11
  Before do
12
- Dir.chdir TMP_DIR
13
- FileUtils.rm_rf 'features'
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,18 @@
1
+ consistent_empty_lines:
2
+ enabled: false
3
+
4
+
5
+ consistent_table_headers:
6
+ enabled: false
7
+
8
+
9
+ consistent_table_whitespace:
10
+ enabled: false
11
+
12
+
13
+ no_empty_features:
14
+ enabled: false
15
+
16
+
17
+ no_repeating_keywords:
18
+ enabled: false
@@ -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
@@ -0,0 +1,8 @@
1
+ # Monkey-patching Array
2
+ class Array
3
+
4
+ def to_open_struct
5
+ map(&:to_open_struct)
6
+ end
7
+
8
+ end
@@ -0,0 +1,8 @@
1
+ # Monkey-patching BasicObject
2
+ class BasicObject
3
+
4
+ def to_open_struct
5
+ self
6
+ end
7
+
8
+ 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
- def object_to_open_struct object
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
@@ -0,0 +1,7 @@
1
+ # Monkey-patching String
2
+ class String
3
+
4
+ alias_method :uppercase, :upcase
5
+ alias_method :lowercase, :downcase
6
+
7
+ end
@@ -13,8 +13,10 @@ module CucumberLint
13
13
 
14
14
  def initialize args, out: STDOUT
15
15
  @out = out
16
- @fix = args[0] == '--fix'
17
- @results = OpenStruct.new(total: 0, passed: 0, failed: 0, written: 0, errors: [])
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
- linter = FeatureLinter.new filename, fix: @fix
45
+ linted_file = LintedFile.new filename
46
+
47
+ linter = FeatureLinter.new config: @config, linted_file: linted_file
34
48
  linter.lint
35
49
 
36
- if linter.errors?
37
- @results.errors += linter.errors
38
- file_failed
39
- elsif linter.can_fix?
40
- file_written
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
- file_passed
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
- out = ["#{@results.passed} passed".green]
50
- out << "#{@results.written} written".yellow if @results.written > 0
51
- out << "#{@results.failed} failed".red if @results.failed > 0
52
- "(#{out.join(', ')})"
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
- def file_passed
77
- @results.total += 1
78
- @results.passed += 1
79
- @out.print '.'.green
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
- def file_failed
84
- @results.total += 1
85
- @results.failed += 1
86
- @out.print 'F'.red
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
- def file_written
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