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,188 @@
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/parse'
6
+ require 'fit/type_adapter'
7
+
8
+ module Fit
9
+
10
+ class RowFixture < ColumnFixture
11
+
12
+ attr_accessor :results
13
+ attr_accessor :missing, :surplus
14
+
15
+ def initialize
16
+ super
17
+ @missing = []
18
+ @surplus = []
19
+ end
20
+
21
+ def do_rows rows
22
+ begin
23
+ bind rows.parts
24
+ @results = query
25
+ match list(rows.more), @results, 0
26
+ last = rows.last
27
+ last.more = build_rows @surplus
28
+ mark_parse last.more, 'surplus'
29
+ mark_list @missing, 'missing'
30
+ rescue Exception => e
31
+ exception rows.leaf, e
32
+ end
33
+ end
34
+
35
+ # Gets rows to be compared
36
+ def query; end
37
+
38
+ protected
39
+
40
+ def match expected, computed, column_index
41
+ if column_index >= @column_bindings.size
42
+ check_list expected, computed
43
+ elsif @column_bindings[column_index].nil?
44
+ match(expected, computed, column_index + 1)
45
+ else
46
+ e_map = e_sort(expected, column_index)
47
+ c_map = c_sort(computed, column_index)
48
+ keys = e_map.keys | c_map.keys
49
+ keys.each do |key|
50
+ e_list = e_map[key]
51
+ c_list = c_map[key]
52
+ if e_list.nil?
53
+ @surplus += c_list
54
+ elsif c_list.nil?
55
+ @missing += e_list
56
+ elsif e_list.size == 1 and c_list.size == 1
57
+ check_list e_list, c_list
58
+ else
59
+ match(e_list, c_list, column_index + 1)
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ def list rows
66
+ result = []
67
+ until rows.nil?
68
+ result << rows
69
+ rows = rows.more
70
+ end
71
+ result
72
+ end
73
+
74
+ def e_sort list, column_index
75
+ adapter = @column_bindings[column_index]
76
+ result = {}
77
+ list.each do |row|
78
+ cell = row.parts.at(column_index)
79
+ begin
80
+ key = adapter.parse(cell.text)
81
+ bin(result, key, row)
82
+ rescue Exception => e
83
+ exception cell, e
84
+ rest = cell.more
85
+ until rest.nil?
86
+ ignore rest
87
+ rest = rest.more
88
+ end
89
+ end
90
+ end
91
+ result
92
+ end
93
+
94
+ def c_sort list, column_index
95
+ adapter = @column_bindings[column_index]
96
+ result = {}
97
+ list.each do |row|
98
+ begin
99
+ adapter.target = row
100
+ key = adapter.get
101
+ bin(result, key, row)
102
+ rescue Exception => e
103
+ @surplus << row # surplus anything with bad keys, including nil
104
+ end
105
+ end
106
+ result
107
+ end
108
+
109
+ def bin map, key, row
110
+ if map.include? key
111
+ map[key] <<= row
112
+ else
113
+ map[key] = [row]
114
+ end
115
+ end
116
+
117
+ def check_list e_list, c_list
118
+ if e_list.empty?
119
+ @surplus += c_list
120
+ return
121
+ end
122
+ if c_list.empty?
123
+ @missing += e_list
124
+ return
125
+ end
126
+ row = e_list.shift
127
+ cell = row.parts
128
+ obj = c_list.shift
129
+ @column_bindings.each do |adapter|
130
+ adapter.target = obj unless adapter.nil?
131
+ check cell, adapter
132
+ cell = cell.more
133
+ break if cell.nil?
134
+ end
135
+ check_list e_list, c_list
136
+ end
137
+
138
+ def mark_parse rows, message
139
+ annotation = Fixture.label message
140
+ until rows.nil?
141
+ wrong rows.parts
142
+ rows.parts.add_to_body annotation
143
+ rows = rows.more
144
+ end
145
+ end
146
+
147
+ def mark_list rows, message
148
+ annotation = Fixture.label message
149
+ rows.each do |row|
150
+ wrong row.parts
151
+ row.parts.add_to_body annotation
152
+ end
153
+ end
154
+
155
+ def build_rows rows
156
+ root_parse = ParseHolder.create nil, nil, nil, nil
157
+ next_parse = root_parse
158
+ rows.each {|row| next_parse = next_parse.more = ParseHolder.create('tr', nil, build_cells(row), nil)}
159
+ root_parse.more
160
+ end
161
+
162
+ def build_cells row
163
+ if row.nil?
164
+ nihil = ParseHolder.create 'td', 'nil', nil, nil
165
+ nihil.add_to_tag('colspan="' + @column_bindings.size.to_s + '"')
166
+ return nihil
167
+ end
168
+ root_parse = ParseHolder.create nil, nil, nil, nil
169
+ next_parse = root_parse
170
+ @column_bindings.each do |adapter|
171
+ next_parse = next_parse.more = ParseHolder.create('td', '&nbsp;', nil, nil)
172
+ if adapter.nil?
173
+ ignore next_parse
174
+ else
175
+ begin
176
+ adapter.target = row
177
+ next_parse.body = Fixture.gray(Fixture.escape(adapter.to_s(adapter.get)))
178
+ rescue Exception => e
179
+ exception next_parse, e
180
+ end
181
+ end
182
+ end
183
+ root_parse.more
184
+ end
185
+
186
+ end
187
+
188
+ end
@@ -0,0 +1,70 @@
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 Fit
5
+
6
+ # Warning: not (yet) a general number usable in all calculations
7
+ class ScientificDouble
8
+
9
+ attr_accessor :precision
10
+
11
+ def initialize value
12
+ @value = Float(value)
13
+ @precision = 0
14
+ end
15
+
16
+ def ScientificDouble.value_of s
17
+ if s.downcase.index('infinity')
18
+ new (1.0/0.0) # Infinity
19
+ else
20
+ result = new s.to_f
21
+ result.precision = precision s
22
+ result
23
+ end
24
+ end
25
+
26
+ def ScientificDouble.precision s
27
+ value = s.to_f
28
+ bound = tweak(s.strip).to_f
29
+ (bound - value).abs
30
+ end
31
+
32
+ def ScientificDouble.tweak s
33
+ pos = s.downcase.index('e')
34
+ unless pos.nil?
35
+ return tweak(s[0..(pos - 1)]) + s[pos..-1]
36
+ end
37
+ unless s.index('.').nil?
38
+ return s + "5"
39
+ end
40
+ return s + ".5"
41
+ end
42
+
43
+ def == obj
44
+ sd = ScientificDouble.value_of obj.to_s
45
+ self.<=>(sd) == 0
46
+ end
47
+
48
+ def <=> obj
49
+ other = obj.to_f
50
+ diff = @value - other
51
+
52
+ # workaround the much more precise way of Ruby doing floats than Java
53
+ return 0 if @precision.zero? and diff.abs < 1.0e-5
54
+
55
+ precision = @precision > obj.precision ? @precision : obj.precision
56
+ return -1 if diff < -precision
57
+ return 1 if diff > precision
58
+ return 0 if @value.nan? and other.nan?
59
+ return 1 if @value.nan?
60
+ return -1 if other.nan?
61
+ 0
62
+ end
63
+
64
+ def nan?; @value.nan?; end # unused?
65
+ def to_f; @value; end
66
+ def to_s; @value.to_s; end
67
+
68
+ end
69
+
70
+ end
@@ -0,0 +1,46 @@
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 Fit
5
+
6
+ class Summary < Fixture
7
+ @@counts_key = 'counts'
8
+
9
+ def do_table table
10
+ @summary[@@counts_key] = totals
11
+ table.parts.more = rows @summary.keys.sort
12
+ end
13
+
14
+ protected
15
+
16
+ def rows keys
17
+ return nil if keys.empty?
18
+ key = keys.shift
19
+ result = tr(td(key, td(summary[key].to_s, nil)), rows(keys))
20
+ mark(result) if key == @@counts_key
21
+ result
22
+ end
23
+
24
+ def tr parts, more
25
+ ParseHolder.create('tr', nil, parts, more)
26
+ end
27
+
28
+ def td body, more
29
+ ParseHolder.create('td', Fixture.gray(body), nil, more)
30
+ end
31
+
32
+ # Mark summary good or bad without counting
33
+ def mark row
34
+ official = @counts
35
+ @counts = Counts.new # use a fake results holder to avoid counting
36
+ cell = row.parts.more
37
+ if official.total_errors > 0
38
+ wrong cell
39
+ else
40
+ right cell
41
+ end
42
+ @counts = official
43
+ end
44
+ end
45
+
46
+ end
@@ -0,0 +1,35 @@
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/action_fixture'
5
+
6
+ module Fit
7
+
8
+ class TimedActionFixture < ActionFixture
9
+ attr_accessor :format
10
+ def initialize
11
+ super
12
+ @format = '%H:%M:%S'
13
+ end
14
+ def do_table table
15
+ super
16
+ table.parts.parts.last.more = td('time')
17
+ table.parts.parts.last.more = td('split')
18
+ end
19
+ def do_cells cells
20
+ start = time
21
+ super
22
+ split = time - start
23
+ cells.last.more = td(start.strftime(@format))
24
+ cells.last.more = td(split < 1 ? '&nbsp;' : sprintf("%1.1f", split))
25
+ end
26
+ # Utility
27
+ def td body
28
+ ParseHolder.create('td', Fixture.gray(body), nil, nil)
29
+ end
30
+ def time
31
+ Time.now
32
+ end
33
+ end
34
+
35
+ end
@@ -0,0 +1,95 @@
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/scientific_double'
5
+
6
+ module Fit
7
+
8
+ class TypeAdapter
9
+
10
+ attr_accessor :target, :type, :fixture
11
+
12
+ def initialize target, name = '', is_output = false
13
+ @is_output = is_output
14
+ @target = @fixture = target
15
+
16
+ @name=name
17
+ ends_in_qm = is_output && name=~/\?$/
18
+ if @name.index(/[A-Z]/)
19
+ @name = @name.split(/([A-Z][^A-Z]+)/).delete_if {|e| e.empty?}.collect {|e| e.downcase}.join('_')
20
+ end
21
+ @name = @name.gsub(/[^0-9a-zA-Z_]+$/,'').gsub(/[^0-9a-zA-Z_]+/,'_').gsub(/_+/,'_')
22
+ @name << '?' if ends_in_qm
23
+ end
24
+
25
+ # Factories
26
+
27
+ def TypeAdapter.for fixture, name, is_output=(name=~/(\(\))|(\?)$/)
28
+ GenericAdapter.new fixture, name, is_output
29
+ end
30
+
31
+ def TypeAdapter.on fixture, type
32
+ adapter = GenericAdapter.new fixture
33
+ adapter.type = type
34
+ adapter
35
+ end
36
+
37
+ def get
38
+ return nil if @name.nil?
39
+ getter = @name
40
+ getter.chop! if getter =~ /\?$/ && ! @target.respond_to?(getter.to_sym)
41
+ @target.send(getter)
42
+ end
43
+
44
+ def set value
45
+ raise 'Output fields cannot be set' if @is_output
46
+ @target.send("#{@name}=", value)
47
+ end
48
+
49
+ def is_output?
50
+ @is_output
51
+ end
52
+
53
+ def equals a, b
54
+ if ((a.kind_of? Float) and (b.kind_of? Numeric)) or ((a.kind_of? Numeric) and (b.kind_of? Float))
55
+ (a - b).abs < 1.0e-5 # use a delta to test equality between a float and a number
56
+ else
57
+ a == b
58
+ end
59
+ end
60
+
61
+ def to_s target
62
+ target.to_s
63
+ end
64
+
65
+ end
66
+
67
+ # A generic adapter uses the appartent type of its input to store
68
+ # appropriate values. For example, if a cell contains <td>1</td>,
69
+ # a Fixnum is generated; if a cell contains <td>0.5</td>, a Float
70
+ # is generated. Note that this process might not feasible for every
71
+ # type of primitive data.
72
+ class GenericAdapter < TypeAdapter
73
+ def parse value
74
+ return true if value.downcase == 'true'
75
+ return false if value.downcase == 'false'
76
+ unless @type.nil?
77
+ result = @fixture.parse value, @type
78
+ return result unless result.nil?
79
+ end
80
+ return Integer(value) if value =~ /^-?\d+$/
81
+ return Float(value) if (value =~ /^-?\d*\.\d*$/ || value =~ /^-?\d*\.\d*[e|E]\d+$/)
82
+ elements = value.split(',')
83
+ unless elements.size == 1
84
+ array = []
85
+ element_adapter = TypeAdapter.for @target, @name, @is_output
86
+ elements.each do |e|
87
+ array << element_adapter.parse(e.strip)
88
+ end
89
+ return array
90
+ end
91
+ return value
92
+ end
93
+ end
94
+
95
+ end
@@ -0,0 +1,15 @@
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/file_runner'
5
+
6
+ $stderr.puts 'WikiRunner is deprecated: use FileRunner'
7
+
8
+ if __FILE__ == $0
9
+ begin
10
+ Fit::FileRunner.new.run ARGV
11
+ rescue Exception => e
12
+ $stderr.puts e.message
13
+ exit -1
14
+ end
15
+ end
data/lib/fittask.rb ADDED
@@ -0,0 +1,184 @@
1
+ require 'rake'
2
+ require 'rake/tasklib'
3
+
4
+ require 'fit/file_runner'
5
+ require 'fit/parse'
6
+
7
+ module Rake
8
+
9
+ class FitReportRunner < Fit::FileRunner
10
+ def run args
11
+ process_args args
12
+ process
13
+ end
14
+ end
15
+
16
+ class FitRunner < Fit::FileRunner
17
+ def run args
18
+ process_args args
19
+ process
20
+ end
21
+ def process_args args
22
+ input_name = File.expand_path args[0]
23
+ input_file = File.open input_name
24
+ @input = input_file.read
25
+ input_file.close
26
+ @output = OutputStream.new
27
+ end
28
+ end
29
+
30
+ # A dummy output stream to avoid creating output files
31
+ class OutputStream < String
32
+ def print text; end
33
+ def close; end
34
+ end
35
+
36
+ # Create a task that runs a set of FIT tests.
37
+ #
38
+ # If rake is invoked with a ATEST command line option, then the list of
39
+ # test files will be overridden to include only the filename specified on
40
+ # the command line. This provides an easy way to run just one test.
41
+ # The exact syntax of the ATEST option is as follows:
42
+ # ATEST=/path/to/FileHtml:Right:Wrong:Ignores:Exceptions
43
+ # where you can include a path to the HTML file, which must be specified
44
+ # without the .html extension; and where Rights, Wrong, Ignores and
45
+ # Exceptions are the numbers of the expected results from the test run.
46
+ # Note that the report path will be the same as the test path.
47
+ #
48
+ class FitTask < TaskLib
49
+
50
+ attr_accessor :name, :libs, :pattern, :fail_on_failed_test
51
+
52
+ def test_suites=(list)
53
+ @test_suites = list
54
+ end
55
+
56
+ def test_suites
57
+ if ENV['ATEST']
58
+ atest = ENV['ATEST'].split ':'
59
+ filename = atest[0]
60
+ test_name = File.basename(filename)
61
+ test = { :name => test_name,
62
+ :right => atest[1].to_i, :wrong => atest[2].to_i,
63
+ :ignores => atest[3].to_i, :exceptions => atest[4].to_i }
64
+ suite = AcceptanceTestSuite.new
65
+ suite << test
66
+ suite.test_path = suite.report_path = File.dirname(filename) + File::SEPARATOR
67
+ [suite]
68
+ else
69
+ @test_suites
70
+ end
71
+ end
72
+
73
+ def initialize(name=:fittest)
74
+ @name = name
75
+ @libs = ["lib"]
76
+ @pattern = nil
77
+ @test_files = []
78
+ @test_suites = []
79
+ @fail_on_failed_test=false
80
+ @tests_failed=false
81
+ yield self if block_given?
82
+ define name
83
+ end
84
+
85
+ def define task_name
86
+ # describe the fit task
87
+ desc "Run FIT acceptance tests"
88
+ task task_name
89
+ # silence footnote creation since we don't want HTML reports
90
+ task task_name do
91
+ Fit::Parse.send(:define_method, 'footnote', lambda {''})
92
+ end
93
+ # define a fit task for each test suite
94
+ test_suites.each do |suite|
95
+ task task_name do
96
+ @tests_failed = true unless suite.run_tests
97
+ end
98
+ end
99
+
100
+ task task_name do
101
+ raise 'Tests failed.' if @fail_on_failed_test && @tests_failed
102
+ end
103
+
104
+ # describe the fit_report task
105
+ desc "Run FIT acceptance tests with HTML reports"
106
+ task_report_name = (task_name.to_s + '_report').to_sym
107
+ task task_report_name
108
+ # define a fit_report task for each test suite
109
+ test_suites.each do |suite|
110
+ task task_report_name do
111
+ # set footnote path to an appropriate location
112
+ Fit::Parse.footnote_path = suite.report_path
113
+ # run tests
114
+ @tests_failed = true unless suite.run_tests_with_reports
115
+ end
116
+ end
117
+
118
+ task task_report_name do
119
+ raise 'Tests failed.' if @fail_on_failed_test && @tests_failed
120
+ end
121
+
122
+ self
123
+ end
124
+
125
+ def create_test_suite &block
126
+ suite = AcceptanceTestSuite.new
127
+ block.call suite
128
+ @test_suites << suite
129
+ end
130
+
131
+ class AcceptanceTestSuite
132
+ attr_accessor :test_path, :report_path, :tests
133
+ def initialize
134
+ @tests = []
135
+ @test_path = @report_path = ''
136
+ end
137
+ def << test
138
+ @tests << test
139
+ end
140
+
141
+ def run_tests_with_reports; run_tests true; end;
142
+
143
+ def run_tests with_report=false
144
+ all_passed = true
145
+ @tests.each do |test|
146
+ begin
147
+ runner_args = [@test_path + "#{test[:name]}.html"]
148
+ puts "Running #{test[:name]}.html"
149
+
150
+ if with_report
151
+ report_file=@report_path + "Report_#{test[:name]}.html"
152
+ puts " (Writing report to #{report_file})"
153
+ runner_args << report_file
154
+ runner = Rake::FitReportRunner.new
155
+ else
156
+ runner = Rake::FitRunner.new
157
+ end
158
+
159
+ runner.run runner_args
160
+ result = runner.fixture.counts
161
+ verify test, result
162
+ rescue Exception => e
163
+ puts " #{test[:name]} failed: #{e}"
164
+ all_passed = false
165
+ end
166
+ end
167
+ all_passed
168
+ end
169
+
170
+ def verify test, result
171
+ [:exceptions,:wrong].each { |symbol| test[symbol] = 0 if test[symbol].nil? }
172
+ [:right, :wrong, :ignores, :exceptions].each do |symbol|
173
+ count = result.method(symbol).call
174
+ expected = test[symbol]
175
+ unless expected.nil? || count == expected
176
+ raise Exception.new("#{expected} #{symbol} expected, found #{count} instead.")
177
+ end
178
+ end
179
+ end
180
+ end
181
+
182
+ end
183
+
184
+ end
data/test/all_tests.rb ADDED
@@ -0,0 +1,13 @@
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 'test/unit'
5
+
6
+ require 'test/file_runner_test'
7
+ require 'test/fit_server_test'
8
+ require 'test/fixture_test'
9
+ #require 'test/framework_test'
10
+ require 'test/parse_test'
11
+ require 'test/scientific_double_test'
12
+ require 'test/type_adapter_test'
13
+ require 'test/fixture_loader_test'
@@ -0,0 +1,52 @@
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 'test/unit'
5
+ # Make the test run location independent
6
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
7
+ require 'fit/file_runner'
8
+
9
+ module Fit
10
+
11
+ class FileRunnerTest < Test::Unit::TestCase
12
+ def test_simple_html
13
+ simple_html = "<table>" +
14
+ " <tr><td>fit.Fixture</td></tr>" +
15
+ "</table>"
16
+ do_html simple_html
17
+ end
18
+ def test_wiki_html
19
+ wiki_html = "<table><tr><td>extra formatting" +
20
+ " <wiki>" +
21
+ " <table>" +
22
+ " <tr><td>fit.Fixture</td></tr>" +
23
+ " </table>" +
24
+ " </wiki>" +
25
+ "</td></tr></table>"
26
+ do_html wiki_html
27
+ end
28
+ def do_html text
29
+ runner = FileRunner.new
30
+ runner.fixture = TempFixture.new
31
+ runner.input = text
32
+ runner.output = OutputStream.new
33
+ runner.process
34
+
35
+ assert_equal 'fit.Fixture', $tempParse.leaf.text
36
+ end
37
+ end
38
+
39
+ # What's the Ruby equivalent of Java anonymous classes?
40
+ class TempFixture < Fixture
41
+ def do_tables tables
42
+ $tempParse = tables
43
+ end
44
+ end
45
+
46
+ # A dummy output stream
47
+ class OutputStream < String
48
+ def print text; end
49
+ def close; end
50
+ end
51
+
52
+ end