fit 1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.txt +203 -0
- data/Rakefile +111 -0
- data/bin/FitServer.rb +6 -0
- data/bin/fit +10 -0
- data/bin/fit.cgi +36 -0
- data/doc/examples/AllCombinations.html +55 -0
- data/doc/examples/AllFiles.html +60 -0
- data/doc/examples/AllPairs/function/cosine.html +57 -0
- data/doc/examples/AllPairs/function/sine.html +57 -0
- data/doc/examples/AllPairs/magnitude/180+30.html +45 -0
- data/doc/examples/AllPairs/magnitude/30.html +33 -0
- data/doc/examples/AllPairs/magnitude/360+30.html +45 -0
- data/doc/examples/AllPairs/magnitude/90-30.html +45 -0
- data/doc/examples/AllPairs/sign/change-sign.html +27 -0
- data/doc/examples/AllPairs/sign/multiply.html +31 -0
- data/doc/examples/AllPairs/sign/no-change.html +23 -0
- data/doc/examples/AllPairs.html +51 -0
- data/doc/examples/BinaryChop.html +89 -0
- data/doc/examples/CalculatorExample.html +108 -0
- data/doc/examples/ColumnIndex.html +43 -0
- data/doc/examples/ExampleTests.html +43 -0
- data/doc/examples/FitAcceptanceTests.html +53 -0
- data/doc/examples/GeoCoordinate.html +87 -0
- data/doc/examples/MusicExample.html +143 -0
- data/doc/examples/MusicExampleWithErrors.html +128 -0
- data/doc/examples/NetworkExample.html +47 -0
- data/doc/examples/WebPageExample.html +92 -0
- data/doc/examples/arithmetic.html +211 -0
- data/doc/examples/files/hp35bk.jpg +0 -0
- data/doc/examples/logo.gif +0 -0
- data/doc/fitnesse/FitNesse.RubY.AcceptanceTests.FixtureParameters.html +81 -0
- data/doc/fitnesse/FitNesse.RubY.AcceptanceTests.GracefulFixtureNames.html +87 -0
- data/doc/fitnesse/FitNesse.RubY.AcceptanceTests.GracefulMemberNames.html +73 -0
- data/doc/fitnesse/FitNesse.RubY.AcceptanceTests.ImportFixture.html +61 -0
- data/doc/fitnesse/FitNesse.RubY.AcceptanceTests.WaysToSpecifyaFixtureNamespace.html +81 -0
- data/doc/spec/annotation.html +3833 -0
- data/doc/spec/extensions.html +302 -0
- data/doc/spec/fixtures.html +5181 -0
- data/doc/spec/index.html +947 -0
- data/doc/spec/parse.html +3094 -0
- data/lib/eg/all_combinations.rb +44 -0
- data/lib/eg/all_files.rb +94 -0
- data/lib/eg/all_pairs.rb +172 -0
- data/lib/eg/arithmetic_column_fixture.rb +35 -0
- data/lib/eg/arithmetic_fixture.rb +29 -0
- data/lib/eg/binary_chop.rb +100 -0
- data/lib/eg/calculator.rb +69 -0
- data/lib/eg/column_index.rb +85 -0
- data/lib/eg/division.rb +13 -0
- data/lib/eg/echo_args_fixture.rb +9 -0
- data/lib/eg/example_tests.rb +84 -0
- data/lib/eg/music/Music.txt +38 -0
- data/lib/eg/music/browser.rb +60 -0
- data/lib/eg/music/display.rb +24 -0
- data/lib/eg/music/music.rb +67 -0
- data/lib/eg/music/music_library.rb +70 -0
- data/lib/eg/music/music_player.rb +77 -0
- data/lib/eg/music/realtime.rb +39 -0
- data/lib/eg/music/simulator.rb +81 -0
- data/lib/eg/nested/bob.rb +12 -0
- data/lib/eg/nested/bob_the_builder_fixture.rb +11 -0
- data/lib/eg/net/simulator.rb +69 -0
- data/lib/eg/page.rb +91 -0
- data/lib/eg/sqrt.rb +19 -0
- data/lib/fat/annotation_fixture.rb +83 -0
- data/lib/fat/color.rb +45 -0
- data/lib/fat/divide.rb +13 -0
- data/lib/fat/document_parse_fixture.rb +67 -0
- data/lib/fat/equals.rb +59 -0
- data/lib/fat/fixture_name_fixture.rb +67 -0
- data/lib/fat/html_to_text_fixture.rb +20 -0
- data/lib/fat/money.rb +18 -0
- data/lib/fat/output_fixture.rb +32 -0
- data/lib/fat/parse_fixture.rb +92 -0
- data/lib/fat/reference_fixture.rb +31 -0
- data/lib/fat/standard_annotation_fixture.rb +58 -0
- data/lib/fat/string_writer.rb +12 -0
- data/lib/fat/table.rb +23 -0
- data/lib/fat/table_parse_fixture.rb +33 -0
- data/lib/fat/text_to_html_fixture.rb +21 -0
- data/lib/fit/action_fixture.rb +65 -0
- data/lib/fit/column_fixture.rb +104 -0
- data/lib/fit/file_runner.rb +80 -0
- data/lib/fit/fit_protocol.rb +62 -0
- data/lib/fit/fit_server.rb +173 -0
- data/lib/fit/fixture.rb +309 -0
- data/lib/fit/fixture_loader.rb +75 -0
- data/lib/fit/import_fixture.rb +9 -0
- data/lib/fit/parse.rb +206 -0
- data/lib/fit/primitive_fixture.rb +52 -0
- data/lib/fit/row_fixture.rb +188 -0
- data/lib/fit/scientific_double.rb +70 -0
- data/lib/fit/summary.rb +46 -0
- data/lib/fit/timed_action_fixture.rb +35 -0
- data/lib/fit/type_adapter.rb +95 -0
- data/lib/fit/wiki_runner.rb +15 -0
- data/lib/fittask.rb +184 -0
- data/test/all_tests.rb +13 -0
- data/test/file_runner_test.rb +52 -0
- data/test/fit_server_test.rb +214 -0
- data/test/fixture_loader_test.rb +71 -0
- data/test/fixture_test.rb +41 -0
- data/test/fixtures/fail_fixture.rb +9 -0
- data/test/fixtures/pass_fixture.rb +9 -0
- data/test/framework_test.rb +51 -0
- data/test/parse_test.rb +101 -0
- data/test/row_fixture_test.rb +44 -0
- data/test/scientific_double_test.rb +35 -0
- data/test/type_adapter_test.rb +120 -0
- 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
|