chutney 1.6.3 → 2.0.0.rc1
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/.rspec +1 -0
- data/.rubocop.yml +3 -3
- data/README.md +44 -30
- data/Rakefile +10 -24
- data/chutney.gemspec +13 -10
- data/config/{default.yml → chutney.yml} +6 -3
- data/docs/.keep +0 -0
- data/exe/chutney +28 -22
- data/img/chutney.svg +852 -0
- data/img/formatters.png +0 -0
- data/lib/chutney.rb +61 -85
- data/lib/chutney/configuration.rb +6 -7
- data/lib/chutney/formatter.rb +21 -0
- data/lib/chutney/formatter/json_formatter.rb +8 -0
- data/lib/chutney/formatter/pie_formatter.rb +78 -0
- data/lib/chutney/formatter/rainbow_formatter.rb +47 -0
- data/lib/chutney/linter.rb +145 -113
- data/lib/chutney/linter/avoid_full_stop.rb +12 -0
- data/lib/chutney/linter/avoid_outline_for_single_example.rb +3 -6
- data/lib/chutney/linter/avoid_scripting.rb +10 -15
- data/lib/chutney/linter/background_does_more_than_setup.rb +7 -10
- data/lib/chutney/linter/background_requires_multiple_scenarios.rb +2 -3
- data/lib/chutney/linter/bad_scenario_name.rb +4 -11
- data/lib/chutney/linter/file_name_differs_feature_name.rb +5 -10
- data/lib/chutney/linter/givens_after_background.rb +17 -0
- data/lib/chutney/linter/invalid_file_name.rb +14 -6
- data/lib/chutney/linter/invalid_step_flow.rb +18 -18
- data/lib/chutney/linter/missing_example_name.rb +13 -11
- data/lib/chutney/linter/missing_feature_description.rb +2 -9
- data/lib/chutney/linter/missing_feature_name.rb +3 -12
- data/lib/chutney/linter/missing_scenario_name.rb +3 -7
- data/lib/chutney/linter/missing_test_action.rb +3 -6
- data/lib/chutney/linter/missing_verification.rb +3 -4
- data/lib/chutney/linter/required_tags_starts_with.rb +20 -5
- data/lib/chutney/linter/same_tag_for_all_scenarios.rb +24 -28
- data/lib/chutney/linter/scenario_names_match.rb +6 -8
- data/lib/chutney/linter/tag_used_multiple_times.rb +6 -13
- data/lib/chutney/linter/too_clumsy.rb +4 -4
- data/lib/chutney/linter/too_long_step.rb +8 -18
- data/lib/chutney/linter/too_many_different_tags.rb +13 -34
- data/lib/chutney/linter/too_many_steps.rb +10 -6
- data/lib/chutney/linter/too_many_tags.rb +11 -10
- data/lib/chutney/linter/unique_scenario_names.rb +19 -13
- data/lib/chutney/linter/unknown_variable.rb +5 -6
- data/lib/chutney/linter/unused_variable.rb +6 -7
- data/lib/chutney/linter/use_background.rb +11 -29
- data/lib/chutney/linter/use_outline.rb +21 -15
- data/lib/chutney/version.rb +1 -1
- data/lib/config/locales/en.yml +93 -0
- data/spec/chutney_spec.rb +54 -62
- data/spec/spec_helper.rb +103 -0
- metadata +75 -44
- data/Guardfile +0 -3
- data/lib/chutney/linter/avoid_period.rb +0 -19
- data/lib/chutney/linter/be_declarative.rb +0 -49
- data/lib/chutney/linter/tag_collector.rb +0 -10
- data/lib/chutney/linter/tag_constraint.rb +0 -35
- data/spec/configuration_spec.rb +0 -58
- data/spec/required_tags_starts_with_spec.rb +0 -74
- data/spec/shared_contexts/file_exists.rb +0 -12
- data/spec/shared_contexts/gherkin_linter.rb +0 -14
data/Guardfile
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
require 'chutney/linter'
|
2
|
-
|
3
|
-
module Chutney
|
4
|
-
# service class to lint for avoiding periods
|
5
|
-
class AvoidPeriod < Linter
|
6
|
-
MESSAGE = 'Avoid using a period (full-stop) in steps so that it is easier to re-use them'.freeze
|
7
|
-
|
8
|
-
def lint
|
9
|
-
scenarios do |file, feature, scenario|
|
10
|
-
next unless scenario.key? :steps
|
11
|
-
|
12
|
-
scenario[:steps].each do |step|
|
13
|
-
references = [reference(file, feature, scenario, step)]
|
14
|
-
add_error(references, MESSAGE) if step[:text].strip.end_with? '.'
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
@@ -1,49 +0,0 @@
|
|
1
|
-
require 'chutney/linter'
|
2
|
-
require 'engtagger'
|
3
|
-
|
4
|
-
module Chutney
|
5
|
-
# service class to lint for avoiding periods
|
6
|
-
class BeDeclarative < Linter
|
7
|
-
MESSAGE = 'This step does not contain a verb'.freeze
|
8
|
-
|
9
|
-
def initialize
|
10
|
-
super
|
11
|
-
end
|
12
|
-
|
13
|
-
def lint
|
14
|
-
filled_scenarios do |file, feature, scenario|
|
15
|
-
scenario[:steps].each do |step|
|
16
|
-
references = [reference(file, feature, scenario, step)]
|
17
|
-
add_warning(references, MESSAGE) unless verb? step
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def verb?(step)
|
23
|
-
tagged = tagger.add_tags step[:text]
|
24
|
-
step_verbs = verbs tagged
|
25
|
-
|
26
|
-
!step_verbs.empty?
|
27
|
-
end
|
28
|
-
|
29
|
-
def verbs(tagged_text)
|
30
|
-
verbs =
|
31
|
-
%i[
|
32
|
-
get_infinitive_verbs
|
33
|
-
get_past_tense_verbs
|
34
|
-
get_gerund_verbs
|
35
|
-
get_passive_verbs
|
36
|
-
get_present_verbs
|
37
|
-
get_base_present_verbs
|
38
|
-
]
|
39
|
-
|
40
|
-
verbs.map { |verb| tagger.send(verb, tagged_text).keys }.flatten
|
41
|
-
end
|
42
|
-
|
43
|
-
def tagger
|
44
|
-
@tagger = EngTagger.new unless instance_variable_defined? :@tagger
|
45
|
-
|
46
|
-
@tagger
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
module Chutney
|
2
|
-
# Mixin to lint for tags that have certain string contraints
|
3
|
-
module TagConstraint
|
4
|
-
def lint
|
5
|
-
scenarios do |file, feature, scenario|
|
6
|
-
next if match_pattern? tags(feature)
|
7
|
-
next if match_pattern? tags(scenario)
|
8
|
-
|
9
|
-
references = [reference(file, feature, scenario)]
|
10
|
-
add_error(references, 'Required Tag not found')
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def tags(element)
|
15
|
-
return [] unless element.include? :tags
|
16
|
-
|
17
|
-
element[:tags].map { |a| a[:name] }
|
18
|
-
end
|
19
|
-
|
20
|
-
def matcher(pattern)
|
21
|
-
@pattern = pattern
|
22
|
-
validate_input
|
23
|
-
end
|
24
|
-
|
25
|
-
def match_pattern?(_tags)
|
26
|
-
raise NoMethodError, 'This is an abstraction that must be implemented by the includer'
|
27
|
-
end
|
28
|
-
|
29
|
-
def validate_input
|
30
|
-
raise 'No Tags provided in the YAML' if @pattern.nil?
|
31
|
-
|
32
|
-
warn 'Required Tags matcher has no value' if @pattern.empty?
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
data/spec/configuration_spec.rb
DELETED
@@ -1,58 +0,0 @@
|
|
1
|
-
require 'rspec'
|
2
|
-
require 'chutney/configuration'
|
3
|
-
require 'shared_contexts/file_exists'
|
4
|
-
|
5
|
-
describe Chutney::Configuration do
|
6
|
-
subject { Chutney::Configuration.new file }
|
7
|
-
let(:file) { 'default.yml' }
|
8
|
-
|
9
|
-
it 'should do something' do
|
10
|
-
expect(subject.config).to eq('')
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'should have a default config path' do
|
14
|
-
expect(subject.configuration_path).not_to be nil
|
15
|
-
end
|
16
|
-
context 'when a empty config file is present' do
|
17
|
-
include_context 'a file exists'
|
18
|
-
let(:file_content) { '---' }
|
19
|
-
it 'should load a file from the config path' do
|
20
|
-
expect(subject.config).to eq ''
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
context 'when a non-YAML config file is present' do
|
25
|
-
include_context 'a file exists'
|
26
|
-
let(:file_content) do
|
27
|
-
<<-CONTENT
|
28
|
-
foo: [
|
29
|
-
‘bar’, {
|
30
|
-
baz: 42
|
31
|
-
}
|
32
|
-
]'
|
33
|
-
CONTENT
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'should load a file from the config path but fail to parse' do
|
37
|
-
expect { subject.load_configuration }.to raise_error Psych::SyntaxError
|
38
|
-
expect { subject.config }.to raise_error Psych::SyntaxError
|
39
|
-
end
|
40
|
-
end
|
41
|
-
context 'when a valid YAML file is present' do
|
42
|
-
include_context 'a file exists'
|
43
|
-
let(:file_content) do
|
44
|
-
<<-CONTENT
|
45
|
-
---
|
46
|
-
:parent_key: parent_value
|
47
|
-
:child_key: child_value
|
48
|
-
CONTENT
|
49
|
-
end
|
50
|
-
before :each do
|
51
|
-
subject.load_configuration
|
52
|
-
end
|
53
|
-
|
54
|
-
it 'should load the values from the config file' do
|
55
|
-
expect(subject.config).to eq(parent_key: 'parent_value', child_key: 'child_value')
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
@@ -1,74 +0,0 @@
|
|
1
|
-
require 'rspec'
|
2
|
-
require 'chutney/linter/required_tags_starts_with'
|
3
|
-
require 'chutney'
|
4
|
-
require 'shared_contexts/gherkin_linter'
|
5
|
-
|
6
|
-
describe Chutney::RequiredTagsStartsWith do
|
7
|
-
let(:linter) { Chutney::ChutneyLint.new }
|
8
|
-
let(:file) { 'lint.feature' }
|
9
|
-
let(:pattern) { %w[MCC PB] }
|
10
|
-
describe '#matcher' do
|
11
|
-
it 'should raise an error when pattern is nil' do
|
12
|
-
expect { subject.matcher(nil) }.to raise_error('No Tags provided in the YAML')
|
13
|
-
end
|
14
|
-
it 'should raise an error when pattern is empty' do
|
15
|
-
expect { subject.matcher('') }.to output("Required Tags matcher has no value\n").to_stderr
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
describe '#issues' do
|
20
|
-
context 'before linting' do
|
21
|
-
it 'should have no issue' do
|
22
|
-
expect(subject.issues.size).to eq(0)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
context 'after linting a feature file with valid PB tag at the feature level' do
|
27
|
-
include_context 'a gherkin linter'
|
28
|
-
|
29
|
-
let(:file_content) do
|
30
|
-
<<-CONTENT
|
31
|
-
@PB
|
32
|
-
Feature: Test
|
33
|
-
@scenario_tag
|
34
|
-
Scenario: A
|
35
|
-
CONTENT
|
36
|
-
end
|
37
|
-
it 'should have no issues' do
|
38
|
-
expect(subject.issues.size).to eq(0)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
context 'after linting a file with a MCC tag at the scenario level' do
|
43
|
-
include_context 'a gherkin linter'
|
44
|
-
let(:file_content) do
|
45
|
-
<<-CONTENT
|
46
|
-
@feature_tag
|
47
|
-
Feature: Test
|
48
|
-
@MCC
|
49
|
-
Scenario: A
|
50
|
-
CONTENT
|
51
|
-
end
|
52
|
-
|
53
|
-
it 'should have no issues' do
|
54
|
-
expect(subject.issues.size).to eq(0)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
context 'after linting a file with no required tags' do
|
59
|
-
include_context 'a gherkin linter'
|
60
|
-
let(:file_content) do
|
61
|
-
<<-CONTENT
|
62
|
-
@feature_tag
|
63
|
-
Feature: Test
|
64
|
-
@scenario_tag
|
65
|
-
Scenario: A
|
66
|
-
CONTENT
|
67
|
-
end
|
68
|
-
|
69
|
-
it 'should have issues after linting a file without PB or MCC tags' do
|
70
|
-
expect(subject.issues[0].name).to eq(subject.class.name.split('::').last)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
@@ -1,14 +0,0 @@
|
|
1
|
-
require 'rspec'
|
2
|
-
require_relative 'file_exists'
|
3
|
-
|
4
|
-
shared_context 'a gherkin linter' do
|
5
|
-
include_context 'a file exists'
|
6
|
-
|
7
|
-
let(:files) { linter.analyze file }
|
8
|
-
let(:disable_tags) { linter.disable_tags }
|
9
|
-
|
10
|
-
before :each do
|
11
|
-
subject.instance_variable_set(:@pattern, pattern)
|
12
|
-
subject.lint_files({ file: files }, disable_tags)
|
13
|
-
end
|
14
|
-
end
|