fit 1.1

Sign up to get free protection for your applications and to get access to all the features.
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