linkage 0.0.6 → 0.0.8

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 (66) hide show
  1. data/.gitignore +10 -0
  2. data/Gemfile +15 -13
  3. data/Gemfile.lock +67 -37
  4. data/Guardfile +0 -2
  5. data/Rakefile +122 -25
  6. data/lib/linkage/comparator.rb +172 -0
  7. data/lib/linkage/comparators/binary.rb +12 -0
  8. data/lib/linkage/comparators/compare.rb +46 -0
  9. data/lib/linkage/comparators/within.rb +32 -0
  10. data/lib/linkage/configuration.rb +285 -153
  11. data/lib/linkage/data.rb +32 -7
  12. data/lib/linkage/dataset.rb +107 -32
  13. data/lib/linkage/decollation.rb +93 -0
  14. data/lib/linkage/expectation.rb +21 -0
  15. data/lib/linkage/expectations/exhaustive.rb +63 -0
  16. data/lib/linkage/expectations/simple.rb +168 -0
  17. data/lib/linkage/field.rb +30 -4
  18. data/lib/linkage/field_set.rb +6 -3
  19. data/lib/linkage/function.rb +50 -3
  20. data/lib/linkage/functions/binary.rb +30 -0
  21. data/lib/linkage/functions/cast.rb +54 -0
  22. data/lib/linkage/functions/length.rb +29 -0
  23. data/lib/linkage/functions/strftime.rb +12 -11
  24. data/lib/linkage/functions/trim.rb +8 -0
  25. data/lib/linkage/group.rb +20 -0
  26. data/lib/linkage/import_buffer.rb +5 -16
  27. data/lib/linkage/meta_object.rb +139 -0
  28. data/lib/linkage/result_set.rb +74 -17
  29. data/lib/linkage/runner/single_threaded.rb +125 -10
  30. data/lib/linkage/version.rb +3 -0
  31. data/lib/linkage.rb +11 -0
  32. data/linkage.gemspec +16 -121
  33. data/test/config.yml +5 -0
  34. data/test/helper.rb +73 -8
  35. data/test/integration/test_collation.rb +45 -0
  36. data/test/integration/test_configuration.rb +268 -0
  37. data/test/integration/test_cross_linkage.rb +4 -17
  38. data/test/integration/test_dataset.rb +45 -2
  39. data/test/integration/test_dual_linkage.rb +40 -24
  40. data/test/integration/test_functions.rb +22 -0
  41. data/test/integration/test_result_set.rb +85 -0
  42. data/test/integration/test_scoring.rb +84 -0
  43. data/test/integration/test_self_linkage.rb +5 -0
  44. data/test/integration/test_within_comparator.rb +100 -0
  45. data/test/unit/comparators/test_compare.rb +105 -0
  46. data/test/unit/comparators/test_within.rb +57 -0
  47. data/test/unit/expectations/test_exhaustive.rb +111 -0
  48. data/test/unit/expectations/test_simple.rb +303 -0
  49. data/test/unit/functions/test_binary.rb +54 -0
  50. data/test/unit/functions/test_cast.rb +98 -0
  51. data/test/unit/functions/test_length.rb +52 -0
  52. data/test/unit/functions/test_strftime.rb +17 -13
  53. data/test/unit/functions/test_trim.rb +11 -4
  54. data/test/unit/test_comparator.rb +124 -0
  55. data/test/unit/test_configuration.rb +137 -175
  56. data/test/unit/test_data.rb +44 -0
  57. data/test/unit/test_dataset.rb +73 -21
  58. data/test/unit/test_decollation.rb +201 -0
  59. data/test/unit/test_field.rb +38 -14
  60. data/test/unit/test_field_set.rb +12 -8
  61. data/test/unit/test_function.rb +83 -16
  62. data/test/unit/test_group.rb +28 -0
  63. data/test/unit/test_import_buffer.rb +13 -27
  64. data/test/unit/test_meta_object.rb +208 -0
  65. data/test/unit/test_result_set.rb +221 -3
  66. metadata +82 -190
@@ -1,210 +1,172 @@
1
1
  require 'helper'
2
2
 
3
3
  class UnitTests::TestConfiguration < Test::Unit::TestCase
4
- test "linkage_type is self when the two datasets are the same" do
5
- dataset = stub('dataset')
6
- c = Linkage::Configuration.new(dataset, dataset)
7
- assert_equal :self, c.linkage_type
8
- end
9
-
10
- test "linkage_type is dual when the two datasets are different" do
4
+ test "result_set" do
11
5
  dataset_1 = stub('dataset')
12
6
  dataset_2 = stub('dataset')
13
7
  c = Linkage::Configuration.new(dataset_1, dataset_2)
14
- assert_equal :dual, c.linkage_type
15
- end
16
8
 
17
- test "linkage_type is cross when there's a 'cross-join'" do
18
- field_1 = stub('field_1', :to_expr => :foo)
19
- field_2 = stub('field_2', :to_expr => :bar)
20
- dataset = stub('dataset', :field_set => {:foo => field_1, :bar => :field_2})
21
- c = Linkage::Configuration.new(dataset, dataset)
22
- c.configure do
23
- lhs[:foo].must == rhs[:bar]
24
- end
25
- assert_equal :cross, c.linkage_type
26
- end
27
-
28
- test "linkage_type is cross when there's different filters on both sides" do
29
- field = stub('field', :to_expr => :foo)
30
- dataset = stub('dataset')
31
- dataset.stubs(:field_set).returns({:foo => field})
32
- c = Linkage::Configuration.new(dataset, dataset)
33
- c.configure do
34
- lhs[:foo].must == 123
35
- rhs[:foo].must == 456
36
- end
37
- assert_equal :cross, c.linkage_type
9
+ result_set = stub('result set')
10
+ Linkage::ResultSet.expects(:new).with(c).returns(result_set)
11
+ assert_equal result_set, c.result_set
38
12
  end
39
13
 
40
- test "linkage_type is self when there's identical static filters on each side" do
41
- field = stub('field', :to_expr => :foo)
42
- dataset = stub('dataset')
43
- dataset.stubs(:field_set).returns({:foo => field})
44
- c = Linkage::Configuration.new(dataset, dataset)
45
- exp_1 = stub('expectation', :kind => :filter)
46
- c.configure do
47
- lhs[:foo].must == 123
48
- rhs[:foo].must == 123
49
- end
50
- assert_equal :self, c.linkage_type
14
+ test "groups_table_needed? is false if there are no simple expectations" do
15
+ dataset_1 = stub('dataset')
16
+ dataset_2 = stub('dataset')
17
+ conf = Linkage::Configuration.new(dataset_1, dataset_2)
18
+ assert !conf.groups_table_needed?
51
19
  end
52
20
 
53
- test "linkage_type is self when there's a two-field filter on one side" do
54
- field_1 = stub('field 1', :to_expr => :foo)
55
- field_2 = stub('field 2', :to_expr => :bar)
56
- dataset = stub('dataset')
57
- dataset.stubs(:field_set).returns({:foo => field_1, :bar => field_2})
58
- c = Linkage::Configuration.new(dataset, dataset)
59
- c.configure do
60
- lhs[:foo].must == lhs[:bar]
61
- lhs[:foo].must == rhs[:foo]
62
- end
63
- assert_equal :self, c.linkage_type
21
+ test "groups_table_needed? is true if there are any simple expectations" do
22
+ dataset_1 = stub('dataset')
23
+ dataset_2 = stub('dataset')
24
+ conf = Linkage::Configuration.new(dataset_1, dataset_2)
25
+ exp = stub('simple expectation', :decollation_needed? => false)
26
+ conf.add_simple_expectation(exp)
27
+ assert conf.groups_table_needed?
64
28
  end
65
29
 
66
- test "static expectation" do
30
+ test "scores_table_needed? is false if there are no exhaustive expectations" do
67
31
  dataset_1 = stub('dataset')
68
- field = stub('field', :to_expr => :foo)
69
- dataset_1.stubs(:field_set).returns({:foo => field})
70
32
  dataset_2 = stub('dataset')
71
- c = Linkage::Configuration.new(dataset_1, dataset_2)
72
- c.configure do
73
- lhs[:foo].must == 123
74
- end
75
- dataset_1.expects(:filter).with({:foo => 123}).returns(dataset_1)
76
- c.expectations[0].apply_to(dataset_1, :lhs)
33
+ conf = Linkage::Configuration.new(dataset_1, dataset_2)
34
+ assert !conf.scores_table_needed?
77
35
  end
78
36
 
79
- test "complain if an invalid field is accessed" do
37
+ test "scores_table_needed? is true if there are any exhaustive expectations" do
80
38
  dataset_1 = stub('dataset')
81
- field_1 = stub('field 1')
82
- dataset_1.stubs(:field_set).returns({:foo => field_1})
83
-
84
39
  dataset_2 = stub('dataset')
85
- field_2 = stub('field 2')
86
- dataset_2.stubs(:field_set).returns({:bar => field_2})
87
-
88
- c = Linkage::Configuration.new(dataset_1, dataset_2)
89
- assert_raises(ArgumentError) do
90
- c.configure do
91
- lhs[:foo].must == rhs[:non_existant_field]
92
- end
93
- end
40
+ conf = Linkage::Configuration.new(dataset_1, dataset_2)
41
+ exp = stub('exhaustive expectation')
42
+ conf.add_exhaustive_expectation(exp)
43
+ assert conf.scores_table_needed?
94
44
  end
95
45
 
96
- operators = [:>, :<, :>=, :<=]
97
- operators.each do |operator|
98
- test "DSL #{operator} filter operator" do
99
- dataset_1 = stub('dataset 1')
100
- field_1 = stub('field 1', :to_expr => :foo)
101
- dataset_1.stubs(:field_set).returns({:foo => field_1})
102
-
103
- dataset_2 = stub('dataset 2')
104
-
105
- c = Linkage::Configuration.new(dataset_1, dataset_2)
106
- block = eval("Proc.new { lhs[:foo].must #{operator} rhs[:bar] }")
107
- c.configure do
108
- lhs[:foo].must.send(operator, 123)
109
- end
110
- expr = Sequel::SQL::BooleanExpression.new(operator, Sequel::SQL::Identifier.new(:foo), 123)
111
- dataset_1.expects(:filter).with(expr).returns(dataset_1)
112
- c.expectations[0].apply_to(dataset_1, :lhs)
113
- end
46
+ test "scores_table_schema" do
47
+ dataset_1 = stub('dataset 1', {
48
+ :field_set => stub('field set 1', {
49
+ :primary_key => stub('primary key 1', {
50
+ :ruby_type => {:type => Integer}
51
+ })
52
+ })
53
+ })
54
+ dataset_2 = stub('dataset 2', {
55
+ :field_set => stub('field set 2', {
56
+ :primary_key => stub('primary key 2', {
57
+ :ruby_type => {:type => String, :opts => {:size => 10}}
58
+ })
59
+ })
60
+ })
61
+ conf = Linkage::Configuration.new(dataset_1, dataset_2)
62
+ exp_1 = stub('exhaustive expectation 1')
63
+ exp_2 = stub('exhaustive expectation 2')
64
+ conf.add_exhaustive_expectation(exp_1)
65
+ conf.add_exhaustive_expectation(exp_2)
66
+
67
+ expected = [
68
+ [:id, Integer, {:primary_key => true}],
69
+ [:comparator_id, Integer, {}],
70
+ [:record_1_id, Integer, {}],
71
+ [:record_2_id, String, {:size => 10}],
72
+ [:score, Integer, {}],
73
+ ]
74
+ assert_equal expected, conf.scores_table_schema
114
75
  end
115
76
 
116
- test "must_not expectation" do
117
- dataset_1 = stub('dataset 1')
118
- field_1 = stub('field 1', :to_expr => :foo)
119
- dataset_1.stubs(:field_set).returns({:foo => field_1})
120
- dataset_2 = stub('dataset 2')
121
-
122
- c = Linkage::Configuration.new(dataset_1, dataset_2)
123
- c.configure do
124
- lhs[:foo].must_not == 123
125
- end
126
- dataset_1.expects(:filter).with(~{:foo => 123}).returns(dataset_1)
127
- c.expectations[0].apply_to(dataset_1, :lhs)
77
+ test "datasets_with_applied_exhaustive_expectations" do
78
+ dataset_1 = stub('dataset 1', {
79
+ :field_set => stub('field set 1', {
80
+ :primary_key => stub('primary key 1', {
81
+ :to_expr => :foo_id
82
+ })
83
+ })
84
+ })
85
+ dataset_2 = stub('dataset 2', {
86
+ :field_set => stub('field set 2', {
87
+ :primary_key => stub('primary key 2', {
88
+ :to_expr => :bar_id
89
+ })
90
+ })
91
+ })
92
+ dataset_1a = stub('dataset 1a')
93
+ dataset_2a = stub('dataset 2a')
94
+ dataset_1b = stub('dataset 1b')
95
+ dataset_2b = stub('dataset 2b')
96
+ dataset_1c = stub('dataset 1c')
97
+ dataset_2c = stub('dataset 2c')
98
+ exp_1 = stub('exhaustive expectation 1')
99
+ exp_2 = stub('exhaustive expectation 2')
100
+
101
+ conf = Linkage::Configuration.new(dataset_1, dataset_2)
102
+ conf.add_exhaustive_expectation(exp_1)
103
+ conf.add_exhaustive_expectation(exp_2)
104
+
105
+ dataset_1.expects(:select).with(:foo_id).returns(dataset_1a)
106
+ dataset_2.expects(:select).with(:bar_id).returns(dataset_2a)
107
+ exp_1.expects(:apply_to).with(dataset_1a, :lhs).returns(dataset_1b)
108
+ exp_1.expects(:apply_to).with(dataset_2a, :rhs).returns(dataset_2b)
109
+ exp_2.expects(:apply_to).with(dataset_1b, :lhs).returns(dataset_1c)
110
+ exp_2.expects(:apply_to).with(dataset_2b, :rhs).returns(dataset_2c)
111
+
112
+ assert_equal [dataset_1c, dataset_2c], conf.datasets_with_applied_exhaustive_expectations
128
113
  end
129
114
 
130
- test "dynamic database function" do
131
- dataset_1 = stub('dataset', :adapter_scheme => :sqlite)
132
- field_1 = stub('field 1')
133
- dataset_1.stubs(:field_set).returns({:foo => field_1})
134
- dataset_2 = stub('dataset', :adapter_scheme => :mysql2)
135
- field_2 = stub('field 2', :to_expr => :foo)
136
- dataset_2.stubs(:field_set).returns({:foo => field_2})
137
-
138
- func_expr = stub('function expression')
139
- func = stub('function', :static? => false, :to_expr => func_expr)
140
- Linkage::Functions::Trim.expects(:new).with(field_1).returns(func)
141
- merged_field = stub('merged field', :name => :trim_foo_foo)
142
- func.expects(:merge).with(field_2).returns(merged_field)
143
-
144
- c = Linkage::Configuration.new(dataset_1, dataset_2)
145
- c.configure do
146
- trim(lhs[:foo]).must == rhs[:foo]
147
- end
148
- dataset_1.expects(:match).with(func_expr, :trim_foo_foo).returns(dataset_1)
149
- c.expectations[0].apply_to(dataset_1, :lhs)
150
-
151
- dataset_2.expects(:match).with(:foo, :trim_foo_foo).returns(dataset_2)
152
- c.expectations[0].apply_to(dataset_2, :rhs)
115
+ test "matches_table_schema" do
116
+ dataset_1 = stub('dataset 1', {
117
+ :field_set => stub('field set 1', {
118
+ :primary_key => stub('primary key 1', {
119
+ :ruby_type => {:type => Integer}
120
+ })
121
+ })
122
+ })
123
+ dataset_2 = stub('dataset 2', {
124
+ :field_set => stub('field set 2', {
125
+ :primary_key => stub('primary key 2', {
126
+ :ruby_type => {:type => String, :opts => {:size => 10}}
127
+ })
128
+ })
129
+ })
130
+ conf = Linkage::Configuration.new(dataset_1, dataset_2)
131
+
132
+ expected = [
133
+ [:id, Integer, {:primary_key => true}],
134
+ [:record_1_id, Integer, {}],
135
+ [:record_2_id, String, {:size => 10}],
136
+ [:total_score, Integer, {}],
137
+ ]
138
+ assert_equal expected, conf.matches_table_schema
153
139
  end
154
140
 
155
- test "static database function" do
156
- dataset_1 = stub('dataset', :adapter_scheme => :sqlite)
157
- field_1 = stub('field 1', :to_expr => :foo)
158
- dataset_1.stubs(:field_set).returns({:foo => field_1})
159
- dataset_2 = stub('dataset', :adapter_scheme => :mysql)
160
- field_2 = stub('field 2')
161
- dataset_2.stubs(:field_set).returns({:foo => field_2})
162
-
163
- func_expr = stub('function expression')
164
- func = stub('function', :static? => true, :to_expr => func_expr)
165
- Linkage::Functions::Trim.expects(:new).with("foo").returns(func)
166
-
167
- c = Linkage::Configuration.new(dataset_1, dataset_2)
168
- c.configure do
169
- lhs[:foo].must == trim("foo")
170
- end
171
- dataset_1.expects(:filter).with({:foo => func_expr}).returns(dataset_1)
172
- c.expectations[0].apply_to(dataset_1, :lhs)
141
+ test "change groups table name from default" do
142
+ dataset = stub('dataset')
143
+ conf = Linkage::Configuration.new(dataset, dataset)
144
+ assert_equal :groups, conf.groups_table_name
145
+ conf.groups_table_name = :foo_groups
146
+ assert_equal :foo_groups, conf.groups_table_name
173
147
  end
174
148
 
175
- test "save_results_in" do
176
- dataset_1 = stub('dataset')
177
- dataset_2 = stub('dataset')
178
- c = Linkage::Configuration.new(dataset_1, dataset_2)
179
- c.configure do
180
- save_results_in("mysql://localhost/results", {:foo => 'bar'})
181
- end
182
- assert_equal "mysql://localhost/results", c.results_uri
183
- assert_equal({:foo => 'bar'}, c.results_uri_options)
149
+ test "change original groups table name from default" do
150
+ dataset = stub('dataset')
151
+ conf = Linkage::Configuration.new(dataset, dataset)
152
+ assert_equal :original_groups, conf.original_groups_table_name
153
+ conf.original_groups_table_name = :foo_original_groups
154
+ assert_equal :foo_original_groups, conf.original_groups_table_name
184
155
  end
185
156
 
186
- test "result_set" do
187
- dataset_1 = stub('dataset')
188
- dataset_2 = stub('dataset')
189
- c = Linkage::Configuration.new(dataset_1, dataset_2)
190
-
191
- result_set = stub('result set')
192
- Linkage::ResultSet.expects(:new).with(c).returns(result_set)
193
- assert_equal result_set, c.result_set
157
+ test "change scores table name from default" do
158
+ dataset = stub('dataset')
159
+ conf = Linkage::Configuration.new(dataset, dataset)
160
+ assert_equal :scores, conf.scores_table_name
161
+ conf.scores_table_name = :foo_scores
162
+ assert_equal :foo_scores, conf.scores_table_name
194
163
  end
195
164
 
196
- test "case insensitive field names" do
197
- field_1 = stub('field_1', :to_expr => :foo)
198
- field_2 = stub('field_2', :to_expr => :bar)
199
- field_set = {:foo => field_1, :bar => :field_2}
200
- field_set.expects(:has_key?).with(:Foo).returns(true)
201
- field_set.expects(:has_key?).with(:baR).returns(true)
202
- dataset = stub('dataset', :field_set => field_set)
203
- c = Linkage::Configuration.new(dataset, dataset)
204
- assert_nothing_raised do
205
- c.configure do
206
- lhs[:Foo].must == rhs[:baR]
207
- end
208
- end
165
+ test "change matches table name from default" do
166
+ dataset = stub('dataset')
167
+ conf = Linkage::Configuration.new(dataset, dataset)
168
+ assert_equal :matches, conf.matches_table_name
169
+ conf.matches_table_name = :foo_matches
170
+ assert_equal :foo_matches, conf.matches_table_name
209
171
  end
210
172
  end
@@ -24,6 +24,13 @@ class UnitTests::TestData < Test::Unit::TestCase
24
24
  assert_raises(NotImplementedError) { d.to_expr }
25
25
  end
26
26
 
27
+ test "database_type" do
28
+ dataset = mock('dataset')
29
+ data_1 = new_data(:foo, {}, dataset)
30
+ dataset.expects(:database_type).returns(:mysql)
31
+ assert_equal :mysql, data_1.database_type
32
+ end
33
+
27
34
  test "merge two identical fields" do
28
35
  data_1 = new_data(:id, {:type =>Integer})
29
36
  data_2 = new_data(:id, {:type =>Integer})
@@ -398,4 +405,41 @@ class UnitTests::TestData < Test::Unit::TestCase
398
405
  data_2 = new_data(:foo, {:type => Date})
399
406
  assert_raises { data_1.merge(data_2).ruby_type }
400
407
  end
408
+
409
+ test "merging two string fields with different collations strips the collation" do
410
+ dataset_1 = stub('dataset 1', :database_type => :mysql)
411
+ data_1 = new_data(:foo, {:type => String, :opts => {:collate => :foo}}, dataset_1)
412
+ dataset_2 = stub('dataset 2', :database_type => :mysql)
413
+ data_2 = new_data(:foo, {:type => String, :opts => {:collate => :bar}}, dataset_2)
414
+
415
+ result_data = data_1.merge(data_2)
416
+ result_opts = result_data.ruby_type[:opts] || {}
417
+ assert_nil result_opts[:collate]
418
+ end
419
+
420
+ test "merging two string fields with different database types strips the collation" do
421
+ dataset_1 = stub('dataset 1', :database_type => :mysql)
422
+ data_1 = new_data(:foo, {:type => String, :opts => {:collate => :foo}}, dataset_1)
423
+ dataset_2 = stub('dataset 2', :database_type => :sqlite)
424
+ data_2 = new_data(:foo, {:type => String, :opts => {:collate => :foo}}, dataset_2)
425
+
426
+ result_data = data_1.merge(data_2)
427
+ result_opts = result_data.ruby_type[:opts] || {}
428
+ assert_nil result_opts[:collate]
429
+ end
430
+
431
+ test "merged field has database type if they're the same" do
432
+ dataset_1 = stub('dataset 1', :database_type => :mysql)
433
+ data_1 = new_data(:foo, {:type => String}, dataset_1)
434
+ dataset_2 = stub('dataset 2', :database_type => :mysql)
435
+ data_2 = new_data(:foo, {:type => String}, dataset_2)
436
+ result_data = data_1.merge(data_2)
437
+ assert_equal :mysql, result_data.database_type
438
+ end
439
+
440
+ test "collation returns nil by default" do
441
+ dataset = stub('dataset')
442
+ data = new_data(:foo, {:type => String}, dataset)
443
+ assert_nil data.collation
444
+ end
401
445
  end
@@ -8,8 +8,9 @@ class UnitTests::TestDataset < Test::Unit::TestCase
8
8
  [:first_name, {:allow_null=>true, :default=>nil, :primary_key=>false, :db_type=>"varchar(255)", :type=>:string, :ruby_default=>nil}],
9
9
  [:last_name, {:allow_null=>true, :default=>nil, :primary_key=>false, :db_type=>"varchar(255)", :type=>:string, :ruby_default=>nil}]
10
10
  ]
11
- @dataset = stub('Sequel dataset')
12
- @database = stub('database', :schema => @schema, :[] => @dataset)
11
+ @dataset = stub('Sequel dataset', :first_source_table => :foo)
12
+ @database = stub('database', :schema => @schema, :[] => @dataset, :extend => nil)
13
+ @dataset.stubs(:db).returns(@database)
13
14
  Sequel.stubs(:connect).returns(@database)
14
15
  @field_set = stub("field set")
15
16
  Linkage::FieldSet.stubs(:new).returns(@field_set)
@@ -17,48 +18,97 @@ class UnitTests::TestDataset < Test::Unit::TestCase
17
18
 
18
19
  test "initialize with uri and table name" do
19
20
  Sequel.expects(:connect).with('foo:/bar', {:foo => 'bar'}).returns(@database)
20
- @database.expects(:schema).with(:foo).returns(@schema)
21
+ @database.expects(:extend).with(Sequel::Collation)
21
22
  @database.expects(:[]).with(:foo).returns(@dataset)
22
- Linkage::FieldSet.expects(:new).with(@schema).returns(@field_set)
23
+ Linkage::FieldSet.expects(:new).with(kind_of(Linkage::Dataset)).returns(@field_set)
23
24
  ds = Linkage::Dataset.new('foo:/bar', "foo", {:foo => 'bar'})
24
25
  end
25
26
 
27
+ test "initialize with sequel dataset" do
28
+ Linkage::Dataset.new(@dataset)
29
+ end
30
+
31
+ test "extend Sequel::Collation when initializing with sequel dataset" do
32
+ @database.stubs(:kind_of?).with(Sequel::Collation).returns(false)
33
+ @database.expects(:extend).with(Sequel::Collation)
34
+ ds = Linkage::Dataset.new(@dataset)
35
+ end
36
+
37
+ test "don't extend already extended database" do
38
+ @database.stubs(:kind_of?).with(Sequel::Collation).returns(true)
39
+ @database.expects(:extend).with(Sequel::Collation).never
40
+ ds = Linkage::Dataset.new(@dataset)
41
+ end
42
+
26
43
  test "table_name" do
27
44
  ds = Linkage::Dataset.new('foo:/bar', "foo", {:foo => 'bar'})
28
45
  assert_equal :foo, ds.table_name
29
46
  end
30
47
 
31
- test "adapter_scheme" do
48
+ test "table_name when initialized from sequel dataset" do
49
+ ds = Linkage::Dataset.new(@dataset)
50
+ assert_equal :foo, ds.table_name
51
+ end
52
+
53
+ test "schema" do
54
+ ds = Linkage::Dataset.new('foo:/bar', "foo", {:foo => 'bar'})
55
+ @database.expects(:schema).with(:foo).returns(@schema)
56
+ assert_equal @schema, ds.schema
57
+ end
58
+
59
+ test "schema when initialized from sequel dataset" do
60
+ ds = Linkage::Dataset.new(@dataset)
61
+ @database.expects(:schema).with(:foo).returns(@schema)
62
+ assert_equal @schema, ds.schema
63
+ end
64
+
65
+ test "database_type" do
32
66
  ds = Linkage::Dataset.new('foo:/bar', "foo", {:foo => 'bar'})
33
67
  @dataset.stubs(:db).returns(@database)
34
- @database.expects(:adapter_scheme).returns(:foo)
35
- assert_equal :foo, ds.adapter_scheme
68
+ @database.expects(:database_type).returns(:foo)
69
+ assert_equal :foo, ds.database_type
36
70
  end
37
71
 
38
- test "add match expression" do
72
+ test "set group_match" do
39
73
  ds_1 = Linkage::Dataset.new('foo:/bar', "foo", {:foo => 'bar'})
40
74
  @dataset.expects(:clone).returns(@dataset)
41
- ds_2 = ds_1.match(:foo)
75
+ meta_object = stub_instance(Linkage::MetaObject)
76
+ ds_2 = ds_1.group_match(meta_object)
42
77
  assert_not_same ds_1, ds_2
43
- assert_not_equal ds_1.instance_variable_get(:@_match),
44
- ds_2.instance_variable_get(:@_match)
78
+ assert_not_equal ds_1.instance_variable_get(:@linkage_options),
79
+ ds_2.instance_variable_get(:@linkage_options)
45
80
  end
46
81
 
47
- test "add match expression with alias, then each_group" do
82
+ test "subsequent group_match replaces old options" do
48
83
  ds_1 = Linkage::Dataset.new('foo:/bar', "foo", {:foo => 'bar'})
49
- @dataset.expects(:clone).returns(@dataset)
50
- ds_2 = ds_1.match(:foo, :aliased_foo)
51
- @dataset.expects(:group_and_count).with(:foo.as(:aliased_foo)).returns(@dataset)
52
- @dataset.expects(:having).returns(@dataset)
53
- @dataset.expects(:each).yields({:aliased_foo => 123, :count => 1})
54
- ds_2.each_group { |g| }
84
+ @dataset.expects(:clone).at_least_once.returns(@dataset)
85
+ meta_object_1 = stub_instance(Linkage::MetaObject)
86
+ ds_2 = ds_1.group_match(meta_object_1)
87
+ assert_equal([{:meta_object => meta_object_1}], ds_2.linkage_options[:group_match])
88
+
89
+ meta_object_2 = stub_instance(Linkage::MetaObject)
90
+ ds_3 = ds_2.group_match(meta_object_2)
91
+ assert_equal([{:meta_object => meta_object_2}], ds_3.linkage_options[:group_match])
92
+ end
93
+
94
+ test "group_match_more appends to group_match options" do
95
+ ds_1 = Linkage::Dataset.new('foo:/bar', "foo", {:foo => 'bar'})
96
+ @dataset.expects(:clone).at_least_once.returns(@dataset)
97
+ meta_object_1 = stub_instance(Linkage::MetaObject)
98
+ ds_2 = ds_1.group_match(meta_object_1)
99
+ assert_equal([{:meta_object => meta_object_1}], ds_2.linkage_options[:group_match])
100
+
101
+ meta_object_2 = stub_instance(Linkage::MetaObject)
102
+ ds_3 = ds_2.group_match_more(meta_object_2)
103
+ assert_equal([{:meta_object => meta_object_1}, {:meta_object => meta_object_2}], ds_3.linkage_options[:group_match])
55
104
  end
56
105
 
57
106
  test "group_by_matches" do
58
107
  ds = Linkage::Dataset.new('foo:/bar', "foo", {:foo => 'bar'})
59
108
 
60
109
  @dataset.expects(:clone).returns(@dataset)
61
- ds = ds.match(:foo)
110
+ meta_object = stub_instance(Linkage::MetaObject, :to_expr => :foo)
111
+ ds = ds.group_match(meta_object)
62
112
  @dataset.expects(:group).with(:foo).returns(@dataset)
63
113
 
64
114
  ds.group_by_matches
@@ -67,7 +117,8 @@ class UnitTests::TestDataset < Test::Unit::TestCase
67
117
  test "dataset_for_group" do
68
118
  ds = Linkage::Dataset.new('foo:/bar', "foo", {:foo => 'bar'})
69
119
  @dataset.expects(:clone).returns(@dataset)
70
- ds = ds.match(:foo, :foo_bar)
120
+ meta_object = stub_instance(Linkage::MetaObject, :to_expr => :foo)
121
+ ds = ds.group_match({:meta_object => meta_object, :alias => :foo_bar})
71
122
 
72
123
  group = stub("group", :values => {:foo_bar => 'baz'})
73
124
  filtered_dataset = stub('filtered dataset')
@@ -78,7 +129,8 @@ class UnitTests::TestDataset < Test::Unit::TestCase
78
129
  test "dataset_for_group without aliases" do
79
130
  ds = Linkage::Dataset.new('foo:/bar', "foo", {:foo => 'bar'})
80
131
  @dataset.expects(:clone).returns(@dataset)
81
- ds = ds.match(:foo)
132
+ meta_object = stub_instance(Linkage::MetaObject, :to_expr => :foo)
133
+ ds = ds.group_match(meta_object)
82
134
 
83
135
  group = stub("group", :values => {:foo => 'baz'})
84
136
  filtered_dataset = stub('filtered dataset')