2008-06-12 02:00:35 -04:00
# Results formatter
module Formatter
2008-06-17 19:58:05 -04:00
# Base abstract class for results formatting.
2008-06-12 02:00:35 -04:00
class Formatter
2008-06-17 19:58:05 -04:00
# Takes an output stream and a print width.
2008-06-18 18:24:34 -04:00
def initialize ( o , w = 100 )
2008-06-12 02:00:35 -04:00
raise TypeError . new ( " Type %s of parameter %s is not IO " % [ o . class , o ] ) \
unless o . instance_of? IO
@out = o
@maxWidth = w
@rowCount = 0
end
2008-06-17 19:58:05 -04:00
attr_reader :rowCount
2008-06-12 02:00:35 -04:00
def header ( args = [ ] )
2008-06-17 19:58:05 -04:00
row ( args , false ) if args . length > 0
2008-06-12 02:00:35 -04:00
@rowCount = 0
end
2008-06-17 19:58:05 -04:00
# Output a row.
# Inset is whether or not to offset row by a space.
def row ( args = [ ] , inset = true )
2008-06-12 02:00:35 -04:00
if not args or args . length == 0
# Print out nothing
return
end
2008-06-17 19:58:05 -04:00
if args . class == String
output ( @maxWidth , args )
puts
return
end
2008-06-12 02:00:35 -04:00
# TODO: Look at the type. Is it RowResult?
if args . length == 1
splits = split ( @maxWidth , dump ( args [ 0 ] ) )
for l in splits
output ( @maxWidth , l )
puts
end
elsif args . length == 2
2008-06-18 18:24:34 -04:00
col1width = @maxWidth / 4
col2width = @maxWidth - col1width - 2
2008-06-12 02:00:35 -04:00
splits1 = split ( col1width , dump ( args [ 0 ] ) )
splits2 = split ( col2width , dump ( args [ 1 ] ) )
biggest = ( splits2 . length > splits1 . length ) ? splits2 . length : splits1 . length
index = 0
while index < biggest
2008-06-17 19:58:05 -04:00
if inset
# Inset by one space if inset is set.
@out . print ( " " )
end
2008-06-12 02:00:35 -04:00
output ( col1width , splits1 [ index ] )
2008-06-17 19:58:05 -04:00
if not inset
# Add extra space so second column lines up w/ second column output
@out . print ( " " )
end
2008-06-12 02:00:35 -04:00
@out . print ( " " )
output ( col2width , splits2 [ index ] )
index += 1
puts
end
else
# Print a space to set off multi-column rows
print ' '
first = true
for e in args
@out . print " " unless first
first = false
@out . print e
end
puts
end
@rowCount += 1
end
def split ( width , str )
result = [ ]
index = 0
while index < str . length do
result << str . slice ( index , index + width )
index += width
end
result
end
def dump ( str )
# Remove double-quotes added by 'dump'.
2008-06-17 19:58:05 -04:00
if str . instance_of? Fixnum
return
end
2008-06-12 02:00:35 -04:00
return str . dump . slice ( 1 , str . length )
end
def output ( width , str )
# Make up a spec for printf
2008-06-18 14:18:26 -04:00
spec = " %%-%ds " % width
@out . printf ( spec , str )
2008-06-12 02:00:35 -04:00
end
def footer ( startTime = nil )
if not startTime
return
end
# Only output elapsed time and row count if startTime passed
2008-06-17 19:58:05 -04:00
@out . puts ( " %d row(s) in %.4f seconds " % [ @rowCount , Time . now - startTime ] )
2008-06-12 02:00:35 -04:00
end
end
class Console < Formatter
end
class XHTMLFormatter < Formatter
# http://www.germane-software.com/software/rexml/doc/classes/REXML/Document.html
# http://www.crummy.com/writing/RubyCookbook/test_results/75942.html
end
class JSON < Formatter
end
# Do a bit of testing.
if $0 == __FILE__
formatter = Console . new ( STDOUT )
formatter . header ( [ 'a' , 'b' ] )
formatter . row ( [ 'a' , 'b' ] )
formatter . row ( [ 'xxxxxxxxx xxxxxxxxxxx xxxxxxxxxxx xxxxxxxxxxxx xxxxxxxxx xxxxxxxxxxxx xxxxxxxxxxxxxxx xxxxxxxxx xxxxxxxxxxxxxx' ] )
formatter . row ( [ 'yyyyyy yyyyyy yyyyy yyy' , 'xxxxxxxxx xxxxxxxxxxx xxxxxxxxxxx xxxxxxxxxxxx xxxxxxxxx xxxxxxxxxxxx xxxxxxxxxxxxxxx xxxxxxxxx xxxxxxxxxxxxxx xxx xx x xx xxx xx xx xx x xx x x xxx x x xxx x x xx x x x x x x xx ' ] )
formatter . footer ( )
end
end