cuke_sniffer 0.0.8 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,96 +1,131 @@
1
- <div class="title" onclick="toggleById('summary_data', this)">
2
- Summary -
3
- </div>
4
- <div class="shrink_section" style="display: block;" id="summary_data">
5
- <% data_symbols = [:features, :scenarios, :step_definitions, :hooks] %>
6
- <table style="padding-left:2px; width: 100%;" class="notes" border="0" cellspacing="0">
7
- <tr class="divide_row">
8
- <td class="table_top"></td>
9
- <td class="table_top">Features</td>
10
- <td class="table_top">Scenarios</td>
11
- <td class="table_top">Step Definitions</td>
12
- <td class="table_top">Hooks</td>
13
- </tr>
14
- <tr class="blue_row">
15
- <td>
16
- Total Score
17
- <a title="Total Points for a section." class="help">(?)</a>
18
- </td>
19
- <% data_symbols.each do |symbol| %>
20
- <td>
21
- <%= cuke_sniffer.summary[symbol][:total_score] %>
22
- </td>
23
- <% end %>
24
- </tr>
25
- <tr>
26
- <td>
27
- Count
28
- <a title="Total Number of objects found in the project." class="help" class="help">(?)</a>
29
- </td>
30
- <% data_symbols.each do |symbol| %>
31
- <td><%= cuke_sniffer.summary[symbol][:total].inspect %></td>
32
- <% end %>
33
- </tr>
34
- <tr/>
35
- <tr class="blue_row">
36
- <td>
37
- Lowest Score
38
- <a title="Score of the best object found." class="help">(?)</a>
39
- </td>
40
- <% data_symbols.each do |symbol| %>
41
- <td><%= cuke_sniffer.summary[symbol][:min] %></td>
42
- <% end %>
43
- </tr>
44
- <tr>
45
- <td>
46
- Highest Score
47
- <a title="Score of the object with the most to improve on." class="help">(?)</a>
48
- </td>
49
- <% data_symbols.each do |symbol| %>
50
- <td><%= cuke_sniffer.summary[symbol][:max] %></td>
51
- <% end %>
52
- </tr>
53
- <tr class="blue_row">
54
- <td>
55
- Average Score
56
- <a title="Average score of a section." class="help">(?)</a>
57
- </td>
58
- <% data_symbols.each do |symbol| %>
59
- <td><%= cuke_sniffer.summary[symbol][:average] %></td>
60
- <% end %>
61
- </tr>
62
- <tr/>
63
- <tr>
64
- <td>
65
- Threshold
66
- <a title="The maximum score an object can have to be considered good." class="help">(?)</a>
67
- </td>
68
- <% data_symbols.each do |symbol| %>
69
- <td><%= cuke_sniffer.summary[symbol][:threshold] %></td>
70
- <% end %>
71
- </tr>
72
- <tr class="blue_row">
73
- <td>
74
- Good
75
- <a title="Percentage of the objects that can be considered good in the project." class="help">(?)</a>
76
- </td>
77
- <% data_symbols.each do |symbol| %>
78
- <td><%= ((cuke_sniffer.summary[symbol][:good].to_f/cuke_sniffer.summary[symbol][:total].to_f) * 100).round(2) %>
79
- %
80
- </td>
81
- <% end %>
82
- </tr>
83
- <tr>
84
- <td>
85
- Bad
86
- <a title="Percentage of the objects that can be considered bad in the project." class="help">(?)</a>
87
- </td>
88
- <% data_symbols.each do |symbol| %>
89
- <td><%= ((cuke_sniffer.summary[symbol][:bad].to_f/cuke_sniffer.summary[symbol][:total].to_f) * 100).round(2) %>
90
- %
91
- </td>
92
- <% end %>
93
- </tr>
94
- </table>
95
- </div>
96
- <br style="clear:both">
1
+ <div class="row">
2
+ <div id="summaryPanel" class="panel panel-default">
3
+ <div class="panel-heading panel-title" data-toggle="collapse" data-target="#summaryTable">
4
+ Summary <span class="glyphicon glyphicon-menu-up"></span>
5
+ </div>
6
+ <% data_symbols = [:features, :scenarios, :step_definitions, :hooks] %>
7
+ <table id="summaryTable" class="table table-responsive table-striped collapse in">
8
+ <tr>
9
+ <td></td>
10
+ <td>
11
+ <span class="full-page">Features</span>
12
+ <span class="small-page" title="Features">F</span>
13
+ </td>
14
+ <td>
15
+ <span class="full-page">Scenarios</span>
16
+ <span class="small-page" title="Scenarios">S</span>
17
+ </td>
18
+ <td>
19
+ <span class="full-page">Step Definitions</span>
20
+ <span class="small-page" title="Step Definitions">S.D.</span>
21
+ </td>
22
+ <td>
23
+ <span class="full-page">Hooks</span>
24
+ <span class="small-page" title="Hooks">H</span>
25
+ </td>
26
+ </tr>
27
+ <tr>
28
+ <td>
29
+ Total Score
30
+ <span title="Total Points for a section." class="glyphicon glyphicon-question-sign"
31
+ data-toggle="tooltip" data-placement="right"></span>
32
+ </td>
33
+ <% data_symbols.each do |symbol| %>
34
+ <td>
35
+ <%= cuke_sniffer.summary[symbol][:total_score] %>
36
+ </td>
37
+ <% end %>
38
+ </tr>
39
+ <tr>
40
+ <td>
41
+ Count
42
+ <span title="Total Number of objects found in the project." class="glyphicon glyphicon-question-sign"
43
+ data-toggle="tooltip" data-placement="right"></span>
44
+ </td>
45
+ <% data_symbols.each do |symbol| %>
46
+ <td><%= cuke_sniffer.summary[symbol][:total].inspect %></td>
47
+ <% end %>
48
+ </tr>
49
+ <tr>
50
+ <td>
51
+ Lowest Score
52
+ <span title="Score of the best object found." class="glyphicon glyphicon-question-sign"
53
+ data-toggle="tooltip" data-placement="right"></span>
54
+ </td>
55
+ <% data_symbols.each do |symbol| %>
56
+ <td><%= cuke_sniffer.summary[symbol][:min] %></td>
57
+ <% end %>
58
+ </tr>
59
+ <tr>
60
+ <td>
61
+ Highest Score
62
+ <span title="Score of the object with the most to improve on." class="glyphicon glyphicon-question-sign"
63
+ data-toggle="tooltip" data-placement="right"></span>
64
+ </td>
65
+ <% data_symbols.each do |symbol| %>
66
+ <td><%= cuke_sniffer.summary[symbol][:max] %></td>
67
+ <% end %>
68
+ </tr>
69
+ <tr>
70
+ <td>
71
+ Average Score
72
+ <span title="Average score of a section." class="glyphicon glyphicon-question-sign"
73
+ data-toggle="tooltip" data-placement="right"></span>
74
+ </td>
75
+ <% data_symbols.each do |symbol| %>
76
+ <td>
77
+ <% if cuke_sniffer.summary[symbol][:average].nan?%>
78
+ 0
79
+ <% else %>
80
+ <%= cuke_sniffer.summary[symbol][:average] %>
81
+ <% end %>
82
+ </td>
83
+ <% end %>
84
+ </tr>
85
+ <tr>
86
+ <td>
87
+ Threshold
88
+ <span title="The maximum score an object can have to be considered good." class="glyphicon glyphicon-question-sign"
89
+ data-toggle="tooltip" data-placement="right"></span>
90
+ </td>
91
+ <% data_symbols.each do |symbol| %>
92
+ <td><%= cuke_sniffer.summary[symbol][:threshold] %></td>
93
+ <% end %>
94
+ </tr>
95
+ <tr>
96
+ <td>
97
+ Good
98
+ <span title="Percentage of the objects that can be considered good in the project."
99
+ class="glyphicon glyphicon-question-sign" data-toggle="tooltip" data-placement="right"></span>
100
+ </td>
101
+ <% data_symbols.each do |symbol| %>
102
+ <td>
103
+ <% if cuke_sniffer.summary[symbol][:good] == 0 %>
104
+ 0
105
+ <% else %>
106
+ <%= ((cuke_sniffer.summary[symbol][:good].to_f/cuke_sniffer.summary[symbol][:total].to_f) * 100).round(2) %>
107
+ <% end %>
108
+ %
109
+ </td>
110
+ <% end %>
111
+ </tr>
112
+ <tr>
113
+ <td>
114
+ Bad
115
+ <span title="Percentage of the objects that can be considered bad in the project."
116
+ class="glyphicon glyphicon-question-sign" data-toggle="tooltip" data-placement="right"></span>
117
+ </td>
118
+ <% data_symbols.each do |symbol| %>
119
+ <td>
120
+ <% if cuke_sniffer.summary[symbol][:bad] == 0 %>
121
+ 0
122
+ <% else %>
123
+ <%= ((cuke_sniffer.summary[symbol][:bad].to_f/cuke_sniffer.summary[symbol][:total].to_f) * 100).round(2) %>
124
+ <% end %>
125
+ %
126
+ </td>
127
+ <% end %>
128
+ </tr>
129
+ </table>
130
+ </div>
131
+ </div>
@@ -1,9 +1,13 @@
1
- <div style="font-family: Arial; float: left; color: #509f50; font-size: 20px; font-weight: bold; padding-bottom: 1px;">
2
- Cuke Sniffer
3
- </div>
4
- <br style="clear:both">
5
- <div style="border-top: 2px solid #509f50; text-align: right;">
6
- <div style="font-family: Arial;border-bottom-left-radius: 15px; border-bottom-right-radius: 15px;float: right; background-color:#509f50; color:white;padding-left:40px;font-size:11pt;font-weight:bold;padding-right:10px;">
7
- Score: <%= cuke_sniffer.summary[:total_score] %></div>
8
- </div>
9
- <br style="clear:both">
1
+ <div class="row">
2
+ <div class="page-header">
3
+ <h1>
4
+ Cuke Sniffer <a class="black" target="_blank" href="https://github.com/r-cochran/cuke_sniffer"><span class="fa fa-github"></span></a>
5
+ <% if Gem.loaded_specs["cuke_sniffer"] %>
6
+ <small><%= Gem.loaded_specs["cuke_sniffer"].version %></small>
7
+ <% end %>
8
+ </h1>
9
+ <div>Score:
10
+ <span class="score"><%= cuke_sniffer.summary[:total_score] %></span>
11
+ </div>
12
+ </div>
13
+ </div>
@@ -7,6 +7,7 @@ module CukeSniffer
7
7
  # Mixins: ROXML
8
8
  class Rule
9
9
  include ROXML
10
+ xml_accessor :symbol
10
11
  xml_accessor :enabled
11
12
  xml_accessor :phrase
12
13
  xml_accessor :score
@@ -275,12 +275,12 @@ module CukeSniffer
275
275
  },
276
276
  :feature_same_tag => {
277
277
  :enabled => true,
278
- :phrase => "Same tag appears on Feature.",
278
+ :phrase => "Same tag appears on both Feature and Scenario",
279
279
  :score => WARNING,
280
280
  :targets => ["Feature"],
281
281
  :reason => lambda { |feature, rule| if(feature.scenarios.count >= 2)
282
282
  feature.scenarios[1..-1].each do |scenario|
283
- feature.scenarios.first.tags.each do |tag|
283
+ feature.tags.each do |tag|
284
284
  feature.store_rule(rule) if scenario.tags.include?(tag)
285
285
  end
286
286
  end
@@ -29,8 +29,7 @@ module CukeSniffer
29
29
  judge_object(feature, "Feature")
30
30
  judge_object(feature.background, "Background") unless feature.background.nil?
31
31
  judge_objects(feature.scenarios, "Scenario")
32
- feature.total_score += feature.update_score
33
-
32
+ feature.update_score
34
33
  end
35
34
 
36
35
  def judge_objects(objects, type)
@@ -83,41 +83,85 @@ module CukeSniffer
83
83
  private
84
84
 
85
85
  def split_scenario(scenario)
86
+ ranges = define_ranges(scenario)
87
+ split_tag_list(ranges[:tags])
88
+ split_name_and_type(ranges[:name].join(" "))
89
+ split_scenario_body(ranges[:body])
90
+ split_examples(ranges[:examples]) unless ranges[:examples].nil?
91
+ end
92
+
93
+ def define_ranges(scenario)
94
+ ranges = {}
86
95
  index = 0
87
- until index >= scenario.length or scenario[index] =~ SCENARIO_TITLE_STYLES
88
- update_tag_list(scenario[index])
89
- index += 1
96
+ index += 1 until index >= scenario.length or scenario[index] =~ SCENARIO_TITLE_STYLES
97
+ ranges[:tags] = scenario[0...index]
98
+
99
+ start_index = index
100
+ index += 1 until index >= scenario.length or scenario[index].match STEP_REGEX or scenario[index].include?("Examples:")
101
+ ranges[:name] = scenario[start_index...index]
102
+
103
+ start_index = index
104
+ index += 1 until index >= scenario.length or scenario[index].include?("Examples:")
105
+ ranges[:body] = scenario[start_index...index]
106
+
107
+ ranges[:examples] = scenario[index + 1..scenario.size] if index < scenario.length and scenario[index].include?("Examples:")
108
+ ranges
109
+ end
110
+
111
+ def split_tag_list(list_of_tag_lines)
112
+ list_of_tag_lines.each do |line|
113
+ update_tag_list(line)
90
114
  end
115
+ end
91
116
 
92
- until index >= scenario.length or scenario[index].match STEP_REGEX or scenario[index].include?("Examples:")
93
- match = scenario[index].match(SCENARIO_TITLE_STYLES)
94
- @type = match[:type] unless match.nil?
95
- create_name(scenario[index], SCENARIO_TITLE_STYLES)
96
- index += 1
117
+ def split_name_and_type(name_section)
118
+ match = name_section.match(SCENARIO_TITLE_STYLES)
119
+ @type = match[:type] unless match.nil?
120
+ create_name(name_section, SCENARIO_TITLE_STYLES)
121
+ end
122
+
123
+ def split_scenario_body(scenario_body)
124
+ extract_steps(scenario_body)
125
+ extract_inline_tables(scenario_body)
126
+ end
127
+
128
+ def extract_steps(scenario_body)
129
+ scenario_body.each do |line|
130
+ next if line =~ /^\|.*\|/ or line.empty? or line.match(STEP_REGEX).nil?
131
+ @steps << line
97
132
  end
133
+ end
98
134
 
99
- until index >= scenario.length or scenario[index].include?("Examples:")
100
- if scenario[index] =~ /^\|.*\|/
101
- step = scenario[index - 1]
102
- @inline_tables[step] = []
103
- until index >= scenario.length or scenario[index] =~ /(#{STEP_REGEX}|^\s*Examples:)/
104
- @inline_tables[step] << scenario[index]
135
+ def extract_inline_tables(scenario_body)
136
+ index = 0
137
+ while index < scenario_body.size
138
+ if scenario_body[index] =~ /^\|.*\|/
139
+ start_index = index
140
+ while index < scenario_body.size and scenario_body[index] =~ /^\|.*\|/
105
141
  index += 1
106
142
  end
107
- else
108
- @steps << scenario[index] if scenario[index] =~ STEP_REGEX
109
- index += 1
143
+ @inline_tables[scenario_body[start_index-1]] = scenario_body[start_index..index]
110
144
  end
145
+ index += 1
111
146
  end
147
+ end
112
148
 
113
- if index < scenario.length and scenario[index].include?("Examples:")
149
+ def split_examples(examples_section)
150
+ remove_examples_declaration(examples_section).each do |line|
151
+ next if line.include?("Examples:")
152
+ @examples_table << line if line =~ /#{COMMENT_REGEX}\|.*\|/
153
+ end
154
+ end
155
+
156
+ def remove_examples_declaration(examples_section)
157
+ return_section = []
158
+ index = 0
159
+ while index < examples_section.size
160
+ index += 2 if(examples_section[index].include?("Examples:"))
161
+ return_section << examples_section[index]
114
162
  index += 1
115
- until index >= scenario.length
116
- index += 2 if scenario[index].include?("Examples:")
117
- @examples_table << scenario[index] if scenario[index] =~ /#{COMMENT_REGEX}\|.*\|/
118
- index += 1
119
- end
120
163
  end
164
+ return_section
121
165
  end
122
166
  end
123
167
  end
@@ -1,91 +1,91 @@
1
- module CukeSniffer
2
- # Author:: Robert Cochran (mailto:cochrarj@miamioh.edu)
3
- # Copyright:: Copyright (C) 2014 Robert Cochran
4
- # License:: Distributes under the MIT License
5
- # Mixins: CukeSniffer::Constants
6
- # A static class used to help with handling summary data for CukeSniffer::CLI
7
- class SummaryHelper
8
- include CukeSniffer::Constants
9
-
10
- # Sorts the list of improvements in descending order of times found.
11
- def self.sort_improvement_list(improvement_list)
12
- sorted_array = improvement_list.sort_by { |improvement, occurrence| occurrence }.reverse
13
- sorted_improvement_list = {}
14
- sorted_array.each { |node|
15
- sorted_improvement_list[node[0]] = node[1]
16
- }
17
- sorted_improvement_list
18
- end
19
-
20
- # Builds a default assessment hash.
21
- def self.make_assessment_hash
22
- {
23
- :total => 0,
24
- :total_score => 0,
25
- :min => nil,
26
- :min_file => nil,
27
- :max => nil,
28
- :max_file => nil,
29
- :average => 0,
30
- :threshold => nil,
31
- :good => 0,
32
- :bad => 0,
33
- :improvement_list => {}
34
- }
35
- end
36
-
37
- # Initializes an assessment hash for the rule target list
38
- def self.initialize_assessment_hash(rule_target_list, type)
39
- assessment_hash = make_assessment_hash
40
- assessment_hash[:total] = rule_target_list.count
41
- assessment_hash[:threshold] = THRESHOLDS[type]
42
-
43
- unless rule_target_list.empty?
44
- score = rule_target_list.first.score
45
- location = rule_target_list.first.location
46
- assessment_hash[:min] = score
47
- assessment_hash[:min_file] = location
48
- assessment_hash[:max] = score
49
- assessment_hash[:max_file] = location
50
- end
51
- assessment_hash
52
- end
53
-
54
- # Returns a summary hash for the rule_target_list
55
- def self.assess_rule_target_list(rule_target_list, type)
56
- assessment_hash = initialize_assessment_hash(rule_target_list, type)
57
- rule_target_list.each do |rule_target|
58
- score = rule_target.score
59
- assessment_hash[:total_score] += score
60
- assessment_hash[rule_target.good? ? :good : :bad] += 1
61
- if score < assessment_hash[:min]
62
- assessment_hash[:min] = score
63
- assessment_hash[:min_file] = rule_target.location
64
- end
65
- if score > assessment_hash[:max]
66
- assessment_hash[:max] = score
67
- assessment_hash[:max_file] = rule_target.location
68
- end
69
- rule_target.rules_hash.each_key do |key|
70
- assessment_hash[:improvement_list][key] ||= 0
71
- assessment_hash[:improvement_list][key] += rule_target.rules_hash[key]
72
- end
73
- end
74
- assessment_hash[:average] = (assessment_hash[:total_score].to_f/rule_target_list.count.to_f).round(2)
75
- assessment_hash
76
- end
77
-
78
- # Returns a CukeSniffer::SummaryNode object for the passed hash
79
- def self.load_summary_data(summary_hash)
80
- summary_node = SummaryNode.new
81
- summary_node.count = summary_hash[:total]
82
- summary_node.score = summary_hash[:total_score]
83
- summary_node.average = summary_hash[:average]
84
- summary_node.threshold = summary_hash[:threshold]
85
- summary_node.good = summary_hash[:good]
86
- summary_node.bad = summary_hash[:bad]
87
- summary_node
88
- end
89
-
90
- end
1
+ module CukeSniffer
2
+ # Author:: Robert Cochran (mailto:cochrarj@miamioh.edu)
3
+ # Copyright:: Copyright (C) 2014 Robert Cochran
4
+ # License:: Distributes under the MIT License
5
+ # Mixins: CukeSniffer::Constants
6
+ # A static class used to help with handling summary data for CukeSniffer::CLI
7
+ class SummaryHelper
8
+ include CukeSniffer::Constants
9
+
10
+ # Sorts the list of improvements in descending order of times found.
11
+ def self.sort_improvement_list(improvement_list)
12
+ sorted_array = improvement_list.sort_by { |improvement, occurrence| occurrence }.reverse
13
+ sorted_improvement_list = {}
14
+ sorted_array.each { |node|
15
+ sorted_improvement_list[node[0]] = node[1]
16
+ }
17
+ sorted_improvement_list
18
+ end
19
+
20
+ # Builds a default assessment hash.
21
+ def self.make_assessment_hash
22
+ {
23
+ :total => 0,
24
+ :total_score => 0,
25
+ :min => nil,
26
+ :min_file => nil,
27
+ :max => nil,
28
+ :max_file => nil,
29
+ :average => 0,
30
+ :threshold => nil,
31
+ :good => 0,
32
+ :bad => 0,
33
+ :improvement_list => {}
34
+ }
35
+ end
36
+
37
+ # Initializes an assessment hash for the rule target list
38
+ def self.initialize_assessment_hash(rule_target_list, type)
39
+ assessment_hash = make_assessment_hash
40
+ assessment_hash[:total] = rule_target_list.count
41
+ assessment_hash[:threshold] = THRESHOLDS[type]
42
+
43
+ unless rule_target_list.empty?
44
+ score = rule_target_list.first.score
45
+ location = rule_target_list.first.location
46
+ assessment_hash[:min] = score
47
+ assessment_hash[:min_file] = location
48
+ assessment_hash[:max] = score
49
+ assessment_hash[:max_file] = location
50
+ end
51
+ assessment_hash
52
+ end
53
+
54
+ # Returns a summary hash for the rule_target_list
55
+ def self.assess_rule_target_list(rule_target_list, type)
56
+ assessment_hash = initialize_assessment_hash(rule_target_list, type)
57
+ rule_target_list.each do |rule_target|
58
+ score = rule_target.score
59
+ assessment_hash[:total_score] += score
60
+ assessment_hash[rule_target.good? ? :good : :bad] += 1
61
+ if score < assessment_hash[:min]
62
+ assessment_hash[:min] = score
63
+ assessment_hash[:min_file] = rule_target.location
64
+ end
65
+ if score > assessment_hash[:max]
66
+ assessment_hash[:max] = score
67
+ assessment_hash[:max_file] = rule_target.location
68
+ end
69
+ rule_target.rules_hash.each_key do |key|
70
+ assessment_hash[:improvement_list][key] ||= 0
71
+ assessment_hash[:improvement_list][key] += rule_target.rules_hash[key]
72
+ end
73
+ end
74
+ assessment_hash[:average] = (assessment_hash[:total_score].to_f/rule_target_list.count.to_f).round(2)
75
+ assessment_hash
76
+ end
77
+
78
+ # Returns a CukeSniffer::SummaryNode object for the passed hash
79
+ def self.load_summary_data(summary_hash)
80
+ summary_node = SummaryNode.new
81
+ summary_node.count = summary_hash[:total]
82
+ summary_node.score = summary_hash[:total_score]
83
+ summary_node.average = summary_hash[:average]
84
+ summary_node.threshold = summary_hash[:threshold]
85
+ summary_node.good = summary_hash[:good]
86
+ summary_node.bad = summary_hash[:bad]
87
+ summary_node
88
+ end
89
+
90
+ end
91
91
  end