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.
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