linkage 0.0.8 → 0.1.0.pre

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 (105) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.yardopts +1 -0
  4. data/Gemfile +1 -19
  5. data/Gemfile-java +3 -0
  6. data/README.markdown +88 -34
  7. data/Rakefile +16 -15
  8. data/TODO +4 -0
  9. data/lib/linkage/comparator.rb +139 -144
  10. data/lib/linkage/comparators/compare.rb +236 -29
  11. data/lib/linkage/comparators/strcompare.rb +85 -0
  12. data/lib/linkage/comparators/within.rb +24 -20
  13. data/lib/linkage/configuration.rb +44 -466
  14. data/lib/linkage/dataset.rb +28 -127
  15. data/lib/linkage/exceptions.rb +5 -0
  16. data/lib/linkage/field.rb +6 -37
  17. data/lib/linkage/field_set.rb +3 -3
  18. data/lib/linkage/match_recorder.rb +22 -0
  19. data/lib/linkage/match_set.rb +34 -0
  20. data/lib/linkage/match_sets/csv.rb +39 -0
  21. data/lib/linkage/match_sets/database.rb +45 -0
  22. data/lib/linkage/matcher.rb +30 -0
  23. data/lib/linkage/result_set.rb +25 -110
  24. data/lib/linkage/result_sets/csv.rb +54 -0
  25. data/lib/linkage/result_sets/database.rb +42 -0
  26. data/lib/linkage/runner.rb +57 -16
  27. data/lib/linkage/score_recorder.rb +30 -0
  28. data/lib/linkage/score_set.rb +49 -0
  29. data/lib/linkage/score_sets/csv.rb +64 -0
  30. data/lib/linkage/score_sets/database.rb +77 -0
  31. data/lib/linkage/version.rb +1 -1
  32. data/lib/linkage.rb +14 -17
  33. data/linkage.gemspec +13 -1
  34. data/linkage.gemspec-java +32 -0
  35. data/test/helper.rb +30 -23
  36. data/test/integration/test_cross_linkage.rb +46 -25
  37. data/test/integration/test_database_result_set.rb +55 -0
  38. data/test/integration/test_dual_linkage.rb +19 -94
  39. data/test/integration/test_self_linkage.rb +100 -203
  40. data/test/integration/test_within_comparator.rb +24 -77
  41. data/test/unit/comparators/test_compare.rb +254 -50
  42. data/test/unit/comparators/test_strcompare.rb +45 -0
  43. data/test/unit/comparators/test_within.rb +14 -26
  44. data/test/unit/match_sets/test_csv.rb +78 -0
  45. data/test/unit/match_sets/test_database.rb +63 -0
  46. data/test/unit/result_sets/test_csv.rb +111 -0
  47. data/test/unit/result_sets/test_database.rb +68 -0
  48. data/test/unit/score_sets/test_csv.rb +151 -0
  49. data/test/unit/score_sets/test_database.rb +149 -0
  50. data/test/unit/test_comparator.rb +46 -83
  51. data/test/unit/test_comparators.rb +4 -0
  52. data/test/unit/test_configuration.rb +99 -145
  53. data/test/unit/test_dataset.rb +52 -73
  54. data/test/unit/test_field.rb +4 -55
  55. data/test/unit/test_field_set.rb +6 -6
  56. data/test/unit/test_match_recorder.rb +23 -0
  57. data/test/unit/test_match_set.rb +23 -0
  58. data/test/unit/test_match_sets.rb +4 -0
  59. data/test/unit/test_matcher.rb +44 -0
  60. data/test/unit/test_result_set.rb +24 -223
  61. data/test/unit/test_result_sets.rb +4 -0
  62. data/test/unit/test_runner.rb +122 -17
  63. data/test/unit/test_runners.rb +4 -0
  64. data/test/unit/test_score_recorder.rb +25 -0
  65. data/test/unit/test_score_set.rb +37 -0
  66. data/test/unit/test_score_sets.rb +4 -0
  67. metadata +183 -90
  68. data/Gemfile.lock +0 -92
  69. data/lib/linkage/comparators/binary.rb +0 -12
  70. data/lib/linkage/data.rb +0 -175
  71. data/lib/linkage/decollation.rb +0 -93
  72. data/lib/linkage/expectation.rb +0 -21
  73. data/lib/linkage/expectations/exhaustive.rb +0 -63
  74. data/lib/linkage/expectations/simple.rb +0 -168
  75. data/lib/linkage/function.rb +0 -148
  76. data/lib/linkage/functions/binary.rb +0 -30
  77. data/lib/linkage/functions/cast.rb +0 -54
  78. data/lib/linkage/functions/length.rb +0 -29
  79. data/lib/linkage/functions/strftime.rb +0 -33
  80. data/lib/linkage/functions/trim.rb +0 -30
  81. data/lib/linkage/group.rb +0 -55
  82. data/lib/linkage/meta_object.rb +0 -139
  83. data/lib/linkage/runner/single_threaded.rb +0 -187
  84. data/lib/linkage/utils.rb +0 -164
  85. data/lib/linkage/warnings.rb +0 -5
  86. data/test/integration/test_collation.rb +0 -45
  87. data/test/integration/test_configuration.rb +0 -268
  88. data/test/integration/test_dataset.rb +0 -116
  89. data/test/integration/test_functions.rb +0 -88
  90. data/test/integration/test_result_set.rb +0 -85
  91. data/test/integration/test_scoring.rb +0 -84
  92. data/test/unit/expectations/test_exhaustive.rb +0 -111
  93. data/test/unit/expectations/test_simple.rb +0 -303
  94. data/test/unit/functions/test_binary.rb +0 -54
  95. data/test/unit/functions/test_cast.rb +0 -98
  96. data/test/unit/functions/test_length.rb +0 -52
  97. data/test/unit/functions/test_strftime.rb +0 -60
  98. data/test/unit/functions/test_trim.rb +0 -43
  99. data/test/unit/runner/test_single_threaded.rb +0 -12
  100. data/test/unit/test_data.rb +0 -445
  101. data/test/unit/test_decollation.rb +0 -201
  102. data/test/unit/test_function.rb +0 -233
  103. data/test/unit/test_group.rb +0 -38
  104. data/test/unit/test_meta_object.rb +0 -208
  105. data/test/unit/test_utils.rb +0 -341
@@ -1,6 +1,6 @@
1
- require 'helper'
1
+ require File.expand_path("../../test_comparators", __FILE__)
2
2
 
3
- class UnitTests::TestCompare < Test::Unit::TestCase
3
+ class UnitTests::TestComparators::TestCompare < Test::Unit::TestCase
4
4
  def self.const_missing(name)
5
5
  if Linkage::Comparators.const_defined?(name)
6
6
  Linkage::Comparators.const_get(name)
@@ -9,97 +9,301 @@ class UnitTests::TestCompare < Test::Unit::TestCase
9
9
  end
10
10
  end
11
11
 
12
- test "subclass of Binary" do
13
- assert_equal Binary, Compare.superclass
14
- end
15
-
16
- test "valid parameters" do
17
- meta_object_1 = stub('meta object', :name => :foo, :side => :lhs, :ruby_type => { :type => Integer }, :static? => false)
18
- meta_object_2 = stub('meta object', :object => '>', :ruby_type => { :type => String }, :static? => true, :raw? => true)
19
- meta_object_3 = stub('meta object', :name => :bar, :side => :rhs, :ruby_type => { :type => Integer }, :static? => false)
20
- assert_nothing_raised do
21
- Compare.new(meta_object_1, meta_object_2, meta_object_3)
22
- end
12
+ test "subclass of Comparator" do
13
+ assert_equal Linkage::Comparator, Compare.superclass
23
14
  end
24
15
 
25
16
  test "score for not equal to" do
26
- meta_object_1 = stub('meta object', :name => :foo, :side => :lhs, :ruby_type => { :type => Integer }, :static? => false)
27
- meta_object_2 = stub('meta object', :object => '!=', :ruby_type => { :type => String }, :static? => true, :raw? => true)
28
- meta_object_3 = stub('meta object', :name => :bar, :side => :rhs, :ruby_type => { :type => Integer }, :static? => false)
29
- comp = Compare.new(meta_object_1, meta_object_2, meta_object_3)
17
+ field_1 = stub('foo field', :name => :foo, :ruby_type => { :type => Integer })
18
+ field_2 = stub('bar field', :name => :bar, :ruby_type => { :type => Integer })
19
+ comp = Compare.new([field_1], [field_2], :not_equal)
20
+ assert_equal :simple, comp.type
30
21
  assert_equal 1, comp.score({:foo => 10}, {:bar => 5})
31
22
  assert_equal 0, comp.score({:foo => 5}, {:bar => 5})
32
23
  assert_equal 1, comp.score({:foo => 0}, {:bar => 5})
33
24
  end
34
25
 
26
+ test "score for not equal to with multiple fields" do
27
+ field_1 = stub('foo field', :name => :foo, :ruby_type => { :type => Integer })
28
+ field_2 = stub('bar field', :name => :bar, :ruby_type => { :type => Integer })
29
+ field_3 = stub('baz field', :name => :baz, :ruby_type => { :type => Integer })
30
+ field_4 = stub('qux field', :name => :qux, :ruby_type => { :type => Integer })
31
+ comp = Compare.new([field_1, field_2], [field_3, field_4], :not_equal)
32
+ assert_equal :simple, comp.type
33
+ assert_equal 1, comp.score({:foo => 10, :bar => 5}, {:baz => 5, :qux => 10})
34
+ assert_equal 0, comp.score({:foo => 10, :bar => 5}, {:baz => 10, :qux => 5})
35
+ assert_equal 0, comp.score({:foo => 10, :bar => 5}, {:baz => 10, :qux => 7})
36
+ assert_equal 0, comp.score({:foo => 10, :bar => 5}, {:baz => 7, :qux => 5})
37
+ end
38
+
35
39
  test "score for greater than" do
36
- meta_object_1 = stub('meta object', :name => :foo, :side => :lhs, :ruby_type => { :type => Integer }, :static? => false)
37
- meta_object_2 = stub('meta object', :object => '>', :ruby_type => { :type => String }, :static? => true, :raw? => true)
38
- meta_object_3 = stub('meta object', :name => :bar, :side => :rhs, :ruby_type => { :type => Integer }, :static? => false)
39
- comp = Compare.new(meta_object_1, meta_object_2, meta_object_3)
40
+ field_1 = stub('foo field', :name => :foo, :ruby_type => { :type => Integer })
41
+ field_2 = stub('bar field', :name => :bar, :ruby_type => { :type => Integer })
42
+ comp = Compare.new([field_1], [field_2], :greater_than)
43
+ assert_equal :simple, comp.type
40
44
  assert_equal 1, comp.score({:foo => 10}, {:bar => 5})
41
45
  assert_equal 0, comp.score({:foo => 5}, {:bar => 5})
42
46
  assert_equal 0, comp.score({:foo => 0}, {:bar => 5})
43
47
  end
44
48
 
49
+ test "score for greater than with multiple fields" do
50
+ field_1 = stub('foo field', :name => :foo, :ruby_type => { :type => Integer })
51
+ field_2 = stub('bar field', :name => :bar, :ruby_type => { :type => Integer })
52
+ field_3 = stub('baz field', :name => :baz, :ruby_type => { :type => Integer })
53
+ field_4 = stub('qux field', :name => :qux, :ruby_type => { :type => Integer })
54
+ comp = Compare.new([field_1, field_2], [field_3, field_4], :greater_than)
55
+ assert_equal :simple, comp.type
56
+ assert_equal 1, comp.score({:foo => 10, :bar => 5}, {:baz => 5, :qux => 0})
57
+ assert_equal 0, comp.score({:foo => 10, :bar => 5}, {:baz => 15, :qux => 10})
58
+ assert_equal 0, comp.score({:foo => 10, :bar => 5}, {:baz => 15, :qux => 0})
59
+ assert_equal 0, comp.score({:foo => 10, :bar => 5}, {:baz => 5, :qux => 10})
60
+ end
61
+
45
62
  test "score for greater than or equal to" do
46
- meta_object_1 = stub('meta object', :name => :foo, :side => :lhs, :ruby_type => { :type => Integer }, :static? => false)
47
- meta_object_2 = stub('meta object', :object => '>=', :ruby_type => { :type => String }, :static? => true, :raw? => true)
48
- meta_object_3 = stub('meta object', :name => :bar, :side => :rhs, :ruby_type => { :type => Integer }, :static? => false)
49
- comp = Compare.new(meta_object_1, meta_object_2, meta_object_3)
63
+ field_1 = stub('foo field', :name => :foo, :ruby_type => { :type => Integer })
64
+ field_2 = stub('bar field', :name => :bar, :ruby_type => { :type => Integer })
65
+ comp = Compare.new([field_1], [field_2], :greater_than_or_equal)
66
+ assert_equal :simple, comp.type
50
67
  assert_equal 1, comp.score({:foo => 10}, {:bar => 5})
51
68
  assert_equal 1, comp.score({:foo => 5}, {:bar => 5})
52
69
  assert_equal 0, comp.score({:foo => 0}, {:bar => 5})
53
70
  end
54
71
 
72
+ test "score for greater than or equal to with multiple fields" do
73
+ field_1 = stub('foo field', :name => :foo, :ruby_type => { :type => Integer })
74
+ field_2 = stub('bar field', :name => :bar, :ruby_type => { :type => Integer })
75
+ field_3 = stub('baz field', :name => :baz, :ruby_type => { :type => Integer })
76
+ field_4 = stub('qux field', :name => :qux, :ruby_type => { :type => Integer })
77
+ comp = Compare.new([field_1, field_2], [field_3, field_4], :greater_than_or_equal)
78
+ assert_equal :simple, comp.type
79
+ assert_equal 1, comp.score({:foo => 10, :bar => 5}, {:baz => 5, :qux => 0})
80
+ assert_equal 1, comp.score({:foo => 10, :bar => 5}, {:baz => 10, :qux => 5})
81
+ assert_equal 0, comp.score({:foo => 10, :bar => 5}, {:baz => 5, :qux => 10})
82
+ assert_equal 0, comp.score({:foo => 10, :bar => 5}, {:baz => 15, :qux => 0})
83
+ end
84
+
55
85
  test "score for less than or equal to" do
56
- meta_object_1 = stub('meta object', :name => :foo, :side => :lhs, :ruby_type => { :type => Integer }, :static? => false)
57
- meta_object_2 = stub('meta object', :object => '<=', :ruby_type => { :type => String }, :static? => true, :raw? => true)
58
- meta_object_3 = stub('meta object', :name => :bar, :side => :rhs, :ruby_type => { :type => Integer }, :static? => false)
59
- comp = Compare.new(meta_object_1, meta_object_2, meta_object_3)
60
- assert_equal 0, comp.score({:foo => 10}, {:bar => 5})
86
+ field_1 = stub('foo field', :name => :foo, :ruby_type => { :type => Integer })
87
+ field_2 = stub('bar field', :name => :bar, :ruby_type => { :type => Integer })
88
+ comp = Compare.new([field_1], [field_2], :less_than_or_equal)
89
+ assert_equal :simple, comp.type
61
90
  assert_equal 1, comp.score({:foo => 5}, {:bar => 5})
62
91
  assert_equal 1, comp.score({:foo => 0}, {:bar => 5})
92
+ assert_equal 0, comp.score({:foo => 10}, {:bar => 5})
93
+ end
94
+
95
+ test "score for less than or equal to with multiple fields" do
96
+ field_1 = stub('foo field', :name => :foo, :ruby_type => { :type => Integer })
97
+ field_2 = stub('bar field', :name => :bar, :ruby_type => { :type => Integer })
98
+ field_3 = stub('baz field', :name => :baz, :ruby_type => { :type => Integer })
99
+ field_4 = stub('qux field', :name => :qux, :ruby_type => { :type => Integer })
100
+ comp = Compare.new([field_1, field_2], [field_3, field_4], :less_than_or_equal)
101
+ assert_equal :simple, comp.type
102
+ assert_equal 1, comp.score({:foo => 5, :bar => 0}, {:baz => 10, :qux => 5})
103
+ assert_equal 1, comp.score({:foo => 5, :bar => 0}, {:baz => 5, :qux => 0})
104
+ assert_equal 0, comp.score({:foo => 5, :bar => 0}, {:baz => 0, :qux => 5})
105
+ assert_equal 0, comp.score({:foo => 5, :bar => 0}, {:baz => 10, :qux => -5})
63
106
  end
64
107
 
65
108
  test "score for less than" do
66
- meta_object_1 = stub('meta object', :name => :foo, :side => :lhs, :ruby_type => { :type => Integer }, :static? => false)
67
- meta_object_2 = stub('meta object', :object => '<', :ruby_type => { :type => String }, :static? => true, :raw? => true)
68
- meta_object_3 = stub('meta object', :name => :bar, :side => :rhs, :ruby_type => { :type => Integer }, :static? => false)
69
- comp = Compare.new(meta_object_1, meta_object_2, meta_object_3)
109
+ field_1 = stub('foo field', :name => :foo, :ruby_type => { :type => Integer })
110
+ field_2 = stub('bar field', :name => :bar, :ruby_type => { :type => Integer })
111
+ comp = Compare.new([field_1], [field_2], :less_than)
112
+ assert_equal :simple, comp.type
113
+ assert_equal 1, comp.score({:foo => 0}, {:bar => 5})
70
114
  assert_equal 0, comp.score({:foo => 10}, {:bar => 5})
71
115
  assert_equal 0, comp.score({:foo => 5}, {:bar => 5})
72
- assert_equal 1, comp.score({:foo => 0}, {:bar => 5})
116
+ end
117
+
118
+ test "score for less than with multiple fields" do
119
+ field_1 = stub('foo field', :name => :foo, :ruby_type => { :type => Integer })
120
+ field_2 = stub('bar field', :name => :bar, :ruby_type => { :type => Integer })
121
+ field_3 = stub('baz field', :name => :baz, :ruby_type => { :type => Integer })
122
+ field_4 = stub('qux field', :name => :qux, :ruby_type => { :type => Integer })
123
+ comp = Compare.new([field_1, field_2], [field_3, field_4], :less_than)
124
+ assert_equal :simple, comp.type
125
+ assert_equal 1, comp.score({:foo => 5, :bar => 0}, {:baz => 10, :qux => 5})
126
+ assert_equal 0, comp.score({:foo => 5, :bar => 0}, {:baz => 5, :qux => 0})
127
+ assert_equal 0, comp.score({:foo => 5, :bar => 0}, {:baz => 0, :qux => 5})
128
+ assert_equal 0, comp.score({:foo => 5, :bar => 0}, {:baz => 10, :qux => -5})
129
+ end
130
+
131
+ test "score_datasets with one field equality" do
132
+ field_1 = stub('foo field', :name => :foo, :ruby_type => { :type => Integer })
133
+ field_2 = stub('bar field', :name => :bar, :ruby_type => { :type => Integer })
134
+ comp = Compare.new([field_1], [field_2], :equal)
135
+ assert_equal :advanced, comp.type
136
+ observer = stub('observer', :update => nil)
137
+ comp.add_observer(observer)
138
+
139
+ dataset_1 = stub('dataset 1')
140
+ dataset_1.expects(:order).with(:foo).returns(dataset_1)
141
+ dataset_1.expects(:each).multiple_yields(
142
+ [(record_1_1 = {:id => 1, :foo => 123})],
143
+ [(record_1_2 = {:id => 2, :foo => 456})],
144
+ [(record_1_3 = {:id => 3, :foo => 456})]
145
+ )
146
+
147
+ dataset_2 = stub('dataset 2')
148
+ dataset_2.expects(:order).with(:bar).returns(dataset_2)
149
+ dataset_2.expects(:each).multiple_yields(
150
+ [(record_2_1 = {:id => 100, :bar => 123})],
151
+ [(record_2_2 = {:id => 101, :bar => 456})],
152
+ [(record_2_3 = {:id => 102, :bar => 456})]
153
+ )
154
+
155
+ observer.expects(:update).with(comp, record_1_1, record_2_1, 1)
156
+ observer.expects(:update).with(comp, record_1_2, record_2_2, 1)
157
+ observer.expects(:update).with(comp, record_1_2, record_2_3, 1)
158
+ observer.expects(:update).with(comp, record_1_3, record_2_2, 1)
159
+ observer.expects(:update).with(comp, record_1_3, record_2_3, 1)
160
+
161
+ comp.score_datasets(dataset_1, dataset_2)
162
+ end
163
+
164
+ test "score_datasets with multiple field equality" do
165
+ field_1_1 = stub('foo field', :name => :foo, :ruby_type => { :type => Integer })
166
+ field_1_2 = stub('bar field', :name => :bar, :ruby_type => { :type => Integer })
167
+ field_2_1 = stub('baz field', :name => :baz, :ruby_type => { :type => Integer })
168
+ field_2_2 = stub('qux field', :name => :qux, :ruby_type => { :type => Integer })
169
+ comp = Compare.new([field_1_1, field_1_2], [field_2_1, field_2_2], :equal)
170
+ assert_equal :advanced, comp.type
171
+ observer = stub('observer', :update => nil)
172
+ comp.add_observer(observer)
173
+
174
+ dataset_1 = stub('dataset 1')
175
+ dataset_1.expects(:order).with(:foo, :bar).returns(dataset_1)
176
+ dataset_1.expects(:each).multiple_yields(
177
+ [(record_1_1 = {:id => 1, :foo => 123, :bar => 123})],
178
+ [(record_1_2 = {:id => 2, :foo => 123, :bar => 456})],
179
+ [(record_1_3 = {:id => 3, :foo => 123, :bar => 789})],
180
+ [(record_1_4 = {:id => 4, :foo => 456, :bar => 123})]
181
+ )
182
+
183
+ dataset_2 = stub('dataset 2')
184
+ dataset_2.expects(:order).with(:baz, :qux).returns(dataset_2)
185
+ dataset_2.expects(:each).multiple_yields(
186
+ [(record_2_1 = {:id => 100, :baz => 123, :qux => 123})],
187
+ [(record_2_2 = {:id => 101, :baz => 123, :qux => 123})],
188
+ [(record_2_3 = {:id => 102, :baz => 123, :qux => 789})],
189
+ [(record_2_4 = {:id => 103, :baz => 456, :qux => 123})],
190
+ [(record_2_5 = {:id => 104, :baz => 456, :qux => 456})]
191
+ )
192
+
193
+ observer.expects(:update).with(comp, record_1_1, record_2_1, 1)
194
+ observer.expects(:update).with(comp, record_1_1, record_2_2, 1)
195
+ observer.expects(:update).with(comp, record_1_3, record_2_3, 1)
196
+ observer.expects(:update).with(comp, record_1_4, record_2_4, 1)
197
+
198
+ comp.score_datasets(dataset_1, dataset_2)
199
+ end
200
+
201
+ test "score_dataset with same single field equality" do
202
+ field = stub('foo field', :name => :foo, :ruby_type => { :type => Integer })
203
+ comp = Compare.new([field], [field], :equal)
204
+ assert_equal :advanced, comp.type
205
+ observer = stub('observer', :update => nil)
206
+ comp.add_observer(observer)
207
+
208
+ dataset = stub('dataset')
209
+ dataset.expects(:order).with(:foo).returns(dataset)
210
+ dataset.expects(:each).multiple_yields(
211
+ [(record_1 = {:id => 1, :foo => 123})],
212
+ [(record_2 = {:id => 2, :foo => 456})],
213
+ [(record_3 = {:id => 3, :foo => 456})]
214
+ )
215
+
216
+ observer.expects(:update).with(comp, record_2, record_3, 1)
217
+ comp.score_dataset(dataset)
218
+ end
219
+
220
+ test "score_dataset with same multiple field equality" do
221
+ field_1 = stub('foo field', :name => :foo, :ruby_type => { :type => Integer })
222
+ field_2 = stub('bar field', :name => :bar, :ruby_type => { :type => Integer })
223
+ comp = Compare.new([field_1, field_2], [field_1, field_2], :equal)
224
+ assert_equal :advanced, comp.type
225
+ observer = stub('observer', :update => nil)
226
+ comp.add_observer(observer)
227
+
228
+ dataset = stub('dataset')
229
+ dataset.expects(:order).with(:foo, :bar).returns(dataset)
230
+ dataset.expects(:each).multiple_yields(
231
+ [(record_1 = {:id => 1, :foo => 123, :bar => 123})],
232
+ [(record_2 = {:id => 2, :foo => 123, :bar => 123})],
233
+ [(record_3 = {:id => 3, :foo => 123, :bar => 123})],
234
+ [(record_4 = {:id => 4, :foo => 123, :bar => 456})],
235
+ [(record_5 = {:id => 5, :foo => 456, :bar => 123})],
236
+ [(record_6 = {:id => 6, :foo => 456, :bar => 456})],
237
+ [(record_7 = {:id => 7, :foo => 456, :bar => 456})]
238
+ )
239
+
240
+ observer.expects(:update).with(comp, record_1, record_2, 1)
241
+ observer.expects(:update).with(comp, record_1, record_3, 1)
242
+ observer.expects(:update).with(comp, record_2, record_3, 1)
243
+ observer.expects(:update).with(comp, record_6, record_7, 1)
244
+
245
+ comp.score_dataset(dataset)
246
+ end
247
+
248
+ test "score_dataset with different single field equality" do
249
+ field_1 = stub('foo field', :name => :foo, :ruby_type => { :type => Integer })
250
+ field_2 = stub('bar field', :name => :bar, :ruby_type => { :type => Integer })
251
+ comp = Compare.new([field_1], [field_2], :equal)
252
+ assert_equal :advanced, comp.type
253
+ observer = stub('observer', :update => nil)
254
+ comp.add_observer(observer)
255
+
256
+ dataset = stub('dataset')
257
+ dataset_1 = stub('dataset 1')
258
+ dataset.expects(:order).with(:foo).returns(dataset_1)
259
+ dataset_1.expects(:each).multiple_yields(
260
+ [(record_1 = {:id => 1, :foo => 123, :bar => 456})],
261
+ [(record_2 = {:id => 2, :foo => 456, :bar => 456})],
262
+ [(record_3 = {:id => 3, :foo => 456, :bar => 123})]
263
+ )
264
+
265
+ dataset_2 = stub('dataset 2')
266
+ dataset.expects(:order).with(:bar).returns(dataset_2)
267
+ dataset_2.expects(:each).multiple_yields(
268
+ [record_3],
269
+ [record_1],
270
+ [record_2]
271
+ )
272
+
273
+ observer.expects(:update).with(comp, record_1, record_3, 1)
274
+ observer.expects(:update).with(comp, record_2, record_1, 1)
275
+ observer.expects(:update).with(comp, record_2, record_2, 1)
276
+ observer.expects(:update).with(comp, record_3, record_1, 1)
277
+ observer.expects(:update).with(comp, record_3, record_2, 1)
278
+
279
+ comp.score_dataset(dataset)
73
280
  end
74
281
 
75
282
  test "registers itself" do
76
283
  assert_equal Compare, Linkage::Comparator['compare']
77
284
  end
78
285
 
79
- test "requires argument from each side" do
80
- meta_object_1 = stub('meta object', :name => :foo, :side => :lhs, :ruby_type => { :type => Integer }, :static? => false)
81
- meta_object_2 = stub('meta object', :object => '>=', :ruby_type => { :type => String }, :static? => true, :raw? => true)
82
- meta_object_3 = stub('meta object', :name => :bar, :side => :lhs, :ruby_type => { :type => Integer }, :static? => false)
286
+ test "requires equal size sets" do
287
+ field_1 = stub('foo field', :name => :foo, :ruby_type => { :type => Integer })
288
+ field_2 = stub('bar field', :name => :bar, :ruby_type => { :type => Integer })
83
289
  assert_raises do
84
- Compare.new(meta_object_1, meta_object_2, meta_object_3)
290
+ Compare.new([field_1, field_2], [], :greater_than_or_equal)
85
291
  end
86
292
  end
87
293
 
88
- test "requires that 3rd argument has the same type as the first argument" do
89
- meta_object_1 = stub('meta object', :name => :foo, :side => :lhs, :ruby_type => { :type => Integer }, :static? => false)
90
- meta_object_2 = stub('meta object', :object => '>=', :ruby_type => { :type => String }, :static? => true, :raw? => true)
91
- meta_object_3 = stub('meta object', :name => :bar, :side => :rhs, :ruby_type => { :type => Date }, :static? => false)
294
+ test "requires that sets have values with alike types" do
295
+ field_1 = stub('foo field', :name => :foo, :ruby_type => { :type => Integer })
296
+ field_2 = stub('bar field', :name => :bar, :ruby_type => { :type => Date })
92
297
  assert_raises do
93
- Compare.new(meta_object_1, meta_object_2, meta_object_3)
298
+ Compare.new([field_1], [field_2], :greater_than_or_equal)
94
299
  end
95
300
  end
96
301
 
97
- test "requires raw operator to be >, >=, <=, <, or !=" do
98
- meta_object_1 = stub('meta object', :name => :foo, :side => :lhs, :ruby_type => { :type => Integer }, :static? => false)
99
- meta_object_2 = stub('meta object', :object => 'foo', :ruby_type => { :type => String }, :static? => true, :raw? => true)
100
- meta_object_3 = stub('meta object', :name => :bar, :side => :rhs, :ruby_type => { :type => Integer }, :static? => false)
302
+ test "requires valid operation" do
303
+ field_1 = stub('foo field', :name => :foo, :ruby_type => { :type => Integer })
304
+ field_2 = stub('bar field', :name => :bar, :ruby_type => { :type => Integer })
101
305
  assert_raises do
102
- Compare.new(meta_object_1, meta_object_2, meta_object_3)
306
+ Compare.new([field_1], [field_2], 'foo')
103
307
  end
104
308
  end
105
309
  end
@@ -0,0 +1,45 @@
1
+ require File.expand_path("../../test_comparators", __FILE__)
2
+
3
+ class UnitTests::TestComparators::TestStrcompare < Test::Unit::TestCase
4
+ def self.const_missing(name)
5
+ if Linkage::Comparators.const_defined?(name)
6
+ Linkage::Comparators.const_get(name)
7
+ else
8
+ super
9
+ end
10
+ end
11
+
12
+ test "subclass of Comparator" do
13
+ assert_equal Linkage::Comparator, Strcompare.superclass
14
+ end
15
+
16
+ test "requires string types" do
17
+ field_1 = stub('field 1', :name => :foo, :ruby_type => { :type => Integer })
18
+ field_2 = stub('field 2', :name => :bar, :ruby_type => { :type => Integer })
19
+ assert_raises do
20
+ Strcompare.new(field_1, field_2, :jarowinkler)
21
+ end
22
+ end
23
+
24
+ test "requires valid operator" do
25
+ field_1 = stub('field 1', :name => :foo, :ruby_type => { :type => String })
26
+ field_2 = stub('field 2', :name => :bar, :ruby_type => { :type => String })
27
+ assert_raises do
28
+ Strcompare.new(field_1, field_2, 'foo')
29
+ end
30
+ end
31
+
32
+ test "score for jarowinkler" do
33
+ field_1 = stub('field 1', :name => :foo, :ruby_type => { :type => String })
34
+ field_2 = stub('field 2', :name => :bar, :ruby_type => { :type => String })
35
+ comp = Strcompare.new(field_1, field_2, :jarowinkler)
36
+ assert_equal 0.961, comp.score({:foo => 'martha'}, {:bar => 'marhta'})
37
+ assert_equal 0.840, comp.score({:foo => 'dwayne'}, {:bar => 'duane'})
38
+ assert_equal 0.813, comp.score({:foo => 'dixon'}, {:bar => 'dicksonx'})
39
+ assert_equal 0, comp.score({:foo => 'cat'}, {:bar => 'dog'})
40
+ end
41
+
42
+ test "registers itself" do
43
+ assert_equal Strcompare, Linkage::Comparator['strcompare']
44
+ end
45
+ end
@@ -1,6 +1,6 @@
1
- require 'helper'
1
+ require File.expand_path("../../test_comparators", __FILE__)
2
2
 
3
- class UnitTests::TestWithin < Test::Unit::TestCase
3
+ class UnitTests::TestComparators::TestWithin < Test::Unit::TestCase
4
4
  def self.const_missing(name)
5
5
  if Linkage::Comparators.const_defined?(name)
6
6
  Linkage::Comparators.const_get(name)
@@ -9,24 +9,22 @@ class UnitTests::TestWithin < Test::Unit::TestCase
9
9
  end
10
10
  end
11
11
 
12
- test "subclass of Binary" do
13
- assert_equal Linkage::Comparators::Binary, Within.superclass
12
+ test "subclass of Comparator" do
13
+ assert_equal Linkage::Comparator, Within.superclass
14
14
  end
15
15
 
16
16
  test "valid parameters" do
17
- meta_object_1 = stub('meta object', :name => :foo, :side => :lhs, :ruby_type => { :type => Integer }, :static? => false)
18
- meta_object_2 = stub('meta object', :object => 123, :ruby_type => { :type => Fixnum }, :static? => true, :object => 123)
19
- meta_object_3 = stub('meta object', :name => :bar, :side => :rhs, :ruby_type => { :type => Integer }, :static? => false)
17
+ field_1 = stub('field 1', :name => :foo, :ruby_type => { :type => Integer })
18
+ field_2 = stub('field 2', :name => :bar, :ruby_type => { :type => Integer })
20
19
  assert_nothing_raised do
21
- Within.new(meta_object_1, meta_object_2, meta_object_3)
20
+ Within.new(field_1, field_2, 123)
22
21
  end
23
22
  end
24
23
 
25
24
  test "score" do
26
- meta_object_1 = stub('meta object', :name => :foo, :side => :lhs, :ruby_type => { :type => Integer }, :static? => false)
27
- meta_object_2 = stub('meta object', :object => 123, :ruby_type => { :type => Fixnum }, :static? => true, :object => 123)
28
- meta_object_3 = stub('meta object', :name => :bar, :side => :rhs, :ruby_type => { :type => Integer }, :static? => false)
29
- comp = Within.new(meta_object_1, meta_object_2, meta_object_3)
25
+ field_1 = stub('field 1', :name => :foo, :ruby_type => { :type => Integer })
26
+ field_2 = stub('field 2', :name => :bar, :ruby_type => { :type => Integer })
27
+ comp = Within.new(field_1, field_2, 123)
30
28
  assert_equal 1, comp.score({:foo => 123}, {:bar => 124})
31
29
  assert_equal 1, comp.score({:foo => 124}, {:bar => 123})
32
30
  assert_equal 1, comp.score({:foo => 0}, {:bar => 123})
@@ -37,21 +35,11 @@ class UnitTests::TestWithin < Test::Unit::TestCase
37
35
  assert_equal Within, Linkage::Comparator['within']
38
36
  end
39
37
 
40
- test "requires argument from each side" do
41
- meta_object_1 = stub('meta object', :name => :foo, :side => :lhs, :ruby_type => { :type => Integer }, :static? => false)
42
- meta_object_2 = stub('meta object', :object => 123, :ruby_type => { :type => Fixnum }, :static? => true, :object => 123)
43
- meta_object_3 = stub('meta object', :name => :bar, :side => :lhs, :ruby_type => { :type => Integer }, :static? => false)
38
+ test "requires that second argument has the same type as the first argument" do
39
+ field_1 = stub('field 1', :name => :foo, :ruby_type => { :type => Integer })
40
+ field_2 = stub('field 2', :name => :bar, :ruby_type => { :type => Date })
44
41
  assert_raises do
45
- Within.new(meta_object_1, meta_object_2, meta_object_3)
46
- end
47
- end
48
-
49
- test "requires that 3rd argument has the same type as the first argument" do
50
- meta_object_1 = stub('meta object', :name => :foo, :side => :lhs, :ruby_type => { :type => Integer }, :static? => false)
51
- meta_object_2 = stub('meta object', :object => 123, :ruby_type => { :type => Fixnum }, :static? => true, :object => 123)
52
- meta_object_3 = stub('meta object', :name => :bar, :side => :rhs, :ruby_type => { :type => Date }, :static? => false)
53
- assert_raises do
54
- Within.new(meta_object_1, meta_object_2, meta_object_3)
42
+ Within.new(field_1, field_2, 123)
55
43
  end
56
44
  end
57
45
  end
@@ -0,0 +1,78 @@
1
+ require File.expand_path("../../test_match_sets", __FILE__)
2
+
3
+ class UnitTests::TestMatchSets::TestCSV < Test::Unit::TestCase
4
+ test "open_for_writing" do
5
+ match_set = Linkage::MatchSets::CSV.new('foo.csv')
6
+ csv = stub('csv')
7
+ CSV.expects(:open).with('foo.csv', 'wb').returns(csv)
8
+ csv.expects(:<<).with(%w{id_1 id_2 score})
9
+ match_set.open_for_writing
10
+ end
11
+
12
+ test "open_for_writing when already open" do
13
+ match_set = Linkage::MatchSets::CSV.new('foo.csv')
14
+ csv = stub('csv')
15
+ CSV.expects(:open).once.with('foo.csv', 'wb').returns(csv)
16
+ csv.expects(:<<).once.with(%w{id_1 id_2 score})
17
+ match_set.open_for_writing
18
+ match_set.open_for_writing
19
+ end
20
+
21
+ test "open_for_writing when file exists" do
22
+ match_set = Linkage::MatchSets::CSV.new('foo.csv')
23
+ File.expects(:exist?).with('foo.csv').returns(true)
24
+ assert_raises(Linkage::ExistsError) do
25
+ match_set.open_for_writing
26
+ end
27
+ end
28
+
29
+ test "open_for_writing when file exists and forcing overwrite" do
30
+ match_set = Linkage::MatchSets::CSV.new('foo.csv', :overwrite => true)
31
+ File.stubs(:exist?).with('foo.csv').returns(true)
32
+ assert_nothing_raised do
33
+ csv = stub('csv')
34
+ CSV.expects(:open).with('foo.csv', 'wb').returns(csv)
35
+ csv.expects(:<<).with(%w{id_1 id_2 score})
36
+ match_set.open_for_writing
37
+ end
38
+ end
39
+
40
+ test "add_match when unopened raises exception" do
41
+ match_set = Linkage::MatchSets::CSV.new('foo.csv')
42
+ assert_raises { match_set.add_match(1, 2, 1) }
43
+ end
44
+
45
+ test "add_match" do
46
+ tempfile = Tempfile.new('linkage')
47
+ tempfile.close
48
+ match_set = Linkage::MatchSets::CSV.new(tempfile.path, :overwrite => true)
49
+ match_set.open_for_writing
50
+ match_set.add_match(1, 2, 1)
51
+ match_set.close
52
+
53
+ expected = "id_1,id_2,score\n1,2,1\n"
54
+ assert_equal expected, File.read(tempfile.path)
55
+ end
56
+
57
+ test "add_match removes extra decimals" do
58
+ match_set = Linkage::MatchSets::CSV.new('foo.csv')
59
+ csv = stub('csv')
60
+ CSV.stubs(:open).with('foo.csv', 'wb').returns(csv)
61
+ csv.stubs(:<<).with(%w{id_1 id_2 score})
62
+ match_set.open_for_writing
63
+
64
+ csv.expects(:<<).with do |(id_1, id_2, score)|
65
+ id_1 == 1 && id_2 == 2 && score.equal?(1)
66
+ end
67
+ match_set.add_match(1, 2, 1.0)
68
+
69
+ csv.expects(:<<).with do |(id_1, id_2, score)|
70
+ id_1 == 1 && id_2 == 2 && score.equal?(0)
71
+ end
72
+ match_set.add_match(1, 2, 0.0)
73
+ end
74
+
75
+ test "registers itself" do
76
+ assert_equal Linkage::MatchSets::CSV, Linkage::MatchSet['csv']
77
+ end
78
+ end
@@ -0,0 +1,63 @@
1
+ require File.expand_path("../../test_match_sets", __FILE__)
2
+
3
+ class UnitTests::TestMatchSets::TestDatabase < Test::Unit::TestCase
4
+ def setup
5
+ @dataset = stub('dataset')
6
+ @database = stub('database', :[] => @dataset)
7
+ end
8
+
9
+ test "open_for_writing for database with no matches table" do
10
+ match_set = Linkage::MatchSets::Database.new(@database)
11
+ @database.stubs(:table_exists?).with(:matches).returns(false)
12
+ @database.expects(:create_table).with(:matches)
13
+ @database.expects(:[]).with(:matches).returns(@dataset)
14
+ match_set.open_for_writing
15
+ end
16
+
17
+ test "open_for_writing when already open" do
18
+ match_set = Linkage::MatchSets::Database.new(@database)
19
+ @database.stubs(:table_exists?).with(:matches).returns(false)
20
+ @database.expects(:create_table).with(:matches)
21
+ @database.expects(:[]).with(:matches).returns(@dataset)
22
+ match_set.open_for_writing
23
+ match_set.open_for_writing
24
+ end
25
+
26
+ test "open_for_writing when matches table already exists" do
27
+ match_set = Linkage::MatchSets::Database.new(@database)
28
+ @database.expects(:table_exists?).with(:matches).returns(true)
29
+ @database.expects(:create_table).with(:matches).never
30
+ assert_raises(Linkage::ExistsError) do
31
+ match_set.open_for_writing
32
+ end
33
+ end
34
+
35
+ test "open_for_writing when matches table already exists and in overwrite mode" do
36
+ match_set = Linkage::MatchSets::Database.new(@database, :overwrite => true)
37
+ @database.expects(:drop_table?).with(:matches)
38
+ @database.expects(:create_table).with(:matches)
39
+ @database.expects(:[]).with(:matches).returns(@dataset)
40
+ match_set.open_for_writing
41
+ end
42
+
43
+ test "add_match when unopened raises exception" do
44
+ match_set = Linkage::MatchSets::Database.new(@database)
45
+ assert_raises { match_set.add_match(1, 2, 1) }
46
+ end
47
+
48
+ test "add_match" do
49
+ match_set = Linkage::MatchSets::Database.new(@database)
50
+ @database.stubs(:table_exists?).with(:matches).returns(false)
51
+ @database.stubs(:create_table)
52
+ match_set.open_for_writing
53
+
54
+ @dataset.expects(:insert).with({
55
+ :id_1 => 1, :id_2 => 2, :score => 1
56
+ })
57
+ match_set.add_match(1, 2, 1)
58
+ end
59
+
60
+ test "registers itself" do
61
+ assert_equal Linkage::MatchSets::Database, Linkage::MatchSet['database']
62
+ end
63
+ end