fit 1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. data/README.txt +203 -0
  2. data/Rakefile +111 -0
  3. data/bin/FitServer.rb +6 -0
  4. data/bin/fit +10 -0
  5. data/bin/fit.cgi +36 -0
  6. data/doc/examples/AllCombinations.html +55 -0
  7. data/doc/examples/AllFiles.html +60 -0
  8. data/doc/examples/AllPairs/function/cosine.html +57 -0
  9. data/doc/examples/AllPairs/function/sine.html +57 -0
  10. data/doc/examples/AllPairs/magnitude/180+30.html +45 -0
  11. data/doc/examples/AllPairs/magnitude/30.html +33 -0
  12. data/doc/examples/AllPairs/magnitude/360+30.html +45 -0
  13. data/doc/examples/AllPairs/magnitude/90-30.html +45 -0
  14. data/doc/examples/AllPairs/sign/change-sign.html +27 -0
  15. data/doc/examples/AllPairs/sign/multiply.html +31 -0
  16. data/doc/examples/AllPairs/sign/no-change.html +23 -0
  17. data/doc/examples/AllPairs.html +51 -0
  18. data/doc/examples/BinaryChop.html +89 -0
  19. data/doc/examples/CalculatorExample.html +108 -0
  20. data/doc/examples/ColumnIndex.html +43 -0
  21. data/doc/examples/ExampleTests.html +43 -0
  22. data/doc/examples/FitAcceptanceTests.html +53 -0
  23. data/doc/examples/GeoCoordinate.html +87 -0
  24. data/doc/examples/MusicExample.html +143 -0
  25. data/doc/examples/MusicExampleWithErrors.html +128 -0
  26. data/doc/examples/NetworkExample.html +47 -0
  27. data/doc/examples/WebPageExample.html +92 -0
  28. data/doc/examples/arithmetic.html +211 -0
  29. data/doc/examples/files/hp35bk.jpg +0 -0
  30. data/doc/examples/logo.gif +0 -0
  31. data/doc/fitnesse/FitNesse.RubY.AcceptanceTests.FixtureParameters.html +81 -0
  32. data/doc/fitnesse/FitNesse.RubY.AcceptanceTests.GracefulFixtureNames.html +87 -0
  33. data/doc/fitnesse/FitNesse.RubY.AcceptanceTests.GracefulMemberNames.html +73 -0
  34. data/doc/fitnesse/FitNesse.RubY.AcceptanceTests.ImportFixture.html +61 -0
  35. data/doc/fitnesse/FitNesse.RubY.AcceptanceTests.WaysToSpecifyaFixtureNamespace.html +81 -0
  36. data/doc/spec/annotation.html +3833 -0
  37. data/doc/spec/extensions.html +302 -0
  38. data/doc/spec/fixtures.html +5181 -0
  39. data/doc/spec/index.html +947 -0
  40. data/doc/spec/parse.html +3094 -0
  41. data/lib/eg/all_combinations.rb +44 -0
  42. data/lib/eg/all_files.rb +94 -0
  43. data/lib/eg/all_pairs.rb +172 -0
  44. data/lib/eg/arithmetic_column_fixture.rb +35 -0
  45. data/lib/eg/arithmetic_fixture.rb +29 -0
  46. data/lib/eg/binary_chop.rb +100 -0
  47. data/lib/eg/calculator.rb +69 -0
  48. data/lib/eg/column_index.rb +85 -0
  49. data/lib/eg/division.rb +13 -0
  50. data/lib/eg/echo_args_fixture.rb +9 -0
  51. data/lib/eg/example_tests.rb +84 -0
  52. data/lib/eg/music/Music.txt +38 -0
  53. data/lib/eg/music/browser.rb +60 -0
  54. data/lib/eg/music/display.rb +24 -0
  55. data/lib/eg/music/music.rb +67 -0
  56. data/lib/eg/music/music_library.rb +70 -0
  57. data/lib/eg/music/music_player.rb +77 -0
  58. data/lib/eg/music/realtime.rb +39 -0
  59. data/lib/eg/music/simulator.rb +81 -0
  60. data/lib/eg/nested/bob.rb +12 -0
  61. data/lib/eg/nested/bob_the_builder_fixture.rb +11 -0
  62. data/lib/eg/net/simulator.rb +69 -0
  63. data/lib/eg/page.rb +91 -0
  64. data/lib/eg/sqrt.rb +19 -0
  65. data/lib/fat/annotation_fixture.rb +83 -0
  66. data/lib/fat/color.rb +45 -0
  67. data/lib/fat/divide.rb +13 -0
  68. data/lib/fat/document_parse_fixture.rb +67 -0
  69. data/lib/fat/equals.rb +59 -0
  70. data/lib/fat/fixture_name_fixture.rb +67 -0
  71. data/lib/fat/html_to_text_fixture.rb +20 -0
  72. data/lib/fat/money.rb +18 -0
  73. data/lib/fat/output_fixture.rb +32 -0
  74. data/lib/fat/parse_fixture.rb +92 -0
  75. data/lib/fat/reference_fixture.rb +31 -0
  76. data/lib/fat/standard_annotation_fixture.rb +58 -0
  77. data/lib/fat/string_writer.rb +12 -0
  78. data/lib/fat/table.rb +23 -0
  79. data/lib/fat/table_parse_fixture.rb +33 -0
  80. data/lib/fat/text_to_html_fixture.rb +21 -0
  81. data/lib/fit/action_fixture.rb +65 -0
  82. data/lib/fit/column_fixture.rb +104 -0
  83. data/lib/fit/file_runner.rb +80 -0
  84. data/lib/fit/fit_protocol.rb +62 -0
  85. data/lib/fit/fit_server.rb +173 -0
  86. data/lib/fit/fixture.rb +309 -0
  87. data/lib/fit/fixture_loader.rb +75 -0
  88. data/lib/fit/import_fixture.rb +9 -0
  89. data/lib/fit/parse.rb +206 -0
  90. data/lib/fit/primitive_fixture.rb +52 -0
  91. data/lib/fit/row_fixture.rb +188 -0
  92. data/lib/fit/scientific_double.rb +70 -0
  93. data/lib/fit/summary.rb +46 -0
  94. data/lib/fit/timed_action_fixture.rb +35 -0
  95. data/lib/fit/type_adapter.rb +95 -0
  96. data/lib/fit/wiki_runner.rb +15 -0
  97. data/lib/fittask.rb +184 -0
  98. data/test/all_tests.rb +13 -0
  99. data/test/file_runner_test.rb +52 -0
  100. data/test/fit_server_test.rb +214 -0
  101. data/test/fixture_loader_test.rb +71 -0
  102. data/test/fixture_test.rb +41 -0
  103. data/test/fixtures/fail_fixture.rb +9 -0
  104. data/test/fixtures/pass_fixture.rb +9 -0
  105. data/test/framework_test.rb +51 -0
  106. data/test/parse_test.rb +101 -0
  107. data/test/row_fixture_test.rb +44 -0
  108. data/test/scientific_double_test.rb +35 -0
  109. data/test/type_adapter_test.rb +120 -0
  110. metadata +165 -0
@@ -0,0 +1,58 @@
1
+ # Copyright (c) 2002 Cunningham & Cunningham, Inc.
2
+ # Released under the terms of the GNU General Public License version 2 or later.
3
+
4
+ require 'fit/column_fixture'
5
+ require 'fat/string_writer'
6
+
7
+ module Fat
8
+
9
+ class StandardAnnotationFixture < Fit::ColumnFixture
10
+
11
+ attr_accessor :original_html, :annotation, :text
12
+
13
+ def initialize
14
+ super
15
+ @original_html = 'Text'
16
+ end
17
+
18
+ def output
19
+ parse = Fit::Parse.new @original_html, ['td']
20
+ testbed = Fit::Fixture.new
21
+ case @annotation
22
+ when 'right' then testbed.right(parse)
23
+ when 'wrong' then testbed.wrong(parse, @text)
24
+ when 'error' then testbed.error(parse, @text)
25
+ when 'info' then testbed.info(parse, @text)
26
+ when 'ignore' then testbed.ignore(parse)
27
+ else return "unknown type: #@type"
28
+ end
29
+ generate_output parse
30
+ end
31
+
32
+ def do_cell cell, column
33
+ begin
34
+ if column == 4
35
+ cell.body = rendered_output
36
+ else
37
+ super
38
+ end
39
+ rescue Exception => e
40
+ exception cell, e
41
+ end
42
+ end
43
+
44
+ def rendered_output
45
+ '<table border="1"><tr>' + output + '</tr></table>'
46
+ end
47
+
48
+ # Code smell note: copied from Fat::ParseFixture
49
+ def generate_output parse
50
+ result = StringWriter.new
51
+ parse.print result
52
+ result.to_s
53
+ end
54
+
55
+ private :generate_output
56
+ end
57
+
58
+ end
@@ -0,0 +1,12 @@
1
+ # Copyright (c) 2002 Cunningham & Cunningham, Inc.
2
+ # Released under the terms of the GNU General Public License version 2 or later.
3
+
4
+ module Fat
5
+
6
+ class StringWriter
7
+ def initialize; @s = ''; end
8
+ def print s; @s += s.to_s; end
9
+ def to_s; @s; end
10
+ end
11
+
12
+ end
data/lib/fat/table.rb ADDED
@@ -0,0 +1,23 @@
1
+ # Copyright (c) 2002 Cunningham & Cunningham, Inc.
2
+ # Released under the terms of the GNU General Public License version 2 or later.
3
+
4
+ require 'fit/fixture'
5
+ require 'fit/parse'
6
+
7
+ module Fat
8
+
9
+ class Table < Fit::Fixture
10
+ @@table = nil
11
+ def Table.table; @@table; end
12
+ def Table.table= table; @@table = table; end
13
+ def do_rows rows
14
+ @@table = Fit::ParseHolder.create('table', nil, Table.copy(rows), nil)
15
+ # evaluate the rest of the table like a runner
16
+ Fit::Fixture.new.do_tables @@table
17
+ end
18
+ def Table.copy tree
19
+ tree.nil? ? nil : Fit::ParseHolder.create(tree.tag, tree.body, Table.copy(tree.parts), Table.copy(tree.more))
20
+ end
21
+ end
22
+
23
+ end
@@ -0,0 +1,33 @@
1
+ # Copyright (c) 2002 Cunningham & Cunningham, Inc.
2
+ # Released under the terms of the GNU General Public License version 2 or later.
3
+
4
+ require 'fit/column_fixture'
5
+
6
+ module Fat
7
+
8
+ class TableParseFixture < Fit::ColumnFixture
9
+ attr_accessor :html, :row, :column
10
+ def cell_body
11
+ cell.body
12
+ end
13
+ def cell_tag
14
+ cell.tag
15
+ end
16
+ def row_tag
17
+ row.tag
18
+ end
19
+ def table_tag
20
+ table.tag
21
+ end
22
+ def cell
23
+ row.at 0, @column - 1
24
+ end
25
+ def row
26
+ table.at 0, @row - 1
27
+ end
28
+ def table
29
+ Fit::Parse.new(@html)
30
+ end
31
+ end
32
+
33
+ end
@@ -0,0 +1,21 @@
1
+ # Copyright (c) 2002 Cunningham & Cunningham, Inc.
2
+ # Released under the terms of the GNU General Public License version 2 or later.
3
+
4
+ require 'fit/column_fixture'
5
+ require 'fit/fixture'
6
+
7
+ module Fat
8
+
9
+ class TextToHtmlFixture < Fit::ColumnFixture
10
+ attr_accessor :text
11
+ def html
12
+ @text = unescape_ascii @text
13
+ Fit::Fixture.escape @text
14
+ end
15
+ def unescape_ascii text
16
+ text.gsub(/\\n/, "\n").gsub(/\\r/, "\r")
17
+ end
18
+ private :unescape_ascii
19
+ end
20
+
21
+ end
@@ -0,0 +1,65 @@
1
+ # Copyright (c) 2002 Cunningham & Cunningham, Inc.
2
+ # Released under the terms of the GNU General Public License version 2 or later.
3
+
4
+ require 'fit/fixture'
5
+ require 'fit/type_adapter'
6
+
7
+ module Fit
8
+
9
+ class ActionFixture < Fixture
10
+
11
+ attr_reader :cells
12
+ protected :cells
13
+ @@actor = nil
14
+
15
+ def ActionFixture.actor; @@actor; end
16
+ def ActionFixture.actor= value
17
+ @@actor = value
18
+ end
19
+
20
+ def do_cells cells
21
+ @cells = cells
22
+ begin
23
+ send(cells.text)
24
+ rescue Exception => e
25
+ exception cells, e
26
+ end
27
+ end
28
+
29
+ def start
30
+ klass = find_class @cells.more.text # using reflection
31
+ @@actor = klass.new
32
+ end
33
+
34
+ # ActionFixture.enter could be called with regular methods
35
+ # featuring a single argument, or on setters methods of the
36
+ # form 'name=' when an assignment on an attr is tried.
37
+ def enter
38
+ method_name = Fixture.camel @cells.more.text
39
+ parameter = @cells.more.more.text
40
+ adapter = TypeAdapter.for(@@actor, method_name, false)
41
+ adapter.type = @@actor.class.metadata[method_name]
42
+ argument = adapter.parse(parameter)
43
+ m = @@actor.method method_name
44
+ if m.arity == 1
45
+ @@actor.send(method_name, argument)
46
+ else
47
+ adapter.set argument
48
+ end
49
+ end
50
+
51
+ def press
52
+ method_name = Fixture.camel @cells.more.text
53
+ @@actor.send method_name
54
+ end
55
+
56
+ def check
57
+ method_name = Fixture.camel @cells.more.text
58
+ adapter = TypeAdapter.for(@@actor, method_name, false)
59
+ adapter.type = @@actor.class.metadata[method_name]
60
+ super(@cells.more.more, adapter)
61
+ end
62
+
63
+ end
64
+
65
+ end
@@ -0,0 +1,104 @@
1
+ # Copyright (c) 2002 Cunningham & Cunningham, Inc.
2
+ # Released under the terms of the GNU General Public License version 2 or later.
3
+
4
+ require 'fit/fixture'
5
+ require 'fit/type_adapter'
6
+
7
+ module Fit
8
+
9
+ class ColumnFixture < Fixture
10
+
11
+ attr_accessor :column_bindings, :has_executed
12
+ protected :column_bindings, :column_bindings=, :has_executed, :has_executed=
13
+
14
+ # Traversal
15
+
16
+ def do_rows rows
17
+ bind rows.parts
18
+ super(rows.more)
19
+ end
20
+
21
+ def do_row row
22
+ @has_executed = false
23
+ begin
24
+ reset
25
+ super
26
+ execute if not @has_executed
27
+ rescue Exception => e
28
+ exception row.leaf, e
29
+ end
30
+ end
31
+
32
+ def do_cell cell, column_index
33
+ adapter = @column_bindings[column_index]
34
+ begin
35
+ text = cell.text
36
+ if text.empty?
37
+ check cell, adapter
38
+ elsif adapter.nil?
39
+ ignore cell
40
+ elsif adapter.is_output?
41
+ check cell, adapter
42
+ else
43
+ adapter.set(adapter.parse(text))
44
+ end
45
+ rescue Exception => e
46
+ exception cell, e
47
+ end
48
+ end
49
+
50
+ def check cell, adapter
51
+ unless @has_executed
52
+ begin
53
+ execute
54
+ rescue Exception => e
55
+ exception cell, e
56
+ end
57
+ @has_executed = true
58
+ end
59
+ super
60
+ end
61
+
62
+ def reset
63
+ # about to process first cell of row
64
+ end
65
+
66
+ def execute
67
+ # about to process first method call of row
68
+ end
69
+
70
+ # Utility
71
+
72
+ protected
73
+
74
+ def bind heads
75
+ @column_bindings = []
76
+ until heads.nil?
77
+ name = heads.text
78
+ begin
79
+ if name.empty?
80
+ @column_bindings << nil
81
+ else
82
+ suffix = ''
83
+ if name =~ /\(\)$/
84
+ suffix = '()'
85
+ name = name[0...-2]
86
+ end
87
+ name = name.split(/([a-zA-Z][^A-Z]+)/).delete_if {|e| e.empty?}.collect {|e| e.downcase}.join('_')
88
+ name += suffix
89
+ adapter = TypeAdapter.for(self, name)
90
+ adapter.type = get_target_class.metadata[name]
91
+ @column_bindings << adapter
92
+ end
93
+ rescue Exception => e
94
+ exception heads, e
95
+ end
96
+ heads = heads.more
97
+ end
98
+ end
99
+
100
+ def get_target_class; self.class; end
101
+
102
+ end
103
+
104
+ end
@@ -0,0 +1,80 @@
1
+ # Copyright (c) 2002 Cunningham & Cunningham, Inc.
2
+ # Released under the terms of the GNU General Public License version 2 or later.
3
+
4
+ require 'fit/fixture'
5
+ require 'fit/parse'
6
+
7
+ require 'fileutils' # for report generation
8
+
9
+ module Fit
10
+
11
+ class FileRunner
12
+ attr_accessor :input, :tables, :fixture, :output
13
+
14
+ def initialize
15
+ @fixture = Fixture.new
16
+ end
17
+
18
+ def run args
19
+ process_args args
20
+ process
21
+ $stderr.puts @fixture.totals
22
+ exit @fixture.total_errors
23
+ end
24
+
25
+ def process_args args
26
+ error "Usage: #{File.basename($0)} input_file output_file" unless args.size == 2
27
+
28
+ input_name = File.expand_path args[0]
29
+ input_file = File.open input_name
30
+ output_name = File.expand_path args[1]
31
+ FileUtils.mkpath File.dirname(output_name)
32
+ @output = File.open output_name, 'w'
33
+ @fixture.summary['input file'] = input_name
34
+ @fixture.summary['input update'] = input_file.mtime.to_s
35
+ @fixture.summary['output file'] = output_name
36
+ @input = input_file.read
37
+ input_file.close
38
+ end
39
+
40
+ def process
41
+ begin
42
+ unless @input.index('<wiki>').nil?
43
+ @tables = Parse.new @input, ['wiki', 'table', 'tr', 'td']
44
+ @fixture.do_tables @tables.parts
45
+ else
46
+ @tables = Parse.new @input, ['table', 'tr', 'td']
47
+ @fixture.do_tables @tables
48
+ end
49
+ rescue Exception => e
50
+ exception e
51
+ end
52
+ @tables.print @output
53
+ @output.close
54
+ end
55
+
56
+ def exception e
57
+ @tables = ParseHolder.create 'body', 'Unable to parse input. Input ignored.', nil, nil
58
+ @fixture.exception @tables, e
59
+ end
60
+
61
+ def error msg
62
+ $stderr.puts msg
63
+ exit -1
64
+ end
65
+
66
+ protected :exception, :error
67
+
68
+ end
69
+
70
+ end
71
+
72
+ # The main loop of the program
73
+ # if __FILE__ == $0
74
+ # begin
75
+ # Fit::FileRunner.new.run ARGV
76
+ # rescue Exception => e
77
+ # $stderr.puts e.message
78
+ # exit -1
79
+ # end
80
+ # end
@@ -0,0 +1,62 @@
1
+ require 'fit/fixture'
2
+
3
+ module Fit
4
+
5
+ class FitProtocol
6
+
7
+ def FitProtocol.read_size(input)
8
+ str_value = read(10, input)
9
+ return str_value.to_i
10
+ end
11
+
12
+ def FitProtocol.read(bytes, input)
13
+ value = input.read(bytes)
14
+ return value
15
+ end
16
+
17
+ def FitProtocol.read_document(input)
18
+ byte_count = read_size(input)
19
+ return read(byte_count, input)
20
+ end
21
+
22
+ def FitProtocol.read_counts(input)
23
+ counts = Counts.new
24
+ counts.right = FitProtocol.read_size(input)
25
+ counts.wrong = FitProtocol.read_size(input)
26
+ counts.ignores = FitProtocol.read_size(input)
27
+ counts.exceptions = FitProtocol.read_size(input)
28
+ return counts
29
+ end
30
+
31
+ def FitProtocol.write_size(size, output)
32
+ formatted_size = FitProtocol.format_number(size)
33
+ output.write(formatted_size)
34
+ output.flush
35
+ end
36
+
37
+ def FitProtocol.write_document(document, output)
38
+ FitProtocol.write_size(document.size, output)
39
+ output.write(document)
40
+ output.flush
41
+ end
42
+
43
+ def FitProtocol.write_counts(counts, output)
44
+ FitProtocol.write_size(0, output)
45
+ FitProtocol.write_size(counts.right, output)
46
+ FitProtocol.write_size(counts.wrong, output)
47
+ FitProtocol.write_size(counts.ignores, output)
48
+ FitProtocol.write_size(counts.exceptions, output)
49
+ end
50
+
51
+ def FitProtocol.format_number(size)
52
+ number_of_zeros = 10 - size.to_s.size
53
+ formatted_value = ""
54
+ number_of_zeros.times do
55
+ formatted_value << '0'
56
+ end
57
+ formatted_value << size.to_s
58
+ return formatted_value
59
+ end
60
+ end
61
+
62
+ end
@@ -0,0 +1,173 @@
1
+ # Written by Object Mentor, Inc. 2005
2
+ # Copyright (c) 2002 Cunningham & Cunningham, Inc.
3
+ # Released under the terms of the GNU General Public License version 2 or later.
4
+
5
+ require 'fit/fixture'
6
+ require 'fit/parse'
7
+ require 'fit/fit_protocol'
8
+ require 'socket'
9
+
10
+ module Fit
11
+
12
+ class FitServer
13
+
14
+ attr_accessor :host, :port, :test_ticket, :verbose
15
+ attr_reader :reason_for_bad_connection, :counts
16
+
17
+ def run(args)
18
+ if args(args)
19
+ connected = establish_connection
20
+ if not connected
21
+ puts "Could not connect. " + @reason_for_bad_connection
22
+ return -1
23
+ else
24
+ process
25
+ close_connection
26
+ finish
27
+ return exit_code
28
+ end
29
+ else
30
+ usage
31
+ return -1
32
+ end
33
+ end
34
+
35
+ def args(arg_list)
36
+ begin
37
+ arg_count = arg_list.size
38
+ if arg_count == 4 and arg_list.shift == '-v'
39
+ @verbose = true
40
+ elsif arg_count != 3
41
+ return false
42
+ end
43
+ @host = arg_list.shift
44
+ @port = arg_list.shift.to_i
45
+ return false if @port.zero?;
46
+ @test_ticket = arg_list.shift
47
+ return true
48
+ rescue => exception
49
+ return false
50
+ end
51
+ end
52
+
53
+ def usage
54
+ puts "Usage: ruby FitServer.rb [options] <host> <port> <test_ticket>"
55
+ puts " -v: verbose"
56
+ end
57
+
58
+ def build_request
59
+ return "GET /?responder=socketCatcher&ticket=" + @test_ticket + " HTTP/1.1\r\n\r\n"
60
+ end
61
+
62
+ def close_connection
63
+ @socket.close
64
+ end
65
+
66
+ def establish_connection
67
+ say "Connecting to " + @host.to_s + ":" + @port.to_s
68
+ @socket = TCPSocket.new(@host, @port)
69
+ @socket.print(build_request)
70
+ @socket.flush
71
+ status = FitProtocol.read_size(@socket)
72
+ unless status.zero?
73
+ @reason_for_bad_connection = FitProtocol.read(status, @socket)
74
+ say "\t> failed to connect: " + @reason_for_bad_connection
75
+ return false
76
+ else
77
+ say "\t> connected"
78
+ return true
79
+ end
80
+ end
81
+
82
+ def process
83
+ @fixture_listener = TablePrintingFixtureListener.new(@socket)
84
+ @counts = Counts.new
85
+ document_size = 0
86
+ begin
87
+ while ((document_size = FitProtocol.read_size(@socket)) != 0)
88
+ begin
89
+ say "Processing document with " + document_size.to_s + " bytes"
90
+ document = FitProtocol.read(document_size, @socket)
91
+ tables = Parse.new(document, ['table', 'tr', 'td'])
92
+ new_fixture
93
+ @fixture.do_tables(tables)
94
+ say "\t> " + @fixture.counts.to_s
95
+ @counts.tally(@fixture.counts)
96
+ rescue Fit::ParseException => e
97
+ exception(e)
98
+ end
99
+ end
100
+ rescue => e
101
+ exception(e)
102
+ end
103
+ end
104
+
105
+ def new_fixture
106
+ @fixture = Fixture.new
107
+ @fixture.listener = @fixture_listener
108
+ end
109
+
110
+ def good_connection?
111
+ return reason_for_bad_connection.nil?
112
+ end
113
+
114
+ def finish
115
+ say "Final counts: " + @counts.to_s
116
+ say "Exiting with code " + exit_code().to_s
117
+ end
118
+
119
+ def exit_code()
120
+ return @counts.wrong + @counts.exceptions
121
+ end
122
+
123
+ def say(message)
124
+ puts message if @verbose
125
+ end
126
+
127
+ def exception(e)
128
+ say "Exception occured!"
129
+ say "\t> " + e.to_s
130
+ parse = ParseHolder.create("span", "Exception occurred: ", nil, nil)
131
+ if @fixture.nil?
132
+ new_fixture
133
+ end
134
+ @fixture.exception(parse, e)
135
+ @counts.exceptions = @counts.exceptions + 1
136
+ @fixture_listener.table_finished(parse)
137
+ @fixture_listener.tables_finished(@fixture.counts)
138
+ end
139
+
140
+ end
141
+
142
+ class PrintString
143
+ def initialize; @buffer = ''; end
144
+ def print text; @buffer += text; end
145
+ def to_s; @buffer; end
146
+ end
147
+
148
+ class TablePrintingFixtureListener
149
+ def initialize(socket)
150
+ @socket = socket
151
+ end
152
+
153
+ def table_finished(tableParse)
154
+ buffer = PrintString.new
155
+ print_table(tableParse, buffer)
156
+ FitProtocol.write_document(buffer.to_s, @socket)
157
+ end
158
+
159
+ def print_table(table, output)
160
+ more = table.more
161
+ table.more = nil
162
+ if table.trailer.nil?
163
+ table.trailer = ""
164
+ end
165
+ table.print(output)
166
+ table.more = more
167
+ end
168
+
169
+ def tables_finished(counts)
170
+ FitProtocol.write_counts(counts, @socket)
171
+ end
172
+ end
173
+ end