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 CHANGED
@@ -1,34 +1,51 @@
1
- #!/usr/bin/env ruby
2
- require 'cuke_sniffer'
3
-
4
- if ARGV.include? "-h" or ARGV.include? "--help"
5
- puts HELP_CMD_TEXT
6
- exit
7
- end
8
-
9
- @cuke_sniffer = nil
10
- if (ARGV[0] != nil and File.directory?(ARGV[0])) and (ARGV[1] != nil and File.directory?(ARGV[1]))
11
- @cuke_sniffer = CukeSniffer::CLI.new(ARGV[0], ARGV[1])
12
- else
13
- @cuke_sniffer = CukeSniffer::CLI.new
14
- end
15
-
16
- def print_results
17
- puts @cuke_sniffer.output_results
18
- end
19
-
20
- if ARGV.include? "--out" or ARGV.include? "-o"
21
- index = ARGV.index("--out")
22
- index ||= ARGV.index("-o")
23
- out_type = ARGV[index + 1]
24
- case out_type
25
- when "html"
26
- @cuke_sniffer.output_html
27
- else
28
- print_results
29
- end
30
- else
31
- print_results
32
- end
33
-
34
- puts "Completed Sniffing."
1
+ #!/usr/bin/env ruby
2
+ require 'cuke_sniffer'
3
+
4
+ help_cmd_txt = "Welcome to CukeSniffer!
5
+ Calling CukeSniffer with no arguments will run it against the current directory.
6
+ Other Options for Running include:
7
+ <feature_file_path>, <step_def_file_path> : Runs CukeSniffer against the
8
+ specified paths.
9
+ -o, --out html (name) : Runs CukeSniffer then outputs an
10
+ html file in the current
11
+ directory (with optional name).
12
+ -h, --help : You get this lovely document."
13
+
14
+
15
+ if ARGV.include? "-h" or ARGV.include? "--help"
16
+ puts help_cmd_txt
17
+ exit
18
+ end
19
+
20
+ cuke_sniffer = nil
21
+ if (ARGV[0] != nil and File.directory?(ARGV[0])) and (ARGV[1] != nil and File.directory?(ARGV[1]))
22
+ cuke_sniffer = CukeSniffer::CLI.new(ARGV[0], ARGV[1])
23
+ else
24
+ cuke_sniffer = CukeSniffer::CLI.new
25
+ end
26
+
27
+ def print_results(cuke_sniffer)
28
+ puts cuke_sniffer.output_results
29
+ end
30
+
31
+ if ARGV.include? "--out" or ARGV.include? "-o"
32
+ index = ARGV.index("--out")
33
+ index ||= ARGV.index("-o")
34
+ out_type = ARGV[index + 1]
35
+ case out_type
36
+ when "html"
37
+ file_name = ARGV[index + 2]
38
+ if file_name.nil?
39
+ cuke_sniffer.output_html
40
+ else
41
+ file_name = file_name + ".html" unless file_name =~ /\.html$/
42
+ cuke_sniffer.output_html(file_name)
43
+ end
44
+ else
45
+ print_results(cuke_sniffer)
46
+ end
47
+ else
48
+ print_results(cuke_sniffer)
49
+ end
50
+
51
+ puts "Completed Sniffing."
data/lib/cuke_sniffer.rb CHANGED
@@ -1,13 +1,13 @@
1
-
2
- require 'cuke_sniffer/constants'
3
- require 'cuke_sniffer/rule_config'
4
- require 'cuke_sniffer/rules_evaluator'
5
- require 'cuke_sniffer/feature_rules_evaluator'
6
- require 'cuke_sniffer/feature'
7
- require 'cuke_sniffer/scenario'
8
- require 'cuke_sniffer/step_definition'
9
- require 'cuke_sniffer/cli'
10
-
11
- module CukeSniffer
12
-
13
- end
1
+
2
+ require 'cuke_sniffer/constants'
3
+ require 'cuke_sniffer/rule_config'
4
+ require 'cuke_sniffer/rules_evaluator'
5
+ require 'cuke_sniffer/feature_rules_evaluator'
6
+ require 'cuke_sniffer/feature'
7
+ require 'cuke_sniffer/scenario'
8
+ require 'cuke_sniffer/step_definition'
9
+ require 'cuke_sniffer/cli'
10
+
11
+ module CukeSniffer
12
+
13
+ end
@@ -1,226 +1,246 @@
1
- require 'erb'
2
- require 'cuke_sniffer/constants'
3
-
4
- module CukeSniffer
5
- class CLI
6
- include CukeSniffer::Constants
7
-
8
- attr_accessor :features, :step_definitions, :summary
9
-
10
- def initialize(features_location = Dir.getwd, step_definitions_location = Dir.getwd)
11
- @features_location = features_location
12
- @step_definitions_location = step_definitions_location
13
- @features = []
14
- @step_definitions = []
15
-
16
- puts "\nFeatures:"
17
- unless features_location.nil?
18
- if File.file?(features_location)
19
- @features = [Feature.new(features_location)]
20
- else
21
- build_file_list_from_folder(features_location, ".feature").each { |location|
22
- @features << Feature.new(location)
23
- print '.'
24
- }
25
- end
26
- end
27
-
28
- puts("\nStep Definitions:")
29
- unless step_definitions_location.nil?
30
- if File.file?(step_definitions_location)
31
- @step_definitions = [build_step_definitions(step_definitions_location)]
32
- else
33
- build_file_list_from_folder(step_definitions_location, "steps.rb").each { |location|
34
- @step_definitions << build_step_definitions(location)
35
- print '.'
36
- }
37
- end
38
- end
39
-
40
- @step_definitions.flatten!
41
- @summary = {
42
- :total_score => 0,
43
- :features => {},
44
- :step_definitions => {},
45
- :improvement_list => {}
46
- }
47
- puts "\nCataloging Step Calls: "
48
- catalog_step_calls
49
- puts "\nAssessing Score: "
50
- assess_score
51
- end
52
-
53
- def build_file_list_from_folder(folder_name, extension)
54
- list = []
55
- Dir.entries(folder_name).each_entry do |file_name|
56
- unless FILE_IGNORE_LIST.include?(file_name)
57
- file_name = "#{folder_name}/#{file_name}"
58
- if File.directory?(file_name)
59
- list << build_file_list_from_folder(file_name, extension)
60
- elsif file_name.include?(extension)
61
- list << file_name
62
- end
63
- end
64
- end
65
- list.flatten
66
- end
67
-
68
- def build_step_definitions(file_name)
69
- step_file_lines = []
70
- step_file = File.open(file_name)
71
- step_file.each_line { |line| step_file_lines << line }
72
- step_file.close
73
-
74
- counter = 0
75
- step_code = []
76
- step_definitions = []
77
- found_first_step = false
78
- until counter >= step_file_lines.length
79
- if step_file_lines[counter] =~ STEP_DEFINITION_REGEX and !step_code.empty? and found_first_step
80
- step_definitions << StepDefinition.new("#{file_name}:#{counter+1 - step_code.count}", step_code)
81
- step_code = []
82
- end
83
- found_first_step = true if step_file_lines[counter] =~ STEP_DEFINITION_REGEX
84
- step_code << step_file_lines[counter].strip
85
- counter+=1
86
- end
87
- step_definitions << StepDefinition.new("#{file_name}:#{counter+1}", step_code) unless step_code.empty?
88
- step_definitions
89
- end
90
-
91
- def assess_array(array)
92
- min, max, min_file, max_file = nil
93
- total = 0
94
- array.each do |node|
95
- score = node.score
96
- @summary[:total_score] += score
97
- node.rules_hash.each_key do |key|
98
- @summary[:improvement_list][key] ||= 0
99
- @summary[:improvement_list][key] += node.rules_hash[key]
100
- end
101
- min, min_file = score, node.location if (min.nil? or score < min)
102
- max, max_file = score, node.location if (max.nil? or score > max)
103
- total += score
104
- end
105
- {
106
- :total => array.count,
107
- :min => min,
108
- :min_file => min_file,
109
- :max => max,
110
- :max_file => max_file,
111
- :average => (total.to_f/array.count.to_f).round(2)
112
- }
113
- end
114
-
115
- def assess_score
116
- @summary[:features] = assess_array(@features)
117
- @summary[:step_definitions] = assess_array(@step_definitions) unless @step_definitions.empty?
118
- sort_improvement_list
119
- end
120
-
121
- def sort_improvement_list
122
- sorted_array = @summary[:improvement_list].sort_by { |improvement, occurrence| occurrence }
123
- @summary[:improvement_list] = {}
124
- sorted_array.reverse.each { |node|
125
- @summary[:improvement_list][node[0]] = node[1]
126
- }
127
- end
128
-
129
- def output_results
130
- feature_results = @summary[:features]
131
- step_definition_results = @summary[:step_definitions]
132
- #todo this string is completely dependent on the tabbing in the string
133
- output = "Suite Summary
134
- Total Score: #{@summary[:total_score]}
135
- Features (#@features_location)
136
- Min: #{feature_results[:min]} (#{feature_results[:min_file]})
137
- Max: #{feature_results[:max]} (#{feature_results[:max_file]})
138
- Average: #{feature_results[:average]}
139
- Step Definitions (#@step_definitions_location)
140
- Min: #{step_definition_results[:min]} (#{step_definition_results[:min_file]})
141
- Max: #{step_definition_results[:max]} (#{step_definition_results[:max_file]})
142
- Average: #{step_definition_results[:average]}
143
- Improvements to make:"
144
- create_improvement_list.each { |item| output << "\n #{item}" }
145
- output
146
- end
147
-
148
- def create_improvement_list
149
- output = []
150
- @summary[:improvement_list].each_key { |improvement| output << "(#{summary[:improvement_list][improvement]})#{improvement}" }
151
- output
152
- end
153
-
154
- def get_all_steps
155
- steps = {}
156
- @features.each do |feature|
157
- feature.scenarios.each do |scenario|
158
- counter = 1
159
- scenario.steps.each do |step|
160
- location = scenario.location.gsub(/:\d*/, ":#{scenario.start_line + counter}")
161
- steps[location] = step
162
- counter += 1
163
- end
164
- end
165
- end
166
- @step_definitions.each do |definition|
167
- definition.nested_steps.each_key do |key|
168
- steps[key] = definition.nested_steps[key]
169
- end
170
- end
171
- steps
172
- end
173
-
174
- def catalog_step_calls
175
- steps = get_all_steps
176
- @step_definitions.each do |step_definition|
177
- print '.'
178
- calls = steps.find_all { |location, step| step.gsub(STEP_STYLES, "") =~ step_definition.regex }
179
- calls.each { |call|
180
- step_definition.add_call(call[0], call[1])
181
- }
182
- end
183
- end
184
-
185
- def update_step_definition(location, step)
186
- @step_definitions.each do |step_definition|
187
- if step.gsub(STEP_STYLES, "") =~ step_definition.regex
188
- step_definition.add_call(location, step)
189
- break
190
- end
191
- end
192
- end
193
-
194
- def get_dead_steps
195
- dead_steps = []
196
- @step_definitions.each do |step_definition|
197
- dead_steps << step_definition if step_definition.calls.empty?
198
- end
199
- dead_steps
200
- end
201
-
202
- def sort_by_score(array)
203
- array.sort_by { |item| item.score }.reverse
204
- end
205
-
206
- def extract_markup
207
- markup_location = File.join(File.dirname(__FILE__), 'report', 'markup.rhtml')
208
- markup = ""
209
- File.open(markup_location).lines.each do |line|
210
- markup << line
211
- end
212
- markup
213
- end
214
-
215
- def output_html(file_name = "cuke_sniffer_results.html", cuke_sniffer = self)
216
- @features = sort_by_score(@features)
217
- @step_definitions = sort_by_score(@step_definitions)
218
-
219
- markup_erb = ERB.new extract_markup
220
- output = markup_erb.result(binding)
221
- File.open(file_name, 'w') do |f|
222
- f.write(output)
223
- end
224
- end
225
- end
226
- end
1
+ require 'erb'
2
+
3
+ module CukeSniffer
4
+ class CLI
5
+ include CukeSniffer::Constants
6
+
7
+ attr_accessor :features_location,:step_definitions_location, :features, :scenarios, :step_definitions, :summary
8
+
9
+ def initialize(features_location = Dir.getwd, step_definitions_location = Dir.getwd)
10
+ @features_location = features_location
11
+ @step_definitions_location = step_definitions_location
12
+ @features = []
13
+ @scenarios = []
14
+ @step_definitions = []
15
+
16
+ puts "\nFeatures:"
17
+ unless features_location.nil?
18
+ if File.file?(features_location)
19
+ @features = [CukeSniffer::Feature.new(features_location)]
20
+ else
21
+ build_file_list_from_folder(features_location, ".feature").each { |location|
22
+ @features << CukeSniffer::Feature.new(location)
23
+ print '.'
24
+ }
25
+ end
26
+ end
27
+
28
+ @scenarios = get_all_scenarios(@features)
29
+
30
+ puts("\nStep Definitions:")
31
+ unless step_definitions_location.nil?
32
+ if File.file?(step_definitions_location)
33
+ @step_definitions = [build_step_definitions(step_definitions_location)]
34
+ else
35
+ build_file_list_from_folder(step_definitions_location, ".rb").each { |location|
36
+ @step_definitions << build_step_definitions(location)
37
+ print '.'
38
+ }
39
+ end
40
+ end
41
+
42
+ @step_definitions.flatten!
43
+ @summary = {
44
+ :total_score => 0,
45
+ :features => {},
46
+ :step_definitions => {},
47
+ :improvement_list => {}
48
+ }
49
+ puts "\nCataloging Step Calls: "
50
+ catalog_step_calls
51
+ puts "\nAssessing Score: "
52
+ assess_score
53
+ end
54
+
55
+ def good?
56
+ @summary[:total_score] <= Constants::THRESHOLDS["Project"]
57
+ end
58
+
59
+ def problem_percentage
60
+ @summary[:total_score].to_f / Constants::THRESHOLDS["Project"].to_f
61
+ end
62
+
63
+ def build_file_list_from_folder(folder_name, extension)
64
+ list = []
65
+ Dir.entries(folder_name).each_entry do |file_name|
66
+ unless FILE_IGNORE_LIST.include?(file_name)
67
+ file_name = "#{folder_name}/#{file_name}"
68
+ if File.directory?(file_name)
69
+ list << build_file_list_from_folder(file_name, extension)
70
+ elsif file_name.downcase.include?(extension)
71
+ list << file_name
72
+ end
73
+ end
74
+ end
75
+ list.flatten
76
+ end
77
+
78
+ def build_step_definitions(file_name)
79
+ step_file_lines = []
80
+ step_file = File.open(file_name)
81
+ step_file.each_line { |line| step_file_lines << line }
82
+ step_file.close
83
+
84
+ counter = 0
85
+ step_code = []
86
+ step_definitions = []
87
+ found_first_step = false
88
+ until counter >= step_file_lines.length
89
+ if step_file_lines[counter] =~ STEP_DEFINITION_REGEX and !step_code.empty? and found_first_step
90
+ step_definitions << CukeSniffer::StepDefinition.new("#{file_name}:#{counter+1 - step_code.count}", step_code)
91
+ step_code = []
92
+ end
93
+ found_first_step = true if step_file_lines[counter] =~ STEP_DEFINITION_REGEX
94
+ step_code << step_file_lines[counter].strip
95
+ counter+=1
96
+ end
97
+ step_definitions << CukeSniffer::StepDefinition.new("#{file_name}:#{counter+1}", step_code) unless step_code.empty? or !found_first_step
98
+ step_definitions
99
+ end
100
+
101
+ def assess_array(array, type)
102
+ min, max, min_file, max_file = nil
103
+ total = 0
104
+ good = 0
105
+ bad = 0
106
+ total_score = 0
107
+ array.each do |node|
108
+ score = node.score
109
+ @summary[:total_score] += score
110
+ total_score += score
111
+ node.rules_hash.each_key do |key|
112
+ @summary[:improvement_list][key] ||= 0
113
+ @summary[:improvement_list][key] += node.rules_hash[key]
114
+ end
115
+ min, min_file = score, node.location if (min.nil? or score < min)
116
+ max, max_file = score, node.location if (max.nil? or score > max)
117
+ if node.good?
118
+ good += 1
119
+ else
120
+ bad += 1
121
+ end
122
+ total += score
123
+ end
124
+ {
125
+ :total => array.count,
126
+ :total_score => total_score,
127
+ :min => min,
128
+ :min_file => min_file,
129
+ :max => max,
130
+ :max_file => max_file,
131
+ :average => (total.to_f/array.count.to_f).round(2),
132
+ :threshold => THRESHOLDS[type],
133
+ :good => good,
134
+ :bad => bad,
135
+ }
136
+ end
137
+
138
+ def assess_score
139
+ @summary[:features] = assess_array(@features, "Feature")
140
+ @summary[:scenarios] = assess_array(@scenarios, "Scenario")
141
+ @summary[:step_definitions] = assess_array(@step_definitions, "StepDefinition") unless @step_definitions.empty?
142
+ sort_improvement_list
143
+ end
144
+
145
+ def get_all_scenarios(features)
146
+ scenarios = []
147
+ features.each do |feature|
148
+ scenarios << feature.background unless feature.background.nil?
149
+ scenarios << feature.scenarios
150
+ end
151
+ scenarios.flatten
152
+ end
153
+
154
+ def sort_improvement_list
155
+ sorted_array = @summary[:improvement_list].sort_by { |improvement, occurrence| occurrence }
156
+ @summary[:improvement_list] = {}
157
+ sorted_array.reverse.each { |node|
158
+ @summary[:improvement_list][node[0]] = node[1]
159
+ }
160
+ end
161
+
162
+ def output_results
163
+ feature_results = @summary[:features]
164
+ step_definition_results = @summary[:step_definitions]
165
+ output = "Suite Summary
166
+ Total Score: #{@summary[:total_score]}
167
+ Features (#@features_location)
168
+ Min: #{feature_results[:min]} (#{feature_results[:min_file]})
169
+ Max: #{feature_results[:max]} (#{feature_results[:max_file]})
170
+ Average: #{feature_results[:average]}
171
+ Step Definitions (#@step_definitions_location)
172
+ Min: #{step_definition_results[:min]} (#{step_definition_results[:min_file]})
173
+ Max: #{step_definition_results[:max]} (#{step_definition_results[:max_file]})
174
+ Average: #{step_definition_results[:average]}
175
+ Improvements to make:"
176
+ create_improvement_list.each { |item| output << "\n #{item}" }
177
+ output
178
+ end
179
+
180
+ def create_improvement_list
181
+ output = []
182
+ @summary[:improvement_list].each_key { |improvement| output << "(#{summary[:improvement_list][improvement]})#{improvement}" }
183
+ output
184
+ end
185
+
186
+ def get_all_steps
187
+ steps = {}
188
+ @features.each do |feature|
189
+ feature.scenarios.each do |scenario|
190
+ counter = 1
191
+ scenario.steps.each do |step|
192
+ location = scenario.location.gsub(/:\d*$/, ":#{scenario.start_line + counter}")
193
+ steps[location] = step
194
+ counter += 1
195
+ end
196
+ end
197
+ end
198
+ @step_definitions.each do |definition|
199
+ definition.nested_steps.each_key do |key|
200
+ steps[key] = definition.nested_steps[key]
201
+ end
202
+ end
203
+ steps
204
+ end
205
+
206
+ def catalog_step_calls
207
+ steps = get_all_steps
208
+ @step_definitions.each do |step_definition|
209
+ print '.'
210
+ calls = steps.find_all { |location, step| step.gsub(STEP_STYLES, "") =~ step_definition.regex }
211
+ calls.each { |call|
212
+ step_definition.add_call(call[0], call[1].gsub(STEP_STYLES, ""))
213
+ }
214
+ end
215
+ end
216
+
217
+ def get_dead_steps
218
+ dead_steps = []
219
+ @step_definitions.each do |step_definition|
220
+ dead_steps << step_definition if step_definition.calls.empty?
221
+ end
222
+
223
+ dead_steps.sort_by{|step| step.location}
224
+ end
225
+
226
+ def extract_markup
227
+ markup_location = File.join(File.dirname(__FILE__), 'report', 'markup.rhtml')
228
+ markup = ""
229
+ File.open(markup_location).lines.each do |line|
230
+ markup << line
231
+ end
232
+ markup
233
+ end
234
+
235
+ def output_html(file_name = "cuke_sniffer_results.html", cuke_sniffer = self)
236
+ @features = @features.sort_by { |feature| feature.total_score }.reverse
237
+ @step_definitions = @step_definitions.sort_by { |step_definition| step_definition.score }.reverse
238
+
239
+ markup_erb = ERB.new extract_markup
240
+ output = markup_erb.result(binding)
241
+ File.open(file_name, 'w') do |f|
242
+ f.write(output)
243
+ end
244
+ end
245
+ end
246
+ end