linkage 0.0.8 → 0.1.0.pre

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,111 @@
1
+ require File.expand_path("../../test_result_sets", __FILE__)
2
+
3
+ class UnitTests::TestResultSets::TestCSV < Test::Unit::TestCase
4
+ def setup
5
+ @tmpdir = Dir.mktmpdir('linkage')
6
+ end
7
+
8
+ def teardown
9
+ FileUtils.remove_entry_secure(@tmpdir)
10
+ end
11
+
12
+ test "no directory option uses current directory" do
13
+ result_set = Linkage::ResultSets::CSV.new
14
+
15
+ expected_score_file = './scores.csv'
16
+ score_set = stub('score set')
17
+ Linkage::ScoreSets::CSV.expects(:new).with(expected_score_file, {}).returns(score_set)
18
+ assert_same score_set, result_set.score_set
19
+
20
+ expected_match_file = './matches.csv'
21
+ match_set = stub('match set')
22
+ Linkage::MatchSets::CSV.expects(:new).with(expected_match_file, {}).returns(match_set)
23
+ assert_same match_set, result_set.match_set
24
+ end
25
+
26
+ test "directory option" do
27
+ opts = {
28
+ :dir => File.join(@tmpdir, 'foo')
29
+ }
30
+ result_set = Linkage::ResultSets::CSV.new(opts)
31
+ assert Dir.exist?(opts[:dir])
32
+
33
+ expected_score_file = File.join(@tmpdir, 'foo', 'scores.csv')
34
+ score_set = stub('score set')
35
+ Linkage::ScoreSets::CSV.expects(:new).with(expected_score_file, {}).returns(score_set)
36
+ assert_same score_set, result_set.score_set
37
+
38
+ expected_match_file = File.join(@tmpdir, 'foo', 'matches.csv')
39
+ match_set = stub('match set')
40
+ Linkage::MatchSets::CSV.expects(:new).with(expected_match_file, {}).returns(match_set)
41
+ assert_same match_set, result_set.match_set
42
+ end
43
+
44
+ test "directory argument" do
45
+ dir = File.join(@tmpdir, 'foo')
46
+ result_set = Linkage::ResultSets::CSV.new(dir)
47
+ assert Dir.exist?(dir)
48
+
49
+ expected_score_file = File.join(@tmpdir, 'foo', 'scores.csv')
50
+ score_set = stub('score set')
51
+ Linkage::ScoreSets::CSV.expects(:new).with(expected_score_file, {}).returns(score_set)
52
+ assert_same score_set, result_set.score_set
53
+
54
+ expected_match_file = File.join(@tmpdir, 'foo', 'matches.csv')
55
+ match_set = stub('match set')
56
+ Linkage::MatchSets::CSV.expects(:new).with(expected_match_file, {}).returns(match_set)
57
+ assert_same match_set, result_set.match_set
58
+ end
59
+
60
+ test "directory path is expanded" do
61
+ opts = {
62
+ :dir => "~/foo"
63
+ }
64
+ FileUtils.expects(:mkdir_p).with(File.expand_path("~/foo"))
65
+ result_set = Linkage::ResultSets::CSV.new(opts)
66
+ end
67
+
68
+ test "custom filenames" do
69
+ opts = {
70
+ :dir => File.join(@tmpdir, 'foo'),
71
+ :scores => {:filename => 'foo-scores.csv'},
72
+ :matches => {:filename => 'foo-matches.csv'}
73
+ }
74
+ result_set = Linkage::ResultSets::CSV.new(opts)
75
+ assert Dir.exist?(opts[:dir])
76
+
77
+ expected_score_file = File.join(@tmpdir, 'foo', 'foo-scores.csv')
78
+ score_set = stub('score set')
79
+ Linkage::ScoreSets::CSV.expects(:new).with(expected_score_file, {}).returns(score_set)
80
+ assert_same score_set, result_set.score_set
81
+
82
+ expected_match_file = File.join(@tmpdir, 'foo', 'foo-matches.csv')
83
+ match_set = stub('match set')
84
+ Linkage::MatchSets::CSV.expects(:new).with(expected_match_file, {}).returns(match_set)
85
+ assert_same match_set, result_set.match_set
86
+ end
87
+
88
+ test "miscellaneous options" do
89
+ opts = {
90
+ :dir => File.join(@tmpdir, 'foo'),
91
+ :scores => {:foo => 'bar'},
92
+ :matches => {:baz => 'qux'}
93
+ }
94
+ result_set = Linkage::ResultSets::CSV.new(opts)
95
+ assert Dir.exist?(opts[:dir])
96
+
97
+ expected_score_file = File.join(@tmpdir, 'foo', 'scores.csv')
98
+ score_set = stub('score set')
99
+ Linkage::ScoreSets::CSV.expects(:new).with(expected_score_file, :foo => 'bar').returns(score_set)
100
+ assert_same score_set, result_set.score_set
101
+
102
+ expected_match_file = File.join(@tmpdir, 'foo', 'matches.csv')
103
+ match_set = stub('match set')
104
+ Linkage::MatchSets::CSV.expects(:new).with(expected_match_file, :baz => 'qux').returns(match_set)
105
+ assert_same match_set, result_set.match_set
106
+ end
107
+
108
+ test "registers itself" do
109
+ assert_same Linkage::ResultSets::CSV, Linkage::ResultSet['csv']
110
+ end
111
+ end
@@ -0,0 +1,68 @@
1
+ require File.expand_path("../../test_result_sets", __FILE__)
2
+
3
+ class UnitTests::TestResultSets::TestDatabase < Test::Unit::TestCase
4
+ test "with database object" do
5
+ database = stub('database')
6
+ database.stubs(:kind_of?).with(Sequel::Database).returns(true)
7
+ result_set = Linkage::ResultSets::Database.new(database)
8
+
9
+ score_set = stub('score set')
10
+ Linkage::ScoreSets::Database.expects(:new).with(database, {}).returns(score_set)
11
+ assert_same score_set, result_set.score_set
12
+
13
+ match_set = stub('match set')
14
+ Linkage::MatchSets::Database.expects(:new).with(database, {}).returns(match_set)
15
+ assert_same match_set, result_set.match_set
16
+ end
17
+
18
+ test "with uri string" do
19
+ database = stub('database')
20
+ Sequel.expects(:connect).with("foo://bar").returns(database)
21
+ result_set = Linkage::ResultSets::Database.new("foo://bar")
22
+
23
+ score_set = stub('score set')
24
+ Linkage::ScoreSets::Database.expects(:new).with(database, {}).returns(score_set)
25
+ assert_same score_set, result_set.score_set
26
+
27
+ match_set = stub('match set')
28
+ Linkage::MatchSets::Database.expects(:new).with(database, {}).returns(match_set)
29
+ assert_same match_set, result_set.match_set
30
+ end
31
+
32
+ test "with connect options" do
33
+ database = stub('database')
34
+ Sequel.expects(:connect).with(:foo => 'bar').returns(database)
35
+ result_set = Linkage::ResultSets::Database.new(:foo => 'bar')
36
+
37
+ score_set = stub('score set')
38
+ Linkage::ScoreSets::Database.expects(:new).with(database, {}).returns(score_set)
39
+ assert_same score_set, result_set.score_set
40
+
41
+ match_set = stub('match set')
42
+ Linkage::MatchSets::Database.expects(:new).with(database, {}).returns(match_set)
43
+ assert_same match_set, result_set.match_set
44
+ end
45
+
46
+ test "with database options and scores/matches options" do
47
+ opts = {
48
+ :foo => 'bar',
49
+ :scores => {:baz => 'qux'},
50
+ :matches => {:corge => 'grault'}
51
+ }
52
+ database = stub('database')
53
+ Sequel.expects(:connect).with(:foo => 'bar').returns(database)
54
+ result_set = Linkage::ResultSets::Database.new(opts)
55
+
56
+ score_set = stub('score set')
57
+ Linkage::ScoreSets::Database.expects(:new).with(database, opts[:scores]).returns(score_set)
58
+ assert_same score_set, result_set.score_set
59
+
60
+ match_set = stub('match set')
61
+ Linkage::MatchSets::Database.expects(:new).with(database, opts[:matches]).returns(match_set)
62
+ assert_same match_set, result_set.match_set
63
+ end
64
+
65
+ test "registers itself" do
66
+ assert_same Linkage::ResultSets::Database, Linkage::ResultSet['database']
67
+ end
68
+ end
@@ -0,0 +1,151 @@
1
+ require File.expand_path("../../test_score_sets", __FILE__)
2
+
3
+ class UnitTests::TestScoreSets::TestCSV < Test::Unit::TestCase
4
+ test "open_for_writing" do
5
+ score_set = Linkage::ScoreSets::CSV.new('foo.csv')
6
+ csv = stub('csv')
7
+ CSV.expects(:open).with('foo.csv', 'wb').returns(csv)
8
+ csv.expects(:<<).with(%w{comparator_id id_1 id_2 score})
9
+ score_set.open_for_writing
10
+ end
11
+
12
+ test "open_for_writing when already open" do
13
+ score_set = Linkage::ScoreSets::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{comparator_id id_1 id_2 score})
17
+ score_set.open_for_writing
18
+ score_set.open_for_writing
19
+ end
20
+
21
+ test "open_for_writing when file exists" do
22
+ score_set = Linkage::ScoreSets::CSV.new('foo.csv')
23
+ File.expects(:exist?).with('foo.csv').returns(true)
24
+ assert_raises(Linkage::ExistsError) do
25
+ score_set.open_for_writing
26
+ end
27
+ end
28
+
29
+ test "open_for_writing when file exists and forcing overwrite" do
30
+ score_set = Linkage::ScoreSets::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{comparator_id id_1 id_2 score})
36
+ score_set.open_for_writing
37
+ end
38
+ end
39
+
40
+ test "open_for_reading" do
41
+ score_set = Linkage::ScoreSets::CSV.new('foo.csv')
42
+ File.stubs(:exist?).with('foo.csv').returns(true)
43
+ csv = stub('csv')
44
+ CSV.expects(:open).with('foo.csv', 'rb', {:headers => true}).returns(csv)
45
+ score_set.open_for_reading
46
+ end
47
+
48
+ test "open_for_reading when already open" do
49
+ score_set = Linkage::ScoreSets::CSV.new('foo.csv')
50
+ File.stubs(:exist?).with('foo.csv').returns(true)
51
+ csv = stub('csv')
52
+ CSV.expects(:open).once.with('foo.csv', 'rb', {:headers => true}).returns(csv)
53
+ score_set.open_for_reading
54
+ score_set.open_for_reading
55
+ end
56
+
57
+ test "open_for_reading when file doesn't exist" do
58
+ score_set = Linkage::ScoreSets::CSV.new('foo.csv')
59
+ File.expects(:exist?).with('foo.csv').returns(false)
60
+ assert_raises(Linkage::MissingError) do
61
+ score_set.open_for_reading
62
+ end
63
+ end
64
+
65
+ test "open_for_writing when in read mode raises exception" do
66
+ score_set = Linkage::ScoreSets::CSV.new('foo.csv')
67
+ File.stubs(:exist?).with('foo.csv').returns(true)
68
+ csv = stub('csv')
69
+ CSV.stubs(:open).returns(csv)
70
+ score_set.open_for_reading
71
+ assert_raises(RuntimeError) { score_set.open_for_writing }
72
+ end
73
+
74
+ test "open_for_reading when in write mode raises exception" do
75
+ score_set = Linkage::ScoreSets::CSV.new('foo.csv')
76
+ csv = stub('csv', :<< => nil)
77
+ CSV.stubs(:open).returns(csv)
78
+ score_set.open_for_writing
79
+ assert_raises(RuntimeError) { score_set.open_for_reading }
80
+ end
81
+
82
+ test "add_score when unopened raises exception" do
83
+ score_set = Linkage::ScoreSets::CSV.new('foo.csv')
84
+ assert_raises { score_set.add_score(1, 1, 2, 1) }
85
+ end
86
+
87
+ test "add_score when in read mode raises exception" do
88
+ score_set = Linkage::ScoreSets::CSV.new('foo.csv')
89
+ File.stubs(:exist?).with('foo.csv').returns(true)
90
+ csv = stub('csv')
91
+ CSV.stubs(:open).returns(csv)
92
+ score_set.open_for_reading
93
+ assert_raises { score_set.add_score(1, 1, 2, 1) }
94
+ end
95
+
96
+ test "add_score" do
97
+ tempfile = Tempfile.new('linkage')
98
+ tempfile.close
99
+ score_set = Linkage::ScoreSets::CSV.new(tempfile.path, :overwrite => true)
100
+ score_set.open_for_writing
101
+ score_set.add_score(1, 1, 2, 1)
102
+ score_set.close
103
+
104
+ expected = "comparator_id,id_1,id_2,score\n1,1,2,1\n"
105
+ assert_equal expected, File.read(tempfile.path)
106
+ end
107
+
108
+ test "each_pair" do
109
+ tempfile = Tempfile.new('linkage')
110
+ tempfile.write(<<-EOF.gsub(/^\s*/, ""))
111
+ comparator_id,id_1,id_2,score
112
+ 1,1,2,0.5
113
+ 1,2,3,1
114
+ 2,1,2,0
115
+ 2,2,3,1
116
+ 2,3,4,1
117
+ 1,3,4,0
118
+ 3,4,5,0
119
+ EOF
120
+ tempfile.close
121
+ score_set = Linkage::ScoreSets::CSV.new(tempfile.path)
122
+
123
+ pairs = []
124
+ score_set.each_pair { |*args| pairs << args }
125
+ assert_equal 4, pairs.length
126
+
127
+ pair_1 = pairs.detect { |pair| pair[0] == "1" && pair[1] == "2" }
128
+ assert pair_1
129
+ expected_1 = {1 => 0.5, 2 => 0}
130
+ assert_equal expected_1, pair_1[2]
131
+
132
+ pair_2 = pairs.detect { |pair| pair[0] == "2" && pair[1] == "3" }
133
+ assert pair_2
134
+ expected_2 = {1 => 1, 2 => 1}
135
+ assert_equal expected_2, pair_2[2]
136
+
137
+ pair_3 = pairs.detect { |pair| pair[0] == "3" && pair[1] == "4" }
138
+ assert pair_3
139
+ expected_3 = {1 => 0, 2 => 1}
140
+ assert_equal expected_3, pair_3[2]
141
+
142
+ pair_4 = pairs.detect { |pair| pair[0] == "4" && pair[1] == "5" }
143
+ assert pair_3
144
+ expected_4 = {3 => 0}
145
+ assert_equal expected_4, pair_4[2]
146
+ end
147
+
148
+ test "registers itself" do
149
+ assert_equal Linkage::ScoreSets::CSV, Linkage::ScoreSet['csv']
150
+ end
151
+ end
@@ -0,0 +1,149 @@
1
+ require File.expand_path("../../test_score_sets", __FILE__)
2
+
3
+ class UnitTests::TestScoreSets::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 scores table" do
10
+ score_set = Linkage::ScoreSets::Database.new(@database)
11
+ @database.stubs(:table_exists?).with(:scores).returns(false)
12
+ @database.expects(:create_table).with(:scores)
13
+ @database.expects(:[]).with(:scores).returns(@dataset)
14
+ score_set.open_for_writing
15
+ end
16
+
17
+ test "open_for_writing when already open" do
18
+ score_set = Linkage::ScoreSets::Database.new(@database)
19
+ @database.stubs(:table_exists?).with(:scores).returns(false)
20
+ @database.expects(:create_table).with(:scores)
21
+ @database.expects(:[]).with(:scores).returns(@dataset)
22
+ score_set.open_for_writing
23
+ score_set.open_for_writing
24
+ end
25
+
26
+ test "open_for_writing when scores table already exists" do
27
+ score_set = Linkage::ScoreSets::Database.new(@database)
28
+ @database.expects(:table_exists?).with(:scores).returns(true)
29
+ @database.expects(:create_table).with(:scores).never
30
+ assert_raises(Linkage::ExistsError) do
31
+ score_set.open_for_writing
32
+ end
33
+ end
34
+
35
+ test "open_for_writing when scores table already exists and in overwrite mode" do
36
+ score_set = Linkage::ScoreSets::Database.new(@database, :overwrite => true)
37
+ @database.expects(:drop_table?).with(:scores)
38
+ @database.expects(:create_table).with(:scores)
39
+ @database.expects(:[]).with(:scores).returns(@dataset)
40
+ score_set.open_for_writing
41
+ end
42
+
43
+ test "open_for_reading" do
44
+ score_set = Linkage::ScoreSets::Database.new(@database)
45
+ @database.stubs(:table_exists?).with(:scores).returns(true)
46
+ @database.expects(:[]).with(:scores).returns(@dataset)
47
+ score_set.open_for_reading
48
+ end
49
+
50
+ test "open_for_reading when already open" do
51
+ score_set = Linkage::ScoreSets::Database.new(@database)
52
+ @database.stubs(:table_exists?).with(:scores).returns(true)
53
+ @database.expects(:[]).with(:scores).returns(@dataset)
54
+ score_set.open_for_reading
55
+ score_set.open_for_reading
56
+ end
57
+
58
+ test "open_for_reading when table is missing" do
59
+ score_set = Linkage::ScoreSets::Database.new(@database)
60
+ @database.expects(:table_exists?).with(:scores).returns(false)
61
+ @database.expects(:[]).with(:scores).returns(@dataset).never
62
+ assert_raises(Linkage::MissingError) do
63
+ score_set.open_for_reading
64
+ end
65
+ end
66
+
67
+ test "open_for_writing when in read mode raises exception" do
68
+ score_set = Linkage::ScoreSets::Database.new(@database)
69
+ @database.stubs(:table_exists?).with(:scores).returns(true)
70
+ score_set.open_for_reading
71
+ assert_raises(RuntimeError) { score_set.open_for_writing }
72
+ end
73
+
74
+ test "open_for_reading when in write mode raises exception" do
75
+ score_set = Linkage::ScoreSets::Database.new(@database)
76
+ @database.stubs(:table_exists?).with(:scores).returns(false)
77
+ @database.stubs(:create_table)
78
+ score_set.open_for_writing
79
+ assert_raises(RuntimeError) { score_set.open_for_reading }
80
+ end
81
+
82
+ test "add_score when unopened raises exception" do
83
+ score_set = Linkage::ScoreSets::Database.new(@database)
84
+ assert_raises { score_set.add_score(1, 1, 2, 1) }
85
+ end
86
+
87
+ test "add_score when in read mode raises exception" do
88
+ score_set = Linkage::ScoreSets::Database.new(@database)
89
+ @database.stubs(:table_exists?).with(:scores).returns(true)
90
+ score_set.open_for_reading
91
+ assert_raises { score_set.add_score(1, 1, 2, 1) }
92
+ end
93
+
94
+ test "add_score" do
95
+ score_set = Linkage::ScoreSets::Database.new(@database)
96
+ @database.stubs(:table_exists?).with(:scores).returns(false)
97
+ @database.stubs(:create_table)
98
+ score_set.open_for_writing
99
+
100
+ @dataset.expects(:insert).with({
101
+ :comparator_id => 1, :id_1 => 1, :id_2 => 2, :score => 1
102
+ })
103
+ score_set.add_score(1, 1, 2, 1)
104
+ end
105
+
106
+ test "each_pair" do
107
+ score_set = Linkage::ScoreSets::Database.new(@database)
108
+ @database.stubs(:table_exists?).with(:scores).returns(true)
109
+ score_set.open_for_reading
110
+
111
+ @dataset.expects(:order).with(:id_1, :id_2, :comparator_id).returns(@dataset)
112
+ @dataset.expects(:each).multiple_yields(
113
+ [{:comparator_id => 1, :id_1 => '1', :id_2 => '2', :score => 0.5}],
114
+ [{:comparator_id => 2, :id_1 => '1', :id_2 => '2', :score => 0}],
115
+ [{:comparator_id => 1, :id_1 => '2', :id_2 => '3', :score => 1}],
116
+ [{:comparator_id => 2, :id_1 => '2', :id_2 => '3', :score => 1}],
117
+ [{:comparator_id => 1, :id_1 => '3', :id_2 => '4', :score => 0}],
118
+ [{:comparator_id => 2, :id_1 => '3', :id_2 => '4', :score => 1}],
119
+ [{:comparator_id => 3, :id_1 => '4', :id_2 => '5', :score => 0}]
120
+ )
121
+ pairs = []
122
+ score_set.each_pair { |*args| pairs << args }
123
+ assert_equal 4, pairs.length
124
+
125
+ pair_1 = pairs.detect { |pair| pair[0] == "1" && pair[1] == "2" }
126
+ assert pair_1
127
+ expected_1 = {1 => 0.5, 2 => 0}
128
+ assert_equal expected_1, pair_1[2]
129
+
130
+ pair_2 = pairs.detect { |pair| pair[0] == "2" && pair[1] == "3" }
131
+ assert pair_2
132
+ expected_2 = {1 => 1, 2 => 1}
133
+ assert_equal expected_2, pair_2[2]
134
+
135
+ pair_3 = pairs.detect { |pair| pair[0] == "3" && pair[1] == "4" }
136
+ assert pair_3
137
+ expected_3 = {1 => 0, 2 => 1}
138
+ assert_equal expected_3, pair_3[2]
139
+
140
+ pair_4 = pairs.detect { |pair| pair[0] == "4" && pair[1] == "5" }
141
+ assert pair_3
142
+ expected_4 = {3 => 0}
143
+ assert_equal expected_4, pair_4[2]
144
+ end
145
+
146
+ test "registers itself" do
147
+ assert_equal Linkage::ScoreSets::Database, Linkage::ScoreSet['database']
148
+ end
149
+ end
@@ -11,114 +11,77 @@ class UnitTests::TestComparator < Test::Unit::TestCase
11
11
  super
12
12
  end
13
13
 
14
- test "comparator_name raises error in base class" do
15
- assert_raises(NotImplementedError) { Linkage::Comparator.comparator_name }
16
- end
17
-
18
- test "registering subclass requires comparator_name" do
19
- klass = Class.new(Linkage::Comparator)
20
- assert_raises(ArgumentError) { Linkage::Comparator.register(klass) }
14
+ test "default subclass has type of simple" do
15
+ klass = new_comparator
16
+ instance = klass.new
17
+ assert_equal :simple, instance.type
21
18
  end
22
19
 
23
20
  test "getting a registered subclass" do
24
- klass = new_comparator('foo', [[String]], 0..1)
25
- Linkage::Comparator.register(klass)
21
+ klass = new_comparator
22
+ Linkage::Comparator.register('foo', klass)
26
23
  assert_equal klass, Linkage::Comparator['foo']
27
24
  end
28
25
 
29
- test "parameters raises error in base class" do
30
- assert_raises(NotImplementedError) { Linkage::Comparator.parameters }
31
- end
32
-
33
- test "subclasses required to define parameters class method" do
34
- klass = new_comparator('foo')
35
- assert_raises(ArgumentError) { Linkage::Comparator.register(klass) }
36
- end
37
-
38
- test "subclasses required to define at least one parameter" do
39
- klass = new_comparator('foo', [])
40
- assert_raises(ArgumentError) { Linkage::Comparator.register(klass) }
41
- end
26
+ test "registering subclass with advanced scoring methods" do
27
+ klass = new_comparator do
28
+ remove_method :score
42
29
 
43
- test "subclasses required to define score_range class method" do
44
- klass = new_comparator('foo', [[String]])
45
- assert_raises(ArgumentError) { Linkage::Comparator.register(klass) }
46
- end
30
+ def score_datasets(dataset_1, dataset_2)
31
+ end
47
32
 
48
- test "score_range class should be a Range of two numbers" do
49
- klass = new_comparator('foo', [[String]], "foo".."bar")
50
- assert_raises(ArgumentError) { Linkage::Comparator.register(klass) }
33
+ def score_dataset(dataset)
34
+ end
35
+ end
36
+ assert_nothing_raised { Linkage::Comparator.register('foo', klass) }
51
37
  end
52
38
 
53
- test "subclasses required to define score method" do
54
- klass = new_comparator('foo', [[String]]) do
39
+ test "subclasses required to define either simple or advanced scoring methods" do
40
+ klass = new_comparator do
55
41
  remove_method :score
56
42
  end
57
- assert_raises(ArgumentError) { Linkage::Comparator.register(klass) }
58
- end
59
-
60
- test "comparator with one valid argument" do
61
- klass = new_comparator('foo', [[String]])
62
- meta_object = stub('meta object', :side => :lhs, :ruby_type => { :type => String }, :static? => false)
63
- f = klass.new(meta_object)
64
- end
65
-
66
- test "comparator with one invalid argument" do
67
- klass = new_comparator('foo', [[String]])
68
- meta_object = stub('meta_object', :ruby_type => { :type => Fixnum }, :static? => false)
69
- assert_raises(TypeError) { klass.new(meta_object) }
70
- end
43
+ assert_raises(ArgumentError) { Linkage::Comparator.register('foo', klass) }
71
44
 
72
- test "comparator with too few arguments" do
73
- klass = new_comparator('foo', [[String]])
74
- assert_raises(ArgumentError) { klass.new }
75
- end
45
+ klass = new_comparator do
46
+ remove_method :score
76
47
 
77
- test "comparator with too many arguments" do
78
- klass = new_comparator('foo', [[String]])
79
- meta_object = stub('meta_object', :ruby_type => { :type => String }, :static? => false)
80
- assert_raises(ArgumentError) { klass.new(meta_object, meta_object) }
48
+ def score_datasets(dataset_1, dataset_2)
49
+ end
50
+ end
51
+ assert_raises(ArgumentError) { Linkage::Comparator.register('foo', klass) }
81
52
  end
82
53
 
83
- test "requiring argument to be non-static" do
84
- klass = new_comparator('foo', [[String, :static => false]])
85
- meta_object = stub('meta_object', :ruby_type => { :type => String }, :static? => true)
86
- assert_raise_message("argument 1 was expected to not be static") do
87
- klass.new(meta_object)
54
+ test "score raises NotImplementedError" do
55
+ comparator = Linkage::Comparator.new
56
+ assert_raises(NotImplementedError) do
57
+ comparator.score(stub('record 1'), stub('record 2'))
88
58
  end
89
59
  end
90
60
 
91
- test "requiring argument to be static" do
92
- klass = new_comparator('foo', [[String, :static => true]])
93
- meta_object = stub('meta_object', :ruby_type => { :type => String }, :static? => false)
94
- assert_raise_message("argument 1 was expected to be static") do
95
- klass.new(meta_object)
61
+ test "score_datasets raises NotImplementedError" do
62
+ comparator = Linkage::Comparator.new
63
+ assert_raises(NotImplementedError) do
64
+ comparator.score_datasets(stub('dataset 1'), stub('dataset 2'))
96
65
  end
97
66
  end
98
67
 
99
- test "special :any parameter" do
100
- klass = new_comparator('foo', [[:any]])
101
- meta_object_1 = stub('meta_object', :side => :lhs, :ruby_type => { :type => String }, :static? => false)
102
- meta_object_2 = stub('meta_object', :side => :rhs, :ruby_type => { :type => Fixnum }, :static? => false)
103
- assert_nothing_raised do
104
- klass.new(meta_object_1)
105
- klass.new(meta_object_2)
68
+ test "score_dataset raises NotImplementedError" do
69
+ comparator = Linkage::Comparator.new
70
+ assert_raises(NotImplementedError) do
71
+ comparator.score_dataset(stub('dataset'))
106
72
  end
107
73
  end
108
74
 
109
- test "lhs_args" do
110
- klass = new_comparator('foo', [[String], [String]])
111
- meta_object_1 = stub('meta object 1', :side => :lhs, :ruby_type => { :type => String }, :static? => false)
112
- meta_object_2 = stub('meta object 2', :side => :rhs, :ruby_type => { :type => String }, :static? => false)
113
- obj = klass.new(meta_object_1, meta_object_2)
114
- assert_equal [meta_object_1], obj.lhs_args
115
- end
75
+ test "score_and_notify" do
76
+ klass = new_comparator
77
+ instance = klass.new
78
+
79
+ observer = stub('observer', :update => nil)
80
+ instance.add_observer(observer)
116
81
 
117
- test "rhs_args" do
118
- klass = new_comparator('foo', [[String], [String]])
119
- meta_object_1 = stub('meta object 1', :side => :lhs, :ruby_type => { :type => String }, :static? => false)
120
- meta_object_2 = stub('meta object 2', :side => :rhs, :ruby_type => { :type => String }, :static? => false)
121
- obj = klass.new(meta_object_1, meta_object_2)
122
- assert_equal [meta_object_2], obj.rhs_args
82
+ record_1 = stub('record 1')
83
+ record_2 = stub('record 2')
84
+ observer.expects(:update).with(instance, record_1, record_2, 1)
85
+ instance.score_and_notify(record_1, record_2)
123
86
  end
124
87
  end
@@ -0,0 +1,4 @@
1
+ require 'helper'
2
+
3
+ module UnitTests::TestComparators
4
+ end