odba 1.1.9 → 1.2.0
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.
- checksums.yaml +4 -4
- data/.github/workflows/devenv.yml +30 -0
- data/.github/workflows/ruby.yml +8 -7
- data/.gitignore +11 -0
- data/{History.txt → History.md} +40 -20
- data/README.md +77 -1
- data/Rakefile +3 -15
- data/devenv.lock +171 -0
- data/devenv.nix +53 -0
- data/devenv.yaml +8 -0
- data/lib/odba/cache.rb +395 -344
- data/lib/odba/cache_entry.rb +42 -31
- data/lib/odba/connection_pool.rb +99 -72
- data/lib/odba/drbwrapper.rb +26 -18
- data/lib/odba/id_server.rb +20 -20
- data/lib/odba/index.rb +249 -215
- data/lib/odba/index_definition.rb +17 -17
- data/lib/odba/marshal.rb +15 -14
- data/lib/odba/odba.rb +40 -32
- data/lib/odba/odba_error.rb +4 -2
- data/lib/odba/persistable.rb +460 -414
- data/lib/odba/storage.rb +328 -277
- data/lib/odba/stub.rb +166 -153
- data/lib/odba/version.rb +1 -1
- data/lib/odba.rb +9 -9
- data/odba.gemspec +8 -3
- data/test/example.rb +47 -0
- data/test/helper.rb +6 -0
- data/test/suite.rb +7 -0
- data/test/test_array.rb +38 -33
- data/test/test_cache.rb +657 -622
- data/test/test_cache_entry.rb +51 -71
- data/test/test_connection_pool.rb +70 -25
- data/test/test_drbwrapper.rb +24 -19
- data/test/test_hash.rb +98 -89
- data/test/test_id_server.rb +30 -32
- data/test/test_index.rb +191 -158
- data/test/test_marshal.rb +15 -25
- data/test/test_persistable.rb +378 -369
- data/test/test_storage.rb +510 -471
- data/test/test_stub.rb +147 -135
- metadata +63 -20
- data/Guide.txt +0 -36
- data/Manifest.txt +0 -38
- data/install.rb +0 -1098
- data/lib/odba/18_19_loading_compatibility.rb +0 -77
data/test/test_cache_entry.rb
CHANGED
|
@@ -1,113 +1,93 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
# TestCacheEntry -- odba-- 29.04.2004 -- hwyss@ywesee.com mwalder@ywesee.com
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
require 'minitest/autorun'
|
|
8
|
-
require 'flexmock/test_unit'
|
|
9
|
-
require 'flexmock'
|
|
10
|
-
require 'odba/cache_entry'
|
|
11
|
-
require 'odba/odba'
|
|
12
|
-
require 'odba/persistable'
|
|
3
|
+
require_relative "helper"
|
|
4
|
+
require "odba/cache_entry"
|
|
5
|
+
require "odba/odba"
|
|
6
|
+
require "odba/persistable"
|
|
13
7
|
|
|
14
8
|
module ODBA
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
9
|
+
class CacheEntry
|
|
10
|
+
attr_accessor :accessed_by
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
class TestCacheEntry < Test::Unit::TestCase
|
|
19
14
|
include FlexMock::TestCase
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
def setup
|
|
16
|
+
@mock = flexmock
|
|
22
17
|
@mock.should_receive(:odba_add_observer)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
18
|
+
@mock.should_receive(:odba_observers).and_return { [] }
|
|
19
|
+
@mock.should_receive(:odba_id).and_return { 123 }
|
|
20
|
+
@cache_entry = ODBA::CacheEntry.new(@mock)
|
|
21
|
+
ODBA.cache = flexmock("cache")
|
|
27
22
|
ODBA.cache.should_receive(:retire_age).and_return(0.9)
|
|
28
23
|
ODBA.cache.should_receive(:destroy_age).and_return(0.9)
|
|
29
|
-
|
|
24
|
+
end
|
|
25
|
+
|
|
30
26
|
def teardown
|
|
31
27
|
super
|
|
32
28
|
end
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
obj_2.extend(Persistable)
|
|
45
|
-
obj_2.instance_variable_set('@odba_id', 34)
|
|
46
|
-
ODBA.cache.should_receive(:include?).with(34).and_return(false)
|
|
47
|
-
ODBA.cache.should_receive(:include?).with(35).and_return(false)
|
|
48
|
-
ODBA.cache.should_receive(:include?).with(36).and_return(true)
|
|
49
|
-
ODBA.cache.should_receive(:fetch).with(36).and_return(obj_1)
|
|
50
|
-
hash = {}
|
|
51
|
-
hash.instance_variable_set('@odba_id', 35)
|
|
52
|
-
hash.instance_variable_set('@odba_persistent', true)
|
|
53
|
-
@cache_entry.accessed_by = {
|
|
54
|
-
obj_1.object_id => 36,
|
|
55
|
-
obj_2.object_id => 34,
|
|
56
|
-
hash.object_id => 35,
|
|
57
|
-
}
|
|
58
|
-
@cache_entry.odba_retire
|
|
59
|
-
assert_equal({hash.object_id => 35}, @cache_entry.accessed_by)
|
|
60
|
-
end
|
|
61
|
-
def test_odba_add_reference
|
|
62
|
-
mock = flexmock
|
|
63
|
-
@cache_entry.odba_add_reference(mock)
|
|
29
|
+
|
|
30
|
+
def test_retire_check
|
|
31
|
+
@mock.should_receive(:odba_unsaved?).and_return { false }
|
|
32
|
+
@mock.should_receive(:odba_unsaved?).and_return { false }
|
|
33
|
+
assert_equal(false, @cache_entry.odba_old?(Time.now - 1))
|
|
34
|
+
assert_equal(true, @cache_entry.odba_old?(Time.now + 1))
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def test_odba_add_reference
|
|
38
|
+
mock = flexmock
|
|
39
|
+
@cache_entry.odba_add_reference(mock)
|
|
64
40
|
id = mock.object_id
|
|
65
41
|
assert_equal({id => nil}, @cache_entry.accessed_by)
|
|
66
42
|
mock2 = flexmock
|
|
67
43
|
mock2.should_receive(:odba_id).and_return(123)
|
|
68
|
-
|
|
44
|
+
@cache_entry.odba_add_reference(mock2)
|
|
69
45
|
assert_equal({mock2.object_id => 123, id => nil}, @cache_entry.accessed_by)
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def test_odba_id
|
|
49
|
+
assert_equal(123, @cache_entry.odba_id)
|
|
50
|
+
end
|
|
51
|
+
|
|
74
52
|
def test_odba_cut_connections
|
|
75
53
|
## transaction-rollback for unsaved items
|
|
76
|
-
item1 = flexmock(
|
|
77
|
-
item2 = flexmock(
|
|
54
|
+
item1 = flexmock("Item1", odba_id: 145)
|
|
55
|
+
item2 = flexmock("Item2", odba_id: 148)
|
|
78
56
|
ODBA.cache.should_receive(:include?).with(145).and_return(false)
|
|
79
57
|
ODBA.cache.should_receive(:include?).with(148).and_return(true)
|
|
80
58
|
ODBA.cache.should_receive(:fetch).with(148).and_return(item2)
|
|
81
59
|
@cache_entry.accessed_by.store(item1.object_id, 145)
|
|
82
60
|
@cache_entry.accessed_by.store(item2.object_id, 148)
|
|
83
|
-
item1.should_receive(:respond_to?).with(:odba_cut_connection)
|
|
61
|
+
item1.should_receive(:respond_to?).with(:odba_cut_connection)
|
|
84
62
|
.and_return(false)
|
|
85
|
-
item2.should_receive(:respond_to?).with(:odba_cut_connection)
|
|
63
|
+
item2.should_receive(:respond_to?).with(:odba_cut_connection)
|
|
86
64
|
.and_return(true)
|
|
87
|
-
item2.should_receive(:odba_cut_connection).with(@mock)
|
|
65
|
+
item2.should_receive(:odba_cut_connection).with(@mock)
|
|
88
66
|
.times(1).and_return { assert(true) }
|
|
89
67
|
@cache_entry.odba_cut_connections!
|
|
90
68
|
end
|
|
69
|
+
|
|
91
70
|
def test_odba_replace
|
|
92
71
|
## transaction-rollback for saved items
|
|
93
72
|
modified = Object.new
|
|
94
73
|
modified.extend(ODBA::Persistable)
|
|
95
|
-
modified.instance_variable_set(
|
|
96
|
-
modified.instance_variable_set(
|
|
74
|
+
modified.instance_variable_set(:@data, "foo")
|
|
75
|
+
modified.instance_variable_set(:@odba_id, 124)
|
|
97
76
|
cache_entry = CacheEntry.new(modified)
|
|
98
77
|
|
|
99
78
|
reloaded = modified.dup
|
|
100
79
|
|
|
101
|
-
modified.instance_variable_set(
|
|
102
|
-
assert_equal(
|
|
103
|
-
|
|
80
|
+
modified.instance_variable_set(:@data, "bar")
|
|
81
|
+
assert_equal("bar", modified.instance_variable_get(:@data))
|
|
82
|
+
|
|
104
83
|
cache_entry.odba_replace!(reloaded)
|
|
105
|
-
assert_equal(
|
|
84
|
+
assert_equal("foo", modified.instance_variable_get(:@data))
|
|
106
85
|
end
|
|
86
|
+
|
|
107
87
|
def test_odba_notify_observers
|
|
108
|
-
@mock.should_receive(:odba_notify_observers).with(:foo, 2,
|
|
88
|
+
@mock.should_receive(:odba_notify_observers).with(:foo, 2, "bar")
|
|
109
89
|
.and_return { assert(true) }
|
|
110
|
-
@cache_entry.odba_notify_observers(:foo, 2,
|
|
90
|
+
@cache_entry.odba_notify_observers(:foo, 2, "bar")
|
|
111
91
|
end
|
|
112
|
-
|
|
92
|
+
end
|
|
113
93
|
end
|
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
# TestConnectionPool -- odba -- 03.08.2005 -- hwyss@ywesee.com
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
require 'minitest/autorun'
|
|
7
|
-
require 'flexmock/test_unit'
|
|
8
|
-
require 'flexmock'
|
|
9
|
-
require 'odba/connection_pool'
|
|
3
|
+
require_relative "helper"
|
|
4
|
+
require "odba/connection_pool"
|
|
10
5
|
## connection_pool requires 'dbi', which unshifts the site_ruby dir
|
|
11
6
|
# to the first position in $LOAD_PATH ( == $: ). As a result, files are
|
|
12
7
|
# loaded from site_ruby if they are installed there, and thus ignored
|
|
@@ -14,64 +9,114 @@ require 'odba/connection_pool'
|
|
|
14
9
|
# $:.shift
|
|
15
10
|
|
|
16
11
|
module ODBA
|
|
17
|
-
class TestConnectionPool <
|
|
12
|
+
class TestConnectionPool < Test::Unit::TestCase
|
|
18
13
|
include FlexMock::TestCase
|
|
19
14
|
def test_survive_error
|
|
20
|
-
flexstub(DBI).should_receive(:connect).times(10).and_return {
|
|
15
|
+
flexstub(DBI).should_receive(:connect).times(10).and_return {
|
|
21
16
|
conn = FlexMock.new("Connection")
|
|
22
17
|
conn.should_ignore_missing
|
|
23
18
|
conn
|
|
24
19
|
}
|
|
25
|
-
pool = ConnectionPool.new
|
|
20
|
+
pool = ConnectionPool.new
|
|
26
21
|
pool.connections.each { |conn|
|
|
27
|
-
conn.should_receive(:execute).and_return {
|
|
28
|
-
raise DBI::InterfaceError.new
|
|
22
|
+
conn.should_receive(:execute).and_return {
|
|
23
|
+
raise DBI::InterfaceError.new
|
|
29
24
|
## after the first error is raised, ConnectionPool reconnects.
|
|
30
25
|
}
|
|
31
26
|
}
|
|
32
|
-
pool.execute(
|
|
27
|
+
pool.execute("statement")
|
|
33
28
|
end
|
|
29
|
+
|
|
34
30
|
def test_multiple_errors__give_up
|
|
35
|
-
flexstub(DBI).should_receive(:connect).times(20).and_return {
|
|
31
|
+
flexstub(DBI).should_receive(:connect).times(20).and_return {
|
|
36
32
|
conn = FlexMock.new("Connection")
|
|
37
|
-
conn.should_receive(:execute).and_return {
|
|
38
|
-
raise DBI::InterfaceError.new
|
|
33
|
+
conn.should_receive(:execute).and_return {
|
|
34
|
+
raise DBI::InterfaceError.new
|
|
39
35
|
}
|
|
40
36
|
conn
|
|
41
37
|
}
|
|
42
|
-
pool = ConnectionPool.new
|
|
43
|
-
assert_raises(DBI::InterfaceError) { pool.execute(
|
|
38
|
+
pool = ConnectionPool.new
|
|
39
|
+
assert_raises(DBI::InterfaceError) { pool.execute("statement") }
|
|
44
40
|
end
|
|
41
|
+
|
|
42
|
+
# ydbd-pg reports a lost connection as DBI::ProgrammingError, which used
|
|
43
|
+
# to be excluded from the retry - so a database restart broke the pool
|
|
44
|
+
# for good.
|
|
45
|
+
def test_survive_lost_connection_reported_as_programming_error
|
|
46
|
+
flexstub(DBI).should_receive(:connect).times(10).and_return {
|
|
47
|
+
conn = FlexMock.new("Connection")
|
|
48
|
+
conn.should_ignore_missing
|
|
49
|
+
conn
|
|
50
|
+
}
|
|
51
|
+
pool = ConnectionPool.new
|
|
52
|
+
pool.connections.each { |conn|
|
|
53
|
+
conn.should_receive(:execute).and_return {
|
|
54
|
+
raise DBI::ProgrammingError.new("PQsocket() can't get socket descriptor")
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
## after the first error is raised, ConnectionPool reconnects.
|
|
58
|
+
assert_nothing_raised { pool.execute("statement") }
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def test_genuine_programming_error__give_up_at_once
|
|
62
|
+
flexstub(DBI).should_receive(:connect).times(5).and_return {
|
|
63
|
+
conn = FlexMock.new("Connection")
|
|
64
|
+
conn.should_receive(:execute).and_return {
|
|
65
|
+
raise DBI::ProgrammingError.new('syntax error at or near "selct"')
|
|
66
|
+
}
|
|
67
|
+
conn
|
|
68
|
+
}
|
|
69
|
+
pool = ConnectionPool.new
|
|
70
|
+
## a broken statement must not be retried on a fresh connection
|
|
71
|
+
assert_raises(DBI::ProgrammingError) { pool.execute("selct 1") }
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def test_retryable
|
|
75
|
+
flexstub(DBI).should_receive(:connect).times(5).and_return {
|
|
76
|
+
conn = FlexMock.new("Connection")
|
|
77
|
+
conn.should_ignore_missing
|
|
78
|
+
conn
|
|
79
|
+
}
|
|
80
|
+
pool = ConnectionPool.new
|
|
81
|
+
assert(pool.retryable?(DBI::InterfaceError.new("anything")))
|
|
82
|
+
assert(pool.retryable?(NoMethodError.new("undefined method")))
|
|
83
|
+
assert(pool.retryable?(DBI::ProgrammingError.new("PQsocket() can't get socket descriptor")))
|
|
84
|
+
assert(pool.retryable?(DBI::ProgrammingError.new("no connection to the server")))
|
|
85
|
+
assert(!pool.retryable?(DBI::ProgrammingError.new("relation does not exist")))
|
|
86
|
+
end
|
|
87
|
+
|
|
45
88
|
def test_size
|
|
46
|
-
flexstub(DBI).should_receive(:connect).times(5).and_return {
|
|
89
|
+
flexstub(DBI).should_receive(:connect).times(5).and_return {
|
|
47
90
|
conn = FlexMock.new("Connection")
|
|
48
91
|
conn.should_ignore_missing
|
|
49
92
|
conn
|
|
50
93
|
}
|
|
51
|
-
pool = ConnectionPool.new
|
|
94
|
+
pool = ConnectionPool.new
|
|
52
95
|
assert_equal(5, pool.size)
|
|
53
96
|
end
|
|
97
|
+
|
|
54
98
|
def test_disconnect
|
|
55
|
-
flexstub(DBI).should_receive(:connect).times(5).and_return {
|
|
99
|
+
flexstub(DBI).should_receive(:connect).times(5).and_return {
|
|
56
100
|
conn = FlexMock.new("Connection")
|
|
57
101
|
conn.should_ignore_missing
|
|
58
102
|
conn
|
|
59
103
|
}
|
|
60
|
-
pool = ConnectionPool.new
|
|
104
|
+
pool = ConnectionPool.new
|
|
61
105
|
pool.connections.each { |conn|
|
|
62
106
|
conn.should_receive(:disconnect).and_return { assert(true) }
|
|
63
107
|
}
|
|
64
108
|
pool.disconnect
|
|
65
109
|
end
|
|
110
|
+
|
|
66
111
|
def test_disconnect_error
|
|
67
|
-
flexstub(DBI).should_receive(:connect).times(5).and_return {
|
|
112
|
+
flexstub(DBI).should_receive(:connect).times(5).and_return {
|
|
68
113
|
conn = FlexMock.new("Connection")
|
|
69
|
-
conn.should_receive(:disconnect).times(1).and_return {
|
|
114
|
+
conn.should_receive(:disconnect).times(1).and_return {
|
|
70
115
|
raise DBI::InterfaceError.new
|
|
71
116
|
}
|
|
72
117
|
conn
|
|
73
118
|
}
|
|
74
|
-
pool = ConnectionPool.new
|
|
119
|
+
pool = ConnectionPool.new
|
|
75
120
|
pool.disconnect
|
|
76
121
|
end
|
|
77
122
|
end
|
data/test/test_drbwrapper.rb
CHANGED
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
# TestDRbWrapper -- odba -- 13.06.2006 -- hwyss@ywesee.com
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
require 'minitest/autorun'
|
|
7
|
-
require 'flexmock/test_unit'
|
|
8
|
-
require 'flexmock'
|
|
9
|
-
require 'odba/drbwrapper'
|
|
3
|
+
require_relative "helper"
|
|
4
|
+
require "odba/drbwrapper"
|
|
10
5
|
|
|
11
6
|
module ODBA
|
|
12
|
-
class TestDRbWrapper <
|
|
7
|
+
class TestDRbWrapper < Test::Unit::TestCase
|
|
13
8
|
include FlexMock::TestCase
|
|
14
9
|
def test_include
|
|
15
10
|
obj = FlexMock.new
|
|
@@ -22,6 +17,7 @@ module ODBA
|
|
|
22
17
|
assert_equal(true, arr.include?(DRbWrapper.new(obj)))
|
|
23
18
|
assert_equal(false, arr.include?(DRbWrapper.new(obj2)))
|
|
24
19
|
end
|
|
20
|
+
|
|
25
21
|
def test_respond_to
|
|
26
22
|
obj = FlexMock.new
|
|
27
23
|
wrap = DRbWrapper.new(obj)
|
|
@@ -30,12 +26,13 @@ module ODBA
|
|
|
30
26
|
assert_equal(true, wrap.respond_to?(:foo))
|
|
31
27
|
assert_equal(false, wrap.respond_to?(:bar))
|
|
32
28
|
end
|
|
29
|
+
|
|
33
30
|
def test_method_missing
|
|
34
31
|
obj = FlexMock.new
|
|
35
32
|
wrap = DRbWrapper.new(obj)
|
|
36
|
-
obj.should_receive(:foo).with(:arg1, :arg2).times(1).and_return(
|
|
37
|
-
assert_equal(
|
|
38
|
-
pers = flexmock(
|
|
33
|
+
obj.should_receive(:foo).with(:arg1, :arg2).times(1).and_return("result_foo")
|
|
34
|
+
assert_equal("result_foo", wrap.foo(:arg1, :arg2))
|
|
35
|
+
pers = flexmock("Persistable")
|
|
39
36
|
pers.should_receive(:is_a?).with(Persistable).and_return(true)
|
|
40
37
|
obj.should_receive(:bar).with(:arg1).times(1).and_return([pers])
|
|
41
38
|
res = wrap.bar(:arg1)
|
|
@@ -53,50 +50,58 @@ module ODBA
|
|
|
53
50
|
}
|
|
54
51
|
end
|
|
55
52
|
end
|
|
56
|
-
|
|
53
|
+
|
|
54
|
+
class TestDRbIdConv < Test::Unit::TestCase
|
|
57
55
|
include FlexMock::TestCase
|
|
58
56
|
def setup
|
|
59
|
-
ODBA.cache = flexmock(
|
|
57
|
+
ODBA.cache = flexmock("cache")
|
|
60
58
|
@idconv = ODBA::DRbIdConv.new
|
|
61
59
|
end
|
|
60
|
+
|
|
62
61
|
def test_to_id
|
|
63
62
|
ODBA.cache.should_receive(:store)
|
|
64
63
|
o = Object.new
|
|
65
64
|
assert_equal(o.object_id, @idconv.to_id(o))
|
|
66
65
|
o.extend(ODBA::Persistable)
|
|
67
|
-
o.instance_variable_set(
|
|
66
|
+
o.instance_variable_set(:@odba_id, 4)
|
|
68
67
|
o.odba_isolated_store
|
|
69
|
-
assert_equal(
|
|
68
|
+
assert_equal("4", @idconv.to_id(o))
|
|
70
69
|
end
|
|
70
|
+
|
|
71
71
|
def test_to_id__odba_unsaved
|
|
72
72
|
o = Object.new
|
|
73
73
|
o.extend(ODBA::Persistable)
|
|
74
74
|
assert_equal(o.object_id, @idconv.to_id(o))
|
|
75
75
|
assert_equal([@idconv], o.odba_observers)
|
|
76
76
|
end
|
|
77
|
+
|
|
77
78
|
def test_to_obj
|
|
78
79
|
ODBA.cache.should_receive(:store)
|
|
79
80
|
o = Object.new
|
|
80
81
|
assert_equal(o, @idconv.to_obj(o.object_id))
|
|
81
82
|
o.extend(ODBA::Persistable)
|
|
82
|
-
o.instance_variable_set(
|
|
83
|
+
o.instance_variable_set(:@odba_id, 4)
|
|
83
84
|
o.odba_isolated_store
|
|
84
85
|
ODBA.cache.should_receive(:fetch).with(4).times(1)
|
|
85
|
-
@idconv.to_obj(
|
|
86
|
+
@idconv.to_obj("4")
|
|
86
87
|
end
|
|
88
|
+
|
|
87
89
|
def test_to_obj__error
|
|
88
|
-
ODBA.cache.should_receive(:fetch).with(4).times(1).and_return {
|
|
90
|
+
ODBA.cache.should_receive(:fetch).with(4).times(1).and_return {
|
|
89
91
|
raise "some error"
|
|
90
92
|
}
|
|
91
|
-
assert_raises(RangeError) { @idconv.to_obj(
|
|
93
|
+
assert_raises(RangeError) { @idconv.to_obj("4") }
|
|
92
94
|
end
|
|
95
|
+
|
|
93
96
|
def test_odba_update
|
|
94
97
|
id = Object.new.object_id
|
|
95
98
|
@idconv.odba_update(:store, 4, id)
|
|
96
99
|
ODBA.cache.should_receive(:fetch).with(4).times(1)
|
|
97
100
|
@idconv.to_obj(id)
|
|
98
101
|
@idconv.odba_update(:clean, 4, id)
|
|
102
|
+
return if RUBY_VERSION.to_f >= 3.3
|
|
99
103
|
GC.start
|
|
104
|
+
assert_raises { @idconv.to_obj(id) }
|
|
100
105
|
assert_raises(RangeError) { @idconv.to_obj(id) }
|
|
101
106
|
end
|
|
102
107
|
end
|
data/test/test_hash.rb
CHANGED
|
@@ -1,112 +1,119 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
# TestHash -- odba -- ??.??.???? -- hwyss@ywesee.com
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
require 'minitest/autorun'
|
|
8
|
-
require 'flexmock/test_unit'
|
|
9
|
-
require 'flexmock'
|
|
10
|
-
require 'odba/persistable'
|
|
11
|
-
require 'odba/stub'
|
|
12
|
-
require 'odba/odba'
|
|
3
|
+
require_relative "helper"
|
|
4
|
+
require "odba/persistable"
|
|
5
|
+
require "odba/stub"
|
|
6
|
+
require "odba/odba"
|
|
13
7
|
|
|
14
8
|
module ODBA
|
|
15
|
-
|
|
9
|
+
class TestHash < Test::Unit::TestCase
|
|
16
10
|
include FlexMock::TestCase
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
11
|
+
class ODBAContainerInHash
|
|
12
|
+
include Persistable
|
|
13
|
+
attr_accessor :non_replaceable, :replaceable, :odba_id
|
|
14
|
+
end
|
|
15
|
+
|
|
21
16
|
class Container
|
|
22
17
|
attr_accessor :content
|
|
23
18
|
end
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
19
|
+
|
|
20
|
+
class TestStub
|
|
21
|
+
attr_accessor :receiver, :odba_replace
|
|
22
|
+
def is_a?(arg)
|
|
23
|
+
true
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def setup
|
|
28
|
+
@hash = {}
|
|
29
|
+
ODBA.cache = flexmock("cache")
|
|
30
|
+
ODBA.storage = flexmock("storage")
|
|
31
|
+
@hash.clear
|
|
32
|
+
end
|
|
33
|
+
|
|
36
34
|
def teardown
|
|
37
35
|
super
|
|
38
36
|
end
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
37
|
+
|
|
38
|
+
def test_odba_unsaved_neighbors_hash
|
|
39
|
+
repkey1 = ODBAContainerInHash.new
|
|
40
|
+
repkey2 = ODBAContainerInHash.new
|
|
41
|
+
repvalue1 = ODBAContainerInHash.new
|
|
42
|
+
repvalue2 = ODBAContainerInHash.new
|
|
43
|
+
@hash.store(repkey1, repvalue1)
|
|
44
|
+
@hash.store(repkey2, repvalue2)
|
|
45
|
+
result = @hash.odba_unsaved_neighbors(1)
|
|
46
|
+
assert_equal(true, result.include?(repkey1))
|
|
47
|
+
assert_equal(true, result.include?(repkey2))
|
|
48
|
+
assert_equal(true, result.include?(repvalue1))
|
|
49
|
+
assert_equal(true, result.include?(repvalue2))
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def test_odba_replace_persistables_hash
|
|
53
|
+
key1 = flexmock("key")
|
|
54
|
+
value1 = flexmock("value")
|
|
55
|
+
@hash.store(key1, value1)
|
|
56
|
+
@hash.odba_replace_persistables
|
|
57
|
+
assert_equal(@hash, {})
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def test_odba_prefetch
|
|
61
|
+
key1 = flexmock("key")
|
|
62
|
+
val1 = flexmock("val1")
|
|
63
|
+
@hash.store(key1, val1)
|
|
64
|
+
assert_equal(false, @hash.odba_prefetch?)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def test_odba_unsaved_true
|
|
68
|
+
key = flexmock("key")
|
|
69
|
+
val = flexmock("val")
|
|
70
|
+
@hash.instance_variable_set(:@odba_persistent, true)
|
|
71
|
+
@hash.store(key, val)
|
|
72
|
+
val.should_receive(:is_a?).and_return { |klass| true }
|
|
73
|
+
val.should_receive(:odba_unsaved?).and_return { true }
|
|
74
|
+
|
|
75
|
+
assert_equal(true, @hash.odba_unsaved?)
|
|
76
|
+
end
|
|
77
|
+
|
|
75
78
|
def test_odba_cut_connection
|
|
76
79
|
remove_obj = Object.new
|
|
77
80
|
remove_obj.extend(ODBA::Persistable)
|
|
78
|
-
remove_obj.instance_variable_set(
|
|
81
|
+
remove_obj.instance_variable_set(:@odba_id, 2)
|
|
79
82
|
other = Object.new
|
|
80
83
|
other.extend(ODBA::Persistable)
|
|
81
|
-
other.instance_variable_set(
|
|
84
|
+
other.instance_variable_set(:@odba_id, 3)
|
|
82
85
|
receiver = ODBA::Stub.new(2, nil, remove_obj)
|
|
83
|
-
ODBA.cache.should_receive(:fetch).with(2,nil).and_return(remove_obj)
|
|
84
|
-
@hash.store(
|
|
85
|
-
@hash.store(receiver,
|
|
86
|
-
@hash.store(
|
|
87
|
-
@hash.store(other,
|
|
86
|
+
ODBA.cache.should_receive(:fetch).with(2, nil).and_return(remove_obj)
|
|
87
|
+
@hash.store("foo", receiver)
|
|
88
|
+
@hash.store(receiver, "bar")
|
|
89
|
+
@hash.store("bar", other)
|
|
90
|
+
@hash.store(other, "baz")
|
|
88
91
|
@hash.odba_cut_connection(remove_obj)
|
|
89
|
-
assert_equal({
|
|
92
|
+
assert_equal({"bar" => other, other => "baz"}, @hash)
|
|
90
93
|
end
|
|
94
|
+
|
|
91
95
|
def test_odba_collection
|
|
92
|
-
@hash.update(
|
|
93
|
-
assert_equal([[
|
|
94
|
-
|
|
96
|
+
@hash.update("foo" => "bar", "trouble" => "not")
|
|
97
|
+
assert_equal([["foo", "bar"], ["trouble", "not"]],
|
|
98
|
+
@hash.odba_collection.sort)
|
|
95
99
|
end
|
|
100
|
+
|
|
96
101
|
def test_odba_replace
|
|
97
|
-
modified = {
|
|
102
|
+
modified = {"foo" => "bar"}
|
|
98
103
|
reloaded = modified.dup
|
|
99
|
-
modified.update(
|
|
104
|
+
modified.update("foo" => "baz", "han" => "solo")
|
|
100
105
|
|
|
101
106
|
modified.odba_replace!(reloaded)
|
|
102
107
|
|
|
103
108
|
assert_equal(reloaded, modified)
|
|
104
109
|
end
|
|
110
|
+
|
|
105
111
|
def test_odba_restore
|
|
106
|
-
collection = [[:foo,
|
|
112
|
+
collection = [[:foo, "bar"], [:trouble, "not"]]
|
|
107
113
|
@hash.odba_restore(collection)
|
|
108
|
-
assert_equal({:
|
|
114
|
+
assert_equal({foo: "bar", trouble: "not"}, @hash)
|
|
109
115
|
end
|
|
116
|
+
|
|
110
117
|
def test_odba_target_ids
|
|
111
118
|
o = ODBAContainerInHash.new
|
|
112
119
|
o.odba_id = 1
|
|
@@ -114,13 +121,14 @@ module ODBA
|
|
|
114
121
|
p.odba_id = 2
|
|
115
122
|
q = ODBAContainerInHash.new
|
|
116
123
|
q.odba_id = 3
|
|
117
|
-
@hash.store(
|
|
118
|
-
@hash.store(p,
|
|
119
|
-
@hash.store(
|
|
120
|
-
@hash.store(q,
|
|
121
|
-
@hash.instance_variable_set(
|
|
122
|
-
assert_equal([1,2,3], @hash.odba_target_ids.sort)
|
|
124
|
+
@hash.store("foo", p)
|
|
125
|
+
@hash.store(p, "bar")
|
|
126
|
+
@hash.store("bar", q)
|
|
127
|
+
@hash.store(q, "baz")
|
|
128
|
+
@hash.instance_variable_set(:@var, o)
|
|
129
|
+
assert_equal([1, 2, 3], @hash.odba_target_ids.sort)
|
|
123
130
|
end
|
|
131
|
+
|
|
124
132
|
def test_odba_stubize
|
|
125
133
|
obj = Object.new
|
|
126
134
|
obj.extend(ODBA::Persistable)
|
|
@@ -129,20 +137,21 @@ module ODBA
|
|
|
129
137
|
assert_equal(11, obj.odba_id)
|
|
130
138
|
hash = {1 => obj}
|
|
131
139
|
assert_equal(12, hash.odba_id)
|
|
132
|
-
assert_equal(true, hash.odba_stubize(obj, :
|
|
140
|
+
assert_equal(true, hash.odba_stubize(obj, force: true))
|
|
133
141
|
assert_equal([1], hash.keys)
|
|
134
142
|
assert_equal false, hash.values.first.is_a?(ODBA::Stub)
|
|
135
143
|
end
|
|
144
|
+
|
|
136
145
|
def test_odba_stubize__key
|
|
137
146
|
obj = Object.new
|
|
138
147
|
obj.extend(ODBA::Persistable)
|
|
139
148
|
id = 10
|
|
140
149
|
ODBA.cache.should_receive(:next_id).times(2).and_return { id += 1 }
|
|
141
150
|
assert_equal(11, obj.odba_id)
|
|
142
|
-
hash = {obj =>
|
|
151
|
+
hash = {obj => "foo"}
|
|
143
152
|
assert_equal(12, hash.odba_id)
|
|
144
|
-
assert_equal(true, hash.odba_stubize(obj, :
|
|
145
|
-
assert_equal({obj =>
|
|
153
|
+
assert_equal(true, hash.odba_stubize(obj, force: true))
|
|
154
|
+
assert_equal({obj => "foo"}, hash)
|
|
146
155
|
end
|
|
147
|
-
|
|
156
|
+
end
|
|
148
157
|
end
|