fit 1.1 → 1.2

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 (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