fit 1.1

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 (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,44 @@
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 'eg/all_files'
5
+
6
+ module Eg
7
+
8
+ class AllCombinations < AllFiles
9
+ def initialize
10
+ super
11
+ @lists = []
12
+ @case_number = 1
13
+ end
14
+ def do_table table
15
+ @row = table.parts.last
16
+ super
17
+ combinations
18
+ end
19
+ protected
20
+ def do_row_files row, files
21
+ @lists << files
22
+ end
23
+ def combinations index = 0, combination = @lists
24
+ if index == @lists.size
25
+ do_case combination
26
+ else
27
+ files = @lists[index]
28
+ files.each do |f|
29
+ comb = combination.dup
30
+ comb[index] = f
31
+ combinations(index + 1, comb)
32
+ end
33
+ end
34
+ end
35
+ def do_case combination
36
+ number = tr(td('#' + @case_number.to_s, nil), nil)
37
+ @case_number += 1
38
+ number.leaf.add_to_tag 'colspan="2"'
39
+ @row.last.more = number
40
+ do_files number, combination
41
+ end
42
+ end
43
+
44
+ end
@@ -0,0 +1,94 @@
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 Eg
8
+
9
+ class AllFiles < Fit::Fixture
10
+ @@file_stack = []
11
+ def do_row row
12
+ cell = row.leaf
13
+ files = expand cell.text
14
+ if files.size > 0
15
+ do_row_files row, files
16
+ else
17
+ ignore cell
18
+ cell.add_to_body Fit::Fixture.gray('no match')
19
+ end
20
+ end
21
+ def expand pattern; Dir[pattern]; end
22
+ protected
23
+ def do_row_files row, files; do_files row, files; end
24
+ def do_files row, files
25
+ files.each do |filename|
26
+ cells = td(File.basename(filename), td('', nil))
27
+ row = (row.more = tr(cells, row.more))
28
+ fixture = Fit::Fixture.new
29
+ run(filename, fixture, cells)
30
+ summarize(fixture, filename)
31
+ end
32
+ end
33
+ def run filename, fixture, cells
34
+ if push_and_check(filename)
35
+ ignore cells
36
+ cells.add_to_body Fit::Fixture.gray('recursive')
37
+ return
38
+ end
39
+ begin
40
+ input = File.open(filename) {|f| f.read}
41
+ if input.index('<wiki>')
42
+ tables = Fit::Parse.new(input, ['wiki', 'table', 'tr', 'td'])
43
+ fixture.do_tables tables.parts
44
+ else
45
+ tables = Fit::Parse.new(input, ['table', 'tr', 'td'])
46
+ fixture.do_tables tables
47
+ end
48
+ cells.more.add_to_body Fit::Fixture.gray(fixture.totals)
49
+ if fixture.total_errors.zero?
50
+ right cells.more
51
+ else
52
+ wrong cells.more
53
+ cells.more.add_to_body tables.footnote
54
+ end
55
+ rescue Exception => e
56
+ exception cells, e
57
+ end
58
+ pop filename
59
+ end
60
+ def push_and_check filename
61
+ return true if @@file_stack.member? filename
62
+ @@file_stack << filename
63
+ false
64
+ end
65
+ def pop filename; @@file_stack.delete filename; end
66
+ def tr cells, more
67
+ Fit::ParseHolder.create('tr', nil, cells, more)
68
+ end
69
+ def td text, more
70
+ Fit::ParseHolder.create('td', Fit::Fixture.gray(text), nil, more)
71
+ end
72
+ private
73
+ def summarize fixture, filename
74
+ fixture.summary['input file'] = filename
75
+ fixture.summary['input update'] = File.open(filename) {|f| f.mtime.to_s}
76
+ run_totals = @summary.include?('counts run') ? @summary['counts run'] : Fit::Counts.new
77
+ run_totals.tally fixture.counts
78
+ @summary['counts run'] = run_totals
79
+ end
80
+ # Self test.
81
+ class Expand < Fit::ColumnFixture
82
+ attr_accessor :path
83
+ def initialize
84
+ super
85
+ @fixture = AllFiles.new
86
+ end
87
+ def expansion
88
+ files = @fixture.expand @path
89
+ files.sort.collect {|filename| File.basename(filename)}
90
+ end
91
+ end
92
+ end
93
+
94
+ end
@@ -0,0 +1,172 @@
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 'eg/all_combinations'
5
+ require 'set'
6
+
7
+ module Eg
8
+
9
+ class AllPairs < AllCombinations
10
+
11
+ attr_accessor :steps, :to_item, :vars, :pairs
12
+ @@rank = 0
13
+ def AllPairs.rank; @@rank; end
14
+
15
+ def initialize
16
+ super
17
+ @steps = 0
18
+ @to_item = {}
19
+ @vars = []
20
+ @pairs = Set.new
21
+ end
22
+
23
+ protected
24
+
25
+ def combinations
26
+ populate
27
+ generate
28
+ end
29
+
30
+ # Populate
31
+
32
+ def populate
33
+ do_all_vars
34
+ do_all_var_pairs
35
+ end
36
+
37
+ def do_all_vars
38
+ @@rank = 0
39
+ @lists.each_with_index do |files, i|
40
+ var = Var.new i, files
41
+ @vars << var
42
+ do_all_items var, files
43
+ end
44
+ end
45
+
46
+ def do_all_items var, files
47
+ files.each_with_index do |file, i|
48
+ item = Item.new var, i, @@rank
49
+ @@rank += 1
50
+ @to_item[file] = item
51
+ var.items << item
52
+ end
53
+ end
54
+
55
+ def do_all_var_pairs
56
+ @vars.each_with_index do |var, i|
57
+ j = i + 1
58
+ while j < @vars.size
59
+ do_all_item_pairs @vars[i], @vars[j]
60
+ j += 1
61
+ end
62
+ end
63
+ end
64
+
65
+ def do_all_item_pairs vl, vr
66
+ vl.items.each do |var_left|
67
+ vr.items.each do |var_right|
68
+ @pairs << Pair.new(var_left, var_right)
69
+ end
70
+ end
71
+ end
72
+
73
+ # Generate
74
+
75
+ def generate
76
+ while @pairs.sort.first.used.zero?
77
+ emit next_case
78
+ end
79
+ end
80
+
81
+ def next_case
82
+ slug = [nil] * @vars.size
83
+ while not is_full?(slug)
84
+ p = next_fit slug
85
+ fill slug, p
86
+ end
87
+ slug
88
+ end
89
+ private :next_case
90
+
91
+ def fill slug, pair
92
+ slug[pair.left.var.index] = pair.left
93
+ slug[pair.right.var.index] = pair.right
94
+ pair.used += 1
95
+ @pairs << pair
96
+ end
97
+
98
+ def is_full? slug
99
+ slug.each {|s| return false if s.nil?}
100
+ true
101
+ end
102
+
103
+ def next_fit slug
104
+ hold = []
105
+ pair = next_pair
106
+ while not pair.is_fit?(slug)
107
+ hold << pair
108
+ pair = next_pair
109
+ end
110
+ @pairs += hold
111
+ pair
112
+ end
113
+
114
+ def next_pair
115
+ first = @pairs.sort.first
116
+ @pairs.delete first
117
+ @steps += 1
118
+ first
119
+ end
120
+
121
+ def emit slug
122
+ combination = []
123
+ slug.each {|s| combination << s.file}
124
+ do_case combination
125
+ end
126
+
127
+ # Helper classes
128
+
129
+ class Var
130
+ attr_accessor :files, :items
131
+ attr_accessor :index
132
+ def initialize index, files
133
+ @index, @files = index, files
134
+ @items = []
135
+ end
136
+ end
137
+
138
+ class Item
139
+ attr_accessor :var
140
+ attr_accessor :index, :rank
141
+ def initialize v, i, n
142
+ @var, @index, @rank = v, i, n
143
+ end
144
+ def file; var.files[@index]; end
145
+ def is_fit? slug
146
+ slug[var.index].nil? or slug[var.index] == self
147
+ end
148
+ end
149
+
150
+ class Pair
151
+ attr_accessor :left, :right
152
+ attr_accessor :used
153
+ def initialize left, right
154
+ @left, @right = left, right
155
+ @used = 0
156
+ end
157
+ def is_fit? slug
158
+ @left.is_fit?(slug) and @right.is_fit?(slug)
159
+ end
160
+ def rank
161
+ AllPairs.rank * (AllPairs.rank * @used + @left.rank) + @right.rank
162
+ end
163
+ def <=> obj
164
+ rank - obj.rank
165
+ end
166
+ end
167
+
168
+ # No self test classes.
169
+
170
+ end
171
+
172
+ 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/column_fixture'
5
+ require 'fit/scientific_double'
6
+
7
+ module Eg
8
+
9
+ class ArithmeticColumnFixture < Fit::ColumnFixture
10
+ attr_accessor :x, :y
11
+ @@metadata = { 'sin()' => Fit::ScientificDouble, 'cos()' => Fit::ScientificDouble }
12
+ def plus
13
+ x + y
14
+ end
15
+ def minus
16
+ x - y
17
+ end
18
+ def times
19
+ x * y
20
+ end
21
+ def divide
22
+ x / y
23
+ end
24
+ def floating
25
+ Float(x) / Float(y)
26
+ end
27
+ def sin
28
+ Fit::ScientificDouble.new Math.sin(x / 180.0 * Math::PI)
29
+ end
30
+ def cos
31
+ Fit::ScientificDouble.new Math.cos(x / 180.0 * Math::PI)
32
+ end
33
+ end
34
+
35
+ end
@@ -0,0 +1,29 @@
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/primitive_fixture'
5
+
6
+ module Eg
7
+
8
+ class ArithmeticFixture < Fit::PrimitiveFixture
9
+ def initialize
10
+ super
11
+ @x = @y = 0
12
+ end
13
+ def do_rows rows
14
+ super(rows.more) # skip column heads
15
+ end
16
+ def do_cell cell, column_index
17
+ case column_index
18
+ when 0 then @x = parse_integer(cell);
19
+ when 1 then @y = parse_integer(cell);
20
+ when 2 then check(cell, parse_integer(cell), @x + @y)
21
+ when 3 then check(cell, parse_integer(cell), @x - @y)
22
+ when 4 then check(cell, parse_integer(cell), @x * @y)
23
+ when 5 then check(cell, parse_integer(cell), @x / @y)
24
+ else ignore(cell)
25
+ end
26
+ end
27
+ end
28
+
29
+ end
@@ -0,0 +1,100 @@
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 Eg
7
+
8
+ class BinaryChop < Fit::ColumnFixture
9
+
10
+ attr_accessor :key
11
+
12
+ def execute
13
+ @array = [] if @array.nil?
14
+ end
15
+
16
+ def array= value
17
+ unless value.kind_of? Array
18
+ @array = [value]
19
+ else
20
+ @array = value
21
+ end
22
+ end
23
+ def array; @array; end
24
+
25
+ def result
26
+ chop_friday key, array
27
+ end
28
+
29
+ def mon; chop_monday(key, array); end
30
+ def tue; chop_tuesday(key, array); end
31
+ def wed; chop_wednesday(key, array); end
32
+ def thr; chop_thursday(key, array); end
33
+ def fri; chop_friday(key, array); end
34
+
35
+ # Search methods
36
+
37
+ def chop_monday key, array
38
+ min = 0
39
+ max = array.size - 1
40
+ while min <= max
41
+ probe = (min + max) / 2
42
+ if key == array[probe]
43
+ return probe
44
+ elsif key > array[probe]
45
+ min = probe + 1
46
+ else
47
+ max = probe - 1
48
+ end
49
+ end
50
+ -1
51
+ end
52
+
53
+ def chop_tuesday key, array
54
+ min = 0
55
+ max = array.size - 1
56
+ while min <= max
57
+ probe = (min + max) / 2
58
+ case key <=> array[probe]
59
+ when 0 then return probe
60
+ when 1 then min = probe + 1
61
+ when -1 then max = probe - 1
62
+ else raise "Unexpected result from <=>"
63
+ end
64
+ end
65
+ -1
66
+ end
67
+
68
+ def chop_wednesday key, array
69
+ return -1 if array.size.zero?
70
+ probe = array.size / 2
71
+ return probe if key == array[probe]
72
+ return chop_wednesday(key, array[0, probe]) if key < array[probe]
73
+ result = chop_wednesday(key, array[(probe + 1)..-1])
74
+ return (result < 0) ? result : result + probe + 1
75
+ end
76
+
77
+ def chop_thursday key, array
78
+ min = 0
79
+ max = array.size - 1
80
+ while min <= max
81
+ probe = (rand * (max - min) + min).to_i
82
+ if key == array[probe]
83
+ return probe
84
+ elsif key > array[probe]
85
+ min = probe + 1
86
+ else
87
+ max = probe - 1
88
+ end
89
+ end
90
+ -1
91
+ end
92
+
93
+ def chop_friday key, array
94
+ array.each_with_index {|e, i| return i if key == e}
95
+ -1
96
+ end
97
+
98
+ end
99
+
100
+ end
@@ -0,0 +1,69 @@
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/scientific_double'
6
+
7
+ module Eg
8
+
9
+ class Hp35
10
+ attr_reader :r
11
+ def initialize
12
+ @r = [0, 0, 0, 0]
13
+ @s = 0
14
+ end
15
+ def key key
16
+ if key.kind_of? Numeric
17
+ push key.to_f
18
+ else
19
+ case key
20
+ when 'enter' then push
21
+ when '+' then push(pop() + pop())
22
+ when '-' then n = pop(); push(pop() - n)
23
+ when '*' then push(pop() * pop())
24
+ when '/' then n = pop(); push(pop() / n)
25
+ when 'x^y' then push(pop() ** pop())
26
+ when 'clx' then @r[0] = 0
27
+ when 'clr' then @r[0] = @r[1] = @r[2] = @r[3] = 0
28
+ when 'chs' then @r[0] = -@r[0]
29
+ when 'x<>y' then @r[0], @r[1] = @r[1], @r[0]
30
+ when 'r!' then @r[3] = pop()
31
+ when 'sto' then @s = @r[0]
32
+ when 'rcl' then push(@s)
33
+ when 'sqrt' then push(Math.sqrt(pop()))
34
+ when 'ln' then push(Math.log(pop()))
35
+ when 'sin' then push(Math.sin(pop() / 180 * Math::PI))
36
+ when 'cos' then push(Math.cos(pop() / 180 * Math::PI))
37
+ when 'tan' then push(Math.tan(pop() / 180 * Math::PI))
38
+ else raise "Can't do key: #{key}"
39
+ end
40
+ end
41
+ end
42
+ def push value = nil
43
+ 3.downto(1) {|i| @r[i] = @r[i - 1]}
44
+ @r[0] = value unless value.nil?
45
+ end
46
+ def pop
47
+ result = @r[0]
48
+ 0.upto(2) {|i| @r[i] = @r[i + 1]}
49
+ result
50
+ end
51
+ end
52
+
53
+ class Calculator < Fit::ColumnFixture
54
+ attr_accessor :volts, :key
55
+ @@metadata = { 'x()' => Fit::ScientificDouble, 'y()' => Fit::ScientificDouble,
56
+ 'z()' => Fit::ScientificDouble, 't()' => Fit::ScientificDouble }
57
+ @@hp = Hp35.new
58
+ def points; false; end
59
+ def flash; false; end
60
+ def watts; 0.5; end
61
+ def reset; key = nil; end
62
+ def execute; @@hp.key(key) unless key.nil?; end
63
+ def x; Fit::ScientificDouble.new @@hp.r[0]; end
64
+ def y; Fit::ScientificDouble.new @@hp.r[1]; end
65
+ def z; Fit::ScientificDouble.new @@hp.r[2]; end
66
+ def t; Fit::ScientificDouble.new @@hp.r[3]; end
67
+ end
68
+
69
+ end
@@ -0,0 +1,85 @@
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/row_fixture'
5
+ require 'set'
6
+
7
+ module Eg
8
+
9
+ class ColumnIndex < Fit::RowFixture
10
+
11
+ def do_rows rows
12
+ @rows = rows
13
+ super
14
+ end
15
+
16
+ def query
17
+ # first find what classes are mentioned in the table...
18
+ names = Set.new
19
+ column_index = 0
20
+ cell = @rows.parts
21
+ until cell.nil?
22
+ break if cell.text == 'className'
23
+ column_index += 1
24
+ cell = cell.more
25
+ end
26
+ row = @rows.more
27
+ until row.nil?
28
+ names.add row.at(0, column_index).text
29
+ row = row.more
30
+ end
31
+ # ...then find the columns in these classes
32
+ columns = []
33
+ names.each do |name|
34
+ obj = Fit::FixtureLoader.new.find_class(name).new
35
+ attributes = obj.methods - Object.new.methods
36
+ setters = attributes.dup.delete_if {|a| a[-1..-1] != "="}
37
+ attributes -= setters
38
+ setters.each do |s|
39
+ getter = s[0..-2]
40
+ if attributes.include? getter
41
+ attributes.delete getter
42
+ columns << Column.create(obj, getter)
43
+ end
44
+ end
45
+ attributes.each do |m|
46
+ meth = obj.method(m.to_sym)
47
+ columns << Column.create(obj, "#{m}()") if meth.arity.zero?
48
+ end
49
+ end
50
+ columns
51
+ end
52
+
53
+ def get_target_class; Column; end
54
+
55
+ def parse string, klass
56
+ return parse_class(string) if klass == Class
57
+ super
58
+ end
59
+
60
+ def parse_class name
61
+ Fit::FixtureLoader.new.find_class(name)
62
+ end
63
+
64
+ # Helper class
65
+
66
+ class Column
67
+ attr_accessor :column, :class_name, :column_name, :column_type
68
+ @@metadata = { 'column_name' => String, 'column_type' => Class, 'column' => Object, 'class_name' => Class }
69
+ def Column.metadata; @@metadata; end
70
+ def Column.create obj, attribute
71
+ c = new
72
+ c.column = attribute
73
+ c.class_name = obj.class
74
+ column_name = attribute.to_s
75
+ column_name_parts = column_name.split(/_/)
76
+ c.column_name = column_name_parts.shift
77
+ column_name_parts.each {|name| c.column_name += name.capitalize}
78
+ c.column_type = obj.class.metadata[column_name]
79
+ c
80
+ end
81
+ end
82
+
83
+ end
84
+
85
+ end
@@ -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 'fit/column_fixture'
5
+
6
+ module Eg
7
+
8
+ class Division < Fit::ColumnFixture
9
+ attr_accessor :numerator, :denominator
10
+ def quotient; @numerator.to_f / @denominator.to_f; end
11
+ end
12
+
13
+ end
@@ -0,0 +1,9 @@
1
+ require 'fit/row_fixture'
2
+
3
+ module Eg
4
+ class EchoArgsFixture < Fit::RowFixture
5
+ def query
6
+ @args
7
+ end
8
+ end
9
+ end