linkage 0.0.8 → 0.1.0.pre

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.yardopts +1 -0
  4. data/Gemfile +1 -19
  5. data/Gemfile-java +3 -0
  6. data/README.markdown +88 -34
  7. data/Rakefile +16 -15
  8. data/TODO +4 -0
  9. data/lib/linkage/comparator.rb +139 -144
  10. data/lib/linkage/comparators/compare.rb +236 -29
  11. data/lib/linkage/comparators/strcompare.rb +85 -0
  12. data/lib/linkage/comparators/within.rb +24 -20
  13. data/lib/linkage/configuration.rb +44 -466
  14. data/lib/linkage/dataset.rb +28 -127
  15. data/lib/linkage/exceptions.rb +5 -0
  16. data/lib/linkage/field.rb +6 -37
  17. data/lib/linkage/field_set.rb +3 -3
  18. data/lib/linkage/match_recorder.rb +22 -0
  19. data/lib/linkage/match_set.rb +34 -0
  20. data/lib/linkage/match_sets/csv.rb +39 -0
  21. data/lib/linkage/match_sets/database.rb +45 -0
  22. data/lib/linkage/matcher.rb +30 -0
  23. data/lib/linkage/result_set.rb +25 -110
  24. data/lib/linkage/result_sets/csv.rb +54 -0
  25. data/lib/linkage/result_sets/database.rb +42 -0
  26. data/lib/linkage/runner.rb +57 -16
  27. data/lib/linkage/score_recorder.rb +30 -0
  28. data/lib/linkage/score_set.rb +49 -0
  29. data/lib/linkage/score_sets/csv.rb +64 -0
  30. data/lib/linkage/score_sets/database.rb +77 -0
  31. data/lib/linkage/version.rb +1 -1
  32. data/lib/linkage.rb +14 -17
  33. data/linkage.gemspec +13 -1
  34. data/linkage.gemspec-java +32 -0
  35. data/test/helper.rb +30 -23
  36. data/test/integration/test_cross_linkage.rb +46 -25
  37. data/test/integration/test_database_result_set.rb +55 -0
  38. data/test/integration/test_dual_linkage.rb +19 -94
  39. data/test/integration/test_self_linkage.rb +100 -203
  40. data/test/integration/test_within_comparator.rb +24 -77
  41. data/test/unit/comparators/test_compare.rb +254 -50
  42. data/test/unit/comparators/test_strcompare.rb +45 -0
  43. data/test/unit/comparators/test_within.rb +14 -26
  44. data/test/unit/match_sets/test_csv.rb +78 -0
  45. data/test/unit/match_sets/test_database.rb +63 -0
  46. data/test/unit/result_sets/test_csv.rb +111 -0
  47. data/test/unit/result_sets/test_database.rb +68 -0
  48. data/test/unit/score_sets/test_csv.rb +151 -0
  49. data/test/unit/score_sets/test_database.rb +149 -0
  50. data/test/unit/test_comparator.rb +46 -83
  51. data/test/unit/test_comparators.rb +4 -0
  52. data/test/unit/test_configuration.rb +99 -145
  53. data/test/unit/test_dataset.rb +52 -73
  54. data/test/unit/test_field.rb +4 -55
  55. data/test/unit/test_field_set.rb +6 -6
  56. data/test/unit/test_match_recorder.rb +23 -0
  57. data/test/unit/test_match_set.rb +23 -0
  58. data/test/unit/test_match_sets.rb +4 -0
  59. data/test/unit/test_matcher.rb +44 -0
  60. data/test/unit/test_result_set.rb +24 -223
  61. data/test/unit/test_result_sets.rb +4 -0
  62. data/test/unit/test_runner.rb +122 -17
  63. data/test/unit/test_runners.rb +4 -0
  64. data/test/unit/test_score_recorder.rb +25 -0
  65. data/test/unit/test_score_set.rb +37 -0
  66. data/test/unit/test_score_sets.rb +4 -0
  67. metadata +183 -90
  68. data/Gemfile.lock +0 -92
  69. data/lib/linkage/comparators/binary.rb +0 -12
  70. data/lib/linkage/data.rb +0 -175
  71. data/lib/linkage/decollation.rb +0 -93
  72. data/lib/linkage/expectation.rb +0 -21
  73. data/lib/linkage/expectations/exhaustive.rb +0 -63
  74. data/lib/linkage/expectations/simple.rb +0 -168
  75. data/lib/linkage/function.rb +0 -148
  76. data/lib/linkage/functions/binary.rb +0 -30
  77. data/lib/linkage/functions/cast.rb +0 -54
  78. data/lib/linkage/functions/length.rb +0 -29
  79. data/lib/linkage/functions/strftime.rb +0 -33
  80. data/lib/linkage/functions/trim.rb +0 -30
  81. data/lib/linkage/group.rb +0 -55
  82. data/lib/linkage/meta_object.rb +0 -139
  83. data/lib/linkage/runner/single_threaded.rb +0 -187
  84. data/lib/linkage/utils.rb +0 -164
  85. data/lib/linkage/warnings.rb +0 -5
  86. data/test/integration/test_collation.rb +0 -45
  87. data/test/integration/test_configuration.rb +0 -268
  88. data/test/integration/test_dataset.rb +0 -116
  89. data/test/integration/test_functions.rb +0 -88
  90. data/test/integration/test_result_set.rb +0 -85
  91. data/test/integration/test_scoring.rb +0 -84
  92. data/test/unit/expectations/test_exhaustive.rb +0 -111
  93. data/test/unit/expectations/test_simple.rb +0 -303
  94. data/test/unit/functions/test_binary.rb +0 -54
  95. data/test/unit/functions/test_cast.rb +0 -98
  96. data/test/unit/functions/test_length.rb +0 -52
  97. data/test/unit/functions/test_strftime.rb +0 -60
  98. data/test/unit/functions/test_trim.rb +0 -43
  99. data/test/unit/runner/test_single_threaded.rb +0 -12
  100. data/test/unit/test_data.rb +0 -445
  101. data/test/unit/test_decollation.rb +0 -201
  102. data/test/unit/test_function.rb +0 -233
  103. data/test/unit/test_group.rb +0 -38
  104. data/test/unit/test_meta_object.rb +0 -208
  105. data/test/unit/test_utils.rb +0 -341
@@ -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