linkage 0.0.6 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +10 -0
- data/Gemfile +15 -13
- data/Gemfile.lock +67 -37
- data/Guardfile +0 -2
- data/Rakefile +122 -25
- data/lib/linkage/comparator.rb +172 -0
- data/lib/linkage/comparators/binary.rb +12 -0
- data/lib/linkage/comparators/compare.rb +46 -0
- data/lib/linkage/comparators/within.rb +32 -0
- data/lib/linkage/configuration.rb +285 -153
- data/lib/linkage/data.rb +32 -7
- data/lib/linkage/dataset.rb +107 -32
- data/lib/linkage/decollation.rb +93 -0
- data/lib/linkage/expectation.rb +21 -0
- data/lib/linkage/expectations/exhaustive.rb +63 -0
- data/lib/linkage/expectations/simple.rb +168 -0
- data/lib/linkage/field.rb +30 -4
- data/lib/linkage/field_set.rb +6 -3
- data/lib/linkage/function.rb +50 -3
- data/lib/linkage/functions/binary.rb +30 -0
- data/lib/linkage/functions/cast.rb +54 -0
- data/lib/linkage/functions/length.rb +29 -0
- data/lib/linkage/functions/strftime.rb +12 -11
- data/lib/linkage/functions/trim.rb +8 -0
- data/lib/linkage/group.rb +20 -0
- data/lib/linkage/import_buffer.rb +5 -16
- data/lib/linkage/meta_object.rb +139 -0
- data/lib/linkage/result_set.rb +74 -17
- data/lib/linkage/runner/single_threaded.rb +125 -10
- data/lib/linkage/version.rb +3 -0
- data/lib/linkage.rb +11 -0
- data/linkage.gemspec +16 -121
- data/test/config.yml +5 -0
- data/test/helper.rb +73 -8
- data/test/integration/test_collation.rb +45 -0
- data/test/integration/test_configuration.rb +268 -0
- data/test/integration/test_cross_linkage.rb +4 -17
- data/test/integration/test_dataset.rb +45 -2
- data/test/integration/test_dual_linkage.rb +40 -24
- data/test/integration/test_functions.rb +22 -0
- data/test/integration/test_result_set.rb +85 -0
- data/test/integration/test_scoring.rb +84 -0
- data/test/integration/test_self_linkage.rb +5 -0
- data/test/integration/test_within_comparator.rb +100 -0
- data/test/unit/comparators/test_compare.rb +105 -0
- data/test/unit/comparators/test_within.rb +57 -0
- data/test/unit/expectations/test_exhaustive.rb +111 -0
- data/test/unit/expectations/test_simple.rb +303 -0
- data/test/unit/functions/test_binary.rb +54 -0
- data/test/unit/functions/test_cast.rb +98 -0
- data/test/unit/functions/test_length.rb +52 -0
- data/test/unit/functions/test_strftime.rb +17 -13
- data/test/unit/functions/test_trim.rb +11 -4
- data/test/unit/test_comparator.rb +124 -0
- data/test/unit/test_configuration.rb +137 -175
- data/test/unit/test_data.rb +44 -0
- data/test/unit/test_dataset.rb +73 -21
- data/test/unit/test_decollation.rb +201 -0
- data/test/unit/test_field.rb +38 -14
- data/test/unit/test_field_set.rb +12 -8
- data/test/unit/test_function.rb +83 -16
- data/test/unit/test_group.rb +28 -0
- data/test/unit/test_import_buffer.rb +13 -27
- data/test/unit/test_meta_object.rb +208 -0
- data/test/unit/test_result_set.rb +221 -3
- metadata +82 -190
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module IntegrationTests
|
4
|
+
class TestWithinComparator < Test::Unit::TestCase
|
5
|
+
test "within comparator with no simple expectations" do
|
6
|
+
database_for('sqlite') do |db|
|
7
|
+
db.create_table(:foo) { primary_key(:id); Integer(:num) }
|
8
|
+
db.create_table(:bar) { primary_key(:id); Integer(:num) }
|
9
|
+
db[:foo].import([:id, :num], (1..10).collect { |i| [i, i] })
|
10
|
+
db[:bar].import([:id, :num], (1..10).collect { |i| [i, i] })
|
11
|
+
end
|
12
|
+
|
13
|
+
db_opts = database_options_for('sqlite')
|
14
|
+
dataset_1 = Linkage::Dataset.new(db_opts, "foo")
|
15
|
+
dataset_2 = Linkage::Dataset.new(db_opts, "bar")
|
16
|
+
conf = dataset_1.link_with(dataset_2) do
|
17
|
+
lhs[:num].must be_within(5).of(rhs[:num])
|
18
|
+
save_results_in(db_opts)
|
19
|
+
end
|
20
|
+
|
21
|
+
runner = Linkage::SingleThreadedRunner.new(conf)
|
22
|
+
runner.execute
|
23
|
+
|
24
|
+
database_for('sqlite') do |db|
|
25
|
+
assert_equal db[:scores].count, 100
|
26
|
+
db[:scores].order(:record_1_id, :record_2_id).each do |score|
|
27
|
+
if (score[:record_2_id] - score[:record_1_id]).abs <= 5
|
28
|
+
assert_equal 1, score[:score], score.inspect
|
29
|
+
else
|
30
|
+
assert_equal 0, score[:score], score.inspect
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
test "within comparator with simple expectations" do
|
37
|
+
database_for('sqlite') do |db|
|
38
|
+
db.create_table(:foo) { primary_key(:id); Integer(:num); String(:parity) }
|
39
|
+
db.create_table(:bar) { primary_key(:id); Integer(:num); String(:parity) }
|
40
|
+
db[:foo].import([:id, :num, :parity], (1..10).collect { |i| [i, i, i % 2 == 0 ? "even" : "odd"] })
|
41
|
+
db[:bar].import([:id, :num, :parity], (1..10).collect { |i| [i, i, i % 2 == 0 ? "even" : "odd"] })
|
42
|
+
end
|
43
|
+
|
44
|
+
db_opts = database_options_for('sqlite')
|
45
|
+
dataset_1 = Linkage::Dataset.new(db_opts, "foo")
|
46
|
+
dataset_2 = Linkage::Dataset.new(db_opts, "bar")
|
47
|
+
conf = dataset_1.link_with(dataset_2) do
|
48
|
+
lhs[:parity].must == rhs[:parity]
|
49
|
+
lhs[:num].must be_within(5).of(rhs[:num])
|
50
|
+
save_results_in(db_opts)
|
51
|
+
end
|
52
|
+
|
53
|
+
runner = Linkage::SingleThreadedRunner.new(conf)
|
54
|
+
runner.execute
|
55
|
+
|
56
|
+
database_for('sqlite') do |db|
|
57
|
+
assert_equal db[:scores].count, 50
|
58
|
+
db[:scores].order(:record_1_id, :record_2_id).each do |score|
|
59
|
+
if (score[:record_2_id] - score[:record_1_id]).abs <= 5
|
60
|
+
assert_equal 1, score[:score]
|
61
|
+
else
|
62
|
+
assert_equal 0, score[:score]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
test "within comparator with simple expectations and functions" do
|
69
|
+
database_for('sqlite') do |db|
|
70
|
+
db.create_table(:foo) { primary_key(:id); Integer(:num); String(:parity) }
|
71
|
+
db.create_table(:bar) { primary_key(:id); Integer(:num); String(:parity) }
|
72
|
+
db[:foo].import([:id, :num, :parity], (1..10).collect { |i| [i, i, i % 2 == 0 ? "even" : "odd"] })
|
73
|
+
db[:bar].import([:id, :num, :parity], (1..10).collect { |i| [i, i, i % 2 == 0 ? "even" : "odd"] })
|
74
|
+
end
|
75
|
+
|
76
|
+
db_opts = database_options_for('sqlite')
|
77
|
+
dataset_1 = Linkage::Dataset.new(db_opts, "foo")
|
78
|
+
dataset_2 = Linkage::Dataset.new(db_opts, "bar")
|
79
|
+
conf = dataset_1.link_with(dataset_2) do
|
80
|
+
lhs[:parity].must == rhs[:parity]
|
81
|
+
cast(lhs[:num], 'integer').must be_within(5).of(cast(rhs[:num], 'integer'))
|
82
|
+
save_results_in(db_opts)
|
83
|
+
end
|
84
|
+
|
85
|
+
runner = Linkage::SingleThreadedRunner.new(conf)
|
86
|
+
runner.execute
|
87
|
+
|
88
|
+
database_for('sqlite') do |db|
|
89
|
+
assert_equal db[:scores].count, 50
|
90
|
+
db[:scores].order(:record_1_id, :record_2_id).each do |score|
|
91
|
+
if (score[:record_2_id] - score[:record_1_id]).abs <= 5
|
92
|
+
assert_equal 1, score[:score]
|
93
|
+
else
|
94
|
+
assert_equal 0, score[:score]
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class UnitTests::TestCompare < 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 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
|
23
|
+
end
|
24
|
+
|
25
|
+
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)
|
30
|
+
assert_equal 1, comp.score({:foo => 10}, {:bar => 5})
|
31
|
+
assert_equal 0, comp.score({:foo => 5}, {:bar => 5})
|
32
|
+
assert_equal 1, comp.score({:foo => 0}, {:bar => 5})
|
33
|
+
end
|
34
|
+
|
35
|
+
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
|
+
assert_equal 1, comp.score({:foo => 10}, {:bar => 5})
|
41
|
+
assert_equal 0, comp.score({:foo => 5}, {:bar => 5})
|
42
|
+
assert_equal 0, comp.score({:foo => 0}, {:bar => 5})
|
43
|
+
end
|
44
|
+
|
45
|
+
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)
|
50
|
+
assert_equal 1, comp.score({:foo => 10}, {:bar => 5})
|
51
|
+
assert_equal 1, comp.score({:foo => 5}, {:bar => 5})
|
52
|
+
assert_equal 0, comp.score({:foo => 0}, {:bar => 5})
|
53
|
+
end
|
54
|
+
|
55
|
+
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})
|
61
|
+
assert_equal 1, comp.score({:foo => 5}, {:bar => 5})
|
62
|
+
assert_equal 1, comp.score({:foo => 0}, {:bar => 5})
|
63
|
+
end
|
64
|
+
|
65
|
+
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)
|
70
|
+
assert_equal 0, comp.score({:foo => 10}, {:bar => 5})
|
71
|
+
assert_equal 0, comp.score({:foo => 5}, {:bar => 5})
|
72
|
+
assert_equal 1, comp.score({:foo => 0}, {:bar => 5})
|
73
|
+
end
|
74
|
+
|
75
|
+
test "registers itself" do
|
76
|
+
assert_equal Compare, Linkage::Comparator['compare']
|
77
|
+
end
|
78
|
+
|
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)
|
83
|
+
assert_raises do
|
84
|
+
Compare.new(meta_object_1, meta_object_2, meta_object_3)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
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)
|
92
|
+
assert_raises do
|
93
|
+
Compare.new(meta_object_1, meta_object_2, meta_object_3)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
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)
|
101
|
+
assert_raises do
|
102
|
+
Compare.new(meta_object_1, meta_object_2, meta_object_3)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class UnitTests::TestWithin < 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 Binary" do
|
13
|
+
assert_equal Linkage::Comparators::Binary, Within.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 => 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)
|
20
|
+
assert_nothing_raised do
|
21
|
+
Within.new(meta_object_1, meta_object_2, meta_object_3)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
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)
|
30
|
+
assert_equal 1, comp.score({:foo => 123}, {:bar => 124})
|
31
|
+
assert_equal 1, comp.score({:foo => 124}, {:bar => 123})
|
32
|
+
assert_equal 1, comp.score({:foo => 0}, {:bar => 123})
|
33
|
+
assert_equal 0, comp.score({:foo => 0}, {:bar => 124})
|
34
|
+
end
|
35
|
+
|
36
|
+
test "registers itself" do
|
37
|
+
assert_equal Within, Linkage::Comparator['within']
|
38
|
+
end
|
39
|
+
|
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)
|
44
|
+
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)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class UnitTests::TestExhaustive < Test::Unit::TestCase
|
4
|
+
test "initialize with comparator, threshold, and mode" do
|
5
|
+
comparator = stub('comparator')
|
6
|
+
exp = Linkage::Expectations::Exhaustive.new(comparator, 100, :min)
|
7
|
+
assert_equal comparator, exp.comparator
|
8
|
+
assert_equal 100, exp.threshold
|
9
|
+
assert_equal :min, exp.mode
|
10
|
+
end
|
11
|
+
|
12
|
+
test "kind is :self when comparator has same args on both sides" do
|
13
|
+
meta_object_1 = stub('meta object 1')
|
14
|
+
meta_object_2 = stub('meta object 2')
|
15
|
+
meta_object_1.expects(:objects_equal?).with(meta_object_2).returns(true)
|
16
|
+
comparator = stub('comparator', {
|
17
|
+
:lhs_args => [meta_object_1], :rhs_args => [meta_object_2]
|
18
|
+
})
|
19
|
+
exp = Linkage::Expectations::Exhaustive.new(comparator, 100, :min)
|
20
|
+
assert_equal :self, exp.kind
|
21
|
+
end
|
22
|
+
|
23
|
+
test "kind is :cross when comparator has args with same dataset but different number of args" do
|
24
|
+
meta_object_1 = stub('meta object 1')
|
25
|
+
meta_object_2 = stub('meta object 2')
|
26
|
+
meta_object_3 = stub('meta object 3')
|
27
|
+
meta_object_1.expects(:datasets_equal?).with(meta_object_2).returns(true)
|
28
|
+
comparator = stub('comparator', {
|
29
|
+
:lhs_args => [meta_object_1], :rhs_args => [meta_object_2, meta_object_3]
|
30
|
+
})
|
31
|
+
exp = Linkage::Expectations::Exhaustive.new(comparator, 100, :min)
|
32
|
+
assert_equal :cross, exp.kind
|
33
|
+
end
|
34
|
+
|
35
|
+
test "kind is :cross when comparator has args with same dataset but different objects" do
|
36
|
+
meta_object_1 = stub('meta object 1')
|
37
|
+
meta_object_2 = stub('meta object 2')
|
38
|
+
meta_object_1.expects(:objects_equal?).with(meta_object_2).returns(false)
|
39
|
+
meta_object_1.expects(:datasets_equal?).with(meta_object_2).returns(true)
|
40
|
+
comparator = stub('comparator', {
|
41
|
+
:lhs_args => [meta_object_1], :rhs_args => [meta_object_2]
|
42
|
+
})
|
43
|
+
exp = Linkage::Expectations::Exhaustive.new(comparator, 100, :min)
|
44
|
+
assert_equal :cross, exp.kind
|
45
|
+
end
|
46
|
+
|
47
|
+
test "kind is :dual when comparator has args with different datasets and different number of args" do
|
48
|
+
meta_object_1 = stub('meta object 1')
|
49
|
+
meta_object_2 = stub('meta object 2')
|
50
|
+
meta_object_3 = stub('meta object 3')
|
51
|
+
meta_object_1.expects(:datasets_equal?).with(meta_object_2).returns(false)
|
52
|
+
comparator = stub('comparator', {
|
53
|
+
:lhs_args => [meta_object_1], :rhs_args => [meta_object_2, meta_object_3]
|
54
|
+
})
|
55
|
+
exp = Linkage::Expectations::Exhaustive.new(comparator, 100, :min)
|
56
|
+
assert_equal :dual, exp.kind
|
57
|
+
end
|
58
|
+
|
59
|
+
test "kind is :dual when comparator has args with different datasets" do
|
60
|
+
meta_object_1 = stub('meta object 1')
|
61
|
+
meta_object_2 = stub('meta object 2')
|
62
|
+
meta_object_1.expects(:objects_equal?).with(meta_object_2).returns(false)
|
63
|
+
meta_object_1.expects(:datasets_equal?).with(meta_object_2).returns(false)
|
64
|
+
comparator = stub('comparator', {
|
65
|
+
:lhs_args => [meta_object_1], :rhs_args => [meta_object_2]
|
66
|
+
})
|
67
|
+
exp = Linkage::Expectations::Exhaustive.new(comparator, 100, :min)
|
68
|
+
assert_equal :dual, exp.kind
|
69
|
+
end
|
70
|
+
|
71
|
+
test "apply_to lhs dataset" do
|
72
|
+
dataset = stub('dataset')
|
73
|
+
new_dataset = stub('new dataset')
|
74
|
+
meta_object_1 = stub('meta object 1', :name => :foo, :to_expr => :foo)
|
75
|
+
meta_object_2 = stub('meta object 2', :name => :bar, :to_expr => :bar)
|
76
|
+
comparator = stub('comparator', :lhs_args => [meta_object_1], :rhs_args => [meta_object_2])
|
77
|
+
exp = Linkage::Expectations::Exhaustive.new(comparator, 100, :min)
|
78
|
+
dataset.expects(:select_more).with(:foo.as(:foo)).returns(new_dataset)
|
79
|
+
assert_equal new_dataset, exp.apply_to(dataset, :lhs)
|
80
|
+
end
|
81
|
+
|
82
|
+
test "apply_to rhs dataset" do
|
83
|
+
dataset = stub('dataset')
|
84
|
+
new_dataset = stub('new dataset')
|
85
|
+
meta_object_1 = stub('meta object 1', :name => :foo, :to_expr => :foo)
|
86
|
+
meta_object_2 = stub('meta object 2', :name => :bar, :to_expr => :bar)
|
87
|
+
comparator = stub('comparator', :lhs_args => [meta_object_1], :rhs_args => [meta_object_2])
|
88
|
+
exp = Linkage::Expectations::Exhaustive.new(comparator, 100, :min)
|
89
|
+
dataset.expects(:select_more).with(:bar.as(:bar)).returns(new_dataset)
|
90
|
+
assert_equal new_dataset, exp.apply_to(dataset, :rhs)
|
91
|
+
end
|
92
|
+
|
93
|
+
test "satisfied? with :equal mode" do
|
94
|
+
meta_object_1 = stub('meta object 1')
|
95
|
+
meta_object_2 = stub('meta object 2')
|
96
|
+
comparator = stub('comparator', :lhs_args => [meta_object_1], :rhs_args => [meta_object_2])
|
97
|
+
exp = Linkage::Expectations::Exhaustive.new(comparator, 50, :equal)
|
98
|
+
assert exp.satisfied?(50)
|
99
|
+
assert !exp.satisfied?(123)
|
100
|
+
end
|
101
|
+
|
102
|
+
test "satisfied? with :min mode" do
|
103
|
+
meta_object_1 = stub('meta object 1')
|
104
|
+
meta_object_2 = stub('meta object 2')
|
105
|
+
comparator = stub('comparator', :lhs_args => [meta_object_1], :rhs_args => [meta_object_2])
|
106
|
+
exp = Linkage::Expectations::Exhaustive.new(comparator, 50, :min)
|
107
|
+
assert exp.satisfied?(50)
|
108
|
+
assert exp.satisfied?(55)
|
109
|
+
assert !exp.satisfied?(45)
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,303 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class UnitTests::TestSimple < Test::Unit::TestCase
|
4
|
+
test "initialize with invalid operator" do
|
5
|
+
assert_raises(ArgumentError) do
|
6
|
+
Linkage::Expectations::Simple.new(stub(), stub(), :foo)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
test "creating filter expectation from a dynamic object and a static object" do
|
11
|
+
field = stub('meta field', :static? => false, :side => :lhs)
|
12
|
+
object = stub('meta object', :static? => true)
|
13
|
+
exp = Linkage::Expectations::Simple.create(field, object, :==)
|
14
|
+
assert_kind_of Linkage::Expectations::Filter, exp
|
15
|
+
assert_equal :lhs, exp.side
|
16
|
+
end
|
17
|
+
|
18
|
+
test "creating expectation from two static objects raises error" do
|
19
|
+
object_1 = stub('meta object 1', :static? => true)
|
20
|
+
object_2 = stub('meta object 2', :static? => true)
|
21
|
+
assert_raises(ArgumentError) do
|
22
|
+
Linkage::Expectations::Simple.create(object_1, object_2, :==)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
test "creating filter expectation from two dynamic objects with the same side" do
|
27
|
+
field_1 = stub('meta field 1', :static? => false, :side => :lhs)
|
28
|
+
field_2 = stub('meta field 2', :static? => false, :side => :lhs)
|
29
|
+
field_1.expects(:datasets_equal?).with(field_2).returns(true)
|
30
|
+
exp = Linkage::Expectations::Simple.create(field_1, field_2, :==)
|
31
|
+
assert_kind_of Linkage::Expectations::Filter, exp
|
32
|
+
assert_equal :lhs, exp.side
|
33
|
+
end
|
34
|
+
|
35
|
+
test "creating filter expectation from two dynamic objects with the same side but different datasets raises error" do
|
36
|
+
field_1 = stub('meta field 1', :static? => false, :side => :lhs)
|
37
|
+
field_2 = stub('meta field 2', :static? => false, :side => :lhs)
|
38
|
+
field_1.expects(:datasets_equal?).with(field_2).returns(false)
|
39
|
+
assert_raises(ArgumentError) do
|
40
|
+
Linkage::Expectations::Simple.create(field_1, field_2, :==)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
test "creating self expectation from two dynamic objects with different sides" do
|
45
|
+
object_1 = stub('meta object 1', :static? => false, :side => :lhs)
|
46
|
+
object_2 = stub('meta object 2', :static? => false, :side => :rhs)
|
47
|
+
object_1.expects(:objects_equal?).with(object_2).returns(true)
|
48
|
+
exp = Linkage::Expectations::Simple.create(object_1, object_2, :==)
|
49
|
+
assert_kind_of Linkage::Expectations::Self, exp
|
50
|
+
end
|
51
|
+
|
52
|
+
test "creating cross expectation from two dynamic objects with different sides but same dataset" do
|
53
|
+
object_1 = stub('meta object 1', :static? => false, :side => :lhs)
|
54
|
+
object_2 = stub('meta object 2', :static? => false, :side => :rhs)
|
55
|
+
object_1.expects(:objects_equal?).with(object_2).returns(false)
|
56
|
+
object_1.expects(:datasets_equal?).with(object_2).returns(true)
|
57
|
+
exp = Linkage::Expectations::Simple.create(object_1, object_2, :==)
|
58
|
+
assert_kind_of Linkage::Expectations::Cross, exp
|
59
|
+
end
|
60
|
+
|
61
|
+
test "creating dual expectation from two dynamic objects with different sides and datasets" do
|
62
|
+
object_1 = stub('meta object 1', :static? => false, :side => :lhs)
|
63
|
+
object_2 = stub('meta object 2', :static? => false, :side => :rhs)
|
64
|
+
object_1.expects(:objects_equal?).with(object_2).returns(false)
|
65
|
+
object_1.expects(:datasets_equal?).with(object_2).returns(false)
|
66
|
+
exp = Linkage::Expectations::Simple.create(object_1, object_2, :==)
|
67
|
+
assert_kind_of Linkage::Expectations::Dual, exp
|
68
|
+
end
|
69
|
+
|
70
|
+
test "apply_to with filter expectation (== operator)" do
|
71
|
+
dataset = stub('dataset')
|
72
|
+
meta_field_1 = stub('meta field 1', :static? => false, :side => :lhs)
|
73
|
+
meta_field_2 = stub('meta field 2', :static? => false, :side => :lhs)
|
74
|
+
meta_field_1.stubs(:datasets_equal?).with(meta_field_2).returns(true)
|
75
|
+
|
76
|
+
exp = Linkage::Expectations::Simple.create(meta_field_1, meta_field_2, :==)
|
77
|
+
meta_field_1.expects(:to_expr).returns(:foo)
|
78
|
+
meta_field_2.expects(:to_expr).returns(:bar)
|
79
|
+
dataset.expects(:filter).with({:foo => :bar}).returns(dataset)
|
80
|
+
assert_equal dataset, exp.apply_to(dataset, :lhs)
|
81
|
+
|
82
|
+
dataset.expects(:filter).never
|
83
|
+
assert_equal dataset, exp.apply_to(dataset, :rhs)
|
84
|
+
end
|
85
|
+
|
86
|
+
test "apply_to with filter expectation (!= operator)" do
|
87
|
+
dataset = stub('dataset')
|
88
|
+
meta_field_1 = stub('meta field 1', :static? => false, :side => :lhs)
|
89
|
+
meta_field_2 = stub('meta field 2', :static? => false, :side => :lhs)
|
90
|
+
meta_field_1.stubs(:datasets_equal?).with(meta_field_2).returns(true)
|
91
|
+
|
92
|
+
exp = Linkage::Expectations::Simple.create(meta_field_1, meta_field_2, :'!=')
|
93
|
+
meta_field_1.expects(:to_expr).returns(:foo)
|
94
|
+
meta_field_2.expects(:to_expr).returns(:bar)
|
95
|
+
dataset.expects(:filter).with(~{:foo => :bar}).returns(dataset)
|
96
|
+
assert_equal dataset, exp.apply_to(dataset, :lhs)
|
97
|
+
|
98
|
+
dataset.expects(:filter).never
|
99
|
+
assert_equal dataset, exp.apply_to(dataset, :rhs)
|
100
|
+
end
|
101
|
+
|
102
|
+
test "apply_to with filter expectation (> operator)" do
|
103
|
+
dataset = stub('dataset')
|
104
|
+
meta_field_1 = stub('meta field 1', :static? => false, :side => :lhs)
|
105
|
+
meta_field_2 = stub('meta field 2', :static? => false, :side => :lhs)
|
106
|
+
meta_field_1.stubs(:datasets_equal?).with(meta_field_2).returns(true)
|
107
|
+
exp = Linkage::Expectations::Simple.create(meta_field_1, meta_field_2, :>)
|
108
|
+
|
109
|
+
identifier_1 = Sequel::SQL::Identifier.new(:foo)
|
110
|
+
meta_field_1.expects(:to_identifier).returns(identifier_1)
|
111
|
+
identifier_2 = Sequel::SQL::Identifier.new(:bar)
|
112
|
+
meta_field_2.expects(:to_identifier).returns(identifier_2)
|
113
|
+
expected = Sequel::SQL::BooleanExpression.new(:>, identifier_1, identifier_2)
|
114
|
+
|
115
|
+
dataset.expects(:filter).with(expected).returns(dataset)
|
116
|
+
assert_equal dataset, exp.apply_to(dataset, :lhs)
|
117
|
+
|
118
|
+
dataset.expects(:filter).never
|
119
|
+
assert_equal dataset, exp.apply_to(dataset, :rhs)
|
120
|
+
end
|
121
|
+
|
122
|
+
test "apply_to with self expectation" do
|
123
|
+
dataset = stub('dataset')
|
124
|
+
object_1 = stub('meta object 1', {
|
125
|
+
:static? => false, :side => :lhs, :dataset => dataset,
|
126
|
+
:to_expr => :foo
|
127
|
+
})
|
128
|
+
object_2 = stub('meta object 2', {
|
129
|
+
:static? => false, :side => :rhs, :dataset => dataset,
|
130
|
+
:to_expr => :foo
|
131
|
+
})
|
132
|
+
object_1.expects(:objects_equal?).with(object_2).returns(true)
|
133
|
+
exp = Linkage::Expectations::Simple.create(object_1, object_2, :==)
|
134
|
+
|
135
|
+
merged_field = stub('merged field', :name => :foo)
|
136
|
+
object_1.expects(:merge).with(object_2).returns(merged_field)
|
137
|
+
dataset.expects(:group_match_more).with({:meta_object => object_1, :alias => :foo}).returns(dataset)
|
138
|
+
assert_equal dataset, exp.apply_to(dataset, :lhs)
|
139
|
+
|
140
|
+
dataset.expects(:group_match_more).with({:meta_object => object_2, :alias => :foo}).returns(dataset)
|
141
|
+
assert_equal dataset, exp.apply_to(dataset, :rhs)
|
142
|
+
end
|
143
|
+
|
144
|
+
test "apply_to with cross expectation" do
|
145
|
+
dataset = stub('dataset')
|
146
|
+
object_1 = stub('meta object 1', {
|
147
|
+
:static? => false, :side => :lhs, :dataset => dataset,
|
148
|
+
:to_expr => :foo
|
149
|
+
})
|
150
|
+
object_2 = stub('meta object 2', {
|
151
|
+
:static? => false, :side => :rhs, :dataset => dataset,
|
152
|
+
:to_expr => :bar
|
153
|
+
})
|
154
|
+
object_1.stubs(:objects_equal?).with(object_2).returns(false)
|
155
|
+
object_1.stubs(:datasets_equal?).with(object_2).returns(true)
|
156
|
+
exp = Linkage::Expectations::Simple.create(object_1, object_2, :==)
|
157
|
+
|
158
|
+
merged_field = stub('merged field', :name => :foo_bar)
|
159
|
+
object_1.expects(:merge).with(object_2).returns(merged_field)
|
160
|
+
dataset.expects(:group_match_more).with({:meta_object => object_1, :alias => :foo_bar}).returns(dataset)
|
161
|
+
assert_equal dataset, exp.apply_to(dataset, :lhs)
|
162
|
+
|
163
|
+
dataset.expects(:group_match_more).with({:meta_object => object_2, :alias => :foo_bar}).returns(dataset)
|
164
|
+
assert_equal dataset, exp.apply_to(dataset, :rhs)
|
165
|
+
end
|
166
|
+
|
167
|
+
test "apply_to with dual expectation" do
|
168
|
+
dataset_1 = stub('dataset 1')
|
169
|
+
object_1 = stub('meta object 1', {
|
170
|
+
:static? => false, :side => :lhs, :dataset => dataset_1,
|
171
|
+
:to_expr => :foo
|
172
|
+
})
|
173
|
+
dataset_2 = stub('dataset 2')
|
174
|
+
object_2 = stub('meta object 2', {
|
175
|
+
:static? => false, :side => :rhs, :dataset => dataset_2,
|
176
|
+
:to_expr => :foo
|
177
|
+
})
|
178
|
+
object_1.stubs(:objects_equal?).with(object_2).returns(false)
|
179
|
+
object_1.stubs(:datasets_equal?).with(object_2).returns(false)
|
180
|
+
exp = Linkage::Expectations::Simple.create(object_1, object_2, :==)
|
181
|
+
|
182
|
+
merged_field = stub('merged field', :name => :foo)
|
183
|
+
object_1.expects(:merge).with(object_2).returns(merged_field)
|
184
|
+
dataset_1.expects(:group_match_more).with({:meta_object => object_1, :alias => :foo}).returns(dataset_1)
|
185
|
+
assert_equal dataset_1, exp.apply_to(dataset_1, :lhs)
|
186
|
+
|
187
|
+
dataset_2.expects(:group_match_more).with({:meta_object => object_2, :alias => :foo}).returns(dataset_2)
|
188
|
+
assert_equal dataset_2, exp.apply_to(dataset_2, :rhs)
|
189
|
+
end
|
190
|
+
|
191
|
+
test "exactly! wraps each side inside the binary function" do
|
192
|
+
dataset_1 = stub('dataset 1')
|
193
|
+
field_1 = stub_field('field 1', :dataset => dataset_1)
|
194
|
+
meta_object_1 = stub('meta object 1', :static? => false, :side => :lhs,
|
195
|
+
:object => field_1, :dataset => dataset_1)
|
196
|
+
|
197
|
+
dataset_2 = stub('dataset 2')
|
198
|
+
field_2 = stub_field('field 2', :dataset => dataset_2)
|
199
|
+
meta_object_2 = stub('meta object 2', :static? => false, :side => :rhs,
|
200
|
+
:object => field_2, :dataset => dataset_2)
|
201
|
+
meta_object_1.stubs(:objects_equal?).with(meta_object_2).returns(true)
|
202
|
+
|
203
|
+
exp = Linkage::Expectations::Simple.create(meta_object_1, meta_object_2, :==)
|
204
|
+
|
205
|
+
klass = Linkage::Functions::Binary
|
206
|
+
func_1 = stub('binary function 1')
|
207
|
+
klass.expects(:new).with(field_1, :dataset => dataset_1).returns(func_1)
|
208
|
+
func_2 = stub('binary function 2')
|
209
|
+
klass.expects(:new).with(field_2, :dataset => dataset_2).returns(func_2)
|
210
|
+
|
211
|
+
new_meta_object_1 = stub('new meta object 1')
|
212
|
+
Linkage::MetaObject.expects(:new).with(func_1, :lhs).returns(new_meta_object_1)
|
213
|
+
new_meta_object_2 = stub('new meta object 2')
|
214
|
+
Linkage::MetaObject.expects(:new).with(func_2, :rhs).returns(new_meta_object_2)
|
215
|
+
|
216
|
+
exp.exactly!
|
217
|
+
# LAZY: assume the expectation set its meta objects appropriately
|
218
|
+
end
|
219
|
+
|
220
|
+
test "#same_except_side with two filter expectations" do
|
221
|
+
field = stub_field('foo')
|
222
|
+
meta_object_1 = stub('meta field 1', {
|
223
|
+
:static? => false, :side => :lhs, :object => field
|
224
|
+
})
|
225
|
+
meta_object_2 = stub('meta object', :static? => true)
|
226
|
+
meta_object_3 = stub('meta field 2', {
|
227
|
+
:static? => false, :side => :rhs, :object => field
|
228
|
+
})
|
229
|
+
|
230
|
+
exp_1 = Linkage::Expectations::Simple.create(meta_object_1, meta_object_2, :==)
|
231
|
+
exp_2 = Linkage::Expectations::Simple.create(meta_object_3, meta_object_2, :==)
|
232
|
+
|
233
|
+
meta_object_1.expects(:objects_equal?).with(meta_object_3).returns(true)
|
234
|
+
meta_object_2.expects(:objects_equal?).with(meta_object_2).returns(true)
|
235
|
+
assert exp_1.same_except_side?(exp_2)
|
236
|
+
end
|
237
|
+
|
238
|
+
test "#decollation_needed? is false when comparing non-string objects" do
|
239
|
+
dataset_1 = stub('dataset 1')
|
240
|
+
object_1 = stub('meta object 1', {
|
241
|
+
:static? => false, :side => :lhs, :dataset => dataset_1,
|
242
|
+
})
|
243
|
+
dataset_2 = stub('dataset 2')
|
244
|
+
object_2 = stub('meta object 2', {
|
245
|
+
:static? => false, :side => :rhs, :dataset => dataset_2,
|
246
|
+
})
|
247
|
+
merged_field = stub('merged field', :ruby_type => {:type => Fixnum})
|
248
|
+
object_1.stubs(:merge).with(object_2).returns(merged_field)
|
249
|
+
exp = Linkage::Expectations::Dual.new(object_1, object_2, :==)
|
250
|
+
assert !exp.decollation_needed?
|
251
|
+
end
|
252
|
+
|
253
|
+
test "#decollation_needed? is false when comparing two dynamic string objects with the same database type and same collation" do
|
254
|
+
dataset_1 = stub('dataset 1')
|
255
|
+
object_1 = stub('meta object 1', {
|
256
|
+
:static? => false, :side => :lhs, :dataset => dataset_1,
|
257
|
+
:collation => 'foo', :database_type => :mysql
|
258
|
+
})
|
259
|
+
dataset_2 = stub('dataset 2')
|
260
|
+
object_2 = stub('meta object 2', {
|
261
|
+
:static? => false, :side => :rhs, :dataset => dataset_2,
|
262
|
+
:collation => 'foo', :database_type => :mysql
|
263
|
+
})
|
264
|
+
merged_field = stub('merged field', :ruby_type => {:type => String})
|
265
|
+
object_1.stubs(:merge).with(object_2).returns(merged_field)
|
266
|
+
exp = Linkage::Expectations::Dual.new(object_1, object_2, :==)
|
267
|
+
assert !exp.decollation_needed?
|
268
|
+
end
|
269
|
+
|
270
|
+
test "#decollation_needed? is true when comparing two dynamic string objects with the same database type but different collations" do
|
271
|
+
dataset_1 = stub('dataset 1')
|
272
|
+
object_1 = stub('meta object 1', {
|
273
|
+
:static? => false, :side => :lhs, :dataset => dataset_1,
|
274
|
+
:collation => 'foo', :database_type => :mysql
|
275
|
+
})
|
276
|
+
dataset_2 = stub('dataset 2')
|
277
|
+
object_2 = stub('meta object 2', {
|
278
|
+
:static? => false, :side => :rhs, :dataset => dataset_2,
|
279
|
+
:collation => 'bar', :database_type => :mysql
|
280
|
+
})
|
281
|
+
merged_field = stub('merged field', :ruby_type => {:type => String})
|
282
|
+
object_1.stubs(:merge).with(object_2).returns(merged_field)
|
283
|
+
exp = Linkage::Expectations::Dual.new(object_1, object_2, :==)
|
284
|
+
assert exp.decollation_needed?
|
285
|
+
end
|
286
|
+
|
287
|
+
test "#decollation_needed? is true when comparing two dynamic string objects with same collation but different database types" do
|
288
|
+
dataset_1 = stub('dataset 1')
|
289
|
+
object_1 = stub('meta object 1', {
|
290
|
+
:static? => false, :side => :lhs, :dataset => dataset_1,
|
291
|
+
:collation => 'foo', :database_type => :foo
|
292
|
+
})
|
293
|
+
dataset_2 = stub('dataset 2')
|
294
|
+
object_2 = stub('meta object 2', {
|
295
|
+
:static? => false, :side => :rhs, :dataset => dataset_2,
|
296
|
+
:collation => 'foo', :database_type => :bar
|
297
|
+
})
|
298
|
+
merged_field = stub('merged field', :ruby_type => {:type => String})
|
299
|
+
object_1.stubs(:merge).with(object_2).returns(merged_field)
|
300
|
+
exp = Linkage::Expectations::Dual.new(object_1, object_2, :==)
|
301
|
+
assert exp.decollation_needed?
|
302
|
+
end
|
303
|
+
end
|