rspec-formatter-webkit 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/History.md +6 -0
  2. data/LICENSE +27 -0
  3. data/README.md +30 -0
  4. data/Rakefile +51 -0
  5. data/data/rspec-formatter-webkit/css/textmate-rspec.css +332 -0
  6. data/data/rspec-formatter-webkit/images/clock.png +0 -0
  7. data/data/rspec-formatter-webkit/images/cross_circle.png +0 -0
  8. data/data/rspec-formatter-webkit/images/cross_circle_frame.png +0 -0
  9. data/data/rspec-formatter-webkit/images/cross_octagon.png +0 -0
  10. data/data/rspec-formatter-webkit/images/cross_octagon_frame.png +0 -0
  11. data/data/rspec-formatter-webkit/images/cross_shield.png +0 -0
  12. data/data/rspec-formatter-webkit/images/exclamation.png +0 -0
  13. data/data/rspec-formatter-webkit/images/exclamation_frame.png +0 -0
  14. data/data/rspec-formatter-webkit/images/exclamation_shield.png +0 -0
  15. data/data/rspec-formatter-webkit/images/exclamation_small.png +0 -0
  16. data/data/rspec-formatter-webkit/images/plus_circle.png +0 -0
  17. data/data/rspec-formatter-webkit/images/plus_circle_frame.png +0 -0
  18. data/data/rspec-formatter-webkit/images/question.png +0 -0
  19. data/data/rspec-formatter-webkit/images/question_frame.png +0 -0
  20. data/data/rspec-formatter-webkit/images/question_shield.png +0 -0
  21. data/data/rspec-formatter-webkit/images/question_small.png +0 -0
  22. data/data/rspec-formatter-webkit/images/tick.png +0 -0
  23. data/data/rspec-formatter-webkit/images/tick_circle.png +0 -0
  24. data/data/rspec-formatter-webkit/images/tick_circle_frame.png +0 -0
  25. data/data/rspec-formatter-webkit/images/tick_shield.png +0 -0
  26. data/data/rspec-formatter-webkit/images/tick_small.png +0 -0
  27. data/data/rspec-formatter-webkit/images/tick_small_circle.png +0 -0
  28. data/data/rspec-formatter-webkit/images/ticket.png +0 -0
  29. data/data/rspec-formatter-webkit/images/ticket_arrow.png +0 -0
  30. data/data/rspec-formatter-webkit/images/ticket_exclamation.png +0 -0
  31. data/data/rspec-formatter-webkit/images/ticket_minus.png +0 -0
  32. data/data/rspec-formatter-webkit/images/ticket_pencil.png +0 -0
  33. data/data/rspec-formatter-webkit/images/ticket_plus.png +0 -0
  34. data/data/rspec-formatter-webkit/images/ticket_small.png +0 -0
  35. data/data/rspec-formatter-webkit/js/jquery-1.4.2.min.js +154 -0
  36. data/data/rspec-formatter-webkit/js/textmate-rspec.js +402 -0
  37. data/data/rspec-formatter-webkit/templates/failed.rhtml +35 -0
  38. data/data/rspec-formatter-webkit/templates/footer.rhtml +9 -0
  39. data/data/rspec-formatter-webkit/templates/header.rhtml +35 -0
  40. data/data/rspec-formatter-webkit/templates/page.rhtml +131 -0
  41. data/data/rspec-formatter-webkit/templates/passed.rhtml +10 -0
  42. data/data/rspec-formatter-webkit/templates/pending-fixed.rhtml +25 -0
  43. data/data/rspec-formatter-webkit/templates/pending.rhtml +14 -0
  44. data/docs/tmrspec-example.png +0 -0
  45. data/docs/tmrspecopts-shellvar.png +0 -0
  46. data/lib/rspec/core/formatters/web_kit.rb +4 -0
  47. data/lib/rspec/core/formatters/webkit.rb +223 -0
  48. data.tar.gz.sig +0 -0
  49. metadata +202 -0
  50. metadata.gz.sig +0 -0
@@ -0,0 +1,402 @@
1
+ /*
2
+ * RSpec WebKit Formatter javascript
3
+ * $Id$
4
+ *
5
+ * Most of these functions were converted from Safari's Web Inspector, which is licensed
6
+ * under the following terms:
7
+ *
8
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
9
+ *
10
+ * Redistribution and use in source and binary forms, with or without
11
+ * modification, are permitted provided that the following conditions
12
+ * are met:
13
+ *
14
+ * 1. Redistributions of source code must retain the above copyright
15
+ * notice, this list of conditions and the following disclaimer.
16
+ * 2. Redistributions in binary form must reproduce the above copyright
17
+ * notice, this list of conditions and the following disclaimer in the
18
+ * documentation and/or other materials provided with the distribution.
19
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
20
+ * its contributors may be used to endorse or promote products derived
21
+ * from this software without specific prior written permission.
22
+ *
23
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
24
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
27
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
+ *
34
+ * All mistakes and modifications are (c) 2009 Michael Granger, and are distributed under
35
+ * the same terms as the original.
36
+ *
37
+ */
38
+
39
+ var polltimer = null;
40
+
41
+ function fade_out_rect( ctx, x, y, w, h, a1, a2 ) {
42
+ ctx.save();
43
+
44
+ var gradient = ctx.createLinearGradient(x, y, x, y + h);
45
+ gradient.addColorStop(0.0, "rgba(0, 0, 0, " + (1.0 - a1) + ")");
46
+ gradient.addColorStop(0.8, "rgba(0, 0, 0, " + (1.0 - a2) + ")");
47
+ gradient.addColorStop(1.0, "rgba(0, 0, 0, 1.0)");
48
+
49
+ ctx.globalCompositeOperation = "destination-out";
50
+
51
+ ctx.fillStyle = gradient;
52
+ ctx.fillRect(x, y, w, h);
53
+
54
+ ctx.restore();
55
+ }
56
+
57
+ function draw_summary_graph( selector, segments ) {
58
+ var graphElement = $(selector).get( 0 );
59
+ var i = 0;
60
+
61
+ if (!graphElement)
62
+ return;
63
+
64
+ if (!segments || !segments.length) {
65
+ segments = [{color: "white", value: 1}];
66
+ // this._showingEmptySummaryGraph = true;
67
+ } // else
68
+ // delete this._showingEmptySummaryGraph;
69
+
70
+ // Calculate the total of all segments.
71
+ var total = 0;
72
+ for (i = 0; i < segments.length; ++i)
73
+ total += segments[i].value;
74
+
75
+ // Calculate the percentage of each segment, rounded to the nearest percent.
76
+ var percents = segments.map(function(s) {
77
+ return Math.max(Math.round(100 * s.value / total), 1);
78
+ });
79
+
80
+ // Calculate the total percentage.
81
+ var percentTotal = 0;
82
+ for (i = 0; i < percents.length; ++i)
83
+ percentTotal += percents[i];
84
+
85
+ // Make sure our percentage total is not greater-than 100, it can be greater
86
+ // if we rounded up for a few segments.
87
+ while (percentTotal > 100) {
88
+ for (i = 0; i < percents.length && percentTotal > 100; ++i) {
89
+ if (percents[i] > 1) {
90
+ --percents[i];
91
+ --percentTotal;
92
+ }
93
+ }
94
+ }
95
+
96
+ // Make sure our percentage total is not less-than 100, it can be less
97
+ // if we rounded down for a few segments.
98
+ while (percentTotal < 100) {
99
+ for (i = 0; i < percents.length && percentTotal < 100; ++i) {
100
+ ++percents[i];
101
+ ++percentTotal;
102
+ }
103
+ }
104
+
105
+ var ctx = graphElement.getContext("2d");
106
+
107
+ var x = 0;
108
+ var y = 0;
109
+ var w = 450;
110
+ var h = 19;
111
+ var r = (h / 2);
112
+
113
+ function drawPillShadow()
114
+ {
115
+ // This draws a line with a shadow that is offset away from the line. The line is stroked
116
+ // twice with different X shadow offsets to give more feathered edges. Later we erase the
117
+ // line with destination-out 100% transparent black, leaving only the shadow. This only
118
+ // works if nothing has been drawn into the canvas yet.
119
+
120
+ ctx.beginPath();
121
+ ctx.moveTo(x + 4, y + h - 3 - 0.5);
122
+ ctx.lineTo(x + w - 4, y + h - 3 - 0.5);
123
+ ctx.closePath();
124
+
125
+ ctx.save();
126
+
127
+ ctx.shadowBlur = 2;
128
+ ctx.shadowColor = "rgba(0, 0, 0, 0.5)";
129
+ ctx.shadowOffsetX = 3;
130
+ ctx.shadowOffsetY = 5;
131
+
132
+ ctx.strokeStyle = "white";
133
+ ctx.lineWidth = 1;
134
+
135
+ ctx.stroke();
136
+
137
+ ctx.shadowOffsetX = -3;
138
+
139
+ ctx.stroke();
140
+
141
+ ctx.restore();
142
+
143
+ ctx.save();
144
+
145
+ ctx.globalCompositeOperation = "destination-out";
146
+ ctx.strokeStyle = "rgba(0, 0, 0, 1)";
147
+ ctx.lineWidth = 1;
148
+
149
+ ctx.stroke();
150
+
151
+ ctx.restore();
152
+ }
153
+
154
+ function drawPill()
155
+ {
156
+ // Make a rounded rect path.
157
+ ctx.beginPath();
158
+ ctx.moveTo(x, y + r);
159
+ ctx.lineTo(x, y + h - r);
160
+ ctx.quadraticCurveTo(x, y + h, x + r, y + h);
161
+ ctx.lineTo(x + w - r, y + h);
162
+ ctx.quadraticCurveTo(x + w, y + h, x + w, y + h - r);
163
+ ctx.lineTo(x + w, y + r);
164
+ ctx.quadraticCurveTo(x + w, y, x + w - r, y);
165
+ ctx.lineTo(x + r, y);
166
+ ctx.quadraticCurveTo(x, y, x, y + r);
167
+ ctx.closePath();
168
+
169
+ // Clip to the rounded rect path.
170
+ ctx.save();
171
+ ctx.clip();
172
+
173
+ // Fill the segments with the associated color.
174
+ var previousSegmentsWidth = 0;
175
+ for (var i = 0; i < segments.length; ++i) {
176
+ var segmentWidth = Math.round(w * percents[i] / 100);
177
+ ctx.fillStyle = segments[i].color;
178
+ ctx.fillRect(x + previousSegmentsWidth, y, segmentWidth, h);
179
+ previousSegmentsWidth += segmentWidth;
180
+ }
181
+
182
+ // Draw the segment divider lines.
183
+ ctx.lineWidth = 1;
184
+ for (i = 1; i < 20; ++i) {
185
+ ctx.beginPath();
186
+ ctx.moveTo(x + (i * Math.round(w / 20)) + 0.5, y);
187
+ ctx.lineTo(x + (i * Math.round(w / 20)) + 0.5, y + h);
188
+ ctx.closePath();
189
+
190
+ ctx.strokeStyle = "rgba(0, 0, 0, 0.2)";
191
+ ctx.stroke();
192
+
193
+ ctx.beginPath();
194
+ ctx.moveTo(x + (i * Math.round(w / 20)) + 1.5, y);
195
+ ctx.lineTo(x + (i * Math.round(w / 20)) + 1.5, y + h);
196
+ ctx.closePath();
197
+
198
+ ctx.strokeStyle = "rgba(255, 255, 255, 0.2)";
199
+ ctx.stroke();
200
+ }
201
+
202
+ // Draw the pill shading.
203
+ var lightGradient = ctx.createLinearGradient(x, y, x, y + (h / 1.5));
204
+ lightGradient.addColorStop(0.0, "rgba(220, 220, 220, 0.6)");
205
+ lightGradient.addColorStop(0.4, "rgba(220, 220, 220, 0.2)");
206
+ lightGradient.addColorStop(1.0, "rgba(255, 255, 255, 0.0)");
207
+
208
+ var darkGradient = ctx.createLinearGradient(x, y + (h / 3), x, y + h);
209
+ darkGradient.addColorStop(0.0, "rgba(0, 0, 0, 0.0)");
210
+ darkGradient.addColorStop(0.8, "rgba(0, 0, 0, 0.2)");
211
+ darkGradient.addColorStop(1.0, "rgba(0, 0, 0, 0.5)");
212
+
213
+ ctx.fillStyle = darkGradient;
214
+ ctx.fillRect(x, y, w, h);
215
+
216
+ ctx.fillStyle = lightGradient;
217
+ ctx.fillRect(x, y, w, h);
218
+
219
+ ctx.restore();
220
+ }
221
+
222
+ ctx.clearRect(x, y, w, (h * 2));
223
+
224
+ drawPillShadow();
225
+ drawPill();
226
+
227
+ ctx.save();
228
+
229
+ ctx.translate(0, (h * 2) + 1);
230
+ ctx.scale(1, -1);
231
+
232
+ drawPill();
233
+
234
+ ctx.restore();
235
+
236
+ fade_out_rect(ctx, x, y + h + 1, w, h, 0.5, 0.0);
237
+ }
238
+
239
+
240
+ function draw_swatch( canvas, color ) {
241
+ var ctx = canvas.getContext("2d");
242
+
243
+ function draw_swatch_square() {
244
+ ctx.fillStyle = color;
245
+ ctx.fillRect(0, 0, 13, 13);
246
+
247
+ var gradient = ctx.createLinearGradient(0, 0, 13, 13);
248
+ gradient.addColorStop(0.0, "rgba(255, 255, 255, 0.2)");
249
+ gradient.addColorStop(1.0, "rgba(255, 255, 255, 0.0)");
250
+
251
+ ctx.fillStyle = gradient;
252
+ ctx.fillRect(0, 0, 13, 13);
253
+
254
+ gradient = ctx.createLinearGradient(13, 13, 0, 0);
255
+ gradient.addColorStop(0.0, "rgba(0, 0, 0, 0.2)");
256
+ gradient.addColorStop(1.0, "rgba(0, 0, 0, 0.0)");
257
+
258
+ ctx.fillStyle = gradient;
259
+ ctx.fillRect(0, 0, 13, 13);
260
+
261
+ ctx.strokeStyle = "rgba(0, 0, 0, 0.6)";
262
+ ctx.strokeRect(0.5, 0.5, 12, 12);
263
+ }
264
+
265
+ ctx.clearRect(0, 0, 13, 24);
266
+
267
+ draw_swatch_square();
268
+
269
+ ctx.save();
270
+
271
+ ctx.translate(0, 25);
272
+ ctx.scale(1, -1);
273
+
274
+ draw_swatch_square();
275
+
276
+ ctx.restore();
277
+
278
+ fade_out_rect(ctx, 0, 13, 13, 13, 0.5, 0.0);
279
+ }
280
+
281
+
282
+ function make_legend_element( label, value, color ) {
283
+ var legendElement = document.createElement("label");
284
+ legendElement.className = "rspec-graph-legend-item " + label.replace(/\W+/g, '-');
285
+
286
+ if (color) {
287
+ var swatch = document.createElement("canvas");
288
+ swatch.className = "rspec-graph-legend-swatch";
289
+ swatch.setAttribute("width", "13");
290
+ swatch.setAttribute("height", "24");
291
+
292
+ legendElement.appendChild(swatch);
293
+
294
+ draw_swatch(swatch, color);
295
+ }
296
+
297
+ var labelElement = document.createElement("div");
298
+ labelElement.className = "rspec-graph-legend-label";
299
+ legendElement.appendChild(labelElement);
300
+
301
+ var headerElement = document.createElement("div");
302
+ headerElement.className = "rspec-graph-legend-header";
303
+ headerElement.textContent = label;
304
+ labelElement.appendChild(headerElement);
305
+
306
+ var valueElement = document.createElement("div");
307
+ valueElement.className = "rspec-graph-legend-value";
308
+ valueElement.textContent = value;
309
+ labelElement.appendChild(valueElement);
310
+
311
+ return legendElement;
312
+ }
313
+
314
+
315
+ function update_summary_graph() {
316
+ var total = $('#spec-count').eq(0).text();
317
+ var graphInfo = {
318
+ passed: $('.spec.passed'),
319
+ pending: $('.spec.pending'),
320
+ failed: $('.spec.failed'),
321
+ 'pending:fixed': $('.spec.pending-fixed'),
322
+ total: parseInt( total, 10 )
323
+ };
324
+
325
+ var categoryOrder = ["passed", "pending", "pending:fixed", "failed"];
326
+ var categoryColors = {
327
+ passed: {r: 0, g: 157, b: 37}, // #009D25
328
+ pending: {r: 227, g: 184, b: 0}, // #E3B800
329
+ 'pending:fixed': {r: 9, g: 60, b: 226}, // #093CE2
330
+ failed: {r: 192, g: 0, b: 0} // #C00000
331
+ };
332
+ var fillSegments = [];
333
+ var doneCount = 0;
334
+
335
+ var legendElement = $( '#rspec-summary-graph-legend' );
336
+ legendElement.empty();
337
+
338
+ jQuery.each( categoryOrder, function(i, val) {
339
+ var category = categoryOrder[i];
340
+ var size = graphInfo[ category ].length;
341
+ if (!size) return true;
342
+ doneCount += size;
343
+
344
+ var color = categoryColors[category];
345
+ var colorString = "rgb(" + color.r + ", " + color.g + ", " + color.b + ")";
346
+
347
+ var fillSegment = {color: colorString, value: size};
348
+ fillSegments.push(fillSegment);
349
+
350
+ var legendLabel = make_legend_element( category, size, colorString );
351
+ legendElement.append( legendLabel );
352
+ });
353
+
354
+ if ( graphInfo.total ) {
355
+ var totalLegendLabel = make_legend_element( "remaining", graphInfo.total - doneCount );
356
+ // totalLegendLabel.addStyleClass( "total" );
357
+ legendElement.append( totalLegendLabel );
358
+ if ( doneCount < graphInfo.total ) {
359
+ var fillSegment = { color: 'rgb(254,254,254)', value: graphInfo.total - doneCount };
360
+ console.log( "Adding segment for examples yet to run: " + fillSegment.toString() );
361
+ fillSegments.push( fillSegment );
362
+ }
363
+ }
364
+
365
+ draw_summary_graph( '#rspec-summary-graph', fillSegments );
366
+ }
367
+
368
+ function toggle_spec_status() {
369
+ var status = $(this).attr( 'class' ).match( /(passed|pending(?:-fixed)?|failed)/ )[0];
370
+ console.log( "Looking for specs with class '" + status + "'." );
371
+ $(this).toggleClass( 'hidden' );
372
+ $( '.spec.' + status ).toggle('fast');
373
+ }
374
+
375
+ function hook_legend_clickables() {
376
+ $('label.passed').click( toggle_spec_status );
377
+ $('label.pending').click( toggle_spec_status );
378
+ $('label.pending-fixed').click( toggle_spec_status );
379
+ $('label.failed').click( toggle_spec_status );
380
+ }
381
+
382
+ function hook_log_clickables() {
383
+ $('.spec:has(div.log-messages)').each( function() {
384
+ $(this).addClass( 'logged' );
385
+ }).find( '.spec-name' ).click( function(e) {
386
+ $(this).parent().find('div.log-messages').toggle();
387
+ });
388
+ }
389
+
390
+ $(document).ready(function() {
391
+ console.log( "Document is ready." );
392
+ clearInterval( polltimer );
393
+
394
+ $('#rspec-summary-stats').html( 'Finished in ' + $('#summary .duration').html() );
395
+
396
+ update_summary_graph();
397
+ hook_legend_clickables();
398
+ hook_log_clickables();
399
+ });
400
+
401
+ polltimer = setInterval( update_summary_graph, 250 );
402
+
@@ -0,0 +1,35 @@
1
+
2
+ <dd class="spec failed">
3
+ <span class="spec-name"><%= h(example.description) %></span>
4
+ <div class="failure" id="failure-<%= counter %>">
5
+
6
+ <div class="message">Failure/Error:
7
+ <code><%= h read_failed_line(exception, example).strip.gsub(/\n/, '<br />') %><br />
8
+ % exception.message.split("\n").each do |line|
9
+ <%= h line %><br />
10
+ % end
11
+ % example.example_group.ancestors.push(example.example_group).each do |group|
12
+ % if group.metadata[:shared_group_name]
13
+ Shared Example Group: "<%= h group.metadata[:shared_group_name] %>" called from
14
+ "<%= backtrace_line(group.metadata[:example_group][:location]) %>
15
+ % break
16
+ % end
17
+ % end
18
+ </code>
19
+ </div>
20
+
21
+ <div class="backtrace"><p><code>
22
+ % format_backtrace(exception.backtrace, example).each do |backtrace_info|
23
+ <span class="backtrace-frame"><%= backtrace_info %></span><br />
24
+ % end
25
+ </code></p></div>
26
+ <%= extra %>
27
+ </div>
28
+
29
+ % unless log_messages.nil? || log_messages.empty?
30
+ <div class="log-messages">
31
+ <%= log_messages.join("\n") %>
32
+ </div>
33
+ % end
34
+ </dd>
35
+
@@ -0,0 +1,9 @@
1
+ </div>
2
+
3
+ <div id="summary">
4
+ <p><%= example_count %> examples run in <span class="duration"><%= duration %>
5
+ seconds</span>. <%= failure_count %> failed, <%= pending_count %> are pending.</p>
6
+ </div>
7
+
8
+ </body>
9
+ </html>
@@ -0,0 +1,35 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
+
4
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
5
+ <head>
6
+ <title>RSpec results</title>
7
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
8
+ <meta http-equiv="Expires" content="-1" />
9
+ <meta http-equiv="Pragma" content="no-cache" />
10
+
11
+ <base href="<%= BASE_HREF %>" />
12
+
13
+ <link rel="stylesheet" href="css/textmate-rspec.css" type="text/css" media="screen"
14
+ title="no title" charset="utf-8" />
15
+
16
+ <script type="text/javascript" charset="utf-8" src="js/jquery-1.4.2.min.js"></script>
17
+ <script type="text/javascript" charset="utf-8" src="js/textmate-rspec.js"></script>
18
+ </head>
19
+ <body>
20
+ <div class="rspec-report">
21
+
22
+ <div id="rspec-header">
23
+ <div id="rspec-title-section">
24
+ <h1>RSpec Results:</h1>
25
+ <span id="rspec-summary-stats">Running (<span id="spec-count"><%= example_count %></span>
26
+ examples)...</span>
27
+ </div>
28
+
29
+ <div id="rspec-summary">
30
+ <canvas width="450" height="38" id="rspec-summary-graph"></canvas>
31
+ <div id="rspec-summary-graph-legend"></div>
32
+ </div>
33
+ </div>
34
+
35
+ <div id="rspec-details">
@@ -0,0 +1,131 @@
1
+ <div class="example-group">
2
+ <dl>
3
+ <dt id="example-group-1">Treequel::Filter</dt>
4
+ <dd class="spec passed"><span class="spec-name">knows that it is promiscuous (will match any entry) if its component is promiscuous</span></dd>
5
+ <dd class="spec passed"><span class="spec-name">knows that it isn't promiscuous if its component isn't promiscuous</span></dd>
6
+ <dd class="spec passed"><span class="spec-name">defaults to selecting everything</span></dd>
7
+ <dd class="spec passed"><span class="spec-name">can be created from a string literal</span></dd>
8
+ <dd class="spec passed"><span class="spec-name">wraps string literal instances in parens if it requires them</span></dd>
9
+ <dd class="spec passed"><span class="spec-name">parses a single Symbol argument as a presence filter</span></dd>
10
+ <dd class="spec passed"><span class="spec-name">parses a single-element Array with a Symbol as a presence filter</span></dd>
11
+ <dd class="spec passed"><span class="spec-name">parses a Symbol+value pair as a simple item equal filter</span></dd>
12
+ <dd class="spec passed"><span class="spec-name">parses a Symbol+value pair in an Array as a simple item equal filter</span></dd>
13
+ <dd class="spec passed"><span class="spec-name">parses an AND expression with only a single clause</span></dd>
14
+ <dd class="spec passed"><span class="spec-name">parses an AND expression with multiple clauses</span></dd>
15
+ <dd class="spec passed"><span class="spec-name">parses an OR expression with only a single clause</span></dd>
16
+ <dd class="spec passed"><span class="spec-name">parses an OR expression with multiple clauses</span></dd>
17
+ <dd class="spec passed"><span class="spec-name">parses an OR expression with String literal clauses</span></dd>
18
+ <dd class="spec passed"><span class="spec-name">parses the hash form of OR expression</span></dd>
19
+ <dd class="spec passed"><span class="spec-name">parses a NOT expression with only a single clause</span></dd>
20
+ <dd class="spec passed"><span class="spec-name">raises an exception with a NOT expression that contains more than one clause</span></dd>
21
+ <dd class="spec passed"><span class="spec-name">parses a Substring item from a filter that includes an asterisk</span></dd>
22
+ <dd class="spec passed"><span class="spec-name">parses a Present item from a filter that is only an asterisk</span></dd>
23
+ <dd class="spec passed"><span class="spec-name">raises an error when an extensible item filter is given</span></dd>
24
+ <dd class="spec passed"><span class="spec-name">parses a complex nested expression</span></dd>
25
+ </dl>
26
+ </div>
27
+ <div class="example-group">
28
+ <dl>
29
+ <dt id="example-group-2">Treequel::Filter operator methods</dt>
30
+ <dd class="spec passed"><span class="spec-name">compares as equal with another filter if their components are equal</span></dd>
31
+ <dd class="spec passed"><span class="spec-name">creates a new AND filter out of two filters that are added together</span></dd>
32
+ <dd class="spec passed"><span class="spec-name">creates a new AND filter out of two filters that are bitwise-ANDed together</span></dd>
33
+ <dd class="spec passed"><span class="spec-name">doesn't include the left operand in an AND filter if it is promiscuous</span></dd>
34
+ <dd class="spec passed"><span class="spec-name">doesn't include the right operand in an AND filter if it is promiscuous</span></dd>
35
+ </dl>
36
+ </div>
37
+ <div class="example-group">
38
+ <dl>
39
+ <dt id="example-group-3">Treequel::Filter components: Treequel::Filter::FilterList</dt>
40
+ <dd class="spec passed"><span class="spec-name">stringifies by joining its stringified members</span></dd>
41
+ </dl>
42
+ </div>
43
+ <div class="example-group">
44
+ <dl>
45
+ <dt id="example-group-4">Treequel::Filter components: Treequel::Filter::Component</dt>
46
+ <dd class="spec passed"><span class="spec-name">is an abstract class</span></dd>
47
+ <dd class="spec passed"><span class="spec-name">is non-promiscuous by default</span></dd>
48
+ </dl>
49
+ </div>
50
+ <div class="example-group">
51
+ <dl>
52
+ <dt id="example-group-5">Treequel::Filter components: Treequel::Filter::SimpleItemComponent</dt>
53
+ <dd class="spec passed"><span class="spec-name">can parse a component object from a string literal</span></dd>
54
+ <dd class="spec passed"><span class="spec-name">raises an ExpressionError if it can't parse a string literal</span></dd>
55
+ <dd class="spec passed"><span class="spec-name">uses the 'equal' operator if none is specified</span></dd>
56
+ <dd class="spec passed"><span class="spec-name">knows what the appropriate operator is for its filtertype</span></dd>
57
+ <dd class="spec passed"><span class="spec-name">knows what the appropriate operator is for its filtertype even if it's set to a string</span></dd>
58
+ <dd class="spec passed"><span class="spec-name">stringifies as &lt;attribute&gt;&lt;operator&gt;&lt;value&gt;</span></dd>
59
+ <dd class="spec passed"><span class="spec-name">uses the '~=' operator if its filtertype is 'approx'</span></dd>
60
+ <dd class="spec passed"><span class="spec-name">uses the '&gt;=' operator if its filtertype is 'greater'</span></dd>
61
+ <dd class="spec pending"><span class="spec-name">uses the '&lt;=' operator if its filtertype is 'less' (PENDING: Because I can)</span></dd>
62
+ <dd class="spec passed"><span class="spec-name">raises an error if it's created with an unknown filtertype</span></dd>
63
+ </dl>
64
+ </div>
65
+ <div class="example-group">
66
+ <dl>
67
+ <dt id="example-group-6">Treequel::Filter components: Treequel::Filter::SubstringItemComponent</dt>
68
+ <dd class="spec failed">
69
+ <span class="spec-name">can parse a component object from a string literal</span>
70
+ <div class="failure" id="failure-1">
71
+ <div class="message"><code>undefined local variable or method `saadsdf' for #&lt;Spec::Example::ExampleGroup::Subclass_1::Subclass_2::Subclass_4:0x1b343d0&gt;</code></div>
72
+ <div class="backtrace">
73
+ <code><a href="txmt://open?url=file:///Users/ged/source/ruby/Treequel/spec/treequel/filter_spec.rb&amp;line=296">/Users/ged/source/ruby/Treequel/spec/treequel/filter_spec.rb:296</a> -:3</code></div>
74
+ <pre class="ruby"><code>
75
+ <span class="linenum">294</span> <span class="ident">comp</span><span class="punct">.</span><span class="ident">attribute</span><span class="punct">.</span><span class="ident">should</span> <span class="punct">==</span> <span class="punct">'</span><span class="string">description</span><span class="punct">'</span>
76
+ <span class="linenum">295</span> <span class="ident">comp</span><span class="punct">.</span><span class="ident">options</span><span class="punct">.</span><span class="ident">should</span> <span class="punct">==</span> <span class="punct">'</span><span class="string"></span><span class="punct">'</span>
77
+ <span class="offending"><span class="linenum">296</span> <span class="ident">saadsdf</span></span>
78
+ <span class="linenum">297</span> <span class="ident">comp</span><span class="punct">.</span><span class="ident">pattern</span><span class="punct">.</span><span class="ident">should</span> <span class="punct">==</span> <span class="punct">'</span><span class="string">*basecamp*</span><span class="punct">'</span>
79
+ <span class="linenum">298</span> <span class="keyword">end</span>
80
+ </code></pre>
81
+ </div>
82
+ </dd>
83
+ <dd class="spec passed"><span class="spec-name">can parse a component object from a string literal with attribute options</span></dd>
84
+ <dd class="spec passed"><span class="spec-name">raises an ExpressionError if it can't parse a string literal</span></dd>
85
+ </dl>
86
+ </div>
87
+ <div class="example-group">
88
+ <dl>
89
+ <dt id="example-group-7">Treequel::Filter components: Treequel::Filter::AndComponent</dt>
90
+ <dd class="spec passed"><span class="spec-name">stringifies as its filters ANDed together</span></dd>
91
+ <dd class="spec passed"><span class="spec-name">allows a single filter</span></dd>
92
+ </dl>
93
+ </div>
94
+ <div class="example-group">
95
+ <dl>
96
+ <dt id="example-group-8">Treequel::Filter components: Treequel::Filter::OrComponent</dt>
97
+ <dd class="spec passed"><span class="spec-name">stringifies as its filters ORed together</span></dd>
98
+ <dd class="spec failed">
99
+ <span class="spec-name">allows a single filter</span>
100
+ <div class="failure" id="failure-2">
101
+ <div class="message"><code>undefined local variable or method `sdsdf' for #&lt;Spec::Example::ExampleGroup::Subclass_1::Subclass_2::Subclass_6:0x1af8308&gt;</code></div>
102
+ <div class="backtrace"><code><a href="txmt://open?url=file:///Users/ged/source/ruby/Treequel/spec/treequel/filter_spec.rb&amp;line=335">/Users/ged/source/ruby/Treequel/spec/treequel/filter_spec.rb:335</a> -:3</code></div>
103
+ <pre class="ruby"><code>
104
+ <span class="linenum">333</span>
105
+ <span class="linenum">334</span> <span class="ident">it</span> <span class="punct">&quot;</span><span class="string">allows a single filter</span><span class="punct">&quot;</span> <span class="keyword">do</span>
106
+ <span class="offending"><span class="linenum">335</span> <span class="ident">sdsdf</span></span>
107
+ <span class="linenum">336</span> <span class="constant">Treequel</span><span class="punct">::</span><span class="constant">Filter</span><span class="punct">::</span><span class="constant">OrComponent</span><span class="punct">.</span><span class="ident">new</span><span class="punct">(</span> <span class="attribute">@filter1</span> <span class="punct">).</span><span class="ident">to_s</span><span class="punct">.</span>
108
+ <span class="linenum">337</span> <span class="ident">should</span> <span class="punct">==</span> <span class="punct">'</span><span class="string">|(filter1)</span><span class="punct">'</span>
109
+ </code></pre>
110
+ </div>
111
+ </dd>
112
+ </dl>
113
+ </div>
114
+ <div class="example-group">
115
+ <dl>
116
+ <dt id="example-group-9">Treequel::Filter components: Treequel::Filter::NotComponent</dt>
117
+ <dd class="spec passed"><span class="spec-name">stringifies as the negation of its filter</span></dd>
118
+ <dd class="spec passed"><span class="spec-name">can't be created with multiple filters</span></dd>
119
+ </dl>
120
+ </div>
121
+ <div class="example-group">
122
+ <dl>
123
+ <dt id="example-group-10">Treequel::Filter support for Sequel expressions</dt>
124
+ <dd class="spec passed"><span class="spec-name">supports the boolean expression syntax</span></dd>
125
+ </dl>
126
+ </div>
127
+ </div>
128
+ </div>
129
+
130
+ </body>
131
+ </html>
@@ -0,0 +1,10 @@
1
+ <dd class="spec passed">
2
+ <span class="spec-name"><%= h(example.description) %></span>
3
+
4
+ % unless log_messages.nil? || log_messages.empty?
5
+ <div class="log-messages">
6
+ <%= log_messages.join("\n") %>
7
+ </div>
8
+ % end
9
+ </dd>
10
+
@@ -0,0 +1,25 @@
1
+
2
+ <dd class="spec pending-fixed">
3
+ <span class="spec-name"><%= h(example.description) %></span>
4
+ <div class="failure" id="failure-<%= counter %>">
5
+
6
+ <div class="message">Expected pending
7
+ <code><%= h(example.metadata[:execution_result][:pending_message]) %></code>
8
+ to fail. No Error was raised.
9
+ </div>
10
+
11
+ <div class="backtrace"><p><code>
12
+ % format_backtrace(exception.backtrace, example).each do |backtrace_info|
13
+ <span class="backtrace-frame"><%= backtrace_info %></span><br />
14
+ % end
15
+ </code></p></div>
16
+ <%= extra %>
17
+ </div>
18
+
19
+ % unless log_messages.nil? || log_messages.empty?
20
+ <div class="log-messages">
21
+ <%= log_messages.join("\n") %>
22
+ </div>
23
+ % end
24
+ </dd>
25
+
@@ -0,0 +1,14 @@
1
+
2
+ <dd class="spec pending">
3
+ <span class="spec-name"><%= h(example.description) %></span>
4
+ <span class="pending-message">
5
+ (Pending <%= example.execution_result[:pending_message] %>)
6
+ </span>
7
+
8
+ % unless log_messages.nil? || log_messages.empty?
9
+ <div class="log-messages">
10
+ <%= log_messages.join("\n") %>
11
+ </div>
12
+ % end
13
+ </dd>
14
+