cuke_sniffer 0.0.7 → 0.0.8
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/lib/cuke_sniffer.rb +8 -23
- data/lib/cuke_sniffer/cli.rb +38 -5
- data/lib/cuke_sniffer/constants.rb +1 -1
- data/lib/cuke_sniffer/cuke_sniffer_helper.rb +1 -1
- data/lib/cuke_sniffer/dead_steps_helper.rb +1 -1
- data/lib/cuke_sniffer/feature.rb +109 -104
- data/lib/cuke_sniffer/feature_rules_evaluator.rb +55 -56
- data/lib/cuke_sniffer/formatter.rb +1 -1
- data/lib/cuke_sniffer/hook.rb +103 -77
- data/lib/cuke_sniffer/report/rules.html.erb +0 -5
- data/lib/cuke_sniffer/rule.rb +26 -27
- data/lib/cuke_sniffer/rule_config.rb +114 -128
- data/lib/cuke_sniffer/rule_target.rb +78 -62
- data/lib/cuke_sniffer/rules_evaluator.rb +52 -64
- data/lib/cuke_sniffer/scenario.rb +123 -102
- data/lib/cuke_sniffer/step_definition.rb +176 -163
- data/lib/cuke_sniffer/summary_helper.rb +1 -1
- data/lib/cuke_sniffer/summary_node.rb +17 -18
- metadata +2 -2
data/lib/cuke_sniffer.rb
CHANGED
@@ -1,23 +1,8 @@
|
|
1
|
-
require 'nokogiri'
|
2
|
-
require 'roxml'
|
3
|
-
|
4
|
-
require 'cuke_sniffer/
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
require 'cuke_sniffer/scenario'
|
10
|
-
require 'cuke_sniffer/step_definition'
|
11
|
-
require 'cuke_sniffer/hook'
|
12
|
-
require 'cuke_sniffer/rule'
|
13
|
-
require 'cuke_sniffer/summary_node'
|
14
|
-
require 'cuke_sniffer/rules_evaluator'
|
15
|
-
require 'cuke_sniffer/cuke_sniffer_helper'
|
16
|
-
require 'cuke_sniffer/summary_helper'
|
17
|
-
require 'cuke_sniffer/dead_steps_helper'
|
18
|
-
require 'cuke_sniffer/cli'
|
19
|
-
require 'cuke_sniffer/formatter'
|
20
|
-
|
21
|
-
module CukeSniffer
|
22
|
-
|
23
|
-
end
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'roxml'
|
3
|
+
|
4
|
+
require 'cuke_sniffer/cli'
|
5
|
+
|
6
|
+
module CukeSniffer
|
7
|
+
|
8
|
+
end
|
data/lib/cuke_sniffer/cli.rb
CHANGED
@@ -1,10 +1,21 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
1
|
+
require 'cuke_sniffer/constants'
|
2
|
+
require 'cuke_sniffer/dead_steps_helper'
|
3
|
+
require 'cuke_sniffer/feature'
|
4
|
+
require 'cuke_sniffer/hook'
|
5
|
+
require 'cuke_sniffer/rule'
|
6
|
+
require 'cuke_sniffer/rule_config'
|
7
|
+
require 'cuke_sniffer/step_definition'
|
8
|
+
require 'cuke_sniffer/summary_node'
|
9
|
+
|
10
|
+
require 'cuke_sniffer/cuke_sniffer_helper'
|
11
|
+
require 'cuke_sniffer/rules_evaluator'
|
12
|
+
require 'cuke_sniffer/summary_helper'
|
13
|
+
require 'cuke_sniffer/formatter'
|
3
14
|
|
4
15
|
module CukeSniffer
|
5
16
|
|
6
17
|
# Author:: Robert Cochran (mailto:cochrarj@miamioh.edu)
|
7
|
-
# Copyright:: Copyright (C)
|
18
|
+
# Copyright:: Copyright (C) 2014 Robert Cochran
|
8
19
|
# License:: Distributes under the MIT License
|
9
20
|
# Mixins: CukeSniffer::Constants, ROXML
|
10
21
|
class CLI
|
@@ -151,10 +162,11 @@ module CukeSniffer
|
|
151
162
|
def catalog_step_calls
|
152
163
|
puts "\nCataloging Step Calls: "
|
153
164
|
steps = CukeSniffer::CukeSnifferHelper.get_all_steps(@features, @step_definitions)
|
165
|
+
steps_map = build_steps_map(steps)
|
154
166
|
@step_definitions.each do |step_definition|
|
155
167
|
print '.'
|
156
|
-
calls =
|
157
|
-
calls
|
168
|
+
calls = steps_map.find_all {|step, location| step =~ step_definition.regex }
|
169
|
+
step_definition.calls = build_stored_calls_map(calls)
|
158
170
|
end
|
159
171
|
|
160
172
|
steps_with_expressions = CukeSniffer::CukeSnifferHelper.get_steps_with_expressions(steps)
|
@@ -286,5 +298,26 @@ module CukeSniffer
|
|
286
298
|
object_list
|
287
299
|
end
|
288
300
|
|
301
|
+
def build_stored_calls_map(calls)
|
302
|
+
stored_calls = {}
|
303
|
+
calls.each do |step, locations|
|
304
|
+
locations.each { |location| stored_calls[location] = step}
|
305
|
+
end
|
306
|
+
stored_calls
|
307
|
+
end
|
308
|
+
|
309
|
+
def build_steps_map(steps)
|
310
|
+
calls_map = {}
|
311
|
+
steps.each do |location, step|
|
312
|
+
sanitized_step = step.gsub(STEP_STYLES, "")
|
313
|
+
if(calls_map.keys.include?(sanitized_step))
|
314
|
+
calls_map[sanitized_step] << location
|
315
|
+
else
|
316
|
+
calls_map[sanitized_step] = [location]
|
317
|
+
end
|
318
|
+
end
|
319
|
+
calls_map
|
320
|
+
end
|
321
|
+
|
289
322
|
end
|
290
323
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module CukeSniffer
|
2
2
|
# Author:: Robert Cochran (mailto:cochrarj@miamioh.edu)
|
3
|
-
# Copyright:: Copyright (C)
|
3
|
+
# Copyright:: Copyright (C) 2014 Robert Cochran
|
4
4
|
# License:: Distributes under the MIT License
|
5
5
|
# A collection of constants that are used throughout the gem
|
6
6
|
module Constants
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module CukeSniffer
|
2
2
|
# Author:: Robert Cochran (mailto:cochrarj@miamioh.edu)
|
3
|
-
# Copyright:: Copyright (C)
|
3
|
+
# Copyright:: Copyright (C) 2014 Robert Cochran
|
4
4
|
# License:: Distributes under the MIT License
|
5
5
|
# Static class used for aiding cuke_sniffer in various tasks
|
6
6
|
class CukeSnifferHelper
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module CukeSniffer
|
2
2
|
# Author:: Robert Cochran (mailto:cochrarj@miamioh.edu)
|
3
|
-
# Copyright:: Copyright (C)
|
3
|
+
# Copyright:: Copyright (C) 2014 Robert Cochran
|
4
4
|
# License:: Distributes under the MIT License
|
5
5
|
# Mixins: CukeSniffer::Constants
|
6
6
|
# A static class to aid in the identification of dead steps.
|
data/lib/cuke_sniffer/feature.rb
CHANGED
@@ -1,104 +1,109 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
#
|
8
|
-
#
|
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
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
44
|
-
|
45
|
-
def
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
until index >= feature_lines.length or feature_lines[index].match
|
61
|
-
|
62
|
-
index += 1
|
63
|
-
end
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
scenario_title_found =
|
87
|
-
|
88
|
-
end
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
scenario
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
1
|
+
require 'cuke_sniffer/feature_rules_evaluator'
|
2
|
+
|
3
|
+
require 'cuke_sniffer/scenario'
|
4
|
+
|
5
|
+
module CukeSniffer
|
6
|
+
|
7
|
+
# Author:: Robert Cochran (mailto:cochrarj@miamioh.edu)
|
8
|
+
# Copyright:: Copyright (C) 2014 Robert Cochran
|
9
|
+
# License:: Distributes under the MIT License
|
10
|
+
# Handles feature files and disassembles and evaluates
|
11
|
+
# its components.
|
12
|
+
# Extends CukeSniffer::FeatureRulesEvaluator
|
13
|
+
class Feature < FeatureRuleTarget
|
14
|
+
|
15
|
+
xml_accessor :scenarios, :as => [CukeSniffer::FeatureRuleTarget], :in => "scenarios"
|
16
|
+
|
17
|
+
SCENARIO_TITLE_REGEX = /#{COMMENT_REGEX}#{SCENARIO_TITLE_STYLES}(?<name>.*)/ # :nodoc:
|
18
|
+
|
19
|
+
# Scenario: The background of a Feature, created as a Scenario object
|
20
|
+
attr_accessor :background
|
21
|
+
|
22
|
+
# Scenario array: A list of all scenarios contained in a feature file
|
23
|
+
attr_accessor :scenarios
|
24
|
+
|
25
|
+
# int: Total score from all of the scenarios contained in the feature
|
26
|
+
attr_accessor :scenarios_score
|
27
|
+
|
28
|
+
# int: Total score of the feature and its scenarios
|
29
|
+
attr_accessor :total_score
|
30
|
+
|
31
|
+
# String array: A list of all the lines in a feature file
|
32
|
+
attr_accessor :feature_lines
|
33
|
+
|
34
|
+
# file_name must be in the format of "file_path\file_name.feature"
|
35
|
+
def initialize(file_name)
|
36
|
+
super(file_name)
|
37
|
+
@type = "Feature"
|
38
|
+
@scenarios = []
|
39
|
+
@scenarios_score = 0
|
40
|
+
@total_score = 0
|
41
|
+
@feature_lines = IO.readlines(file_name)
|
42
|
+
split_feature(file_name, feature_lines) unless @feature_lines == []
|
43
|
+
end
|
44
|
+
|
45
|
+
def ==(comparison_object) # :nodoc:
|
46
|
+
super(comparison_object) &&
|
47
|
+
comparison_object.scenarios == scenarios
|
48
|
+
end
|
49
|
+
|
50
|
+
def update_score
|
51
|
+
@scenarios_score += @background.score unless @background.nil?
|
52
|
+
@scenarios.each { |scenario| @scenarios_score += scenario.score }
|
53
|
+
@total_score = @scenarios_score + @score
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def split_feature(file_name, feature_lines)
|
59
|
+
index = 0
|
60
|
+
until index >= feature_lines.length or feature_lines[index].match /Feature:\s*(?<name>.*)/
|
61
|
+
update_tag_list(feature_lines[index])
|
62
|
+
index += 1
|
63
|
+
end
|
64
|
+
|
65
|
+
until index >= feature_lines.length or feature_lines[index].match TAG_REGEX or feature_lines[index].match SCENARIO_TITLE_REGEX
|
66
|
+
create_name(feature_lines[index], "Feature:")
|
67
|
+
index += 1
|
68
|
+
end
|
69
|
+
|
70
|
+
scenario_title_found = false
|
71
|
+
index_of_title = nil
|
72
|
+
code_block = []
|
73
|
+
until index >= feature_lines.length
|
74
|
+
if scenario_title_found and feature_lines[index].match SCENARIO_TITLE_REGEX
|
75
|
+
not_our_code = []
|
76
|
+
code_block.reverse.each do |line|
|
77
|
+
break if line =~ /#{SCENARIO_TITLE_STYLES}|#{STEP_STYLES}|^\|.*\||Examples:/
|
78
|
+
not_our_code << line
|
79
|
+
end
|
80
|
+
|
81
|
+
if not_our_code.empty?
|
82
|
+
add_scenario_to_feature(code_block, index_of_title)
|
83
|
+
else
|
84
|
+
add_scenario_to_feature(code_block[0...(-1 * not_our_code.length)], index_of_title)
|
85
|
+
end
|
86
|
+
scenario_title_found = false
|
87
|
+
code_block = not_our_code.reverse
|
88
|
+
end
|
89
|
+
code_block << feature_lines[index].strip
|
90
|
+
if feature_lines[index].match SCENARIO_TITLE_REGEX
|
91
|
+
scenario_title_found = true
|
92
|
+
index_of_title = "#{file_name}:#{index + 1}"
|
93
|
+
end
|
94
|
+
index += 1
|
95
|
+
end
|
96
|
+
#TODO - Last scenario falling through above logic, needs a fix (code_block related)
|
97
|
+
add_scenario_to_feature(code_block, index_of_title) unless code_block==[]
|
98
|
+
end
|
99
|
+
|
100
|
+
def add_scenario_to_feature(code_block, index_of_title)
|
101
|
+
scenario = CukeSniffer::Scenario.new(index_of_title, code_block)
|
102
|
+
if scenario.type == "Background"
|
103
|
+
@background = scenario
|
104
|
+
else
|
105
|
+
@scenarios << scenario
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -1,56 +1,55 @@
|
|
1
|
-
require 'cuke_sniffer/constants'
|
2
|
-
require 'cuke_sniffer/
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
@
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
comparison_object.
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
line.
|
38
|
-
line.
|
39
|
-
@name +=
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
line[
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
1
|
+
require 'cuke_sniffer/constants'
|
2
|
+
require 'cuke_sniffer/rule_target'
|
3
|
+
|
4
|
+
module CukeSniffer
|
5
|
+
|
6
|
+
# Author:: Robert Cochran (mailto:cochrarj@miamioh.edu)
|
7
|
+
# Copyright:: Copyright (C) 2014 Robert Cochran
|
8
|
+
# License:: Distributes under the MIT License
|
9
|
+
# Parent class for Feature and Scenario objects
|
10
|
+
# holds shared attributes and rules.
|
11
|
+
# Extends CukeSniffer::RuleTarget
|
12
|
+
class FeatureRuleTarget < RuleTarget
|
13
|
+
|
14
|
+
# string array: Contains all tags attached to a Feature or Scenario
|
15
|
+
attr_accessor :tags
|
16
|
+
|
17
|
+
# string: Name of the Feature or Scenario
|
18
|
+
attr_accessor :name
|
19
|
+
|
20
|
+
# Location must be in the format of "file_path\file_name.rb:line_number"
|
21
|
+
def initialize(location)
|
22
|
+
@name = ""
|
23
|
+
@tags = []
|
24
|
+
super(location)
|
25
|
+
end
|
26
|
+
|
27
|
+
def == (comparison_object) # :nodoc:
|
28
|
+
super(comparison_object) &&
|
29
|
+
comparison_object.name == name &&
|
30
|
+
comparison_object.tags == tags
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def create_name(line, filter)
|
36
|
+
line.gsub!(/#{COMMENT_REGEX}#{filter}/, "")
|
37
|
+
line.strip!
|
38
|
+
@name += " " unless @name.empty? or line.empty?
|
39
|
+
@name += line
|
40
|
+
end
|
41
|
+
|
42
|
+
def update_tag_list(line)
|
43
|
+
comment_start = (line =~ /([^@\w]#)|(^#)/)
|
44
|
+
|
45
|
+
if comment_start
|
46
|
+
line[0...comment_start].split.each { |single_tag| @tags << single_tag }
|
47
|
+
@tags << line[comment_start..line.length].strip
|
48
|
+
else
|
49
|
+
line.split.each { |single_tag| @tags << single_tag }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|