fit 1.1 → 1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/CHANGELOG +27 -0
  2. data/{README.txt → README.rdoc} +28 -9
  3. data/Rakefile +44 -4
  4. data/bin/fit +29 -3
  5. data/doc/book/TestChatServer.html +207 -0
  6. data/doc/book/TestDiscount.html +178 -0
  7. data/doc/book/TestDiscountGroup.html +223 -0
  8. data/doc/book/TestDiscountMoney.html +179 -0
  9. data/doc/book/TestLateHours.html +245 -0
  10. data/doc/bugs/ColumnFixtureFollowedByActionFixture.html +316 -0
  11. data/doc/examples/MusicExampleWithErrors.html +1 -1
  12. data/doc/spec/annotation.html +3634 -3833
  13. data/doc/spec/index.html +1043 -947
  14. data/doc/spec/parse-windows-1252.html +3806 -0
  15. data/doc/spec/parse.html +3806 -3094
  16. data/doc/spec/ui.html +1537 -0
  17. data/lib/eg/all_files.rb +1 -1
  18. data/lib/eg/book/calculate_discount.rb +25 -0
  19. data/lib/eg/book/calculate_discount_money.rb +60 -0
  20. data/lib/eg/book/chat_server_actions.rb +85 -0
  21. data/lib/eg/book/discount_group_ordered_list.rb +59 -0
  22. data/lib/eg/book/rent/calculate_late_hours.rb +35 -0
  23. data/lib/eg/column_index.rb +4 -3
  24. data/lib/eg/music/display.rb +4 -2
  25. data/lib/eg/music/music.rb +4 -2
  26. data/lib/fat/command_line_fixture.rb +33 -0
  27. data/lib/fat/html_to_text_fixture.rb +3 -3
  28. data/lib/fit/column_fixture.rb +11 -7
  29. data/lib/fit/file_runner.rb +65 -10
  30. data/lib/fit/fixture.rb +10 -4
  31. data/lib/fit/fixture_loader.rb +29 -19
  32. data/lib/fit/parse.rb +46 -12
  33. data/lib/fit/type_adapter.rb +8 -3
  34. data/lib/fit/version.rb +26 -0
  35. data/lib/fitlibrary/comment_fixture.rb +12 -0
  36. data/lib/fitlibrary/spec/specify_fixture.rb +154 -0
  37. data/lib/fitlibrary/specify/column_fixture_under_test.rb +17 -0
  38. data/lib/fitlibrary/specify/column_fixture_under_test_with_args.rb +17 -0
  39. data/lib/fittask.rb +43 -47
  40. data/test/all_tests.rb +2 -1
  41. data/test/column_fixture_test.rb +26 -0
  42. data/test/file_runner_test.rb +2 -7
  43. data/test/fixture_loader_test.rb +16 -3
  44. data/test/parse_test.rb +18 -3
  45. data/test/type_adapter_test.rb +58 -44
  46. metadata +180 -156
@@ -0,0 +1,17 @@
1
+ # Copyright (c) 2003 Rick Mugridge, University of Auckland, NZ
2
+ # Released under the terms of the GNU General Public License version 2 or later.
3
+
4
+ require 'fit/column_fixture'
5
+
6
+ module Fitlibrary
7
+ module Specify
8
+
9
+ class ColumnFixtureUnderTestWithArgs < Fit::ColumnFixture
10
+ attr_accessor :third
11
+ def sum
12
+ @args[0].to_i + @args[1].to_i + @third
13
+ end
14
+ end
15
+
16
+ end
17
+ end
@@ -4,46 +4,42 @@ require 'rake/tasklib'
4
4
  require 'fit/file_runner'
5
5
  require 'fit/parse'
6
6
 
7
+ require 'stringio'
8
+
7
9
  module Rake
8
10
 
9
11
  class FitReportRunner < Fit::FileRunner
10
- def run args
12
+ def run args, opts=nil
13
+ @encoding = opts[:encoding].upcase unless opts.nil?
11
14
  process_args args
12
15
  process
13
16
  end
14
17
  end
15
18
 
16
19
  class FitRunner < Fit::FileRunner
17
- def run args
20
+ def run args, opts=nil
21
+ @encoding = opts[:encoding].upcase unless opts.nil?
18
22
  process_args args
19
23
  process
20
24
  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
25
+ def check_output_file arg; end
26
+ def create_output_file output_name
27
+ @output = StringIO.new
27
28
  end
28
29
  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
30
 
36
31
  # Create a task that runs a set of FIT tests.
37
32
  #
38
- # If rake is invoked with a ATEST command line option, then the list of
33
+ # If rake is invoked with an ATEST command line option, then the list of
39
34
  # test files will be overridden to include only the filename specified on
40
35
  # the command line. This provides an easy way to run just one test.
41
36
  # The exact syntax of the ATEST option is as follows:
42
- # ATEST=/path/to/FileHtml:Right:Wrong:Ignores:Exceptions
37
+ # ATEST=/path/to/FileHtml:Right:Wrong:Ignores:Exceptions:Encoding
43
38
  # 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.
39
+ # without the .html extension; where Rights, Wrong, Ignores and Exceptions
40
+ # are the numbers of the expected results from the test run; and where
41
+ # Encoding is the character encoding of the input file. Note that the
42
+ # report path will be the same as the test path.
47
43
  #
48
44
  class FitTask < TaskLib
49
45
 
@@ -58,9 +54,8 @@ module Rake
58
54
  atest = ENV['ATEST'].split ':'
59
55
  filename = atest[0]
60
56
  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 }
57
+ test = { :name => test_name, :right => atest[1].to_i, :wrong => atest[2].to_i,
58
+ :ignores => atest[3].to_i, :exceptions => atest[4].to_i, :encoding => atest[5] }
64
59
  suite = AcceptanceTestSuite.new
65
60
  suite << test
66
61
  suite.test_path = suite.report_path = File.dirname(filename) + File::SEPARATOR
@@ -116,7 +111,7 @@ module Rake
116
111
  end
117
112
 
118
113
  task task_report_name do
119
- raise 'Tests failed.' if @fail_on_failed_test && @tests_failed
114
+ raise 'Tests failed.' if @fail_on_failed_test && @tests_failed
120
115
  end
121
116
 
122
117
  self
@@ -141,35 +136,36 @@ module Rake
141
136
  def run_tests_with_reports; run_tests true; end;
142
137
 
143
138
  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"
139
+ all_passed = true
140
+ @tests.each do |test|
141
+ begin
142
+ runner_args = [@test_path + "#{test[:name]}.html"]
143
+ puts "Running #{test[:name]}.html"
149
144
 
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
145
+ if with_report
146
+ report_file = @report_path + "Report_#{test[:name]}.html"
147
+ puts " (Writing report to #{report_file})"
148
+ runner_args << report_file
149
+ runner = Rake::FitReportRunner.new
150
+ else
151
+ runner = Rake::FitRunner.new
165
152
  end
166
- end
167
- all_passed
153
+
154
+ opts = test[:encoding].nil? ? nil : {:encoding => test[:encoding]}
155
+ runner.run runner_args, opts
156
+ result = runner.fixture.counts
157
+ verify test, result
158
+ rescue Exception => e
159
+ puts " #{test[:name]} failed: #{e}"
160
+ all_passed = false
161
+ end
162
+ end
163
+ all_passed
168
164
  end
169
165
 
170
166
  def verify test, result
171
- [:exceptions,:wrong].each { |symbol| test[symbol] = 0 if test[symbol].nil? }
172
- [:right, :wrong, :ignores, :exceptions].each do |symbol|
167
+ [:exceptions, :wrong].each { |symbol| test[symbol] = 0 if test[symbol].nil? }
168
+ [:right, :wrong, :ignores, :exceptions].each do |symbol|
173
169
  count = result.method(symbol).call
174
170
  expected = test[symbol]
175
171
  unless expected.nil? || count == expected
@@ -3,11 +3,12 @@
3
3
 
4
4
  require 'test/unit'
5
5
 
6
+ require 'test/column_fixture_test'
6
7
  require 'test/file_runner_test'
7
8
  require 'test/fit_server_test'
8
9
  require 'test/fixture_test'
10
+ require 'test/fixture_loader_test'
9
11
  #require 'test/framework_test'
10
12
  require 'test/parse_test'
11
13
  require 'test/scientific_double_test'
12
14
  require 'test/type_adapter_test'
13
- require 'test/fixture_loader_test'
@@ -0,0 +1,26 @@
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/column_fixture'
8
+
9
+ module Fit
10
+
11
+ class ColumnFixtureTest < Test::Unit::TestCase
12
+
13
+ # RubyForge bug #22283
14
+ def test_camel
15
+ fixture = TestColumnFixture.new
16
+ header_text = "Execution Data Value"
17
+ assert_equal "execution_data_value", fixture.camel(header_text)
18
+ end
19
+
20
+ class TestColumnFixture < ColumnFixture
21
+ public :camel
22
+ end
23
+
24
+ end
25
+
26
+ end
@@ -5,6 +5,7 @@ require 'test/unit'
5
5
  # Make the test run location independent
6
6
  $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
7
7
  require 'fit/file_runner'
8
+ require 'stringio'
8
9
 
9
10
  module Fit
10
11
 
@@ -29,7 +30,7 @@ module Fit
29
30
  runner = FileRunner.new
30
31
  runner.fixture = TempFixture.new
31
32
  runner.input = text
32
- runner.output = OutputStream.new
33
+ runner.output = StringIO.new
33
34
  runner.process
34
35
 
35
36
  assert_equal 'fit.Fixture', $tempParse.leaf.text
@@ -43,10 +44,4 @@ module Fit
43
44
  end
44
45
  end
45
46
 
46
- # A dummy output stream
47
- class OutputStream < String
48
- def print text; end
49
- def close; end
50
- end
51
-
52
47
  end
@@ -13,6 +13,11 @@ require 'eg/all_files'
13
13
  require 'eg/nested/bob_the_builder_fixture'
14
14
  require 'eg/music/browser'
15
15
 
16
+
17
+ class A; end
18
+ class AFixture < Fit::Fixture; end
19
+
20
+
16
21
  module Fit
17
22
  class FixtureLoaderTest < Test::Unit::TestCase
18
23
  def setup
@@ -42,20 +47,25 @@ module Fit
42
47
  end
43
48
  def test_it_finds_fixtures_in_the_fit_module
44
49
  assert_instance_of(Fit::ImportFixture, @loader.load('ImportFixture'))
45
- end
50
+ end
46
51
  def test_it_adds_fixture_to_the_end_if_it_cant_find_the_class
47
52
  assert_instance_of(Fit::ImportFixture, @loader.load('Import'))
48
53
  end
49
- def test_it_camalizes_seperated_words
54
+ def test_it_camelizes_separated_words
50
55
  FixtureLoader.add_fixture_package('Eg::Nested')
51
56
  assert_instance_of(Eg::Nested::BobTheBuilderFixture, @loader.load('bob the builder fixture'))
52
57
  assert_instance_of(Eg::Nested::BobTheBuilderFixture, @loader.load('bob the builder'))
53
58
  end
54
- def test_punctuation_seperates_words
59
+ def test_punctuation_separates_words
55
60
  FixtureLoader.add_fixture_package('Eg::Nested')
56
61
  assert_instance_of(Eg::Nested::BobTheBuilderFixture, @loader.load('bob_the!-builder,fixture.'))
57
62
  assert_instance_of(Eg::Nested::BobTheBuilderFixture, @loader.load('bob_the!-builder.'))
58
63
  end
64
+ def test_import_packages_are_unique
65
+ FixtureLoader.add_fixture_package('Eg::Nested')
66
+ FixtureLoader.add_fixture_package('Eg::Nested')
67
+ assert_equal(1, FixtureLoader.fixture_packages.find_all { |e| e =~ /^Eg::Nested/}.size)
68
+ end
59
69
  def test_it_raises_when_it_cant_find_the_fixture
60
70
  @loader.load "NoSuchClass"
61
71
  rescue StandardError => e
@@ -67,5 +77,8 @@ module Fit
67
77
  rescue StandardError => e
68
78
  assert_equal("String is not a fixture.", e.to_s)
69
79
  end
80
+ def test_loading_fixture_when_fixture_name_is_same_as_another_class_name
81
+ assert_instance_of(AFixture, @loader.load('A'))
82
+ end
70
83
  end
71
84
  end
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  # Copyright (c) 2002 Cunningham & Cunningham, Inc.
2
3
  # Released under the terms of the GNU General Public License version 2 or later.
3
4
 
@@ -71,7 +72,7 @@ module Fit
71
72
  assert_equal 'a', Parse.html_to_text('a &nbsp;')
72
73
  assert_equal '&nbsp;', Parse.html_to_text('&amp;nbsp;')
73
74
  assert_equal '1 2', Parse.html_to_text('1 &nbsp; &nbsp; 2')
74
- assert_equal '1 2', Parse.html_to_text("1 \xa0\xa0\xa0\xa02")
75
+ assert_equal '1 2', Parse.html_to_text("1 \302\240\302\240\302\240\302\2402")
75
76
  assert_equal 'a', Parse.html_to_text(' <tag />a')
76
77
  assert_equal "a\nb", Parse.html_to_text('a<br />b')
77
78
  assert_equal 'ab', Parse.html_to_text('<font size=+1>a</font>b')
@@ -86,7 +87,21 @@ module Fit
86
87
  assert_equal 'a>b & b>c &&', Parse.unescape('a&gt;b&nbsp;&amp;&nbsp;b>c &&')
87
88
  assert_equal '&amp;&amp;', Parse.unescape('&amp;amp;&amp;amp;')
88
89
  assert_equal 'a>b & b>c &&', Parse.unescape('a&gt;b&nbsp;&amp;&nbsp;b>c &&')
89
- assert_equal "'\"\"'", Parse.unescape("\221��\222")
90
+ assert_equal "'\"\"'", Parse.unescape("\342\200\230\342\200\234\342\200\235\342\200\231")
91
+ assert_equal 'no-entity', Parse.unescape('no-entity')
92
+ end
93
+ def test_unescape_numeric_entities
94
+ assert_equal 'A', Parse.unescape('&#65;')
95
+ assert_equal 'A', Parse.unescape('&#x41;')
96
+ assert_equal 'A', Parse.unescape('&#X41;')
97
+ assert_equal '!A!', Parse.unescape('!&#65;!')
98
+ assert_equal 'AB', Parse.unescape('&#65;&#66;')
99
+ assert_equal '1A2B3', Parse.unescape('1&#65;2&#66;3')
100
+ assert_equal '&#65', Parse.unescape('&#65')
101
+ assert_equal '&#foo;', Parse.unescape('&#foo;')
102
+ assert_equal '1&#foo;2', Parse.unescape('1&#foo;2')
103
+ assert_equal "\357\277\277", Parse.unescape('&#65535;')
104
+ assert_equal '&#65536;', Parse.unescape('&#65536;')
90
105
  end
91
106
  def test_whitespace_is_condensed
92
107
  assert_equal 'a b', Parse.condense_whitespace(' a b ')
@@ -94,7 +109,7 @@ module Fit
94
109
  assert_equal '', Parse.condense_whitespace(' ')
95
110
  assert_equal '', Parse.condense_whitespace(' ')
96
111
  assert_equal '', Parse.condense_whitespace(' ')
97
- assert_equal '', Parse.condense_whitespace("\240")
112
+ assert_equal '', Parse.condense_whitespace("\302\240")
98
113
  end
99
114
  end
100
115
 
@@ -51,20 +51,34 @@ module Fit
51
51
  adapter = TypeAdapter.for @f, 'sample_integer', false
52
52
  assert_equal '-234567', adapter.parse('-234567').to_s
53
53
  end
54
- def test_method
55
- adapter = TypeAdapter.for @f, 'pi', true
56
- assert_in_delta 3.14159, adapter.get, 0.00001
57
- assert_equal 3.14159265, adapter.get
54
+ def test_double
55
+ adapter = TypeAdapter.for @f, 'sample_float', false
56
+ adapter.set(adapter.parse('6.02e23'))
57
+ assert_in_delta 6.02e23, @f.sample_float, 1e17
58
+ end
59
+ def test_bad_float
60
+ ['.', '3.', '.|0'].each do |bad_float|
61
+ adapter = TypeAdapter.for @f, 'sample_float', false
62
+ adapter.set(adapter.parse(bad_float))
63
+ assert_equal bad_float, @f.sample_float
64
+ end
58
65
  end
59
66
  def test_string
60
67
  adapter = TypeAdapter.for @f, 'sample_string', false
61
68
  adapter.set(adapter.parse('xyzzy'))
62
69
  assert_equal 'xyzzy', @f.sample_string
63
70
  end
64
- def test_double
65
- adapter = TypeAdapter.for @f, 'sample_float', false
66
- adapter.set(adapter.parse('6.02e23'))
67
- assert_in_delta 6.02e23, @f.sample_float, 1e17
71
+ def test_multiline_string_with_numbers
72
+ ["foo\n1", "foo\n1.0"].each do |s|
73
+ adapter = TypeAdapter.for @f, 'sample_string', false
74
+ adapter.set(adapter.parse(s))
75
+ assert_equal s, @f.sample_string
76
+ end
77
+ end
78
+ def test_method
79
+ adapter = TypeAdapter.for @f, 'pi', true
80
+ assert_in_delta 3.14159, adapter.get, 0.00001
81
+ assert_equal 3.14159265, adapter.get
68
82
  end
69
83
  def test_array
70
84
  adapter = TypeAdapter.for @f, 'sample_array', false
@@ -72,49 +86,49 @@ module Fit
72
86
  assert_equal 1, @f.sample_array[0]
73
87
  assert_equal 2, @f.sample_array[1]
74
88
  assert_equal 3, @f.sample_array[2]
75
- assert_equal '123', adapter.to_s(@f.sample_array)
89
+ assert_equal '1, 2, 3', adapter.to_s(@f.sample_array)
76
90
  assert_equal [1,2,3], @f.sample_array
77
91
  end
78
92
  def test_boolean
79
93
  verify_sample_boolean_adapter_setter @f, 'sample_boolean'
80
94
  end
81
95
  def verify_sample_boolean_adapter_setter(fixture,method)
82
- adapter = TypeAdapter.for fixture, method, false
83
- adapter.set(adapter.parse('true'))
84
- assert fixture.sample_boolean
85
- adapter.set(adapter.parse('false'))
86
- assert !fixture.sample_boolean
87
- end
88
- def test_digits_in_the_name
89
- adapter = TypeAdapter.for @f, "sample_with_2_digits1", false
90
- adapter.set(adapter.parse('true'))
91
- assert @f.sample_with_2_digits1
92
- adapter.set(adapter.parse('false'))
93
- assert !@f.sample_with_2_digits1
94
- end
95
- def test_graceful_names_setters
96
- ['SampleBoolean','Sample Boolean','sample boolean','sample? boolean','sample, boolean','sample, boolean?'].each do |name|
97
- verify_sample_boolean_adapter_setter @f, name
98
- end
99
- end
100
- def test_graceful_names_getters
101
- ['sample boolean()','sample_boolean()','Sample Boolean()','SampleBoolean()',
102
- 'sample boolean?','sample_boolean?','Sample Boolean?','SampleBoolean?','Sample.boolean'].each do |name|
103
- adapter=TypeAdapter.for @f, name
104
- [true,false].each { |v| @f.sample_boolean=v; assert_equal(v,adapter.get) }
105
- end
96
+ adapter = TypeAdapter.for fixture, method, false
97
+ adapter.set(adapter.parse('true'))
98
+ assert fixture.sample_boolean
99
+ adapter.set(adapter.parse('false'))
100
+ assert !fixture.sample_boolean
101
+ end
102
+ def test_digits_in_the_name
103
+ adapter = TypeAdapter.for @f, "sample_with_2_digits1", false
104
+ adapter.set(adapter.parse('true'))
105
+ assert @f.sample_with_2_digits1
106
+ adapter.set(adapter.parse('false'))
107
+ assert !@f.sample_with_2_digits1
108
+ end
109
+ def test_graceful_names_setters
110
+ ['SampleBoolean','Sample Boolean','sample boolean','sample? boolean','sample, boolean','sample, boolean?'].each do |name|
111
+ verify_sample_boolean_adapter_setter @f, name
106
112
  end
107
- def test_getters_ending_with_question_mark
108
- # when the request ends in ?, prefer a method ending in ?
109
- adapter = TypeAdapter.for @f, "might_end_in_qm?"
110
- assert adapter.get
111
- # when the request doesn't end in ?, require a method not ending with ?
112
- adapter = TypeAdapter.for @f, "might_end_in_qm"
113
- assert ! adapter.get
114
- # when the request ends in ? accept a method not ending in ?, if one ending in ? is not present
115
- @f.sample_string='no qm'
116
- adapter = TypeAdapter.for @f, "sample_string?"
117
- assert_equal 'no qm',adapter.get
113
+ end
114
+ def test_graceful_names_getters
115
+ ['sample boolean()','sample_boolean()','Sample Boolean()','SampleBoolean()',
116
+ 'sample boolean?','sample_boolean?','Sample Boolean?','SampleBoolean?','Sample.boolean'].each do |name|
117
+ adapter = TypeAdapter.for @f, name
118
+ [true, false].each { |v| @f.sample_boolean = v; assert_equal(v, adapter.get) }
118
119
  end
120
+ end
121
+ def test_getters_ending_with_question_mark
122
+ # when the request ends in ?, prefer a method ending in ?
123
+ adapter = TypeAdapter.for @f, "might_end_in_qm?"
124
+ assert adapter.get
125
+ # when the request doesn't end in ?, require a method not ending with ?
126
+ adapter = TypeAdapter.for @f, "might_end_in_qm"
127
+ assert ! adapter.get
128
+ # when the request ends in ? accept a method not ending in ?, if one ending in ? is not present
129
+ @f.sample_string = 'no qm'
130
+ adapter = TypeAdapter.for @f, "sample_string?"
131
+ assert_equal 'no qm', adapter.get
132
+ end
119
133
  end
120
134
  end