odba 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,371 @@
1
+ #!/usr/bin/env ruby
2
+ # TestIndex -- oddb -- 13.05.2004 -- hwyss@ywesee.com mwalder@ywesee.com
3
+
4
+ $: << File.dirname(__FILE__)
5
+ $: << File.expand_path("../lib", File.dirname(__FILE__))
6
+
7
+ require 'test/unit'
8
+ require 'odba/index'
9
+ require 'odba/index_definition'
10
+ require 'odba/odba'
11
+ require 'flexmock'
12
+
13
+ module ODBA
14
+ class Origin
15
+ attr_accessor :term, :odba_id
16
+ end
17
+ class OriginSubclass < Origin
18
+ end
19
+ class Target
20
+ attr_accessor :origin, :odba_id
21
+ end
22
+ class TargetSubclass < Target
23
+ end
24
+ class TestIndexCommon < Test::Unit::TestCase
25
+ include FlexMock::TestCase
26
+ def setup
27
+ @storage = flexmock('Storage')
28
+ ODBA.storage = @storage
29
+ df = IndexDefinition.new
30
+ df.index_name = 'index'
31
+ df.origin_klass = :Origin
32
+ df.target_klass = :Target
33
+ df.resolve_origin = :origin
34
+ df.resolve_search_term = :term
35
+ @index = IndexCommon.new(df, ODBA)
36
+ end
37
+ def test_delete
38
+ handle = flexmock('DB-Handle')
39
+ @storage.should_receive(:delete_index_element)\
40
+ .with('index', 15, 'origin_id')\
41
+ .times(1).and_return {assert(true) }
42
+ origin = Origin.new
43
+ origin.odba_id = 15
44
+ @index.delete(origin)
45
+ @storage.should_receive(:delete_index_element)\
46
+ .with('index', 16, 'target_id')\
47
+ .times(1).and_return {assert(true) }
48
+ target = Target.new
49
+ target.odba_id = 16
50
+ @index.delete(target)
51
+ end
52
+ def test_do_update_index
53
+ @storage.should_receive(:update_index)\
54
+ .with('index', 12, 'foo', nil).and_return {
55
+ assert(true)
56
+ }
57
+ @index.do_update_index(12, 'foo')
58
+ end
59
+ def test_fill
60
+ df = IndexDefinition.new
61
+ df.index_name = 'index'
62
+ df.resolve_origin = 'get_origin'
63
+ df.resolve_search_term = 'the_search_term'
64
+ index = IndexCommon.new(df, self)
65
+
66
+ origin = flexmock('origin')
67
+ origin.should_receive(:the_search_term).and_return('tst')
68
+ origin.should_receive(:odba_id).and_return(4)
69
+ target = flexmock('target')
70
+ target.should_receive(:get_origin).and_return(origin)
71
+ target.should_receive(:odba_id).and_return(3)
72
+
73
+ targets = [target, [target]]
74
+
75
+ @storage.should_receive(:update_index)\
76
+ .with('index', 4, 'tst', 3).times(2).and_return { assert(true) }
77
+
78
+ index.fill(targets)
79
+ end
80
+ def test_keys
81
+ @storage.should_receive(:index_fetch_keys).with('index', nil)\
82
+ .and_return { ['key1', 'key2', ''] }
83
+ assert_equal(%w{key1 key2}, @index.keys)
84
+ @storage.should_receive(:index_fetch_keys).with('index', 2)\
85
+ .and_return { ['k1', 'k2', ''] }
86
+ assert_equal(%w{k1 k2}, @index.keys(2))
87
+ @storage.should_receive(:index_fetch_keys).with('index', 1)\
88
+ .and_return { ['1', '2', ''] }
89
+ assert_equal(%w{1 2}, @index.keys(1))
90
+ end
91
+ def test_origin_class
92
+ df = IndexDefinition.new
93
+ df.index_name = 'index'
94
+ df.origin_klass = :Origin
95
+ index = IndexCommon.new(df, self)
96
+ assert_equal(true, index.origin_class?(Origin))
97
+ assert_equal(false, index.origin_class?(Target))
98
+ end
99
+ def test_proc_instance_origin
100
+ df = IndexDefinition.new
101
+ df.index_name = 'index'
102
+ index = IndexCommon.new(df, self)
103
+ pr = index.proc_instance_origin
104
+ stub = Object.new
105
+ assert_equal([stub], pr.call(stub))
106
+ end
107
+ def test_proc_resolve_search_term
108
+ df = IndexDefinition.new
109
+ df.index_name = 'index'
110
+ index = IndexCommon.new(df, self)
111
+ pr = index.proc_resolve_search_term
112
+ stub = Object.new
113
+ assert_equal(stub.to_s.downcase, pr.call(stub))
114
+ end
115
+ def test_search_term
116
+ idf = IndexDefinition.new
117
+ idf.index_name = 'index'
118
+ idf.resolve_search_term = 'resolve_it'
119
+ origin = flexmock('origin')
120
+ origin.should_receive(:resolve_it).times(1).and_return('myterm')
121
+ index = IndexCommon.new(idf, ODBA)
122
+ assert_equal('myterm', index.search_term(origin))
123
+ end
124
+ def test_set_relevance
125
+ meta = flexmock('Meta')
126
+ meta.should_receive(:respond_to?).with(:set_relevance).and_return(true)
127
+ meta.should_receive(:set_relevance).with('foo', 'bar').and_return {
128
+ assert(true) }
129
+ meta.should_receive(:set_relevance).with('baz', 'fro').and_return {
130
+ assert(true) }
131
+ @index.set_relevance(meta, [%w{foo bar}, %w{baz fro}])
132
+ end
133
+ def test_update__origin
134
+ origin = Origin.new
135
+ origin.odba_id = 1
136
+ origin.term = "search-term"
137
+ @storage.should_receive(:index_target_ids).with('index', 1)\
138
+ .and_return([[3, 'old-term'], [4, 'old-term']])
139
+ @storage.should_receive(:index_delete_origin).with('index', 1, "old-term")
140
+ @storage.should_receive(:update_index)\
141
+ .with('index', 1, 'search-term', 3).and_return {
142
+ assert(true) }
143
+ @storage.should_receive(:update_index)\
144
+ .with('index', 1, 'search-term', 4).and_return {
145
+ assert(true) }
146
+ @index.update(origin)
147
+ end
148
+ def test_update__target
149
+ origin = Origin.new
150
+ origin.odba_id = 1
151
+ origin.term = "search-term"
152
+ target = Target.new
153
+ target.odba_id = 2
154
+ target.origin = origin
155
+ @storage.should_receive(:index_origin_ids).with('index', 2)\
156
+ .and_return([[1, 'old-term'], [4, 'obsolete-term']])
157
+ @storage.should_receive(:index_delete_target)\
158
+ .with('index', 1, 'old-term', 2).and_return { assert(true) }
159
+ @storage.should_receive(:index_delete_target)\
160
+ .with('index', 4, 'obsolete-term', 2).and_return { assert(true) }
161
+ @storage.should_receive(:update_index)\
162
+ .with('index', 1, 'search-term', 2).and_return {
163
+ assert(true) }
164
+ @index.update(target)
165
+ end
166
+ def test_update__subclass
167
+ origin = OriginSubclass.new
168
+ target = TargetSubclass.new
169
+ assert_nothing_raised {
170
+ @index.update(origin)
171
+ }
172
+ assert_nothing_raised {
173
+ @index.update(target)
174
+ }
175
+ end
176
+ end
177
+ class TestIndex < Test::Unit::TestCase
178
+ include FlexMock::TestCase
179
+ def setup
180
+ @storage = flexmock('Storage')
181
+ @storage.should_receive(:create_index).with('index')
182
+ ODBA.storage = @storage
183
+ df = IndexDefinition.new
184
+ df.index_name = 'index'
185
+ df.origin_klass = :Origin
186
+ df.target_klass = :Target
187
+ df.resolve_origin = :origin
188
+ df.resolve_search_term = :term
189
+ @index = Index.new(df, self)
190
+ end
191
+ def test_fetch_ids
192
+ rows = [[1,3], [2,2], [3,1]]
193
+ @storage.should_receive(:retrieve_from_index)\
194
+ .with('index', 'search-term', false, false).and_return rows
195
+ assert_equal([1,2,3], @index.fetch_ids('search-term'))
196
+ end
197
+ def test_search_terms
198
+ origin = Origin.new
199
+ origin.term = 'resolved'
200
+ assert_equal(['resolved'], @index.search_terms(origin))
201
+ origin.term = ['resolved']
202
+ assert_equal(['resolved'], @index.search_terms(origin))
203
+ end
204
+ end
205
+ class TestConditionIndex < Test::Unit::TestCase
206
+ include FlexMock::TestCase
207
+ def setup
208
+ @storage = flexmock('Storage')
209
+ @storage.should_receive(:create_condition_index)\
210
+ .with('index', {'crit1' => 'text', 'crit2' => 'Integer'})
211
+ ODBA.storage = @storage
212
+ df = IndexDefinition.new
213
+ df.index_name = 'index'
214
+ df.origin_klass = :Origin
215
+ df.target_klass = :Target
216
+ df.resolve_origin = :origin
217
+ df.resolve_search_term = [
218
+ ['crit1', 'term'],
219
+ ['crit2', {'type' => 'Integer', 'resolve' => 'odba_id'}],
220
+ ]
221
+ @index = ConditionIndex.new(df, self)
222
+ end
223
+ def test_do_update_index
224
+ data = {'crit1' => 'foo', 'condition' => 'like'}
225
+ @storage.should_receive(:update_condition_index)\
226
+ .with('index', 2, data, 3)
227
+ @index.do_update_index(2, data, 3)
228
+ end
229
+ def test_fetch_ids
230
+ rows = [[1,3], [2,2], [3,1]]
231
+ data = {'crit1' => 'foo', 'condition' => 'like'}
232
+ @storage.should_receive(:retrieve_from_condition_index)\
233
+ .with('index', data, false).and_return rows
234
+ assert_equal([1,2,3], @index.fetch_ids(data))
235
+ end
236
+ def test_proc_resolve_search_term
237
+ pr = @index.proc_resolve_search_term
238
+ origin = Origin.new
239
+ origin.term = 'search_term'
240
+ origin.odba_id = 15
241
+ expected = {
242
+ 'crit1' => 'search_term',
243
+ 'crit2' => 15,
244
+ }
245
+ assert_equal(expected, pr.call(origin))
246
+ end
247
+ def test_update_target
248
+ @storage.should_receive(:condition_index_ids)\
249
+ .with('index', 4, 'target_id').and_return {
250
+ [
251
+ {'origin_id' => 1, 'crit1' => '1st',
252
+ 'crit2' => 1, 'target_id' => 5},
253
+ {'origin_id' => 1, 'crit1' => '1st',
254
+ 'crit2' => 2, 'target_id' => 5},
255
+ ]
256
+ }
257
+ target = Target.new
258
+ target.odba_id = 4
259
+ origin1 = Origin.new
260
+ origin1.odba_id = 1
261
+ origin1.term = '1st'
262
+ origin2 = Origin.new
263
+ origin2.term = '2nd'
264
+ origin2.odba_id = 2
265
+ target.origin = [origin1, origin2]
266
+ @storage.should_receive(:condition_index_delete)\
267
+ .with('index', 1, [['crit1', '1st'], ['crit2', 2]], 4)\
268
+ .and_return { assert(true) }
269
+ @storage.should_receive(:update_condition_index)\
270
+ .with('index', 2, [['crit1', '2nd'], ['crit2', 2]], 4)\
271
+ .and_return { assert(true) }
272
+ @index.update_target(target)
273
+ end
274
+ def test_update_origin
275
+ @storage.should_receive(:condition_index_ids)\
276
+ .with('index', 1, 'origin_id').and_return {
277
+ [
278
+ {'origin_id' => 1, 'crit1' => '1st',
279
+ 'crit2' => 1, 'target_id' => 5},
280
+ {'origin_id' => 1, 'crit1' => '1st',
281
+ 'crit2' => 2, 'target_id' => 5},
282
+ ]
283
+ }
284
+ target = Target.new
285
+ target.odba_id = 4
286
+ origin1 = Origin.new
287
+ origin1.odba_id = 1
288
+ origin1.term = '1st'
289
+ origin2 = Origin.new
290
+ origin2.term = '2nd'
291
+ origin2.odba_id = 2
292
+ target.origin = [origin1, origin2]
293
+ @storage.should_receive(:condition_index_delete)\
294
+ .with('index', 1, [['crit1', '1st'], ['crit2', 2]])\
295
+ .and_return { assert(true) }
296
+ @storage.should_receive(:update_condition_index)\
297
+ .with('index', 2, [['crit1', '2nd'], ['crit2', 2]])\
298
+ .and_return { assert(true) }
299
+ @index.update_origin(origin1)
300
+ end
301
+ end
302
+ class TestFulltextIndex < Test::Unit::TestCase
303
+ include FlexMock::TestCase
304
+ def setup
305
+ @storage = flexmock('Storage')
306
+ @storage.should_receive(:create_fulltext_index).with('index')
307
+ ODBA.storage = @storage
308
+ df = IndexDefinition.new
309
+ df.index_name = 'index'
310
+ df.dictionary = 'german'
311
+ df.origin_klass = :Origin
312
+ df.target_klass = :Target
313
+ df.resolve_origin = :origin
314
+ df.resolve_search_term = 'term'
315
+ @index = FulltextIndex.new(df, self)
316
+ end
317
+ def test_fetch_ids
318
+ rows = [[1,3], [2,2], [3,1]]
319
+ @storage.should_receive(:retrieve_from_fulltext_index)\
320
+ .with('index', 'search-term', 'german', false).and_return rows
321
+ assert_equal([1,2,3], @index.fetch_ids('search-term'))
322
+ end
323
+ def test_do_update_index
324
+ @storage.should_receive(:update_fulltext_index)\
325
+ .with('index', 3, 'some full text', 4, 'german')
326
+ @index.do_update_index(3, 'some full text', 4)
327
+ end
328
+ def test_update_target
329
+ ## only deletes entries for the current target, and inserts from
330
+ # all origins
331
+ @storage.should_receive(:fulltext_index_delete)\
332
+ .with('index', 4, 'target_id')
333
+ @storage.should_receive(:update_fulltext_index)\
334
+ .with('index', 1, 'fulltext term', 4, 'german')
335
+ @storage.should_receive(:update_fulltext_index)\
336
+ .with('index', 2, 'fulltext term', 4, 'german')
337
+ target = Target.new
338
+ target.odba_id = 4
339
+ origin1 = Origin.new
340
+ origin1.odba_id = 1
341
+ origin1.term = ['fulltext term']
342
+ origin2 = Origin.new
343
+ origin2.term = ['fulltext term']
344
+ origin2.odba_id = 2
345
+ target.origin = [origin1, origin2]
346
+ @index.update(target)
347
+ end
348
+ def test_update_origin
349
+ ## deletes all entries for the current origin and must restore
350
+ # entries for all targets!
351
+ @storage.should_receive(:fulltext_index_target_ids)\
352
+ .times(1).with('index', 1).and_return([[4],[5]])
353
+ @storage.should_receive(:fulltext_index_delete)\
354
+ .times(1).with('index', 1, 'origin_id')
355
+ @storage.should_receive(:update_fulltext_index)\
356
+ .times(1).with('index', 1, 'fulltext term', 4, 'german')
357
+ @storage.should_receive(:update_fulltext_index)\
358
+ .times(1).with('index', 1, 'fulltext term', 5, 'german')
359
+ target = Target.new
360
+ target.odba_id = 4
361
+ origin1 = Origin.new
362
+ origin1.odba_id = 1
363
+ origin1.term = ['fulltext term']
364
+ origin2 = Origin.new
365
+ origin2.term = ['fulltext term']
366
+ origin2.odba_id = 2
367
+ target.origin = [origin1, origin2]
368
+ @index.update(origin1)
369
+ end
370
+ end
371
+ end
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $: << File.expand_path('../lib', File.dirname(__FILE__))
4
+
5
+ require 'test/unit'
6
+ require 'odba/marshal'
7
+
8
+ module ODBA
9
+ class TestMarshal < Test::Unit::TestCase
10
+ def setup
11
+ @foo = Array.new
12
+ end
13
+ def test_dump
14
+ assert_equal("04085b00",ODBA::Marshal.dump(@foo))
15
+ end
16
+ def test_load
17
+ assert_equal(@foo, ODBA::Marshal.load("04085b00"))
18
+ end
19
+ def test_load_18_in_19
20
+ if RUBY_VERSION >= '1.9'
21
+ require 'odba/18_19_loading_compatibility'
22
+ binary = "\004\bu:\tDate=\004\b[\bo:\rRational\a:\017@numeratori\003\205\353J:\021@denominatori\ai\000i\003\031\025#".unpack('H*').first
23
+ date = Marshal.load(binary)
24
+ assert_equal Date.new(2009,5,27), date
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,625 @@
1
+ #!/usr/bin/env ruby
2
+ # TestPersistable -- odba -- ??.??.???? -- hwyss@ywesee.com
3
+
4
+ $: << File.dirname(__FILE__)
5
+ $: << File.expand_path('../lib/', File.dirname(__FILE__))
6
+
7
+ require 'odba/persistable'
8
+ require 'odba/stub'
9
+ require 'odba/cache'
10
+ require 'odba/odba'
11
+ require 'odba/storage'
12
+ require 'odba/marshal'
13
+ require 'test/unit'
14
+ require 'flexmock'
15
+ require 'yaml'
16
+
17
+ module ODBA
18
+ module Persistable
19
+ attr_accessor :odba_references
20
+ attr_writer :odba_id
21
+ public :odba_replace_excluded!
22
+ end
23
+ class TestPersistable < Test::Unit::TestCase
24
+ include FlexMock::TestCase
25
+ class ODBAExcluding
26
+ include ODBA::Persistable
27
+ ODBA_EXCLUDE_VARS = ["@excluded"]
28
+ attr_accessor :included, :excluded
29
+ end
30
+ class ODBAContainer
31
+ include ODBA::Persistable
32
+ ODBA_SERIALIZABLE = ['@serializable']
33
+ attr_accessor :non_replaceable, :replaceable, :replaceable2,
34
+ :array, :odba_persistent, :serializable
35
+ attr_accessor :odba_snapshot_level
36
+ end
37
+ class Hash
38
+ include ODBA::Persistable
39
+ attr_accessor :odba_persistent
40
+ end
41
+ class IndexedStub
42
+ include Persistable
43
+ #attr_accessor :origin
44
+ odba_index :name
45
+ odba_index :foo, :bar
46
+ odba_index :origin, :origin, :non_replaceable, ODBAContainer
47
+ odba_index :redirect, 'redirect.name'
48
+ end
49
+ def setup
50
+ ODBA.storage = flexmock("storage")
51
+ ODBA.marshaller = flexmock("marshaller")
52
+ ODBA.cache = flexmock("cache")
53
+ @odba = ODBAContainer.new
54
+ end
55
+ def teardown
56
+ ODBA.storage.mock_verify
57
+ ODBA.marshaller.mock_verify
58
+ ODBA.cache.mock_verify
59
+ ODBA.storage = nil
60
+ ODBA.marshaller = nil
61
+ ODBA.cache = nil
62
+ end
63
+ def test_odba_id
64
+ ODBA.cache.mock_handle(:next_id) { ||
65
+ 2
66
+ }
67
+ ODBA.marshaller.mock_handle(:dump) { |obj|
68
+ "foo"
69
+ }
70
+ ODBA.storage.mock_handle(:store) { |id,obj|}
71
+ @odba.odba_take_snapshot(1)
72
+ assert_equal(2, @odba.odba_id)
73
+ ODBA.storage.mock_verify
74
+ ODBA.marshaller.mock_verify
75
+ end
76
+ def test_odba_delete
77
+ odba_container = ODBAContainer.new
78
+ odba_container.odba_id = 2
79
+ #ODBA.storage.mock_handle(:transaction) { |block| block.call}
80
+ ODBA.cache.mock_handle(:delete) { |object|
81
+ assert_equal(odba_container, object)
82
+ }
83
+ odba_container.odba_delete
84
+ end
85
+ def test_odba_replace_excluded
86
+ odba = ODBAExcluding.new
87
+ odba.included = "here to stay"
88
+ odba.excluded = "easy come easy go"
89
+ odba.odba_replace_excluded!
90
+ assert_equal("here to stay", odba.included)
91
+ assert_nil(odba.excluded)
92
+ end
93
+ def test_odba_replace_stubs
94
+ stub = flexmock
95
+ stub.should_receive(:odba_id).and_return(6)
96
+ stub.should_receive(:is_a?).with(Stub).and_return(true)
97
+ @odba.replaceable = stub
98
+ substitution = flexmock
99
+ substitution.should_receive(:odba_id).and_return(6)
100
+ @odba.odba_replace_stubs(6, substitution)
101
+ assert_equal(@odba.replaceable, substitution)
102
+ end
103
+ def test_odba_take_snapshot
104
+ level1 = ODBAContainer.new
105
+ level2 = ODBAContainer.new
106
+ @odba.replaceable = level1
107
+ level1.replaceable = level2
108
+
109
+ ODBA.cache.mock_handle(:store) { |obj| 2}
110
+ ODBA.cache.mock_handle(:store) { |obj| 2}
111
+
112
+ ODBA.cache.mock_handle(:store) { |obj| 2}
113
+
114
+ @odba.odba_take_snapshot
115
+ assert_equal(1, @odba.odba_snapshot_level)
116
+ assert_equal(1, level1.odba_snapshot_level)
117
+ assert_equal(1, level2.odba_snapshot_level)
118
+ ODBA.cache.mock_verify
119
+ end
120
+ def test_odba_unsaved_neighbors
121
+ replaceable = flexmock
122
+ @odba.replaceable = replaceable
123
+ =begin
124
+ replaceable.mock_handle(:is_a?) { |arg| false }
125
+ replaceable.mock_handle(:is_a?) { |arg| false }
126
+ =end
127
+ replaceable.mock_handle(:is_a?) { |arg|
128
+ assert_equal(Persistable, arg)
129
+ true
130
+ }
131
+ replaceable.mock_handle(:odba_unsaved?){ |level| true}
132
+ result = @odba.odba_unsaved_neighbors(2)
133
+ assert_equal([replaceable], result)
134
+ replaceable.mock_verify
135
+ end
136
+ def test_odba_unsaved_neighbors_2
137
+ odba = ODBAExcluding.new
138
+ included = flexmock
139
+ excluded = flexmock
140
+ odba.excluded = excluded
141
+ odba.included = included
142
+ =begin
143
+ included.mock_handle(:is_a?) { |klass|
144
+ assert_equal(Hash, klass)
145
+ false
146
+ }
147
+ included.mock_handle(:is_a?) { |klass|
148
+ assert_equal(Array, klass)
149
+ false
150
+ }
151
+ =end
152
+ included.mock_handle(:is_a?) { |klass|
153
+ assert_equal(ODBA::Persistable, klass)
154
+ true
155
+ }
156
+ included.mock_handle(:odba_unsaved?) { true }
157
+ result = odba.odba_unsaved_neighbors(2)
158
+ assert_equal([included], result)
159
+ excluded.mock_verify
160
+ included.mock_verify
161
+ end
162
+ def test_extend_enumerable
163
+ hash = Hash.new
164
+ array = Array.new
165
+ #@odba.odba_extend_enumerable(hash)
166
+ #@odba.odba_extend_enumerable(array)
167
+ assert_equal(true, hash.is_a?(Persistable))
168
+ assert_equal(true, array.is_a?(Persistable))
169
+ end
170
+ def test_odba_stubize
171
+ replaceable = ODBAContainer.new
172
+ non_rep = ODBAContainer.new
173
+ non_rep.odba_id = 32
174
+ replaceable.odba_id = 24
175
+ @odba.replaceable = replaceable
176
+ @odba.non_replaceable = non_rep
177
+ @odba.odba_stubize(replaceable)
178
+ assert_equal(24, @odba.replaceable.odba_id)
179
+ assert_equal(true, @odba.replaceable.is_a?(Stub))
180
+ assert_equal(true, @odba.non_replaceable.is_a?(ODBAContainer))
181
+ end
182
+ def test_odba_replace_persistables
183
+ replaceable = ODBAContainer.new
184
+ replaceable.odba_id = 12
185
+ non_replaceable = flexmock
186
+ @odba.non_replaceable = non_replaceable
187
+ @odba.replaceable = replaceable
188
+ non_replaceable.should_receive(:is_a?).with(Stub)\
189
+ .times(1).and_return(false)
190
+ non_replaceable.should_receive(:is_a?).with(Persistable)\
191
+ .times(1).and_return(false)
192
+ #ODBA.cache.mock_handle(:next_id){ 13 }
193
+ @odba.odba_replace_persistables
194
+ assert_instance_of(FlexMock, @odba.non_replaceable)
195
+ assert_equal(12, @odba.replaceable.odba_id)
196
+ assert_equal(true, @odba.replaceable.is_a?(Stub))
197
+ non_replaceable.mock_verify
198
+ ODBA.cache.mock_verify
199
+ end
200
+ def test_odba_replace_persistables__stubised_serialisable
201
+ non_replaceable = flexmock
202
+ @odba.serializable = non_replaceable
203
+ non_replaceable.mock_handle(:is_a?) { |arg|
204
+ assert_equal(Stub, arg)
205
+ true
206
+ }
207
+ non_replaceable.mock_handle(:odba_instance) {
208
+ 'serialize this'
209
+ }
210
+ @odba.odba_replace_persistables
211
+ assert_equal('serialize this', @odba.serializable)
212
+ non_replaceable.mock_verify
213
+ end
214
+ def test_odba_store_unsaved
215
+ level1 = ODBAContainer.new
216
+ level2 = ODBAContainer.new
217
+ saved = ODBAContainer.new
218
+ @odba.replaceable = level1
219
+ @odba.non_replaceable = saved
220
+ level1.replaceable = level2
221
+
222
+ saved.odba_persistent = true
223
+ ODBA.cache.should_receive(:store).times(3).and_return {
224
+ assert(true)
225
+ 2
226
+ }
227
+
228
+ @odba.odba_store_unsaved
229
+ end
230
+ def test_odba_store_unsaved_hash
231
+ level1 = ODBAContainer.new
232
+ hash_element = ODBAContainer.new
233
+ hash = Hash.new
234
+ non_rep_hash = Hash.new
235
+ level1.replaceable = hash
236
+ level1.non_replaceable = non_rep_hash
237
+ non_rep_hash.odba_persistent = true
238
+
239
+ ODBA.cache.should_receive(:store).times(2).and_return {
240
+ assert(true)
241
+ 2
242
+ }
243
+
244
+ level1.odba_store_unsaved
245
+ end
246
+ def test_dup
247
+ twin = @odba.dup
248
+ assert_nil(twin.instance_variable_get('@odba_id'))
249
+ end
250
+ def test_odba_dup
251
+ stub = flexmock("stub")
252
+ stub2 = flexmock("stub2")
253
+ @odba.replaceable = stub
254
+ @odba.replaceable2 = stub2
255
+ @odba.non_replaceable = 4
256
+ stub.mock_handle(:is_a?) { true }
257
+ stub.mock_handle(:odba_dup) { stub }
258
+ stub_container = nil
259
+ stub.mock_handle(:odba_container=) { |obj|
260
+ stub_container = obj
261
+ }
262
+ stub2.mock_handle(:is_a?) { true }
263
+ stub2.mock_handle(:odba_dup) { stub2 }
264
+ stub_container2 = nil
265
+ stub2.mock_handle(:odba_container=) { |obj|
266
+ stub_container2 = obj
267
+ }
268
+ odba_twin = @odba.odba_dup
269
+ odba_twin.replaceable.mock_verify
270
+ odba_twin.replaceable2.mock_verify
271
+ assert_equal(odba_twin, stub_container)
272
+ assert_equal(odba_twin, stub_container2)
273
+ end
274
+ def test_odba_unsaved_true
275
+ @odba.instance_variable_set("@odba_persistent", false)
276
+ assert_equal(true, @odba.odba_unsaved?)
277
+ end
278
+ def test_odba_target_ids
279
+ replaceable = flexmock("rep")
280
+ replaceable2 = flexmock("rep2")
281
+ @odba.replaceable = replaceable
282
+ @odba.replaceable2 = replaceable2
283
+ replaceable.mock_handle(:is_a?) { |arg|
284
+ true # is_a?(Persistable)
285
+ }
286
+ replaceable.mock_handle(:odba_id) { 12 }
287
+ replaceable2.mock_handle(:is_a?) { |arg| false }
288
+ expected = [12]
289
+ assert_equal(expected, @odba.odba_target_ids.sort)
290
+ replaceable.mock_verify
291
+ replaceable2.mock_verify
292
+ end
293
+ def test_odba_isolated_dump
294
+ replaceable = flexmock("Replaceable")
295
+ replaceable2 = flexmock("Replaceable2")
296
+ @odba.replaceable = replaceable
297
+ @odba.replaceable2 = replaceable2
298
+ ODBA.cache.mock_handle(:next_id){ 11 }
299
+
300
+ ### from odba_dup and odba_replace_persistables
301
+ replaceable2.should_receive(:is_a?).with(Stub)\
302
+ .times(2).and_return(false)
303
+ replaceable2.should_receive(:is_a?).with(Persistable)\
304
+ .times(1).and_return(true)
305
+ replaceable2.should_receive(:odba_id).times(1).and_return(12)
306
+
307
+ ### from odba_dup
308
+ responses = [false, true]
309
+ replaceable.should_receive(:is_a?).with(Stub)\
310
+ .times(2).and_return { responses.shift }
311
+ replaceable.should_receive(:odba_clear_receiver).times(1)
312
+ replaceable.should_receive(:odba_container=).with(@odba.class).times(1)
313
+ ODBA.marshaller.mock_handle(:dump) { |twin|
314
+ assert(twin.replaceable2.is_a?(ODBA::Stub))
315
+ "TheDump"
316
+ }
317
+ result = @odba.odba_isolated_dump
318
+ assert_equal(replaceable, @odba.replaceable)
319
+ assert_equal(replaceable2, @odba.replaceable2)
320
+ assert_equal("TheDump", result)
321
+ replaceable.mock_verify
322
+ replaceable2.mock_verify
323
+ end
324
+ def test_odba_isolated_dump_2
325
+ tmp = ODBA.marshaller
326
+ ODBA.marshaller = ODBA::Marshal
327
+ odba = ODBAExcluding.new
328
+ odba.excluded = "foo"
329
+ odba.included = "baz"
330
+ ODBA.cache.mock_handle(:next_id) { 1 }
331
+ dump, hash = odba.odba_isolated_dump
332
+ obj = ODBA.marshaller.load(dump)
333
+ assert_equal(nil, obj.excluded)
334
+ assert_equal("baz", obj.included)
335
+ ODBA.marshaller = tmp
336
+ end
337
+ def test_odba_id
338
+ @odba.odba_id = nil
339
+ ODBA.cache.mock_handle(:next_id) { 1 }
340
+ assert_equal(1, @odba.odba_id)
341
+ ODBA.storage.mock_verify
342
+ end
343
+ def test_odba_dump_has_id
344
+ @odba.odba_id = nil
345
+ ODBA.cache.mock_handle(:store) { |obj|
346
+ ODBA.cache.mock_handle(:next_id) { 1 }
347
+ assert_equal(1, obj.odba_id)
348
+ }
349
+ @odba.odba_store
350
+ end
351
+ def test_odba_store_error_raised
352
+ @odba.odba_name = "foo"
353
+ #ODBA.storage.mock_handle(:transaction) { |block| block.call}
354
+ ODBA.cache.mock_handle(:store) { |dump|
355
+ raise DBI::ProgrammingError
356
+ }
357
+ assert_raises(DBI::ProgrammingError) {
358
+ @odba.odba_store('baz')
359
+ }
360
+ assert_equal("foo", @odba.odba_name)
361
+ end
362
+ def test_odba_store_no_error_raised
363
+ @odba.odba_name = "foo"
364
+ #ODBA.storage.mock_handle(:transaction) { |block| block.call}
365
+ ODBA.cache.mock_handle(:store) { |obj|
366
+ assert_equal(@odba, obj)
367
+ }
368
+ @odba.odba_store('bar')
369
+ assert_equal("bar", @odba.odba_name)
370
+ end
371
+ def test_inspect_with_stub_in_array
372
+ ODBA.cache.mock_handle(:next_id) { 12 }
373
+ ODBA.cache.mock_handle(:next_id) { 13 }
374
+ content = ODBAContainer.new
375
+ @odba.instance_variable_set('@contents', [content])
376
+ twin = @odba.odba_isolated_twin
377
+ assert_not_nil(/@contents=#<ODBA::Stub:/.match(twin.inspect))
378
+ ODBA.storage.mock_verify
379
+ end
380
+ def test_to_yaml
381
+ yaml = ''
382
+ assert_nothing_raised {
383
+ yaml = @odba.to_yaml
384
+ }
385
+ loaded = YAML.load(yaml)
386
+ assert_instance_of(ODBAContainer, loaded)
387
+ end
388
+ def test_extend
389
+ ODBA.cache.mock_handle(:store) { |obj| assert_equal('foo', obj) }
390
+ str = 'foo'
391
+ str.extend(Persistable)
392
+ assert_nothing_raised {
393
+ str.odba_store
394
+ }
395
+ ODBA.cache.mock_verify
396
+ end
397
+ def test_odba_index__simple
398
+ stub = IndexedStub.new
399
+ assert_respond_to(stub, :name)
400
+ assert_respond_to(stub, :name=)
401
+ assert_respond_to(IndexedStub, :find_by_name)
402
+ result = flexmock('Result')
403
+
404
+ ## search by one key
405
+ name = 'odba_testpersistable_indexedstub_name'
406
+ args = 'xan'
407
+ ODBA.cache.should_receive(:retrieve_from_index).with(name, args)\
408
+ .times(1).and_return([result])
409
+ assert_equal([result], IndexedStub.search_by_name('xan'))
410
+
411
+ ## exact search by one key
412
+ ODBA.cache.should_receive(:retrieve_from_index)\
413
+ .with(name, args, ODBA::Persistable::Exact)\
414
+ .times(1).and_return([result])
415
+ assert_equal([result], IndexedStub.search_by_exact_name('xan'))
416
+
417
+ ## find by one key
418
+ ODBA.cache.should_receive(:retrieve_from_index)\
419
+ .with(name, args, ODBA::Persistable::Find)\
420
+ .times(1).and_return([result])
421
+ assert_equal(result, IndexedStub.find_by_name('xan'))
422
+
423
+ ## list available keys
424
+ ODBA.cache.should_receive(:index_keys).with(name, nil)\
425
+ .times(1).and_return(['key1', 'key2'])
426
+ assert_equal(['key1', 'key2'], IndexedStub.name_keys)
427
+ ODBA.cache.should_receive(:index_keys).with(name, 2)\
428
+ .times(1).and_return(['k1', 'k2'])
429
+ assert_equal(['k1', 'k2'], IndexedStub.name_keys(2))
430
+ end
431
+ def test_odba_index__multikey
432
+ stub = IndexedStub.new
433
+ assert_respond_to(stub, :foo)
434
+ assert_respond_to(stub, :bar)
435
+ assert_respond_to(IndexedStub, :find_by_foo_and_bar)
436
+ result = flexmock('Result')
437
+
438
+ ## search by multiple keys
439
+ name = 'odba_testpersistable_indexedstub_foo_and_bar'
440
+ args = {
441
+ :foo => { 'condition' => 'like', 'value' => 'oof'},
442
+ :bar => { 'condition' => 'like', 'value' => 'rab'},
443
+ }
444
+ ODBA.cache.should_receive(:retrieve_from_index).with(name, args)\
445
+ .times(1).and_return([result])
446
+ assert_equal([result],
447
+ IndexedStub.search_by_foo_and_bar('oof', 'rab'))
448
+
449
+ ## exact search by multiple keys
450
+ args = {:foo => 'oof', :bar => 'rab'}
451
+ ODBA.cache.should_receive(:retrieve_from_index)\
452
+ .with(name, args, Persistable::Exact)\
453
+ .times(1).and_return([result])
454
+ assert_equal([result],
455
+ IndexedStub.search_by_exact_foo_and_bar('oof', 'rab'))
456
+
457
+ ## find by multiple keys
458
+ args = {:foo => {'value' => 7,'condition' => '='},
459
+ :bar => {'value' => 'rab','condition' => 'like'}}
460
+ ODBA.cache.should_receive(:retrieve_from_index)\
461
+ .with(name, args, Persistable::Find)\
462
+ .times(1).and_return([result])
463
+ assert_equal(result, IndexedStub.find_by_foo_and_bar(7, 'rab'))
464
+ end
465
+ def test_odba_index__directional
466
+ stub = IndexedStub.new
467
+ assert_respond_to(stub, :origin)
468
+ assert_respond_to(stub, :origin=)
469
+ assert_respond_to(IndexedStub, :find_by_origin)
470
+ result = flexmock('Result')
471
+
472
+ ## search by one key
473
+ name = 'odba_testpersistable_indexedstub_origin'
474
+ args = 'xan'
475
+ ODBA.cache.should_receive(:retrieve_from_index).with(name, args)\
476
+ .times(1).and_return([result])
477
+ assert_equal([result], IndexedStub.search_by_origin('xan'))
478
+
479
+ ## exact search by one key
480
+ ODBA.cache.should_receive(:retrieve_from_index)\
481
+ .with(name, args, ODBA::Persistable::Exact)\
482
+ .times(1).and_return([result])
483
+ assert_equal([result], IndexedStub.search_by_exact_origin('xan'))
484
+
485
+ ## find by one key
486
+ ODBA.cache.should_receive(:retrieve_from_index)\
487
+ .with(name, args, ODBA::Persistable::Find)\
488
+ .times(1).and_return([result])
489
+ assert_equal(result, IndexedStub.find_by_origin('xan'))
490
+
491
+ ## list available keys
492
+ ODBA.cache.should_receive(:index_keys).with(name, nil)\
493
+ .times(1).and_return(['key1', 'key2'])
494
+ assert_equal(['key1', 'key2'], IndexedStub.origin_keys)
495
+ ODBA.cache.should_receive(:index_keys).with(name, 2)\
496
+ .times(1).and_return(['k1', 'k2'])
497
+ assert_equal(['k1', 'k2'], IndexedStub.origin_keys(2))
498
+ end
499
+ def test_odba_index__redirected
500
+ stub = IndexedStub.new
501
+ assert_respond_to(stub, :redirect)
502
+ assert_respond_to(stub, :redirect=)
503
+ assert_respond_to(IndexedStub, :find_by_redirect)
504
+ result = flexmock('Result')
505
+
506
+ ## search by one key
507
+ name = 'odba_testpersistable_indexedstub_redirect'
508
+ args = 'xan'
509
+ ODBA.cache.should_receive(:retrieve_from_index).with(name, args)\
510
+ .times(1).and_return([result])
511
+ assert_equal([result], IndexedStub.search_by_redirect('xan'))
512
+
513
+ ## exact search by one key
514
+ ODBA.cache.should_receive(:retrieve_from_index)\
515
+ .with(name, args, ODBA::Persistable::Exact)\
516
+ .times(1).and_return([result])
517
+ assert_equal([result], IndexedStub.search_by_exact_redirect('xan'))
518
+
519
+ ## find by one key
520
+ ODBA.cache.should_receive(:retrieve_from_index)\
521
+ .with(name, args, ODBA::Persistable::Find)\
522
+ .times(1).and_return([result])
523
+ assert_equal(result, IndexedStub.find_by_redirect('xan'))
524
+
525
+ ## list available keys
526
+ ODBA.cache.should_receive(:index_keys).with(name, nil)\
527
+ .times(1).and_return(['key1', 'key2'])
528
+ assert_equal(['key1', 'key2'], IndexedStub.redirect_keys)
529
+ ODBA.cache.should_receive(:index_keys).with(name, 2)\
530
+ .times(1).and_return(['k1', 'k2'])
531
+ assert_equal(['k1', 'k2'], IndexedStub.redirect_keys(2))
532
+ end
533
+ def test_odba_extent
534
+ stub = IndexedStub.new
535
+ assert_respond_to(IndexedStub, :odba_extent)
536
+ ODBA.cache.mock_handle(:extent) { |klass|
537
+ assert_equal(IndexedStub, klass)
538
+ []
539
+ }
540
+ assert_equal([], IndexedStub.odba_extent)
541
+ end
542
+ def test_odba_extent__with_block
543
+ stub = IndexedStub.new
544
+ assert_respond_to(IndexedStub, :odba_extent)
545
+ ODBA.cache.mock_handle(:extent) { |klass|
546
+ assert_equal(IndexedStub, klass)
547
+ ['foo']
548
+ }
549
+ IndexedStub.odba_extent { |obj|
550
+ assert_equal('foo', obj)
551
+ }
552
+ end
553
+ def test_odba_replace__in_object
554
+ ## in rollback, replace instance_variables of modified instances with
555
+ # newly loaded unmodified ones
556
+ modified = Object.new
557
+ modified.extend(ODBA::Persistable)
558
+ modified.instance_variable_set('@data', 'foo')
559
+
560
+ reloaded = modified.dup
561
+
562
+ modified.instance_variable_set('@data', 'bar')
563
+ assert_equal('bar', modified.instance_variable_get('@data'))
564
+
565
+ modified.odba_replace!(reloaded)
566
+ assert_equal('foo', modified.instance_variable_get('@data'))
567
+ end
568
+ def test_odba_add_observer
569
+ assert_nil(@odba.instance_variable_get('@odba_observers'))
570
+ obs = flexmock('Observer')
571
+ @odba.odba_add_observer(obs)
572
+ assert_equal([obs], @odba.instance_variable_get('@odba_observers'))
573
+ end
574
+ def test_odba_delete_observer
575
+ obs = flexmock('Observer')
576
+ @odba.instance_variable_set('@odba_observers', [obs])
577
+ @odba.odba_delete_observer(obs)
578
+ assert_equal([], @odba.instance_variable_get('@odba_observers'))
579
+ end
580
+ def test_odba_delete_observers
581
+ obs = flexmock('Observer')
582
+ @odba.instance_variable_set('@odba_observers', [obs])
583
+ @odba.odba_delete_observers
584
+ assert_nil(@odba.instance_variable_get('@odba_observers'))
585
+ end
586
+ def test_odba_notify_observers
587
+ obs = flexmock('Observer')
588
+ @odba.odba_id = 14
589
+ @odba.instance_variable_set('@odba_observers', [obs])
590
+ obs.should_receive(:odba_update).with(:key, 'foo', 'bar')\
591
+ .and_return { assert(true) }
592
+ @odba.odba_notify_observers(:key, 'foo', 'bar')
593
+ end
594
+ def test_odba_dup
595
+ o = Object.new
596
+ stub = ODBA::Stub.new(15, o, nil)
597
+ o.extend(ODBA::Persistable)
598
+ o.instance_variable_set('@stub', stub)
599
+ p = o.odba_dup
600
+ assert(p.is_a?(ODBA::Persistable))
601
+ stub2 = p.instance_variable_get('@stub')
602
+ assert(stub2.is_a?(ODBA::Stub))
603
+ assert_not_equal(stub.object_id, stub2.object_id)
604
+ assert_equal(15, stub2.odba_id)
605
+ end
606
+ def test_odba_isolated_stub
607
+ @odba.odba_id = 14
608
+ stub = @odba.odba_isolated_stub
609
+ assert(stub.is_a?(ODBA::Stub))
610
+ assert(stub.is_a?(ODBAContainer))
611
+ assert_equal(14, stub.odba_id)
612
+ assert_equal(ODBAContainer, stub.class)
613
+ ODBA.cache.mock_handle(:fetch) { |id, clr|
614
+ assert_equal(14, id)
615
+ assert_equal(nil, clr)
616
+ @odba
617
+ }
618
+ assert_equal(@odba, stub.odba_instance)
619
+ end
620
+ def test_odba_collection
621
+ o = ODBAContainer.new
622
+ assert_equal([], o.odba_collection)
623
+ end
624
+ end
625
+ end