Class: RSpec::Core::Formatters::WebKit

Inherits:
BaseFormatter
  • Object
show all
Includes:
ERB::Util
Defined in:
lib/rspec/core/formatters/webkit.rb

Constant Summary collapse

VERSION =

Version constant

'2.7.0'
DATADIR =

Look up the datadir falling back to a relative path (mostly for prerelease testing)

begin
	dir = Pathname( __FILE__ ).dirname.parent.parent.parent.parent +
	           'data/rspec-formatter-webkit'
	Pathname( dir )
end
BASE_HREF =

The base HREF used in the header to map stuff to the datadir

"file://#{DATADIR}/"
TEMPLATE_DIR =

The directory to grab ERb templates out of

DATADIR + 'templates'
HEADER_TEMPLATE =

The page part templates

TEMPLATE_DIR + 'header.rhtml'
PASSED_EXAMPLE_TEMPLATE =
TEMPLATE_DIR + 'passed.rhtml'
FAILED_EXAMPLE_TEMPLATE =
TEMPLATE_DIR + 'failed.rhtml'
PENDING_EXAMPLE_TEMPLATE =
TEMPLATE_DIR + 'pending.rhtml'
PENDFIX_EXAMPLE_TEMPLATE =
TEMPLATE_DIR + 'pending-fixed.rhtml'
SUMMARY_TEMPLATE =
TEMPLATE_DIR + 'summary.rhtml'
DEPRECATIONS_TEMPLATE =
TEMPLATE_DIR + 'deprecations.rhtml'
SEED_TEMPLATE =
TEMPLATE_DIR + 'seed.rhtml'
TEMPLATE_DIR + 'footer.rhtml'
BACKTRACE_EXCLUDE_PATTERN =

Pattern to match for excluding lines from backtraces

%r{spec/mate|textmate-command|rspec(-(core|expectations|mocks))?/}
PENDING_FIXED_EXCEPTION =

Figure out which class pending-example-fixed errors are (2.8 change)

if defined?( RSpec::Core::Pending::PendingExampleFixedError )
	RSpec::Core::Pending::PendingExampleFixedError
else
	RSpec::Core::PendingExampleFixedError
end

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(output) ⇒ WebKit

Create a new formatter



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/rspec/core/formatters/webkit.rb', line 83

def initialize( output ) # :notnew:
	super
	@previous_nesting_depth = 0
	@failcounter = 0
	@snippet_extractor = RSpec::Core::Formatters::HtmlSnippetExtractor.new
	@example_templates = {
		:passed        => self.load_template(PASSED_EXAMPLE_TEMPLATE),
		:failed        => self.load_template(FAILED_EXAMPLE_TEMPLATE),
		:pending       => self.load_template(PENDING_EXAMPLE_TEMPLATE),
		:pending_fixed => self.load_template(PENDFIX_EXAMPLE_TEMPLATE),
	}

	@deprecation_stream = []
	@summary_stream     = []
	@failed_examples    = []

	@deprecations = Set.new

	Thread.current['logger-output'] = []
end

Instance Attribute Details

#deprecationsObject (readonly)

The Set of deprecation notifications



116
117
118
# File 'lib/rspec/core/formatters/webkit.rb', line 116

def deprecations
  @deprecations
end

#example_countObject (readonly)

Attributes made readable for ERb



110
111
112
# File 'lib/rspec/core/formatters/webkit.rb', line 110

def example_count
  @example_count
end

#failcounterObject

The counter for failed example IDs



113
114
115
# File 'lib/rspec/core/formatters/webkit.rb', line 113

def failcounter
  @failcounter
end

#failed_examplesObject (readonly)

The Array of failed examples



119
120
121
# File 'lib/rspec/core/formatters/webkit.rb', line 119

def failed_examples
  @failed_examples
end

Instance Method Details

#close(notification) ⇒ Object

Callback – called at the very end.



260
261
262
263
264
# File 'lib/rspec/core/formatters/webkit.rb', line 260

def close( notification )
	footer = self.render_footer( notification )
	@output.puts( footer )
	@output.flush
end

#deprecation(notification) ⇒ Object

Callback – Add a deprecation warning.



237
238
239
# File 'lib/rspec/core/formatters/webkit.rb', line 237

def deprecation( notification )
	@deprecations.add( notification )
end

#deprecation_summary(notification) ⇒ Object

Callback – Called at the end with a summary of any deprecations encountered during the run.



244
245
246
247
248
# File 'lib/rspec/core/formatters/webkit.rb', line 244

def deprecation_summary( notification )
	html = self.render_deprecations
	@output.puts( html )
	@output.flush
end

#dump_summary(summary) ⇒ Object

Output the content generated at the end of the run.



229
230
231
232
233
# File 'lib/rspec/core/formatters/webkit.rb', line 229

def dump_summary( summary )
	html = self.render_summary( summary )
	@output.puts( html )
	@output.flush
end

#example_failed(notification) ⇒ Object

Callback – called when an example is exited with a failure.



201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/rspec/core/formatters/webkit.rb', line 201

def example_failed( notification )
	example   = notification.example

	self.failed_examples << example
	counter   = self.failed_examples.size

	exception = notification.exception
	extra     = self.extra_failure_content( exception )
	template  = if exception.is_a?( PENDING_FIXED_EXCEPTION )
		then @example_templates[:pending_fixed]
		else @example_templates[:failed]
		end

	@output.puts( template.result(binding()) )
	@output.flush
end

#example_group_started(notification) ⇒ Object

Callback called by each example group when it’s entered –



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/rspec/core/formatters/webkit.rb', line 141

def example_group_started( notification )
	super
	example_group = notification.group
	nesting_depth = example_group.ancestors.length

	# Close the previous example groups if this one isn't a
	# descendent of the previous one
	if @previous_nesting_depth.nonzero? && @previous_nesting_depth >= nesting_depth
		( @previous_nesting_depth - nesting_depth + 1 ).times do
			@output.puts "  </dl>", "</section>", "  </dd>"
		end
	end

	@output.puts "<!-- nesting: %d, previous: %d -->" %
		[ nesting_depth, @previous_nesting_depth ]
	@previous_nesting_depth = nesting_depth

	if @previous_nesting_depth == 1
		@output.puts %{<section class="example-group">}
	else
		@output.puts %{<dd class="nested-group"><section class="example-group">}
	end

	@output.puts %{  <dl>},
		%{  <dt id="%s">%s</dt>} % [
			example_group.name.gsub(/[\W_]+/, '-').downcase,
			h(example_group.description)
		]
	@output.flush
end

#example_passed(notification) ⇒ Object

Callback – called when an example is exited with no failures.



192
193
194
195
196
197
# File 'lib/rspec/core/formatters/webkit.rb', line 192

def example_passed( notification )
	example = notification.example
	status = 'passed'
	@output.puts( @example_templates[:passed].result(binding()) )
	@output.flush
end

#example_pending(notification) ⇒ Object

Callback – called when an example is exited via a ‘pending’.



220
221
222
223
224
225
# File 'lib/rspec/core/formatters/webkit.rb', line 220

def example_pending( notification )
	example = notification.example
	status = 'pending'
	@output.puts( @example_templates[:pending].result(binding()) )
	@output.flush
end

#example_started(notification) ⇒ Object

Callback – called when an example is entered



186
187
188
# File 'lib/rspec/core/formatters/webkit.rb', line 186

def example_started( notification )
	self.log_messages.clear
end

#extra_failure_content(exception) ⇒ Object

Return any stuff that should be appended to the current example because it’s failed. Returns a snippet of the source around the failure.



294
295
296
297
298
299
300
301
302
303
# File 'lib/rspec/core/formatters/webkit.rb', line 294

def extra_failure_content( exception )
	return '' unless exception

	backtrace = ( exception.backtrace || [] ).map do |line|
		RSpec.configuration.backtrace_formatter.backtrace_line( line )
	end.compact

	snippet = @snippet_extractor.snippet( backtrace )
	return "    <pre class=\"ruby\"><code>#{snippet}</code></pre>"
end

#find_shared_group(example) ⇒ Object

Find the innermost shared example group for the given example.



307
308
309
310
# File 'lib/rspec/core/formatters/webkit.rb', line 307

def find_shared_group( example )
	groups = example.example_group.parent_groups + [example.example_group]
	return groups.find {|group| group.[:shared_group_name]}
end

#format_backtrace(notification) ⇒ Object

Overriden to add txmt: links to the file paths in the backtrace.



272
273
274
275
276
277
# File 'lib/rspec/core/formatters/webkit.rb', line 272

def format_backtrace( notification )
	lines = notification.formatted_backtrace
	return lines.map do |line|
		link_backtrace_line( line )
	end
end

Link the filename and line number in the given line from a backtrace.



281
282
283
284
285
286
287
288
# File 'lib/rspec/core/formatters/webkit.rb', line 281

def link_backtrace_line( line )
	return line.strip.sub( /(?<filename>[^:]*\.rb):(?<line>\d*)(?<rest>.*)/ ) do
		match = $~
		fullpath = File.expand_path( match[:filename] )
		%|<a href="txmt://open?url=file://%s&amp;line=%s">%s:%s</a>%s| %
			[ fullpath, match[:line], match[:filename], match[:line], h(match[:rest]) ]
	end
end

#load_template(templatepath) ⇒ Object

Load the ERB template at templatepath and return it.



353
354
355
# File 'lib/rspec/core/formatters/webkit.rb', line 353

def load_template( templatepath )
	return ERB.new( templatepath.read, nil, '%<>' ).freeze
end

#log_messagesObject

Fetch any log messages added to the thread-local Array



123
124
125
# File 'lib/rspec/core/formatters/webkit.rb', line 123

def log_messages
	return Thread.current[ 'logger-output' ] ||= []
end

#render_deprecationsObject

Render the deprecation summary template in the context of the receiver.



332
333
334
335
# File 'lib/rspec/core/formatters/webkit.rb', line 332

def render_deprecations
	template = self.load_template( DEPRECATIONS_TEMPLATE )
	return template.result( binding() )
end

Render the footer template in the context of the receiver.



346
347
348
349
# File 'lib/rspec/core/formatters/webkit.rb', line 346

def render_footer( notification )
	template = self.load_template( FOOTER_TEMPLATE )
	return template.result( binding() )
end

#render_header(notification) ⇒ Object

Render the header template in the context of the receiver.



318
319
320
321
# File 'lib/rspec/core/formatters/webkit.rb', line 318

def render_header( notification )
	template = self.load_template( HEADER_TEMPLATE )
	return template.result( binding() )
end

#render_seed(notification) ⇒ Object

Render the seed template in the context of the receiver.



339
340
341
342
# File 'lib/rspec/core/formatters/webkit.rb', line 339

def render_seed( notification )
	template = self.load_template( SEED_TEMPLATE )
	return template.result( binding() )
end

#render_summary(summary) ⇒ Object

Render the summary template in the context of the receiver.



325
326
327
328
# File 'lib/rspec/core/formatters/webkit.rb', line 325

def render_summary( summary )
	template = self.load_template( SUMMARY_TEMPLATE )
	return template.result( binding() )
end

#seed(notification) ⇒ Object

Callback – called with the random seed if the test suite is run with random ordering.



252
253
254
255
256
# File 'lib/rspec/core/formatters/webkit.rb', line 252

def seed( notification )
	return unless notification.seed_used?
	html = self.render_seed( notification )
	@output.puts( html )
end

#start(notification) ⇒ Object

Start the page by rendering the header.



133
134
135
136
137
# File 'lib/rspec/core/formatters/webkit.rb', line 133

def start( notification )
	super
	@output.puts self.render_header( notification )
	@output.flush
end

#start_dump(notification) ⇒ Object

Callback – called when the examples are finished.



174
175
176
177
178
179
180
181
182
# File 'lib/rspec/core/formatters/webkit.rb', line 174

def start_dump( notification )
	@previous_nesting_depth.downto( 1 ) do |i|
		@output.puts "  </dl>",
		             "</section>"
		@output.puts "  </dd>" unless i == 1
	end

	@output.flush
end