cuke_sniffer 0.0.5 → 0.0.6
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 +85 -63
- data/lib/cuke_sniffer.rb +23 -16
- data/lib/cuke_sniffer/cli.rb +269 -523
- data/lib/cuke_sniffer/constants.rb +5 -2
- data/lib/cuke_sniffer/cuke_sniffer_helper.rb +165 -0
- data/lib/cuke_sniffer/dead_steps_helper.rb +54 -0
- data/lib/cuke_sniffer/feature.rb +13 -81
- data/lib/cuke_sniffer/feature_rules_evaluator.rb +56 -115
- data/lib/cuke_sniffer/formatter.rb +142 -0
- data/lib/cuke_sniffer/hook.rb +77 -160
- data/lib/cuke_sniffer/report/dead_steps.html.erb +36 -0
- data/lib/cuke_sniffer/report/features.html.erb +60 -0
- data/lib/cuke_sniffer/report/hooks.html.erb +49 -0
- data/lib/cuke_sniffer/report/improvement_list.html.erb +18 -0
- data/lib/cuke_sniffer/report/legend.html.erb +167 -0
- data/lib/cuke_sniffer/report/min_template.html.erb +125 -0
- data/lib/cuke_sniffer/report/rules.html.erb +9 -0
- data/lib/cuke_sniffer/report/standard_template.html.erb +137 -0
- data/lib/cuke_sniffer/report/step_definitions.html.erb +49 -0
- data/lib/cuke_sniffer/report/sub_rules.html.erb +24 -0
- data/lib/cuke_sniffer/report/summary.html.erb +71 -0
- data/lib/cuke_sniffer/rule.rb +28 -0
- data/lib/cuke_sniffer/rule_config.rb +241 -48
- data/lib/cuke_sniffer/rule_target.rb +62 -0
- data/lib/cuke_sniffer/rules_evaluator.rb +65 -70
- data/lib/cuke_sniffer/scenario.rb +102 -238
- data/lib/cuke_sniffer/step_definition.rb +163 -239
- data/lib/cuke_sniffer/summary_helper.rb +91 -0
- data/lib/cuke_sniffer/summary_node.rb +19 -0
- metadata +23 -5
- data/lib/cuke_sniffer/report/markup.rhtml +0 -353
@@ -0,0 +1,49 @@
|
|
1
|
+
<div class="title" onclick="toggleById('hooks_data', this)">
|
2
|
+
Hooks +
|
3
|
+
</div>
|
4
|
+
<div class="shrink_section" id="hooks_data">
|
5
|
+
<% if cuke_sniffer.hooks.count == 0 %>
|
6
|
+
<div class="empty_set_message">There were no Hooks to sniff in '<%= cuke_sniffer.hooks_location %>'!</div>
|
7
|
+
<% elsif cuke_sniffer.hooks.count >= 1 && cuke_sniffer.summary[:hooks][:total_score] ==0 %>
|
8
|
+
<div class="empty_set_message">Excellent! No smells found for Hooks!</div>
|
9
|
+
<% end %>
|
10
|
+
<% index = 0 %>
|
11
|
+
<% cuke_sniffer.hooks.each do |hook| %>
|
12
|
+
<% next if hook.score <= 0 %>
|
13
|
+
<div style="cursor: pointer; padding-top: 3px" onclick="updateDisplayStatus(document.getElementById('hook_<%=index%>'))">
|
14
|
+
<div class="red_number" style="float:left"><%= hook.score %></div>
|
15
|
+
<% tags = "(" %>
|
16
|
+
<% hook.tags.each do |tag| %>
|
17
|
+
<% tags << tag %>
|
18
|
+
<% tags << ", " unless tag == hook.tags.last %>
|
19
|
+
<% end %>
|
20
|
+
<% tags += ")" %>
|
21
|
+
<% parameters = "| " %>
|
22
|
+
<% hook.parameters.each do |parameter| %>
|
23
|
+
<% parameters << parameter %>
|
24
|
+
<% parameters << ", " unless parameter == hook.parameters.last %>
|
25
|
+
<% end %>
|
26
|
+
<% parameters += " |" %>
|
27
|
+
<% name = hook.type %>
|
28
|
+
<% name += tags unless tags == "()" %>
|
29
|
+
<% name += " do " %>
|
30
|
+
<% name += parameters unless parameters == "| |" %>
|
31
|
+
<div class="notes"><%= name %></div>
|
32
|
+
</div>
|
33
|
+
<div id="hook_<%= index %>" style="display:none;">
|
34
|
+
<div class="sub_section" style="display:block;">
|
35
|
+
<div style="text-indent: 4%; float: left; width: 45%; border-right: 2px solid #add8e6;">
|
36
|
+
<% hook.rules_hash.each_key do |rule| %>
|
37
|
+
<pre style="margin: 0;"><%= rule %></pre>
|
38
|
+
<% end %>
|
39
|
+
</div>
|
40
|
+
<div style="text-indent: 1%">
|
41
|
+
<%= hook.location.gsub(cuke_sniffer.hooks_location, "") %>
|
42
|
+
</div>
|
43
|
+
<br style="clear:both">
|
44
|
+
</div>
|
45
|
+
</div>
|
46
|
+
<% index += 1 %>
|
47
|
+
<% end %>
|
48
|
+
</div>
|
49
|
+
<br style="clear:both">
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<div class="title" onclick="toggleById('improvement_list_data', this)">
|
2
|
+
Improvement List +
|
3
|
+
</div>
|
4
|
+
<div class="shrink_section" id="improvement_list_data">
|
5
|
+
<% improvement_list = cuke_sniffer.summary[:improvement_list] %>
|
6
|
+
<% if improvement_list.empty? %>
|
7
|
+
<div class="empty_set_message">No Improvements to make!</div>
|
8
|
+
<% end %>
|
9
|
+
<table style="width: 100%">
|
10
|
+
<% improvement_list.each do |improvement, count| %>
|
11
|
+
<tr>
|
12
|
+
<td class="red_number"><%= count %></td>
|
13
|
+
<td class="notes"><%= improvement %></td>
|
14
|
+
</tr>
|
15
|
+
<% end %>
|
16
|
+
</table>
|
17
|
+
</div>
|
18
|
+
<br style="clear:both">
|
@@ -0,0 +1,167 @@
|
|
1
|
+
<style>
|
2
|
+
.legend_header {
|
3
|
+
font-weight: bold;
|
4
|
+
width: 10%;
|
5
|
+
vertical-align:text-top;
|
6
|
+
border-bottom: 2px solid #add8e6;
|
7
|
+
}
|
8
|
+
.legend_description {
|
9
|
+
border-bottom: 2px solid #add8e6;
|
10
|
+
}
|
11
|
+
</style>
|
12
|
+
|
13
|
+
<div class="title" onclick="toggleById('legend', this)">
|
14
|
+
Legend +
|
15
|
+
</div>
|
16
|
+
<div class="shrink_section" style="display: none;" id="legend">
|
17
|
+
<div id="description">
|
18
|
+
<table>
|
19
|
+
<tr>
|
20
|
+
<td class="legend_header">
|
21
|
+
Purpose:
|
22
|
+
</td>
|
23
|
+
<td class="legend_description">
|
24
|
+
cuke_sniffer is an open source project with the goal of aiding others in the maintenance and improvement of their cucumber projects. This tool will identify improvements for readability, misuse of cucumber practices, and point out step definitions that are no longer used (dead steps).
|
25
|
+
</td>
|
26
|
+
</tr>
|
27
|
+
<tr>
|
28
|
+
<td class="legend_header">
|
29
|
+
Scoring:
|
30
|
+
</td>
|
31
|
+
<td class="legend_description">
|
32
|
+
The higher the score the more improvements there are to be made. The score ultimately is unique to the project since projects can vary so much from domain, number of people involved, and how long the project has been around. We suggest that you use it as a measure against yourself as you move forward and make improvements.
|
33
|
+
</td>
|
34
|
+
</tr>
|
35
|
+
<tr>
|
36
|
+
<td class="legend_header">
|
37
|
+
Summary:
|
38
|
+
</td>
|
39
|
+
<td class="legend_description">
|
40
|
+
The summary section is designed to be a birds eye view of the project and give quick feedback on the health of a project.
|
41
|
+
</td>
|
42
|
+
</tr>
|
43
|
+
<tr>
|
44
|
+
<td></td>
|
45
|
+
<td class="legend_description">
|
46
|
+
<table>
|
47
|
+
<tr>
|
48
|
+
<td class="legend_header">
|
49
|
+
Total Score:
|
50
|
+
</td>
|
51
|
+
<td class="legend_description">
|
52
|
+
This is the total points gathered by a given section. More often than not Scenarios will have the highest value in this section.
|
53
|
+
</td>
|
54
|
+
</tr>
|
55
|
+
<tr>
|
56
|
+
<td class="legend_header">
|
57
|
+
Count:
|
58
|
+
</td>
|
59
|
+
<td class="legend_description">
|
60
|
+
This is the total number of cucumber objects found in the project. If you have 30 feature files the features count will be 30. For Scenarios/Step Definitions/Hooks the count will be on objects gathered independent of the files they were found in.
|
61
|
+
</td>
|
62
|
+
</tr>
|
63
|
+
<tr>
|
64
|
+
<td class="legend_header">
|
65
|
+
Lowest Score:
|
66
|
+
</td>
|
67
|
+
<td class="legend_description">
|
68
|
+
This is to show the best score any object had obtained. This will most often be 0 unless every single object had an improvement found.
|
69
|
+
</td>
|
70
|
+
</tr>
|
71
|
+
<tr>
|
72
|
+
<td class="legend_header">
|
73
|
+
Highest Score:
|
74
|
+
</td>
|
75
|
+
<td class="legend_description">
|
76
|
+
This is to show the worst score any object had obtained. This can be used to quickly gauge the biggest area of improvement. The larger scoring sections will be Scenarios and Step Definitions.
|
77
|
+
</td>
|
78
|
+
</tr>
|
79
|
+
<tr>
|
80
|
+
<td class="legend_header">
|
81
|
+
Average Score:
|
82
|
+
</td>
|
83
|
+
<td class="legend_description">
|
84
|
+
This is to show the average score any object had obtained.
|
85
|
+
</td>
|
86
|
+
</tr>
|
87
|
+
<tr>
|
88
|
+
<td class="legend_header">
|
89
|
+
Threshold:
|
90
|
+
</td>
|
91
|
+
<td class="legend_description">
|
92
|
+
This is the value used to determine if a Feature/Scenario/Step Definition/Hook is good or bad. The value can be customized(see wiki on github) to scale what is good/bad for a project.
|
93
|
+
</td>
|
94
|
+
</tr>
|
95
|
+
<tr>
|
96
|
+
<td class="legend_header">
|
97
|
+
Good:
|
98
|
+
</td>
|
99
|
+
<td class="legend_description">
|
100
|
+
The percentage of objects that can be considered good. Based on the Threshold.
|
101
|
+
</td>
|
102
|
+
</tr>
|
103
|
+
<tr>
|
104
|
+
<td class="legend_header">
|
105
|
+
Bad:
|
106
|
+
</td>
|
107
|
+
<td class="legend_description">
|
108
|
+
The percentage of objects that can be considered bad. Based on the Threshold.
|
109
|
+
</td>
|
110
|
+
</tr>
|
111
|
+
</table>
|
112
|
+
</td>
|
113
|
+
</tr>
|
114
|
+
<tr>
|
115
|
+
<td class="legend_header">
|
116
|
+
Improvement List:
|
117
|
+
</td>
|
118
|
+
<td class="legend_description">
|
119
|
+
This displays a sorted list of all the improvements that can be made in the project based on the total times a rule was triggered.
|
120
|
+
</td>
|
121
|
+
</tr>
|
122
|
+
<tr>
|
123
|
+
<td class="legend_header">
|
124
|
+
Rules:
|
125
|
+
</td>
|
126
|
+
<td class="legend_description">
|
127
|
+
This displays all of the rules when evaluating the project. The rules section is divided into Enabled and Disabled to show the status of any given rule.
|
128
|
+
</td>
|
129
|
+
</tr>
|
130
|
+
<tr>
|
131
|
+
<td class="legend_header">
|
132
|
+
Dead Steps:
|
133
|
+
</td>
|
134
|
+
<td class="legend_description">
|
135
|
+
This displays all steps that were found unused in a project. A step definition is considered unused if it is never directly referenced from a scenario or through a nested step call found in a step definition. There are also measures used to do fuzzy matching in the case of step definitions that are only ever called through constructed calls.
|
136
|
+
This section is divided up by step definition file to more easily find/remove the unused step definition. We show the line and regex of each dead step.
|
137
|
+
</td>
|
138
|
+
</tr>
|
139
|
+
<tr>
|
140
|
+
<td class="legend_header">
|
141
|
+
Features:
|
142
|
+
</td>
|
143
|
+
<td class="legend_description">
|
144
|
+
This section contains all details around Features and Scenarios. Expanding each section will show you any rules and the location, title, and improvements. This section will be sorted by the combined score of the feature and its scenarios/background.
|
145
|
+
</td>
|
146
|
+
</tr>
|
147
|
+
<tr>
|
148
|
+
<td class="legend_header">
|
149
|
+
Step Definitions:
|
150
|
+
</td>
|
151
|
+
<td class="legend_description">
|
152
|
+
This section contains all details around Step Definitions. Expanding each section will show you any rules and the location, title, and improvements. This section also shows the number of calls made to this step definition. This includes individual calls from outlines and nested step calls.
|
153
|
+
</td>
|
154
|
+
</tr>
|
155
|
+
<tr>
|
156
|
+
<td class="legend_header">
|
157
|
+
Hooks:
|
158
|
+
</td>
|
159
|
+
<td class="legend_description">
|
160
|
+
This section contains all details around Hooks. Expanding each section will show you any rules and the location, title, and improvements.
|
161
|
+
</td>
|
162
|
+
</tr>
|
163
|
+
</table>
|
164
|
+
</div>
|
165
|
+
</div>
|
166
|
+
|
167
|
+
<br>
|
@@ -0,0 +1,125 @@
|
|
1
|
+
<link rel="stylesheet" type="text/css" >
|
2
|
+
|
3
|
+
<script type="text/javascript">
|
4
|
+
|
5
|
+
function toggleById(item, link) {
|
6
|
+
updateDisplayStatus(document.getElementById(item));
|
7
|
+
toggleText(link)
|
8
|
+
}
|
9
|
+
function updateDisplayStatus(object) {
|
10
|
+
object.style.display = (object.style.display == "block") ? 'none' : "block";
|
11
|
+
}
|
12
|
+
function toggleText(link) {
|
13
|
+
var char_result = link.innerHTML.indexOf("+") > -1 ? "-" : "+";
|
14
|
+
link.innerHTML = link.innerHTML.replace(/(\+|\-)/, char_result)
|
15
|
+
}
|
16
|
+
|
17
|
+
|
18
|
+
</script>
|
19
|
+
|
20
|
+
<style>
|
21
|
+
.title {
|
22
|
+
padding-left: 1%;
|
23
|
+
width: 25%;
|
24
|
+
background-color: green;
|
25
|
+
color: white;
|
26
|
+
border-top: 0;
|
27
|
+
border-bottom: 0;
|
28
|
+
font-weight: bold;
|
29
|
+
font-size: 21pt;
|
30
|
+
cursor: pointer;
|
31
|
+
}
|
32
|
+
|
33
|
+
.shrink_section {
|
34
|
+
border: 2px solid #90ee90;
|
35
|
+
display: none;
|
36
|
+
}
|
37
|
+
|
38
|
+
.table_top {
|
39
|
+
width: 20%;
|
40
|
+
font-size: 14pt;
|
41
|
+
padding: 0;
|
42
|
+
}
|
43
|
+
|
44
|
+
.divide_row {
|
45
|
+
border-bottom: 1px solid black;
|
46
|
+
}
|
47
|
+
|
48
|
+
.red_number {
|
49
|
+
width: 3%;
|
50
|
+
color: red;
|
51
|
+
text-indent: 1%;
|
52
|
+
font-weight: bold;
|
53
|
+
}
|
54
|
+
|
55
|
+
.notes {
|
56
|
+
font-weight: bold;
|
57
|
+
}
|
58
|
+
|
59
|
+
.sub_section {
|
60
|
+
display: none;
|
61
|
+
margin-left: 1%;
|
62
|
+
margin-right: 1%;
|
63
|
+
border-top: 2px solid #add8e6;
|
64
|
+
}
|
65
|
+
|
66
|
+
.empty_set_message {
|
67
|
+
font-weight: bold;
|
68
|
+
margin-left: 1%;
|
69
|
+
}
|
70
|
+
|
71
|
+
.rule_notes {
|
72
|
+
margin-left: 1%;
|
73
|
+
border-left: 2px solid #90ee90;
|
74
|
+
border-top: 2px solid #90ee90;
|
75
|
+
display: block;
|
76
|
+
clear: left;
|
77
|
+
padding-bottom: 0%;
|
78
|
+
text-indent: 0%;
|
79
|
+
padding-left: 0.5%;
|
80
|
+
margin-bottom: 0.5%;
|
81
|
+
}
|
82
|
+
|
83
|
+
.rule_style {
|
84
|
+
margin: 0;
|
85
|
+
text_indent: 3%;
|
86
|
+
|
87
|
+
}
|
88
|
+
.rule_heading {
|
89
|
+
font-weight: bold;
|
90
|
+
margin: 0.25%;
|
91
|
+
}
|
92
|
+
|
93
|
+
ol {
|
94
|
+
list-style-type:none;
|
95
|
+
display: block;
|
96
|
+
padding-left: 1%
|
97
|
+
|
98
|
+
}
|
99
|
+
|
100
|
+
</style>
|
101
|
+
|
102
|
+
<div style="float: left; color: green; font-size: 20px; font-weight: bold; padding-bottom: 1px;">
|
103
|
+
Cuke Sniffer
|
104
|
+
</div>
|
105
|
+
<br style="clear:both">
|
106
|
+
<div style="border-top: 2px solid lightgreen; text-align: right;">
|
107
|
+
<div style="float: right; background-color:green;border-right:2px solid #fff; color:white;padding:4px; padding-left:40px;font-size:11pt;font-weight:bold;padding-right:10px;">
|
108
|
+
Score: <%= cuke_sniffer.summary[:total_score] %></div>
|
109
|
+
</div>
|
110
|
+
<br style="clear:both">
|
111
|
+
|
112
|
+
<%
|
113
|
+
legend = build_page(cuke_sniffer, "legend.html.erb")
|
114
|
+
summary = build_page(cuke_sniffer, "summary.html.erb")
|
115
|
+
rules = rules_template(cuke_sniffer)
|
116
|
+
improvement_list = build_page(cuke_sniffer, "improvement_list.html.erb")
|
117
|
+
%>
|
118
|
+
|
119
|
+
<%= legend %>
|
120
|
+
|
121
|
+
<%= summary %>
|
122
|
+
|
123
|
+
<%= improvement_list %>
|
124
|
+
|
125
|
+
<%= rules %>
|
@@ -0,0 +1,137 @@
|
|
1
|
+
<link rel="stylesheet" type="text/css" >
|
2
|
+
|
3
|
+
<script type="text/javascript">
|
4
|
+
|
5
|
+
function toggleById(item, link) {
|
6
|
+
updateDisplayStatus(document.getElementById(item));
|
7
|
+
toggleText(link)
|
8
|
+
}
|
9
|
+
function updateDisplayStatus(object) {
|
10
|
+
object.style.display = (object.style.display == "block") ? 'none' : "block";
|
11
|
+
}
|
12
|
+
function toggleText(link) {
|
13
|
+
var char_result = link.innerHTML.indexOf("+") > -1 ? "-" : "+";
|
14
|
+
link.innerHTML = link.innerHTML.replace(/(\+|\-)/, char_result)
|
15
|
+
}
|
16
|
+
|
17
|
+
|
18
|
+
</script>
|
19
|
+
|
20
|
+
<style>
|
21
|
+
.title {
|
22
|
+
padding-left: 1%;
|
23
|
+
width: 25%;
|
24
|
+
background-color: green;
|
25
|
+
color: white;
|
26
|
+
border-top: 0;
|
27
|
+
border-bottom: 0;
|
28
|
+
font-weight: bold;
|
29
|
+
font-size: 21pt;
|
30
|
+
cursor: pointer;
|
31
|
+
}
|
32
|
+
|
33
|
+
.shrink_section {
|
34
|
+
border: 2px solid #90ee90;
|
35
|
+
display: none;
|
36
|
+
}
|
37
|
+
|
38
|
+
.table_top {
|
39
|
+
width: 20%;
|
40
|
+
font-size: 14pt;
|
41
|
+
padding: 0;
|
42
|
+
}
|
43
|
+
|
44
|
+
.divide_row {
|
45
|
+
border-bottom: 1px solid black;
|
46
|
+
}
|
47
|
+
|
48
|
+
.red_number {
|
49
|
+
width: 3%;
|
50
|
+
color: red;
|
51
|
+
text-indent: 1%;
|
52
|
+
font-weight: bold;
|
53
|
+
}
|
54
|
+
|
55
|
+
.notes {
|
56
|
+
font-weight: bold;
|
57
|
+
}
|
58
|
+
|
59
|
+
.sub_section {
|
60
|
+
display: none;
|
61
|
+
margin-left: 1%;
|
62
|
+
margin-right: 1%;
|
63
|
+
border-top: 2px solid #add8e6;
|
64
|
+
}
|
65
|
+
|
66
|
+
.empty_set_message {
|
67
|
+
font-weight: bold;
|
68
|
+
margin-left: 1%;
|
69
|
+
}
|
70
|
+
|
71
|
+
.rule_notes {
|
72
|
+
margin-left: 1%;
|
73
|
+
border-left: 2px solid #90ee90;
|
74
|
+
border-top: 2px solid #90ee90;
|
75
|
+
display: block;
|
76
|
+
clear: left;
|
77
|
+
padding-bottom: 0%;
|
78
|
+
text-indent: 0%;
|
79
|
+
padding-left: 0.5%;
|
80
|
+
margin-bottom: 0.5%;
|
81
|
+
}
|
82
|
+
|
83
|
+
.rule_style {
|
84
|
+
margin: 0;
|
85
|
+
text_indent: 3%;
|
86
|
+
|
87
|
+
}
|
88
|
+
.rule_heading {
|
89
|
+
font-weight: bold;
|
90
|
+
margin: 0.25%;
|
91
|
+
}
|
92
|
+
|
93
|
+
ol {
|
94
|
+
list-style-type:none;
|
95
|
+
display: block;
|
96
|
+
padding-left: 1%
|
97
|
+
|
98
|
+
}
|
99
|
+
|
100
|
+
</style>
|
101
|
+
|
102
|
+
<div style="float: left; color: green; font-size: 20px; font-weight: bold; padding-bottom: 1px;">
|
103
|
+
Cuke Sniffer
|
104
|
+
</div>
|
105
|
+
<br style="clear:both">
|
106
|
+
<div style="border-top: 2px solid lightgreen; text-align: right;">
|
107
|
+
<div style="float: right; background-color:green;border-right:2px solid #fff; color:white;padding:4px; padding-left:40px;font-size:11pt;font-weight:bold;padding-right:10px;">
|
108
|
+
Score: <%= cuke_sniffer.summary[:total_score] %></div>
|
109
|
+
</div>
|
110
|
+
<br style="clear:both">
|
111
|
+
|
112
|
+
<%
|
113
|
+
legend = build_page(cuke_sniffer, "legend.html.erb")
|
114
|
+
summary = build_page(cuke_sniffer, "summary.html.erb")
|
115
|
+
rules = rules_template(cuke_sniffer)
|
116
|
+
improvement_list = build_page(cuke_sniffer, "improvement_list.html.erb")
|
117
|
+
dead_steps = build_page(cuke_sniffer, "dead_steps.html.erb")
|
118
|
+
features = build_page(cuke_sniffer, "features.html.erb")
|
119
|
+
step_definitions = build_page(cuke_sniffer, "step_definitions.html.erb")
|
120
|
+
hooks = build_page(cuke_sniffer, "hooks.html.erb")
|
121
|
+
%>
|
122
|
+
|
123
|
+
<%= legend %>
|
124
|
+
|
125
|
+
<%= summary %>
|
126
|
+
|
127
|
+
<%= improvement_list %>
|
128
|
+
|
129
|
+
<%= rules %>
|
130
|
+
|
131
|
+
<%= dead_steps %>
|
132
|
+
|
133
|
+
<%= features %>
|
134
|
+
|
135
|
+
<%= step_definitions %>
|
136
|
+
|
137
|
+
<%= hooks %>
|