webkit-rspec-formatter 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/ChangeLog +81 -0
- data/LICENSE +27 -0
- data/README.md +26 -0
- data/Rakefile +370 -0
- data/data/webkit-rspec-formatter/css/textmate-rspec.css +332 -0
- data/data/webkit-rspec-formatter/images/clock.png +0 -0
- data/data/webkit-rspec-formatter/images/cross_circle.png +0 -0
- data/data/webkit-rspec-formatter/images/cross_circle_frame.png +0 -0
- data/data/webkit-rspec-formatter/images/cross_octagon.png +0 -0
- data/data/webkit-rspec-formatter/images/cross_octagon_frame.png +0 -0
- data/data/webkit-rspec-formatter/images/cross_shield.png +0 -0
- data/data/webkit-rspec-formatter/images/exclamation.png +0 -0
- data/data/webkit-rspec-formatter/images/exclamation_frame.png +0 -0
- data/data/webkit-rspec-formatter/images/exclamation_shield.png +0 -0
- data/data/webkit-rspec-formatter/images/exclamation_small.png +0 -0
- data/data/webkit-rspec-formatter/images/plus_circle.png +0 -0
- data/data/webkit-rspec-formatter/images/plus_circle_frame.png +0 -0
- data/data/webkit-rspec-formatter/images/question.png +0 -0
- data/data/webkit-rspec-formatter/images/question_frame.png +0 -0
- data/data/webkit-rspec-formatter/images/question_shield.png +0 -0
- data/data/webkit-rspec-formatter/images/question_small.png +0 -0
- data/data/webkit-rspec-formatter/images/tick.png +0 -0
- data/data/webkit-rspec-formatter/images/tick_circle.png +0 -0
- data/data/webkit-rspec-formatter/images/tick_circle_frame.png +0 -0
- data/data/webkit-rspec-formatter/images/tick_shield.png +0 -0
- data/data/webkit-rspec-formatter/images/tick_small.png +0 -0
- data/data/webkit-rspec-formatter/images/tick_small_circle.png +0 -0
- data/data/webkit-rspec-formatter/images/ticket.png +0 -0
- data/data/webkit-rspec-formatter/images/ticket_arrow.png +0 -0
- data/data/webkit-rspec-formatter/images/ticket_exclamation.png +0 -0
- data/data/webkit-rspec-formatter/images/ticket_minus.png +0 -0
- data/data/webkit-rspec-formatter/images/ticket_pencil.png +0 -0
- data/data/webkit-rspec-formatter/images/ticket_plus.png +0 -0
- data/data/webkit-rspec-formatter/images/ticket_small.png +0 -0
- data/data/webkit-rspec-formatter/js/jquery-1.4.2.min.js +154 -0
- data/data/webkit-rspec-formatter/js/textmate-rspec.js +402 -0
- data/data/webkit-rspec-formatter/templates/failed.rhtml +35 -0
- data/data/webkit-rspec-formatter/templates/footer.rhtml +9 -0
- data/data/webkit-rspec-formatter/templates/header.rhtml +35 -0
- data/data/webkit-rspec-formatter/templates/page.rhtml +131 -0
- data/data/webkit-rspec-formatter/templates/passed.rhtml +10 -0
- data/data/webkit-rspec-formatter/templates/pending-fixed.rhtml +25 -0
- data/data/webkit-rspec-formatter/templates/pending.rhtml +14 -0
- data/lib/rspec/core/formatters/web_kit.rb +4 -0
- data/lib/rspec/core/formatters/webkit.rb +222 -0
- data/lib/rspec/mate/runner.rb +65 -0
- data/rake/191_compat.rb +26 -0
- data/rake/dependencies.rb +76 -0
- data/rake/documentation.rb +123 -0
- data/rake/helpers.rb +502 -0
- data/rake/hg.rb +287 -0
- data/rake/manual.rb +787 -0
- data/rake/packaging.rb +129 -0
- data/rake/publishing.rb +339 -0
- data/rake/style.rb +62 -0
- data/rake/svn.rb +668 -0
- data/rake/testing.rb +151 -0
- data/rake/verifytask.rb +64 -0
- metadata +217 -0
- metadata.gz.sig +0 -0
@@ -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 <attribute><operator><value></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 '>=' operator if its filtertype is 'greater'</span></dd>
|
61
|
+
<dd class="spec pending"><span class="spec-name">uses the '<=' 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 #<Spec::Example::ExampleGroup::Subclass_1::Subclass_2::Subclass_4:0x1b343d0></code></div>
|
72
|
+
<div class="backtrace">
|
73
|
+
<code><a href="txmt://open?url=file:///Users/ged/source/ruby/Treequel/spec/treequel/filter_spec.rb&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 #<Spec::Example::ExampleGroup::Subclass_1::Subclass_2::Subclass_6:0x1af8308></code></div>
|
102
|
+
<div class="backtrace"><code><a href="txmt://open?url=file:///Users/ged/source/ruby/Treequel/spec/treequel/filter_spec.rb&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">"</span><span class="string">allows a single filter</span><span class="punct">"</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,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
|
+
|
@@ -0,0 +1,222 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'pp'
|
4
|
+
require 'rbconfig'
|
5
|
+
require 'erb'
|
6
|
+
require 'pathname'
|
7
|
+
|
8
|
+
require 'rspec'
|
9
|
+
require 'rspec/core/formatters/base_text_formatter'
|
10
|
+
require 'rspec/core/formatters/snippet_extractor'
|
11
|
+
|
12
|
+
class RSpec::Core::Formatters::WebKit < RSpec::Core::Formatters::BaseTextFormatter
|
13
|
+
include ERB::Util
|
14
|
+
|
15
|
+
# Version constant
|
16
|
+
VERSION = '2.0.0'
|
17
|
+
|
18
|
+
# Look up the datadir falling back to a relative path (mostly for prerelease testing)
|
19
|
+
DEFAULT_DATADIR = Pathname( Config.datadir('webkit-rspec-formatter') )
|
20
|
+
if DEFAULT_DATADIR.exist?
|
21
|
+
BASE_PATH = DEFAULT_DATADIR
|
22
|
+
else
|
23
|
+
BASE_PATH = Pathname( __FILE__ ).dirname.parent.parent.parent.parent +
|
24
|
+
'data/webkit-rspec-formatter'
|
25
|
+
end
|
26
|
+
|
27
|
+
# The base HREF used in the header to map stuff to the datadir
|
28
|
+
BASE_HREF = "file://#{BASE_PATH}/"
|
29
|
+
|
30
|
+
# The directory to grab ERb templates out of
|
31
|
+
TEMPLATE_DIR = BASE_PATH + 'templates'
|
32
|
+
|
33
|
+
# The page part templates
|
34
|
+
HEADER_TEMPLATE = TEMPLATE_DIR + 'header.rhtml'
|
35
|
+
PASSED_EXAMPLE_TEMPLATE = TEMPLATE_DIR + 'passed.rhtml'
|
36
|
+
FAILED_EXAMPLE_TEMPLATE = TEMPLATE_DIR + 'failed.rhtml'
|
37
|
+
PENDING_EXAMPLE_TEMPLATE = TEMPLATE_DIR + 'pending.rhtml'
|
38
|
+
PENDFIX_EXAMPLE_TEMPLATE = TEMPLATE_DIR + 'pending-fixed.rhtml'
|
39
|
+
FOOTER_TEMPLATE = TEMPLATE_DIR + 'footer.rhtml'
|
40
|
+
|
41
|
+
|
42
|
+
### Create a new formatter
|
43
|
+
def initialize( output ) # :notnew:
|
44
|
+
super
|
45
|
+
@previous_nesting_depth = 0
|
46
|
+
@example_number = 0
|
47
|
+
@failcounter = 0
|
48
|
+
@snippet_extractor = RSpec::Core::Formatters::SnippetExtractor.new
|
49
|
+
@example_templates = {
|
50
|
+
:passed => self.load_template(PASSED_EXAMPLE_TEMPLATE),
|
51
|
+
:failed => self.load_template(FAILED_EXAMPLE_TEMPLATE),
|
52
|
+
:pending => self.load_template(PENDING_EXAMPLE_TEMPLATE),
|
53
|
+
:pending_fixed => self.load_template(PENDFIX_EXAMPLE_TEMPLATE),
|
54
|
+
}
|
55
|
+
|
56
|
+
Thread.current['logger-output'] = []
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
######
|
61
|
+
public
|
62
|
+
######
|
63
|
+
|
64
|
+
# Attributes made readable for ERb
|
65
|
+
attr_reader :example_group_number, :example_number, :example_count
|
66
|
+
|
67
|
+
# The counter for failed example IDs
|
68
|
+
attr_accessor :failcounter
|
69
|
+
|
70
|
+
|
71
|
+
### Start the page by rendering the header.
|
72
|
+
def start( example_count )
|
73
|
+
@output.puts self.render_header( example_count )
|
74
|
+
@output.flush
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
### Callback called by each example group when it's entered --
|
79
|
+
def example_group_started( example_group )
|
80
|
+
super
|
81
|
+
nesting_depth = example_group.ancestors.length
|
82
|
+
|
83
|
+
# Close the previous example groups if this one isn't a
|
84
|
+
# descendent of the previous one
|
85
|
+
if @previous_nesting_depth.nonzero? && @previous_nesting_depth >= nesting_depth
|
86
|
+
( @previous_nesting_depth - nesting_depth + 1 ).times do
|
87
|
+
@output.puts " </dl>", "</section>", " </dd>"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
@output.puts "<!-- nesting: %d, previous: %d -->" %
|
92
|
+
[ nesting_depth, @previous_nesting_depth ]
|
93
|
+
@previous_nesting_depth = nesting_depth
|
94
|
+
|
95
|
+
if @previous_nesting_depth == 1
|
96
|
+
@output.puts %{<section class="example-group">}
|
97
|
+
else
|
98
|
+
@output.puts %{<dd class="nested-group"><section class="example-group">}
|
99
|
+
end
|
100
|
+
|
101
|
+
@output.puts %{ <dl>},
|
102
|
+
%{ <dt id="%s">%s</dt>} % [
|
103
|
+
example_group.name.gsub(/[\W_]+/, '-').downcase,
|
104
|
+
h(example_group.description)
|
105
|
+
]
|
106
|
+
@output.flush
|
107
|
+
end
|
108
|
+
alias_method :add_example_group, :example_group_started
|
109
|
+
|
110
|
+
|
111
|
+
### Fetch any log messages added to the thread-local Array
|
112
|
+
def log_messages
|
113
|
+
return Thread.current[ 'logger-output' ] || []
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
### Callback -- called when the examples are finished.
|
118
|
+
def start_dump
|
119
|
+
@previous_nesting_depth.downto( 1 ) do |i|
|
120
|
+
@output.puts " </dl>",
|
121
|
+
"</section>"
|
122
|
+
@output.puts " </dd>" unless i == 1
|
123
|
+
end
|
124
|
+
|
125
|
+
@output.flush
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
### Callback -- called when an example is entered
|
130
|
+
def example_started( example )
|
131
|
+
@example_number += 1
|
132
|
+
Thread.current[ 'logger-output' ] ||= []
|
133
|
+
Thread.current[ 'logger-output' ].clear
|
134
|
+
end
|
135
|
+
|
136
|
+
|
137
|
+
### Callback -- called when an example is exited with no failures.
|
138
|
+
def example_passed( example )
|
139
|
+
status = 'passed'
|
140
|
+
@output.puts( @example_templates[:passed].result(binding()) )
|
141
|
+
@output.flush
|
142
|
+
end
|
143
|
+
|
144
|
+
|
145
|
+
### Callback -- called when an example is exited with a failure.
|
146
|
+
def example_failed( example )
|
147
|
+
super
|
148
|
+
|
149
|
+
counter = self.failcounter += 1
|
150
|
+
exception = example.metadata[:execution_result][:exception_encountered]
|
151
|
+
extra = self.extra_failure_content( exception )
|
152
|
+
template = if exception.is_a?( RSpec::Core::PendingExampleFixedError )
|
153
|
+
then @example_templates[:pending_fixed]
|
154
|
+
else @example_templates[:failed]
|
155
|
+
end
|
156
|
+
|
157
|
+
@output.puts( template.result(binding()) )
|
158
|
+
@output.flush
|
159
|
+
end
|
160
|
+
|
161
|
+
|
162
|
+
### Callback -- called when an example is exited via a 'pending'.
|
163
|
+
def example_pending( example )
|
164
|
+
status = 'pending'
|
165
|
+
@output.puts( @example_templates[:pending].result(binding()) )
|
166
|
+
@output.flush
|
167
|
+
end
|
168
|
+
|
169
|
+
|
170
|
+
### Format backtrace lines to include a textmate link to the file/line in question.
|
171
|
+
def backtrace_line( line )
|
172
|
+
return nil unless line = super
|
173
|
+
return nil if line =~ %r{r?spec/mate|textmate-command}
|
174
|
+
return h( line.strip ).gsub( /([^:]*\.rb):(\d*)/ ) do
|
175
|
+
"<a href=\"txmt://open?url=file://#{File.expand_path($1)}&line=#{$2}\">#{$1}:#{$2}</a> "
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
|
180
|
+
### Return any stuff that should be appended to the current example
|
181
|
+
### because it's failed. Returns a snippet of the source around the
|
182
|
+
### failure.
|
183
|
+
def extra_failure_content( exception )
|
184
|
+
snippet = @snippet_extractor.snippet( exception )
|
185
|
+
return " <pre class=\"ruby\"><code>#{snippet}</code></pre>"
|
186
|
+
end
|
187
|
+
|
188
|
+
|
189
|
+
### Returns content to be output when a failure occurs during the run; overridden to
|
190
|
+
### do nothing, as failures are handled by #example_failed.
|
191
|
+
def dump_failures( *unused )
|
192
|
+
end
|
193
|
+
|
194
|
+
|
195
|
+
### Output the content generated at the end of the run.
|
196
|
+
def dump_summary( duration, example_count, failure_count, pending_count )
|
197
|
+
@output.puts self.render_footer( duration, example_count, failure_count, pending_count )
|
198
|
+
@output.flush
|
199
|
+
end
|
200
|
+
|
201
|
+
|
202
|
+
### Render the header template in the context of the receiver.
|
203
|
+
def render_header( example_count )
|
204
|
+
template = self.load_template( HEADER_TEMPLATE )
|
205
|
+
return template.result( binding() )
|
206
|
+
end
|
207
|
+
|
208
|
+
|
209
|
+
### Render the footer template in the context of the receiver.
|
210
|
+
def render_footer( duration, example_count, failure_count, pending_count )
|
211
|
+
template = self.load_template( FOOTER_TEMPLATE )
|
212
|
+
return template.result( binding() )
|
213
|
+
end
|
214
|
+
|
215
|
+
|
216
|
+
### Load the ERB template at +templatepath+ and return it.
|
217
|
+
### @param [Pathname] templatepath the fully-qualified path to the template file
|
218
|
+
def load_template( templatepath )
|
219
|
+
return ERB.new( templatepath.read, nil, '%<>' ).freeze
|
220
|
+
end
|
221
|
+
|
222
|
+
end # class RSpec::Core::Formatter::WebKitFormatter
|
@@ -0,0 +1,65 @@
|
|
1
|
+
|
2
|
+
rspec_rails_plugin = File.join( ENV['TM_PROJECT_DIRECTORY'], 'vendor', 'plugins', 'rspec', 'lib' )
|
3
|
+
|
4
|
+
if File.directory?( rspec_rails_plugin )
|
5
|
+
$LOAD_PATH.unshift( rspec_rails_plugin )
|
6
|
+
elsif ENV['TM_RSPEC_HOME']
|
7
|
+
rspec_lib = File.join( ENV['TM_RSPEC_HOME'], 'lib' )
|
8
|
+
raise "TM_RSPEC_HOME points to a bad location: #{ENV['TM_RSPEC_HOME']}" unless
|
9
|
+
File.directory?( rspec_lib )
|
10
|
+
$LOAD_PATH.unshift( rspec_lib )
|
11
|
+
end
|
12
|
+
|
13
|
+
begin
|
14
|
+
require 'spec'
|
15
|
+
require 'spec/runner/formatter/webkit'
|
16
|
+
rescue LoadError => err
|
17
|
+
unless Object.const_defined?( :Gem )
|
18
|
+
require 'rubygems'
|
19
|
+
retry
|
20
|
+
end
|
21
|
+
raise
|
22
|
+
end
|
23
|
+
|
24
|
+
class SpecMate
|
25
|
+
def run_files(stdout, options={})
|
26
|
+
files = ENV['TM_SELECTED_FILES'].split(" ").map do |path|
|
27
|
+
File.expand_path(path[1..-2])
|
28
|
+
end
|
29
|
+
options.merge!({:files => files})
|
30
|
+
run(stdout, options)
|
31
|
+
end
|
32
|
+
|
33
|
+
def run_file(stdout, options={})
|
34
|
+
options.merge!({:files => [single_file]})
|
35
|
+
run(stdout, options)
|
36
|
+
end
|
37
|
+
|
38
|
+
def run_focussed(stdout, options={})
|
39
|
+
options.merge!({:files => [single_file], :line => ENV['TM_LINE_NUMBER']})
|
40
|
+
run(stdout, options)
|
41
|
+
end
|
42
|
+
|
43
|
+
def run(stdout, options)
|
44
|
+
formatter = ENV['TM_RSPEC_FORMATTER'] || 'RSpec::Core::Formatter::WebKit'
|
45
|
+
|
46
|
+
argv = []
|
47
|
+
argv += ENV['TM_RSPEC_OPTS'].split(" ") if ENV['TM_RSPEC_OPTS']
|
48
|
+
argv += options[:files].dup
|
49
|
+
argv << '--format' << formatter
|
50
|
+
argv << '--line' << options[:line] if options[:line]
|
51
|
+
|
52
|
+
Dir.chdir(ENV['TM_PROJECT_DIRECTORY']) do
|
53
|
+
::RSpec::Core::CommandLine.run(RSpec::Core::OptionParser.parse(argv, STDERR, stdout))
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
protected
|
58
|
+
def single_file
|
59
|
+
File.expand_path(ENV['TM_FILEPATH'])
|
60
|
+
end
|
61
|
+
|
62
|
+
def project_directory
|
63
|
+
File.expand_path(ENV['TM_PROJECT_DIRECTORY'])
|
64
|
+
end
|
65
|
+
end
|