cuke_sniffer 0.0.1 → 0.0.2
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.
- data/bin/cuke_sniffer.rb +51 -34
- data/lib/cuke_sniffer.rb +13 -13
- data/lib/cuke_sniffer/cli.rb +246 -226
- data/lib/cuke_sniffer/constants.rb +22 -35
- data/lib/cuke_sniffer/feature.rb +107 -116
- data/lib/cuke_sniffer/report/markup.rhtml +385 -310
- data/lib/cuke_sniffer/rule_config.rb +161 -161
- data/lib/cuke_sniffer/rules_evaluator.rb +50 -41
- data/lib/cuke_sniffer/scenario.rb +164 -163
- data/lib/cuke_sniffer/step_definition.rb +143 -116
- metadata +10 -4
@@ -1,161 +1,161 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
module CukeSniffer
|
4
|
-
module RuleConfig
|
5
|
-
|
6
|
-
FATAL = 100 #will prevent suite from executing properly
|
7
|
-
ERROR = 25 #will cause problem with debugging
|
8
|
-
WARNING = 10
|
9
|
-
INFO = 1
|
10
|
-
|
11
|
-
SHARED_RULES = {
|
12
|
-
:too_many_tags => {
|
13
|
-
:enabled => true,
|
14
|
-
:phrase => "{class} has too many tags.",
|
15
|
-
:score => INFO,
|
16
|
-
:max => 8
|
17
|
-
},
|
18
|
-
:no_description => {
|
19
|
-
:enabled => true,
|
20
|
-
:phrase => "{class} has no description.",
|
21
|
-
:score => ERROR,
|
22
|
-
},
|
23
|
-
:numbers_in_description => {
|
24
|
-
:enabled => true,
|
25
|
-
:phrase => "{class} has numbers in the description.",
|
26
|
-
:score => WARNING,
|
27
|
-
},
|
28
|
-
:long_name => {
|
29
|
-
:enabled => true,
|
30
|
-
:phrase => "{class} has a long description.",
|
31
|
-
:score => INFO,
|
32
|
-
:max => 180
|
33
|
-
},
|
34
|
-
:implementation_word => {
|
35
|
-
:enabled => true,
|
36
|
-
:phrase => "Implementation word used: {word}.",
|
37
|
-
:score => INFO,
|
38
|
-
:words => ["page", "site", "url", "button", "drop down", "dropdown", "select list", "click", "text box", "radio button", "check box", "xml", "window", "pop up", "pop-up", "screen"]
|
39
|
-
}
|
40
|
-
}
|
41
|
-
|
42
|
-
FEATURE_RULES = {
|
43
|
-
:background_with_no_scenarios => {
|
44
|
-
:enabled => true,
|
45
|
-
:phrase => "Feature has a background with no scenarios.",
|
46
|
-
:score => WARNING,
|
47
|
-
},
|
48
|
-
:background_with_one_scenario => {
|
49
|
-
:enabled => true,
|
50
|
-
:phrase => "Feature has a background with one scenario.",
|
51
|
-
:score => WARNING,
|
52
|
-
},
|
53
|
-
:no_scenarios => {
|
54
|
-
:enabled => true,
|
55
|
-
:phrase => "Feature with no scenarios.",
|
56
|
-
:score => ERROR,
|
57
|
-
},
|
58
|
-
:too_many_scenarios => {
|
59
|
-
:enabled => true,
|
60
|
-
:phrase => "Feature with too many scenarios.",
|
61
|
-
:score => INFO,
|
62
|
-
:max => 10,
|
63
|
-
},
|
64
|
-
}
|
65
|
-
|
66
|
-
SCENARIO_RULES = {
|
67
|
-
:too_many_steps => {
|
68
|
-
:enabled => true,
|
69
|
-
:phrase => "Scenario with too many steps.",
|
70
|
-
:score => WARNING,
|
71
|
-
:max => 7,
|
72
|
-
},
|
73
|
-
:out_of_order_steps => {
|
74
|
-
:enabled => true,
|
75
|
-
:phrase => "Scenario steps out of Given/When/Then order.",
|
76
|
-
:score => WARNING,
|
77
|
-
},
|
78
|
-
:invalid_first_step => {
|
79
|
-
:enabled => true,
|
80
|
-
:phrase => "Invalid first step. Began with And/But.",
|
81
|
-
:score => WARNING,
|
82
|
-
},
|
83
|
-
:asterisk_step => {
|
84
|
-
:enabled => true,
|
85
|
-
:phrase => "Step includes a * instead of Given/When/Then/And/But.",
|
86
|
-
:score => WARNING,
|
87
|
-
},
|
88
|
-
:commented_step => {
|
89
|
-
:enabled => true,
|
90
|
-
:phrase => "Commented step.",
|
91
|
-
:score => ERROR,
|
92
|
-
},
|
93
|
-
:commented_example => {
|
94
|
-
:enabled => true,
|
95
|
-
:phrase => "Commented example.",
|
96
|
-
:score => ERROR,
|
97
|
-
},
|
98
|
-
:no_examples => {
|
99
|
-
:enabled => true,
|
100
|
-
:phrase => "Scenario Outline with no examples.",
|
101
|
-
:score => FATAL,
|
102
|
-
},
|
103
|
-
:one_example => {
|
104
|
-
:enabled => true,
|
105
|
-
:phrase => "Scenario Outline with only one example.",
|
106
|
-
:score => WARNING,
|
107
|
-
},
|
108
|
-
:no_examples_table => {
|
109
|
-
:enabled => true,
|
110
|
-
:phrase => "Scenario Outline with no examples table.",
|
111
|
-
:score => FATAL,
|
112
|
-
},
|
113
|
-
:too_many_examples => {
|
114
|
-
:enabled => true,
|
115
|
-
:phrase => "Scenario Outline with too many examples.",
|
116
|
-
:score => WARNING,
|
117
|
-
:max => 10
|
118
|
-
},
|
119
|
-
:date_used => {
|
120
|
-
:enabled => true,
|
121
|
-
:phrase => "Date used.",
|
122
|
-
:score => INFO,
|
123
|
-
},
|
124
|
-
:no_steps => {
|
125
|
-
:enabled => true,
|
126
|
-
:phrase => "No steps in Scenario.",
|
127
|
-
:score => ERROR,
|
128
|
-
},
|
129
|
-
}
|
130
|
-
|
131
|
-
STEP_DEFINITION_RULES = {
|
132
|
-
:no_code => {
|
133
|
-
:enabled => true,
|
134
|
-
:phrase => "No code in Step Definition.",
|
135
|
-
:score => ERROR,
|
136
|
-
},
|
137
|
-
:too_many_parameters => {
|
138
|
-
:enabled => true,
|
139
|
-
:phrase => "Too many parameters in Step Definition.",
|
140
|
-
:score => WARNING,
|
141
|
-
:max => 4
|
142
|
-
},
|
143
|
-
:nested_step => {
|
144
|
-
:enabled => true,
|
145
|
-
:phrase => "Nested step call.",
|
146
|
-
:score => INFO,
|
147
|
-
},
|
148
|
-
:recursive_nested_step => {
|
149
|
-
:enabled => true,
|
150
|
-
:phrase => "Recursive nested step call.",
|
151
|
-
:score => FATAL,
|
152
|
-
},
|
153
|
-
:commented_code => {
|
154
|
-
:enabled => true,
|
155
|
-
:phrase => "Commented code in Step Definition.",
|
156
|
-
:score => INFO,
|
157
|
-
},
|
158
|
-
}
|
159
|
-
|
160
|
-
end
|
161
|
-
end
|
1
|
+
|
2
|
+
|
3
|
+
module CukeSniffer
|
4
|
+
module RuleConfig
|
5
|
+
|
6
|
+
FATAL = 100 #will prevent suite from executing properly
|
7
|
+
ERROR = 25 #will cause problem with debugging
|
8
|
+
WARNING = 10 #readibility/misuse of cucumber
|
9
|
+
INFO = 1 #Small improvements that can be made
|
10
|
+
|
11
|
+
SHARED_RULES = {
|
12
|
+
:too_many_tags => {
|
13
|
+
:enabled => true,
|
14
|
+
:phrase => "{class} has too many tags.",
|
15
|
+
:score => INFO,
|
16
|
+
:max => 8
|
17
|
+
},
|
18
|
+
:no_description => {
|
19
|
+
:enabled => true,
|
20
|
+
:phrase => "{class} has no description.",
|
21
|
+
:score => ERROR,
|
22
|
+
},
|
23
|
+
:numbers_in_description => {
|
24
|
+
:enabled => true,
|
25
|
+
:phrase => "{class} has numbers in the description.",
|
26
|
+
:score => WARNING,
|
27
|
+
},
|
28
|
+
:long_name => {
|
29
|
+
:enabled => true,
|
30
|
+
:phrase => "{class} has a long description.",
|
31
|
+
:score => INFO,
|
32
|
+
:max => 180
|
33
|
+
},
|
34
|
+
:implementation_word => {
|
35
|
+
:enabled => true,
|
36
|
+
:phrase => "Implementation word used: {word}.",
|
37
|
+
:score => INFO,
|
38
|
+
:words => ["page", "site", "url", "button", "drop down", "dropdown", "select list", "click", "text box", "radio button", "check box", "xml", "window", "pop up", "pop-up", "screen"]
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
FEATURE_RULES = {
|
43
|
+
:background_with_no_scenarios => {
|
44
|
+
:enabled => true,
|
45
|
+
:phrase => "Feature has a background with no scenarios.",
|
46
|
+
:score => WARNING,
|
47
|
+
},
|
48
|
+
:background_with_one_scenario => {
|
49
|
+
:enabled => true,
|
50
|
+
:phrase => "Feature has a background with one scenario.",
|
51
|
+
:score => WARNING,
|
52
|
+
},
|
53
|
+
:no_scenarios => {
|
54
|
+
:enabled => true,
|
55
|
+
:phrase => "Feature with no scenarios.",
|
56
|
+
:score => ERROR,
|
57
|
+
},
|
58
|
+
:too_many_scenarios => {
|
59
|
+
:enabled => true,
|
60
|
+
:phrase => "Feature with too many scenarios.",
|
61
|
+
:score => INFO,
|
62
|
+
:max => 10,
|
63
|
+
},
|
64
|
+
}
|
65
|
+
|
66
|
+
SCENARIO_RULES = {
|
67
|
+
:too_many_steps => {
|
68
|
+
:enabled => true,
|
69
|
+
:phrase => "Scenario with too many steps.",
|
70
|
+
:score => WARNING,
|
71
|
+
:max => 7,
|
72
|
+
},
|
73
|
+
:out_of_order_steps => {
|
74
|
+
:enabled => true,
|
75
|
+
:phrase => "Scenario steps out of Given/When/Then order.",
|
76
|
+
:score => WARNING,
|
77
|
+
},
|
78
|
+
:invalid_first_step => {
|
79
|
+
:enabled => true,
|
80
|
+
:phrase => "Invalid first step. Began with And/But.",
|
81
|
+
:score => WARNING,
|
82
|
+
},
|
83
|
+
:asterisk_step => {
|
84
|
+
:enabled => true,
|
85
|
+
:phrase => "Step includes a * instead of Given/When/Then/And/But.",
|
86
|
+
:score => WARNING,
|
87
|
+
},
|
88
|
+
:commented_step => {
|
89
|
+
:enabled => true,
|
90
|
+
:phrase => "Commented step.",
|
91
|
+
:score => ERROR,
|
92
|
+
},
|
93
|
+
:commented_example => {
|
94
|
+
:enabled => true,
|
95
|
+
:phrase => "Commented example.",
|
96
|
+
:score => ERROR,
|
97
|
+
},
|
98
|
+
:no_examples => {
|
99
|
+
:enabled => true,
|
100
|
+
:phrase => "Scenario Outline with no examples.",
|
101
|
+
:score => FATAL,
|
102
|
+
},
|
103
|
+
:one_example => {
|
104
|
+
:enabled => true,
|
105
|
+
:phrase => "Scenario Outline with only one example.",
|
106
|
+
:score => WARNING,
|
107
|
+
},
|
108
|
+
:no_examples_table => {
|
109
|
+
:enabled => true,
|
110
|
+
:phrase => "Scenario Outline with no examples table.",
|
111
|
+
:score => FATAL,
|
112
|
+
},
|
113
|
+
:too_many_examples => {
|
114
|
+
:enabled => true,
|
115
|
+
:phrase => "Scenario Outline with too many examples.",
|
116
|
+
:score => WARNING,
|
117
|
+
:max => 10
|
118
|
+
},
|
119
|
+
:date_used => {
|
120
|
+
:enabled => true,
|
121
|
+
:phrase => "Date used.",
|
122
|
+
:score => INFO,
|
123
|
+
},
|
124
|
+
:no_steps => {
|
125
|
+
:enabled => true,
|
126
|
+
:phrase => "No steps in Scenario.",
|
127
|
+
:score => ERROR,
|
128
|
+
},
|
129
|
+
}
|
130
|
+
|
131
|
+
STEP_DEFINITION_RULES = {
|
132
|
+
:no_code => {
|
133
|
+
:enabled => true,
|
134
|
+
:phrase => "No code in Step Definition.",
|
135
|
+
:score => ERROR,
|
136
|
+
},
|
137
|
+
:too_many_parameters => {
|
138
|
+
:enabled => true,
|
139
|
+
:phrase => "Too many parameters in Step Definition.",
|
140
|
+
:score => WARNING,
|
141
|
+
:max => 4
|
142
|
+
},
|
143
|
+
:nested_step => {
|
144
|
+
:enabled => true,
|
145
|
+
:phrase => "Nested step call.",
|
146
|
+
:score => INFO,
|
147
|
+
},
|
148
|
+
:recursive_nested_step => {
|
149
|
+
:enabled => true,
|
150
|
+
:phrase => "Recursive nested step call.",
|
151
|
+
:score => FATAL,
|
152
|
+
},
|
153
|
+
:commented_code => {
|
154
|
+
:enabled => true,
|
155
|
+
:phrase => "Commented code in Step Definition.",
|
156
|
+
:score => INFO,
|
157
|
+
},
|
158
|
+
}
|
159
|
+
|
160
|
+
end
|
161
|
+
end
|
@@ -1,41 +1,50 @@
|
|
1
|
-
module CukeSniffer
|
2
|
-
class RulesEvaluator
|
3
|
-
attr_accessor :location, :score, :rules_hash
|
4
|
-
|
5
|
-
def initialize(location)
|
6
|
-
@location = location
|
7
|
-
@score = 0
|
8
|
-
@rules_hash = {}
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
end
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
end
|
1
|
+
module CukeSniffer
|
2
|
+
class RulesEvaluator
|
3
|
+
attr_accessor :location, :score, :rules_hash
|
4
|
+
|
5
|
+
def initialize(location)
|
6
|
+
@location = location
|
7
|
+
@score = 0
|
8
|
+
@rules_hash = {}
|
9
|
+
@class_type = self.class.to_s.gsub(/.*::/, "")
|
10
|
+
end
|
11
|
+
|
12
|
+
def evaluate_score
|
13
|
+
end
|
14
|
+
|
15
|
+
def good?
|
16
|
+
score <= Constants::THRESHOLDS[@class_type]
|
17
|
+
end
|
18
|
+
|
19
|
+
def problem_percentage
|
20
|
+
score.to_f / Constants::THRESHOLDS[@class_type].to_f
|
21
|
+
end
|
22
|
+
|
23
|
+
def store_rule(rule)
|
24
|
+
if rule[:enabled]
|
25
|
+
@score += rule[:score]
|
26
|
+
@rules_hash[rule[:phrase]] ||= 0
|
27
|
+
@rules_hash[rule[:phrase]] += 1
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def store_updated_rule(rule, phrase)
|
32
|
+
store_rule({:enabled => rule[:enabled], :score => rule[:score], :phrase => phrase})
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
def is_comment?(line)
|
37
|
+
if line =~ /^\#.*$/
|
38
|
+
true
|
39
|
+
else
|
40
|
+
false
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def == (comparison_object)
|
45
|
+
comparison_object.location == location
|
46
|
+
comparison_object.score == score
|
47
|
+
comparison_object.rules_hash == rules_hash
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -1,163 +1,164 @@
|
|
1
|
-
require 'cuke_sniffer/constants'
|
2
|
-
require 'cuke_sniffer/rule_config'
|
3
|
-
|
4
|
-
module CukeSniffer
|
5
|
-
class Scenario < FeatureRulesEvaluator
|
6
|
-
include CukeSniffer::Constants
|
7
|
-
include CukeSniffer::RuleConfig
|
8
|
-
|
9
|
-
attr_accessor :start_line, :type, :steps, :inline_tables, :examples_table
|
10
|
-
|
11
|
-
def initialize(location, scenario)
|
12
|
-
super(location)
|
13
|
-
@start_line = location.match(/:(?<line>\d*)$/)[:line].to_i
|
14
|
-
@steps = []
|
15
|
-
@inline_tables = {}
|
16
|
-
@examples_table = []
|
17
|
-
split_scenario(scenario)
|
18
|
-
evaluate_score
|
19
|
-
end
|
20
|
-
|
21
|
-
def split_scenario(scenario)
|
22
|
-
index = 0
|
23
|
-
until index >= scenario.length or scenario[index] =~ SCENARIO_TITLE_STYLES
|
24
|
-
update_tag_list(scenario[index])
|
25
|
-
index += 1
|
26
|
-
end
|
27
|
-
|
28
|
-
until index >= scenario.length or scenario[index].match STEP_REGEX or scenario[index].include?("Examples:")
|
29
|
-
match = scenario[index].match(SCENARIO_TITLE_STYLES)
|
30
|
-
@type = match[:type] unless match.nil?
|
31
|
-
create_name(scenario[index], SCENARIO_TITLE_STYLES)
|
32
|
-
index += 1
|
33
|
-
end
|
34
|
-
|
35
|
-
until index >= scenario.length or scenario[index].include?("Examples:")
|
36
|
-
if scenario[index] =~
|
37
|
-
step = scenario[index - 1]
|
38
|
-
@inline_tables[step] = []
|
39
|
-
until index >= scenario.length or scenario[index] =~ STEP_REGEX
|
40
|
-
@inline_tables[step] << scenario[index]
|
41
|
-
index += 1
|
42
|
-
end
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
index
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
comparison_object.
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
match = line.match(STEP_REGEX)
|
69
|
-
order << match[:style] unless match.nil?
|
70
|
-
}
|
71
|
-
order
|
72
|
-
end
|
73
|
-
|
74
|
-
def evaluate_score
|
75
|
-
super
|
76
|
-
rule_empty_scenario
|
77
|
-
rule_too_many_steps
|
78
|
-
rule_step_order
|
79
|
-
rule_invalid_first_step
|
80
|
-
rule_asterisk_step
|
81
|
-
rule_commented_step
|
82
|
-
rule_implementation_words
|
83
|
-
rule_date_used_in_step
|
84
|
-
evaluate_outline_scores if type == "Scenario Outline"
|
85
|
-
end
|
86
|
-
|
87
|
-
def evaluate_outline_scores
|
88
|
-
rule_no_examples_table
|
89
|
-
rule_no_examples
|
90
|
-
rule_one_example
|
91
|
-
rule_too_many_examples
|
92
|
-
rule_commented_example
|
93
|
-
end
|
94
|
-
|
95
|
-
def rule_empty_scenario
|
96
|
-
store_rule(SCENARIO_RULES[:no_steps]) if @steps.empty?
|
97
|
-
end
|
98
|
-
|
99
|
-
def rule_too_many_steps
|
100
|
-
rule = SCENARIO_RULES[:too_many_steps]
|
101
|
-
store_rule(rule) if @steps.size >= rule[:max]
|
102
|
-
end
|
103
|
-
|
104
|
-
def rule_step_order
|
105
|
-
step_order = get_step_order.uniq
|
106
|
-
%w(But * And).each { |type| step_order.delete(type) }
|
107
|
-
store_rule(SCENARIO_RULES[:out_of_order_steps]) unless step_order == %w(Given When Then) or step_order == %w(When Then)
|
108
|
-
end
|
109
|
-
|
110
|
-
def rule_invalid_first_step
|
111
|
-
first_step = get_step_order.first
|
112
|
-
store_rule(SCENARIO_RULES[:invalid_first_step]) if %w(And But).include?(first_step)
|
113
|
-
end
|
114
|
-
|
115
|
-
def rule_asterisk_step
|
116
|
-
get_step_order.count('*').times { store_rule(SCENARIO_RULES[:asterisk_step]) }
|
117
|
-
end
|
118
|
-
|
119
|
-
def rule_commented_step
|
120
|
-
@steps.each do |step|
|
121
|
-
store_rule(SCENARIO_RULES[:commented_step]) if is_comment?(step)
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
def rule_implementation_words
|
126
|
-
rule = SHARED_RULES[:implementation_word]
|
127
|
-
@steps.each do |step|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
end
|
1
|
+
require 'cuke_sniffer/constants'
|
2
|
+
require 'cuke_sniffer/rule_config'
|
3
|
+
|
4
|
+
module CukeSniffer
|
5
|
+
class Scenario < FeatureRulesEvaluator
|
6
|
+
include CukeSniffer::Constants
|
7
|
+
include CukeSniffer::RuleConfig
|
8
|
+
|
9
|
+
attr_accessor :start_line, :type, :steps, :inline_tables, :examples_table
|
10
|
+
|
11
|
+
def initialize(location, scenario)
|
12
|
+
super(location)
|
13
|
+
@start_line = location.match(/:(?<line>\d*)$/)[:line].to_i
|
14
|
+
@steps = []
|
15
|
+
@inline_tables = {}
|
16
|
+
@examples_table = []
|
17
|
+
split_scenario(scenario)
|
18
|
+
evaluate_score
|
19
|
+
end
|
20
|
+
|
21
|
+
def split_scenario(scenario)
|
22
|
+
index = 0
|
23
|
+
until index >= scenario.length or scenario[index] =~ SCENARIO_TITLE_STYLES
|
24
|
+
update_tag_list(scenario[index])
|
25
|
+
index += 1
|
26
|
+
end
|
27
|
+
|
28
|
+
until index >= scenario.length or scenario[index].match STEP_REGEX or scenario[index].include?("Examples:")
|
29
|
+
match = scenario[index].match(SCENARIO_TITLE_STYLES)
|
30
|
+
@type = match[:type] unless match.nil?
|
31
|
+
create_name(scenario[index], SCENARIO_TITLE_STYLES)
|
32
|
+
index += 1
|
33
|
+
end
|
34
|
+
|
35
|
+
until index >= scenario.length or scenario[index].include?("Examples:")
|
36
|
+
if scenario[index] =~ /^\|.*\|/
|
37
|
+
step = scenario[index - 1]
|
38
|
+
@inline_tables[step] = []
|
39
|
+
until index >= scenario.length or scenario[index] =~ STEP_REGEX
|
40
|
+
@inline_tables[step] << scenario[index]
|
41
|
+
index += 1
|
42
|
+
end
|
43
|
+
else
|
44
|
+
@steps << scenario[index] if scenario[index] =~ STEP_REGEX
|
45
|
+
index += 1
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
if index < scenario.length and scenario[index].include?("Examples:")
|
50
|
+
index += 1
|
51
|
+
until index >= scenario.length
|
52
|
+
@examples_table << scenario[index] unless scenario[index].empty?
|
53
|
+
index += 1
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def ==(comparison_object)
|
59
|
+
super(comparison_object)
|
60
|
+
comparison_object.steps == steps
|
61
|
+
comparison_object.examples_table == examples_table
|
62
|
+
end
|
63
|
+
|
64
|
+
def get_step_order
|
65
|
+
order = []
|
66
|
+
@steps.each { |line|
|
67
|
+
next if is_comment?(line)
|
68
|
+
match = line.match(STEP_REGEX)
|
69
|
+
order << match[:style] unless match.nil?
|
70
|
+
}
|
71
|
+
order
|
72
|
+
end
|
73
|
+
|
74
|
+
def evaluate_score
|
75
|
+
super
|
76
|
+
rule_empty_scenario
|
77
|
+
rule_too_many_steps
|
78
|
+
rule_step_order
|
79
|
+
rule_invalid_first_step
|
80
|
+
rule_asterisk_step
|
81
|
+
rule_commented_step
|
82
|
+
rule_implementation_words
|
83
|
+
rule_date_used_in_step
|
84
|
+
evaluate_outline_scores if type == "Scenario Outline"
|
85
|
+
end
|
86
|
+
|
87
|
+
def evaluate_outline_scores
|
88
|
+
rule_no_examples_table
|
89
|
+
rule_no_examples
|
90
|
+
rule_one_example
|
91
|
+
rule_too_many_examples
|
92
|
+
rule_commented_example
|
93
|
+
end
|
94
|
+
|
95
|
+
def rule_empty_scenario
|
96
|
+
store_rule(SCENARIO_RULES[:no_steps]) if @steps.empty?
|
97
|
+
end
|
98
|
+
|
99
|
+
def rule_too_many_steps
|
100
|
+
rule = SCENARIO_RULES[:too_many_steps]
|
101
|
+
store_rule(rule) if @steps.size >= rule[:max]
|
102
|
+
end
|
103
|
+
|
104
|
+
def rule_step_order
|
105
|
+
step_order = get_step_order.uniq
|
106
|
+
%w(But * And).each { |type| step_order.delete(type) }
|
107
|
+
store_rule(SCENARIO_RULES[:out_of_order_steps]) unless step_order == %w(Given When Then) or step_order == %w(When Then)
|
108
|
+
end
|
109
|
+
|
110
|
+
def rule_invalid_first_step
|
111
|
+
first_step = get_step_order.first
|
112
|
+
store_rule(SCENARIO_RULES[:invalid_first_step]) if %w(And But).include?(first_step)
|
113
|
+
end
|
114
|
+
|
115
|
+
def rule_asterisk_step
|
116
|
+
get_step_order.count('*').times { store_rule(SCENARIO_RULES[:asterisk_step]) }
|
117
|
+
end
|
118
|
+
|
119
|
+
def rule_commented_step
|
120
|
+
@steps.each do |step|
|
121
|
+
store_rule(SCENARIO_RULES[:commented_step]) if is_comment?(step)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def rule_implementation_words
|
126
|
+
rule = SHARED_RULES[:implementation_word]
|
127
|
+
@steps.each do |step|
|
128
|
+
next if is_comment?(step)
|
129
|
+
rule[:words].each do |word|
|
130
|
+
store_updated_rule(rule, rule[:phrase].gsub(/{.*}/, word)) if step.include?(word)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def rule_date_used_in_step
|
136
|
+
@steps.each do |step|
|
137
|
+
store_rule(SCENARIO_RULES[:date_used]) if step =~ DATE_REGEX
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def rule_no_examples_table
|
142
|
+
store_rule(SCENARIO_RULES[:no_examples_table]) if @examples_table.empty?
|
143
|
+
end
|
144
|
+
|
145
|
+
def rule_no_examples
|
146
|
+
store_rule(SCENARIO_RULES[:no_examples]) if @examples_table.size == 1
|
147
|
+
end
|
148
|
+
|
149
|
+
def rule_one_example
|
150
|
+
store_rule(SCENARIO_RULES[:one_example]) if @examples_table.size == 2 and !is_comment?(@examples_table[1])
|
151
|
+
end
|
152
|
+
|
153
|
+
def rule_too_many_examples
|
154
|
+
store_rule(SCENARIO_RULES[:too_many_examples]) if (@examples_table.size - 1) >= 8
|
155
|
+
end
|
156
|
+
|
157
|
+
def rule_commented_example
|
158
|
+
@examples_table.each do |example|
|
159
|
+
store_rule(SCENARIO_RULES[:commented_example]) if is_comment?(example)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
end
|
164
|
+
end
|