specky/ruby/specky_formatter.rb
branchvim-stuff
changeset 21 cd1f3381c1ed
parent 19 763cef799c74
child 22 ed72213b1788
--- a/specky/ruby/specky_formatter.rb	Sat Dec 18 23:38:55 2010 -0800
+++ b/specky/ruby/specky_formatter.rb	Fri Dec 24 20:01:10 2010 -0800
@@ -14,8 +14,11 @@
 		@indent_level  = 0
 		@failure_index = 0
 		@failures      = []
+		@txt           = ''
+		@summary       = ''
 	end
 
+
 	########################################################################
 	### R S P E C  H O O K S
 	########################################################################
@@ -23,7 +26,6 @@
 	### Example group hook -- increase indentation, emit description
 	###
 	def example_group_started( example_group )
-		output.puts
 		self.out '+', '-' * (example_group.description.length + 2), '+'
 		self.out '| ', example_group.description, ' |'
 		self.out '+', '-' * (example_group.description.length + 2), '+'
@@ -73,13 +75,18 @@
 	### for Vim to fold.
 	###
 	def dump_failures
-		self.out "\n\n\n" unless @failures.empty?
+		self.out "\n" unless @failures.empty?
 
 		@failures.each_with_index do |example, index|
 			desc      = example.metadata[ :full_description ]
 			exception = example.execution_result[ :exception ]
+			file = line = nil
 
+			if exception.backtrace.first =~ /(.*):(\d+)/
+				file, line = $1, $2.to_i
+			end
 			self.out "FAILURE - #%d)" % [ index + 1 ]
+			self.out "%s:%d" % [ file, line ]
 
 			if RSpec::Core::PendingExampleFixedError === exception
 				self.out "%s FIXED" % [ desc ]
@@ -100,27 +107,55 @@
 					end
 				end
 			end
-			self.out "\n"
+
+			self.out exception_source( file, line ) if file && line
 		end
 	end
 
 
+	### Emit the source of the exception, with context lines.
+	###
+	def exception_source( file, line )
+		context = ''
+		low, high = line - 3, line + 3
+
+		File.open( file ).each_with_index do |cline, i|
+			cline.chomp!.rstrip!
+			next unless i >= low && i <= high
+			context << "  %s%4d: %s\n" % [ ( i == line ? '>>' : ' |' ), i, cline ]
+		end
+
+		return context
+
+	rescue
+		'Unable to parse exception context lines.'
+	end
+
+
 	### Emit summary data for all examples.
 	###
 	def dump_summary( duration, example_count, failure_count, pending_count )
 		succeeded = example_count - failure_count - pending_count
-		self.out '+', '-' * 49, '+'
-		self.out '|', ' ' * 18, '-- Summary --', ' ' * 18, '|'
-		self.out '+----------+-----------+--------+---------+-------+'
-		self.out '| Duration | Succeeded | Failed | Pending | Total |'
-		self.out '+----------+-----------+--------+---------+-------+'
+		@summary << "+%s+\n" % [ '-' * 49 ]
+		@summary << "|%s-- Summary --%s|\n" % [ ' ' * 18, ' ' * 18 ]
+		@summary << "+----------+-----------+--------+---------+-------+\n"
+		@summary << "| Duration | Succeeded | Failed | Pending | Total |\n"
+		@summary << "+----------+-----------+--------+---------+-------+\n"
 
-		self.out "| %7ss | %9s | %6s | %7s | %5s |" % [
+		@summary << "| %7ss | %9s | %6s | %7s | %5s |\n" % [
 			"%0.3f" % duration, succeeded, failure_count,
 			pending_count, example_count
 		]
 
-		self.out '+----------+-----------+--------+---------+-------+'
+		@summary << "+----------+-----------+--------+---------+-------+\n\n"
+	end
+
+
+	### End of run.  Dump it all out!
+	###
+	def close
+		output.puts @summary
+		output.puts @txt
 	end
 
 
@@ -132,7 +167,7 @@
 	###
 	def out( *msg )
 		msg = msg.join
-		output.puts "%s%s" % [ '  ' * @indent_level, msg ]
+		@txt << "%s%s\n" % [ '  ' * @indent_level, msg ]
 	end
 
 	### Format the basic example information, along with the run duration.