cuke_sniffer 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -14,7 +14,9 @@ Other Options for Running include:
14
14
  -p, --project <project_root> : Root directory of project.
15
15
  -f, --features <feature_path> : Path to features directory.
16
16
  -s, --step_definitions <step_def_path> : Path to step definitions directory.
17
- -hk, --hooks <hooks_path> : Path to support directory. "
17
+ -hk, --hooks <hooks_path> : Path to support directory.
18
+ -nc, --no_catalog : Disable cataloging of steps. Reduced runtime and no
19
+ "
18
20
 
19
21
  def find_index_by_regex_match(list, regex)
20
22
  list.each do |item|
@@ -29,6 +31,7 @@ def build_cli_hash(argv)
29
31
  :features_location => /-f|--features/,
30
32
  :step_definitions_location => /-s|--step_definitions/,
31
33
  :project_location => /-p|--project/}
34
+
32
35
  cli_hash = {}
33
36
  cucumber_hash.each do |symbol, regex|
34
37
  index_of_key = find_index_by_regex_match(argv, regex)
@@ -36,6 +39,8 @@ def build_cli_hash(argv)
36
39
  cli_hash[symbol] = argv[index_of_key + 1]
37
40
  end
38
41
  end
42
+
43
+ cli_hash[:no_catalog] = true if find_index_by_regex_match(argv, /-nc|--no_catalog/)
39
44
  cli_hash
40
45
  end
41
46
 
@@ -22,6 +22,7 @@ module CukeSniffer
22
22
  xml_accessor :features, :as => [CukeSniffer::Feature], :in => "features"
23
23
  xml_accessor :step_definitions, :as => [CukeSniffer::StepDefinition], :in => "step_definitions"
24
24
  xml_accessor :hooks, :as => [CukeSniffer::Hook], :in => "hooks"
25
+ xml_accessor :cataloged
25
26
 
26
27
 
27
28
  # Feature array: All Features gathered from the specified folder
@@ -53,6 +54,9 @@ module CukeSniffer
53
54
  # Rules hash: All the rules that exist at runtime and their corresponding data
54
55
  attr_accessor :rules
55
56
 
57
+ # Boolean: Status of if the projects step definitions were cataloged for calls
58
+ attr_accessor :cataloged
59
+
56
60
 
57
61
  # Does analysis against the passed features and step definition locations
58
62
  #
@@ -73,6 +77,9 @@ module CukeSniffer
73
77
  # Against folders
74
78
  # cuke_sniffer = CukeSniffer::CLI.new({:features_location =>"my_features_directory\", :step_definitions_location =>"my_steps_directory\"})
75
79
  #
80
+ # Disabling cataloging for improved runtime and no dead steps identified
81
+ # cuke_sniffer = CukeSniffer::CLI.new({:no_catalog => true})
82
+ #
76
83
  # You can mix and match all of the above examples
77
84
  #
78
85
  # Displays the sequence and a . indicator for each new loop in that process.
@@ -82,7 +89,7 @@ module CukeSniffer
82
89
  def initialize(parameters = {})
83
90
  initialize_rule_targets(parameters)
84
91
  evaluate_rules
85
- catalog_step_calls
92
+ catalog_step_calls if @cataloged
86
93
  assess_score
87
94
  end
88
95
 
@@ -155,6 +162,21 @@ module CukeSniffer
155
162
  CukeSniffer::CukeSnifferHelper.catalog_possible_dead_steps(@step_definitions, converted_steps)
156
163
  end
157
164
 
165
+ def assess_score
166
+ puts "\nAssessing Score: "
167
+ initialize_summary
168
+ summarize(:features, @features, "Feature")
169
+ summarize(:scenarios, @scenarios, "Scenario")
170
+ summarize(:step_definitions, @step_definitions, "StepDefinition")
171
+ summarize(:hooks, @hooks, "Hook")
172
+ @summary[:improvement_list] = CukeSniffer::SummaryHelper.sort_improvement_list(@summary[:improvement_list])
173
+ @improvement_list = @summary[:improvement_list]
174
+ end
175
+
176
+ def cataloged?
177
+ @cataloged
178
+ end
179
+
158
180
  private
159
181
 
160
182
  def initialize_rule_targets(parameters)
@@ -166,6 +188,8 @@ module CukeSniffer
166
188
 
167
189
  puts("\nHooks:")
168
190
  @hooks = build_objects_for_extension_from_location(@hooks_location, "rb") { |location| build_hooks(location) }
191
+
192
+ initialize_catalog_status(parameters)
169
193
  end
170
194
 
171
195
  def initialize_locations(parameters)
@@ -180,6 +204,14 @@ module CukeSniffer
180
204
  @scenarios = CukeSniffer::CukeSnifferHelper.get_all_scenarios(@features)
181
205
  end
182
206
 
207
+ def initialize_catalog_status(parameters)
208
+ if parameters[:no_catalog] == true
209
+ @cataloged = false
210
+ else
211
+ @cataloged = true
212
+ end
213
+ end
214
+
183
215
  def evaluate_rules
184
216
  @rules = CukeSniffer::CukeSnifferHelper.build_rules(RULES)
185
217
  CukeSniffer::RulesEvaluator.new(self, @rules)
@@ -192,20 +224,9 @@ module CukeSniffer
192
224
  }
193
225
  end
194
226
 
195
- def assess_score
196
- puts "\nAssessing Score: "
197
- initialize_summary
198
- summarize(:features, @features, "Feature", @features_summary)
199
- summarize(:scenarios, @scenarios, "Scenario", @scenarios_summary)
200
- summarize(:step_definitions, @step_definitions, "StepDefinition", @step_definitions_summary)
201
- summarize(:hooks, @hooks, "Hook", @hooks_summary)
202
- @summary[:improvement_list] = CukeSniffer::SummaryHelper.sort_improvement_list(@summary[:improvement_list])
203
- @improvement_list = @summary[:improvement_list]
204
- end
205
-
206
- def summarize(symbol, list, name, summary_object)
227
+ def summarize(symbol, list, name)
207
228
  @summary[symbol] = CukeSniffer::SummaryHelper.assess_rule_target_list(list, name)
208
- @summary[:total_score] = @summary[symbol][:total_score]
229
+ @summary[:total_score] += @summary[symbol][:total_score]
209
230
  @summary[symbol][:improvement_list].each do |phrase, count|
210
231
  @summary[:improvement_list][phrase] ||= 0
211
232
  @summary[:improvement_list][phrase] += @summary[symbol][:improvement_list][phrase]
@@ -1,165 +1,166 @@
1
- module CukeSniffer
2
- # Author:: Robert Cochran (mailto:cochrarj@miamioh.edu)
3
- # Copyright:: Copyright (C) 2013 Robert Cochran
4
- # License:: Distributes under the MIT License
5
- # Static class used for aiding cuke_sniffer in various tasks
6
- class CukeSnifferHelper
7
-
8
- # Iterates over the passed features list and returns all steps found in scenarios and backgrounds.
9
- def self.extract_steps_from_features(features)
10
- steps = {}
11
- features.each do |feature|
12
- steps.merge! extract_scenario_steps(feature.background) unless feature.background.nil?
13
- feature.scenarios.each do |scenario|
14
- if scenario.type == "Scenario Outline"
15
- steps.merge! extract_scenario_outline_steps(scenario)
16
- else
17
- steps.merge! extract_scenario_steps(scenario)
18
- end
19
- end
20
- end
21
- steps
22
- end
23
-
24
- # Iterates over the passed features list and returns all scenarios and backgrounds found.
25
- def self.get_all_scenarios(features)
26
- scenarios = []
27
- features.each do |feature|
28
- scenarios << feature.background unless feature.background.nil?
29
- scenarios << feature.scenarios
30
- end
31
- scenarios.flatten
32
- end
33
-
34
- # Grabs the values from an example without the bars
35
- def self.extract_variables_from_example(example)
36
- example = example[example.index('|')..example.length]
37
- example.split(/\s*\|\s*/) - [""]
38
- end
39
-
40
- # Creates a step call from the details of an example table
41
- def self.build_updated_step_from_example(step, variable_list, row_variables)
42
- new_step = step.dup
43
- variable_list.each do |variable|
44
- if step.include? variable
45
- table_variable_to_insert = row_variables[variable_list.index(variable)]
46
- table_variable_to_insert ||= ""
47
- new_step.gsub!("<#{variable}>", table_variable_to_insert)
48
- end
49
- end
50
- new_step
51
- end
52
-
53
- # Creates a hash of steps with the build up example step calls.
54
- def self.extract_scenario_outline_steps(scenario)
55
- steps = {}
56
- examples = scenario.examples_table
57
- return {} if examples.empty?
58
- variable_list = extract_variables_from_example(examples.first)
59
- (1...examples.size).each do |example_counter|
60
- #TODO Abstraction needed for this regex matcher (constants?)
61
- next if examples[example_counter] =~ /^\#.*$/
62
- row_variables = extract_variables_from_example(examples[example_counter])
63
- step_counter = 1
64
- scenario.steps.each do |step|
65
- step_line = scenario.start_line + step_counter
66
- location = "#{scenario.location.gsub(/\d+$/, step_line.to_s)}(Example #{example_counter})"
67
- steps[location] = build_updated_step_from_example(step, variable_list, row_variables)
68
- step_counter += 1
69
- end
70
- end
71
- steps
72
- end
73
-
74
- # Returns all steps found in a scenario
75
- def self.extract_scenario_steps(scenario)
76
- steps_hash = {}
77
- counter = 1
78
- scenario.steps.each do |step|
79
- location = scenario.location.gsub(/:\d*$/, ":#{scenario.start_line + counter}")
80
- steps_hash[location] = step
81
- counter += 1
82
- end
83
- steps_hash
84
- end
85
-
86
- # Builds a list of rule objects out of a hash. See CukeSniffer::RulesConfig for hash example.
87
- def self.build_rules(rules)
88
- return [] if rules.nil?
89
- rules.collect do |key, value|
90
- CukeSniffer::CukeSnifferHelper.build_rule(value)
91
- end
92
- end
93
-
94
- # Builds rule object out of a hash. See CukeSniffer::RulesConfig for hash example.
95
- def self.build_rule(rule_hash)
96
- rule = CukeSniffer::Rule.new
97
- rule.phrase = rule_hash[:phrase]
98
- rule.score = rule_hash[:score]
99
- rule.enabled = rule_hash[:enabled]
100
- conditional_keys = rule_hash.keys - [:phrase, :score, :enabled, :targets, :reason]
101
- conditions = {}
102
- conditional_keys.each do |key|
103
- conditions[key] = (rule_hash[key].kind_of? Array) ? Array.new(rule_hash[key]) : rule_hash[key]
104
- end
105
- rule.conditions = conditions
106
- rule.reason = rule_hash[:reason]
107
- rule.targets = rule_hash[:targets]
108
- rule
109
- end
110
-
111
- # Returns a list of all nested step calls found in a step definition.
112
- def self.extract_steps_from_step_definitions(step_definitions)
113
- steps = {}
114
- step_definitions.each do |definition|
115
- definition.nested_steps.each_key do |key|
116
- steps[key] = definition.nested_steps[key]
117
- end
118
- end
119
- steps
120
- end
121
-
122
- # Returns a fuzzy match for a step definition for cataloging steps.
123
- def self.convert_steps_with_expressions(steps_with_expressions)
124
- step_regex_hash = {}
125
- steps_with_expressions.each do |step_location, step_value|
126
- modified_step = step_value.gsub(/\#{[^}]*}/, '.*')
127
- step_regex_hash[step_location] = Regexp.new('^' + modified_step + '$')
128
- end
129
- step_regex_hash
130
- end
131
-
132
- # Extracts all possible step calls from the passed features and step definitions.
133
- def self.get_all_steps(features, step_definitions)
134
- feature_steps = CukeSniffer::CukeSnifferHelper.extract_steps_from_features(features)
135
- step_definition_steps = CukeSniffer::CukeSnifferHelper.extract_steps_from_step_definitions(step_definitions)
136
- feature_steps.merge step_definition_steps
137
- end
138
-
139
- # Applies all possible fuzzy calls to a step definition.
140
- def self.catalog_possible_dead_steps(step_definitions, steps_with_expressions)
141
- step_definitions.each do |step_definition|
142
- next unless step_definition.calls.empty?
143
- regex_as_string = step_definition.regex.to_s.gsub(/\(\?-mix:\^?/, "").gsub(/\$\)$/, "")
144
- steps_with_expressions.each do |step_location, step_value|
145
- if regex_as_string =~ step_value
146
- step_definition.add_call(step_location, step_value)
147
- end
148
- end
149
- end
150
- step_definitions
151
- end
152
-
153
- # Returns a list of all step definitions with a capture group
154
- def self.get_steps_with_expressions(steps)
155
- steps_with_expressions = {}
156
- steps.each do |step_location, step_value|
157
- if step_value =~ /\#{.*}/
158
- steps_with_expressions[step_location] = step_value
159
- end
160
- end
161
- steps_with_expressions
162
- end
163
-
164
- end
1
+ module CukeSniffer
2
+ # Author:: Robert Cochran (mailto:cochrarj@miamioh.edu)
3
+ # Copyright:: Copyright (C) 2013 Robert Cochran
4
+ # License:: Distributes under the MIT License
5
+ # Static class used for aiding cuke_sniffer in various tasks
6
+ class CukeSnifferHelper
7
+
8
+ # Iterates over the passed features list and returns all steps found in scenarios and backgrounds.
9
+ def self.extract_steps_from_features(features)
10
+ steps = {}
11
+ features.each do |feature|
12
+ steps.merge! extract_scenario_steps(feature.background) unless feature.background.nil?
13
+ feature.scenarios.each do |scenario|
14
+ if scenario.type == "Scenario Outline"
15
+ steps.merge! extract_scenario_outline_steps(scenario)
16
+ else
17
+ steps.merge! extract_scenario_steps(scenario)
18
+ end
19
+ end
20
+ end
21
+ steps
22
+ end
23
+
24
+ # Iterates over the passed features list and returns all scenarios and backgrounds found.
25
+ def self.get_all_scenarios(features)
26
+ scenarios = []
27
+ features.each do |feature|
28
+ scenarios << feature.background unless feature.background.nil?
29
+ scenarios << feature.scenarios
30
+ end
31
+ scenarios.flatten
32
+ end
33
+
34
+ # Grabs the values from an example without the bars
35
+ def self.extract_variables_from_example(example)
36
+ example = example[example.index('|')..example.length]
37
+ example.split(/\s*\|\s*/) - [""]
38
+ end
39
+
40
+ # Creates a step call from the details of an example table
41
+ def self.build_updated_step_from_example(step, variable_list, row_variables)
42
+ new_step = step.dup
43
+ variable_list.each do |variable|
44
+ if step.include? variable
45
+ table_variable_to_insert = row_variables[variable_list.index(variable)]
46
+ table_variable_to_insert ||= ""
47
+ new_step.gsub!("<#{variable}>", table_variable_to_insert)
48
+ end
49
+ end
50
+ new_step
51
+ end
52
+
53
+ # Creates a hash of steps with the build up example step calls.
54
+ def self.extract_scenario_outline_steps(scenario)
55
+ steps = {}
56
+ examples = scenario.examples_table
57
+ return {} if examples.empty?
58
+ variable_list = extract_variables_from_example(examples.first)
59
+ (1...examples.size).each do |example_counter|
60
+ #TODO Abstraction needed for this regex matcher (constants?)
61
+ next if examples[example_counter] =~ /^\#.*$/
62
+ row_variables = extract_variables_from_example(examples[example_counter])
63
+ step_counter = 1
64
+ scenario.steps.each do |step|
65
+ step_line = scenario.start_line + step_counter
66
+ location = "#{scenario.location.gsub(/\d+$/, step_line.to_s)}(Example #{example_counter})"
67
+ steps[location] = build_updated_step_from_example(step, variable_list, row_variables)
68
+ step_counter += 1
69
+ end
70
+ end
71
+ steps
72
+ end
73
+
74
+ # Returns all steps found in a scenario
75
+ def self.extract_scenario_steps(scenario)
76
+ steps_hash = {}
77
+ counter = 1
78
+ scenario.steps.each do |step|
79
+ location = scenario.location.gsub(/:\d*$/, ":#{scenario.start_line + counter}")
80
+ steps_hash[location] = step
81
+ counter += 1
82
+ end
83
+ steps_hash
84
+ end
85
+
86
+ # Builds a list of rule objects out of a hash. See CukeSniffer::RulesConfig for hash example.
87
+ def self.build_rules(rules)
88
+ return [] if rules.nil?
89
+ rules.collect do |key, value|
90
+ CukeSniffer::CukeSnifferHelper.build_rule(value)
91
+ end
92
+ end
93
+
94
+ # Builds rule object out of a hash. See CukeSniffer::RulesConfig for hash example.
95
+ def self.build_rule(rule_hash)
96
+ rule = CukeSniffer::Rule.new
97
+ rule.phrase = rule_hash[:phrase]
98
+ rule.score = rule_hash[:score]
99
+ rule.enabled = rule_hash[:enabled]
100
+ conditional_keys = rule_hash.keys - [:phrase, :score, :enabled, :targets, :reason]
101
+ conditions = {}
102
+ conditional_keys.each do |key|
103
+ conditions[key] = (rule_hash[key].kind_of? Array) ? Array.new(rule_hash[key]) : rule_hash[key]
104
+ end
105
+ rule.conditions = conditions
106
+ rule.reason = rule_hash[:reason]
107
+ rule.targets = rule_hash[:targets]
108
+ rule
109
+ end
110
+
111
+ # Returns a list of all nested step calls found in a step definition.
112
+ def self.extract_steps_from_step_definitions(step_definitions)
113
+ steps = {}
114
+ step_definitions.each do |definition|
115
+ definition.nested_steps.each do |location, step|
116
+ steps[location] = step
117
+ end
118
+ end
119
+ steps
120
+ end
121
+
122
+ # Returns a fuzzy match for a step definition for cataloging steps.
123
+ def self.convert_steps_with_expressions(steps_with_expressions)
124
+ step_regex_hash = {}
125
+ steps_with_expressions.each do |step_location, step_value|
126
+ modified_step = step_value.gsub(/\#{[^}]*}/, '.*')
127
+ next if modified_step == '.*'
128
+ step_regex_hash[step_location] = Regexp.new('^' + modified_step + '$')
129
+ end
130
+ step_regex_hash
131
+ end
132
+
133
+ # Extracts all possible step calls from the passed features and step definitions.
134
+ def self.get_all_steps(features, step_definitions)
135
+ feature_steps = CukeSniffer::CukeSnifferHelper.extract_steps_from_features(features)
136
+ step_definition_steps = CukeSniffer::CukeSnifferHelper.extract_steps_from_step_definitions(step_definitions)
137
+ feature_steps.merge step_definition_steps
138
+ end
139
+
140
+ # Applies all possible fuzzy calls to a step definition.
141
+ def self.catalog_possible_dead_steps(step_definitions, steps_with_expressions)
142
+ step_definitions.each do |step_definition|
143
+ next unless step_definition.calls.empty?
144
+ regex_as_string = step_definition.regex.to_s.gsub(/\(\?-mix:\^?/, "").gsub(/\$\)$/, "")
145
+ steps_with_expressions.each do |step_location, step_value|
146
+ if regex_as_string =~ step_value
147
+ step_definition.add_call(step_location, step_value)
148
+ end
149
+ end
150
+ end
151
+ step_definitions
152
+ end
153
+
154
+ # Returns a list of all step definitions with a capture group
155
+ def self.get_steps_with_expressions(steps)
156
+ steps_with_expressions = {}
157
+ steps.each do |step_location, step_value|
158
+ if step_value =~ /\#{.*}/
159
+ steps_with_expressions[step_location] = step_value
160
+ end
161
+ end
162
+ steps_with_expressions
163
+ end
164
+
165
+ end
165
166
  end