ObjectModel 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +849 -0
- data/lib/ObjectModel.res/config.yaml +5 -0
- data/lib/ObjectModel/AnEntity/BackReferences.rb +113 -0
- data/lib/ObjectModel/AnEntity/Bag.rb +129 -0
- data/lib/ObjectModel/AnEntity/BagCopy.rb +29 -0
- data/lib/ObjectModel/AnEntity/ChildrenBag.rb +10 -0
- data/lib/ObjectModel/AnEntity/EntityCopy.rb +38 -0
- data/lib/ObjectModel/AnEntity/EntityType.rb +408 -0
- data/lib/ObjectModel/AnEntity/ReferencesBag.rb +10 -0
- data/lib/ObjectModel/AnEntity/entity_cm.rb +108 -0
- data/lib/ObjectModel/Entity.rb +278 -0
- data/lib/ObjectModel/Errors/LoadError.rb +3 -0
- data/lib/ObjectModel/Errors/NoTransactionError.rb +3 -0
- data/lib/ObjectModel/Errors/NotFoundError.rb +2 -0
- data/lib/ObjectModel/Errors/OutdatedError.rb +8 -0
- data/lib/ObjectModel/Errors/ValidationError.rb +3 -0
- data/lib/ObjectModel/Indexes/HashIndex.rb +64 -0
- data/lib/ObjectModel/Indexes/IndexStorage.rb +64 -0
- data/lib/ObjectModel/Indexes/Manager.rb +72 -0
- data/lib/ObjectModel/Metadata.rb +34 -0
- data/lib/ObjectModel/Metadata.res/after_event_types.rb +25 -0
- data/lib/ObjectModel/Metadata.res/attribute_types_shortcuts.rb +10 -0
- data/lib/ObjectModel/Metadata.res/before_event_types.rb +25 -0
- data/lib/ObjectModel/Metadata.res/child_types_shortcuts.rb +4 -0
- data/lib/ObjectModel/Metadata.res/metadata_checks.rb +9 -0
- data/lib/ObjectModel/Metadata.res/reference_types_shortcuts.rb +4 -0
- data/lib/ObjectModel/Metadata/DSL.rb +11 -0
- data/lib/ObjectModel/Metadata/attribute.rb +56 -0
- data/lib/ObjectModel/Metadata/child.rb +50 -0
- data/lib/ObjectModel/Metadata/events.rb +109 -0
- data/lib/ObjectModel/Metadata/name.rb +20 -0
- data/lib/ObjectModel/Metadata/reference.rb +50 -0
- data/lib/ObjectModel/Metadata/require.rb +10 -0
- data/lib/ObjectModel/Metadata/validate.rb +66 -0
- data/lib/ObjectModel/Repository.rb +326 -0
- data/lib/ObjectModel/Repository/EventProcessor.rb +58 -0
- data/lib/ObjectModel/Repository/ObjectStorage.rb +102 -0
- data/lib/ObjectModel/Repository/StreamID.rb +20 -0
- data/lib/ObjectModel/Repository/StreamStorage.rb +121 -0
- data/lib/ObjectModel/Repository/SystemListener.rb +143 -0
- data/lib/ObjectModel/Repository/Transaction.rb +63 -0
- data/lib/ObjectModel/Repository/TransactionProcessor.rb +36 -0
- data/lib/ObjectModel/Tools/DefaultTransactionStrategy.rb +9 -0
- data/lib/ObjectModel/Tools/InMemoryCache.rb +9 -0
- data/lib/ObjectModel/Tools/NoCache.rb +18 -0
- data/lib/ObjectModel/Tools/OGLRUCache.rb +37 -0
- data/lib/ObjectModel/Types/BagType.rb +94 -0
- data/lib/ObjectModel/Types/BooleanType.rb +42 -0
- data/lib/ObjectModel/Types/ClassType.rb +43 -0
- data/lib/ObjectModel/Types/DataType.rb +44 -0
- data/lib/ObjectModel/Types/DateType.rb +43 -0
- data/lib/ObjectModel/Types/NumberType.rb +62 -0
- data/lib/ObjectModel/Types/ObjectType.rb +164 -0
- data/lib/ObjectModel/Types/ProcType.rb +43 -0
- data/lib/ObjectModel/Types/SingleType.rb +59 -0
- data/lib/ObjectModel/Types/StringType.rb +39 -0
- data/lib/ObjectModel/_require.rb +43 -0
- data/lib/ObjectModel/require.rb +1 -0
- data/rakefile +62 -0
- data/spec/ObjectModel/BasicSpec/BaseClass.rb +7 -0
- data/spec/ObjectModel/BasicSpec/BaseTypes.rb +11 -0
- data/spec/ObjectModel/BasicSpec/Descendant.rb +5 -0
- data/spec/ObjectModel/BasicSpec/EachTest.rb +14 -0
- data/spec/ObjectModel/BasicSpec/UpChild.rb +10 -0
- data/spec/ObjectModel/BasicSpec/UpParent.rb +11 -0
- data/spec/ObjectModel/ErrorsSpec/AfterCommitError.rb +9 -0
- data/spec/ObjectModel/ExtendedSpec/CustomInitialization.rb +11 -0
- data/spec/ObjectModel/ExtendedSpec/UpNotNil.rb +8 -0
- data/spec/ObjectModel/ExtendedSpec/UpParent.rb +11 -0
- data/spec/ObjectModel/ValidationSpec/BaseTypes.rb +11 -0
- data/spec/aspect_spec.rb +55 -0
- data/spec/back_references_spec.rb +161 -0
- data/spec/basic_spec.rb +162 -0
- data/spec/cascade_delete_spec.rb +168 -0
- data/spec/complex_events_spec.rb +134 -0
- data/spec/concurrency_spec.rb +186 -0
- data/spec/containment_spec.rb +146 -0
- data/spec/data_migration_spec.rb +51 -0
- data/spec/errors_spec.rb +65 -0
- data/spec/events_spec.rb +173 -0
- data/spec/extended_spec.rb +171 -0
- data/spec/indexing_spec.rb +56 -0
- data/spec/set_in_memory.rb +2 -0
- data/spec/set_no_cache.rb +2 -0
- data/spec/smoke_test_spec.rb +85 -0
- data/spec/stream_spec.rb +143 -0
- data/spec/stream_storage.rb +148 -0
- data/spec/timer.rb +5 -0
- data/spec/validation_spec.rb +87 -0
- metadata +186 -0
@@ -0,0 +1,146 @@
|
|
1
|
+
require 'ObjectModel/require'
|
2
|
+
require 'spec'
|
3
|
+
|
4
|
+
module ObjectModel
|
5
|
+
module ContainmentSpec
|
6
|
+
describe "Containment" do
|
7
|
+
before :each do
|
8
|
+
CONFIG[:directory] = "#{File.dirname __FILE__}/data"
|
9
|
+
Repository.delete :test
|
10
|
+
@r = Repository.new :test
|
11
|
+
end
|
12
|
+
|
13
|
+
after :each do
|
14
|
+
@r.close
|
15
|
+
Repository.delete :test
|
16
|
+
end
|
17
|
+
|
18
|
+
class SimpleEntity
|
19
|
+
inherit Entity
|
20
|
+
|
21
|
+
metadata do
|
22
|
+
attribute :label, :string
|
23
|
+
child :child
|
24
|
+
child :children, :bag
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it "Access by Path" do
|
29
|
+
@r.transaction{
|
30
|
+
p = SimpleEntity.new('p').set :label => 'Parent'
|
31
|
+
c1 = SimpleEntity.new('c1').set :label => 'Child1'
|
32
|
+
c2 = SimpleEntity.new('c2').set :label => 'Child2'
|
33
|
+
p.child = c1
|
34
|
+
p.children << c2
|
35
|
+
}.commit
|
36
|
+
|
37
|
+
@r.should include('p/c1')
|
38
|
+
@r.should include('p/c2')
|
39
|
+
@r['p/c1'].label.should == "Child1"
|
40
|
+
@r['p/c2'].label.should == "Child2"
|
41
|
+
end
|
42
|
+
|
43
|
+
it "Change name" do
|
44
|
+
@r.transaction{
|
45
|
+
p = SimpleEntity.new 'e', 'id1'
|
46
|
+
p.name = 'e2'
|
47
|
+
}.commit
|
48
|
+
@r.should_not include('e')
|
49
|
+
@r.should include('e2')
|
50
|
+
|
51
|
+
tr = @r.transaction{
|
52
|
+
e = @r['e2']
|
53
|
+
e.name = 'e3'
|
54
|
+
e.name.should == 'e3'
|
55
|
+
}
|
56
|
+
@r.should include('e2')
|
57
|
+
|
58
|
+
tr.commit
|
59
|
+
@r.should_not include('e2')
|
60
|
+
@r.should include('e3')
|
61
|
+
end
|
62
|
+
|
63
|
+
it "Check duplicate name beneath Children" do
|
64
|
+
@r.transaction{
|
65
|
+
p = SimpleEntity.new 'p'
|
66
|
+
lambda{
|
67
|
+
SimpleEntity.new 'p'
|
68
|
+
}.should raise_error(/Not unique/)
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
it "Check duplicate name when moving from Root Space to Children" do
|
73
|
+
@r.transaction{
|
74
|
+
p = SimpleEntity.new 'p'
|
75
|
+
c = SimpleEntity.new 'c'
|
76
|
+
p.child = c
|
77
|
+
|
78
|
+
c2 = SimpleEntity.new 'c'
|
79
|
+
lambda{
|
80
|
+
p.children << c2
|
81
|
+
}.should raise_error(/Not unique/)
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
85
|
+
it "Check duplicate name between Existing Entity and New One" do
|
86
|
+
@r.transaction{
|
87
|
+
SimpleEntity.new 'p'
|
88
|
+
}.commit
|
89
|
+
@r.transaction{
|
90
|
+
lambda{
|
91
|
+
SimpleEntity.new 'p'
|
92
|
+
}.should raise_error(/Not unique/)
|
93
|
+
}
|
94
|
+
end
|
95
|
+
|
96
|
+
it "Check duplicate name when moving Entity to Root space" do
|
97
|
+
@r.transaction{
|
98
|
+
p = SimpleEntity.new 'p'
|
99
|
+
p.child = c = SimpleEntity.new
|
100
|
+
p.child.name = 'p'
|
101
|
+
lambda{
|
102
|
+
p.child = nil
|
103
|
+
p c.parent
|
104
|
+
}.should raise_error(/Not unique/)
|
105
|
+
}.commit
|
106
|
+
end
|
107
|
+
|
108
|
+
it "Check duplicate name when moving Entity to Another Entity" do
|
109
|
+
@r.transaction{
|
110
|
+
p1 = SimpleEntity.new 'p1', 'id1'
|
111
|
+
p2 = SimpleEntity.new 'p2'
|
112
|
+
c1 = SimpleEntity.new 'c1'
|
113
|
+
c2 = SimpleEntity.new 'c2'
|
114
|
+
p1.child = c1
|
115
|
+
p2.child = c2
|
116
|
+
|
117
|
+
c2.name = 'c1'
|
118
|
+
lambda{
|
119
|
+
p1.children << c2
|
120
|
+
}.should raise_error(/Not unique/)
|
121
|
+
}.commit
|
122
|
+
end
|
123
|
+
|
124
|
+
it "Entity methods: [], include_child?" do
|
125
|
+
@r.transaction{
|
126
|
+
p = SimpleEntity.new 'p'
|
127
|
+
c = SimpleEntity.new('c').set :label => "child"
|
128
|
+
p.child = c
|
129
|
+
}.commit
|
130
|
+
@r['p'].should include('c')
|
131
|
+
@r['p']['c'].label.should == "child"
|
132
|
+
lambda{@r['p']['invalid']}.should raise_error(NotFoundError)
|
133
|
+
end
|
134
|
+
|
135
|
+
it "path" do
|
136
|
+
@r.transaction{
|
137
|
+
p = SimpleEntity.new 'p'
|
138
|
+
c = SimpleEntity.new('c').set :label => "child"
|
139
|
+
p.child = c
|
140
|
+
}.commit
|
141
|
+
@r['p'].path.should == 'p'
|
142
|
+
@r['p/c'].path.should == 'p/c'
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'ObjectModel/require'
|
2
|
+
require 'spec'
|
3
|
+
|
4
|
+
module ObjectModel
|
5
|
+
module DataMigrationSpec
|
6
|
+
describe "Data Migration" do
|
7
|
+
it "when loading outdated attribute instead of :default check_for :initialize" do
|
8
|
+
class InitEntity
|
9
|
+
inherit Entity
|
10
|
+
|
11
|
+
metadata do
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
@r.transaction{InitEntity.new "ie"}.commit
|
16
|
+
|
17
|
+
class InitEntity
|
18
|
+
inherit Entity
|
19
|
+
|
20
|
+
metadata do
|
21
|
+
attribute :value, :object, :initialize => "custom value"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
@r.transaction{
|
26
|
+
@r["ie"].value.should == "custom value"
|
27
|
+
}.commit
|
28
|
+
end
|
29
|
+
|
30
|
+
before :all do
|
31
|
+
@restore = ObjectModel::CONFIG[:cache]
|
32
|
+
ObjectModel::CONFIG[:cache] = "ObjectModel::Tools::NoCache"
|
33
|
+
end
|
34
|
+
|
35
|
+
after :all do
|
36
|
+
ObjectModel::CONFIG[:cache] = @restore
|
37
|
+
end
|
38
|
+
|
39
|
+
before :each do
|
40
|
+
CONFIG[:directory] = "#{File.dirname __FILE__}/data"
|
41
|
+
Repository.delete :test
|
42
|
+
@r = Repository.new :test
|
43
|
+
end
|
44
|
+
|
45
|
+
after :each do
|
46
|
+
@r.close
|
47
|
+
Repository.delete :test
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/spec/errors_spec.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'ObjectModel/require'
|
2
|
+
require 'spec'
|
3
|
+
|
4
|
+
module ObjectModel
|
5
|
+
module ErrorsSpec
|
6
|
+
describe "ErrorsSpec" do
|
7
|
+
before :each do
|
8
|
+
CONFIG[:directory] = "#{File.dirname __FILE__}/data"
|
9
|
+
Repository.delete :test
|
10
|
+
@r = Repository.new :test
|
11
|
+
end
|
12
|
+
|
13
|
+
after :each do
|
14
|
+
@r.close
|
15
|
+
Repository.delete :test
|
16
|
+
end
|
17
|
+
|
18
|
+
class SimpleEntity
|
19
|
+
inherit Entity
|
20
|
+
|
21
|
+
metadata do
|
22
|
+
attribute :label, :string
|
23
|
+
attribute :value, :object
|
24
|
+
child :child
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it "Shouldn't raise UniqueEntityID when saving Entity" do
|
29
|
+
@r.transaction{SimpleEntity.new("e")}.commit
|
30
|
+
@r.transaction{@r["e"].name = "e"}.commit # <= Error was here
|
31
|
+
end
|
32
|
+
|
33
|
+
it "Instead of UniqueOMID error raises some strange error" do
|
34
|
+
@r.transaction{SimpleEntity.new("e", "e")}.commit
|
35
|
+
lambda{
|
36
|
+
@r.transaction{SimpleEntity.new("e", "e")}.commit
|
37
|
+
}.should raise_error(/Not Unique :entity_id/)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "Should fill name before :after_commit (from error)" do
|
41
|
+
@r.transaction{AfterCommitError.new("name")}.commit
|
42
|
+
# e = @r["name"]
|
43
|
+
# p e
|
44
|
+
end
|
45
|
+
|
46
|
+
it "Changing name doesn't affects cache" do
|
47
|
+
restore = ObjectModel::CONFIG[:cache]
|
48
|
+
ObjectModel::CONFIG[:cache] = "ObjectModel::Tools::InMemoryCache"
|
49
|
+
Repository.delete :test2
|
50
|
+
r = Repository.new :test2
|
51
|
+
begin
|
52
|
+
|
53
|
+
r.transaction{SimpleEntity.new("e")}.commit
|
54
|
+
r.transaction{r["e"].name = "e2"}.commit
|
55
|
+
r["e2"].name.should == "e2"
|
56
|
+
|
57
|
+
ensure
|
58
|
+
ObjectModel::CONFIG[:cache] = restore
|
59
|
+
r.close
|
60
|
+
Repository.delete :test2
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/spec/events_spec.rb
ADDED
@@ -0,0 +1,173 @@
|
|
1
|
+
require 'ObjectModel/require'
|
2
|
+
require 'spec'
|
3
|
+
|
4
|
+
module ObjectModel
|
5
|
+
module EventsSpec
|
6
|
+
describe "Events" do
|
7
|
+
class MockListener
|
8
|
+
attr_reader :events, :arguments
|
9
|
+
def initialize
|
10
|
+
@events, @arguments = [], []
|
11
|
+
end
|
12
|
+
|
13
|
+
def method_missing m, *p, &b
|
14
|
+
@events << m
|
15
|
+
@arguments << p
|
16
|
+
end
|
17
|
+
|
18
|
+
def respond_to? symbol
|
19
|
+
true
|
20
|
+
end
|
21
|
+
|
22
|
+
def clear
|
23
|
+
@events.clear
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
before :each do
|
28
|
+
ObjectModel::CONFIG[:directory] = "#{File.dirname __FILE__}/data"
|
29
|
+
|
30
|
+
Repository.delete :test
|
31
|
+
@r = Repository.new :test
|
32
|
+
@l = MockListener.new
|
33
|
+
@r.entity_listeners << @l
|
34
|
+
end
|
35
|
+
|
36
|
+
after :each do
|
37
|
+
@r.close
|
38
|
+
Repository.delete :test
|
39
|
+
end
|
40
|
+
|
41
|
+
class EventEntity
|
42
|
+
inherit Entity
|
43
|
+
metadata do
|
44
|
+
attribute :attribute, :string
|
45
|
+
reference :reference
|
46
|
+
child :child
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
it "attribute_update" do
|
51
|
+
@r.transaction{EventEntity.new 'e'}.commit
|
52
|
+
@l.clear
|
53
|
+
tr = @r.transaction{@r['e'].attribute = "string"}.commit
|
54
|
+
@l.events.should == [
|
55
|
+
:before_attribute_update, :after_attribute_update,
|
56
|
+
:before_commit, :after_commit
|
57
|
+
]
|
58
|
+
tr.copies.values[0].updated?.should be_true
|
59
|
+
end
|
60
|
+
|
61
|
+
it "new_reference, delete_reference and new_referrer, delete_referrer" do
|
62
|
+
@r.transaction{EventEntity.new 'e'}.commit
|
63
|
+
@l.clear
|
64
|
+
@r.transaction{@r['e'].reference = @r['e']}.commit
|
65
|
+
@l.events.should == [
|
66
|
+
:before_new_reference,
|
67
|
+
:before_new_referrer, :after_new_referrer,
|
68
|
+
:after_new_reference,
|
69
|
+
:before_commit, :after_commit
|
70
|
+
]
|
71
|
+
|
72
|
+
@l.clear
|
73
|
+
tr = @r.transaction{@r['e'].reference = nil}.commit
|
74
|
+
@l.events.should == [
|
75
|
+
:before_delete_reference,
|
76
|
+
:before_delete_referrer, :after_delete_referrer,
|
77
|
+
:after_delete_reference,
|
78
|
+
:before_commit, :after_commit
|
79
|
+
]
|
80
|
+
tr.copies.values[0].updated?.should be_true
|
81
|
+
end
|
82
|
+
|
83
|
+
it "new_child, delete_child and new_parent, delete_parent" do
|
84
|
+
@r.transaction{EventEntity.new 'e'; EventEntity.new 'child'}.commit
|
85
|
+
@l.clear
|
86
|
+
@r.transaction{@r['e'].child = @r['child']}.commit
|
87
|
+
@l.events.should == [
|
88
|
+
:before_new_child,
|
89
|
+
:before_new_parent, :after_new_parent,
|
90
|
+
:after_new_child,
|
91
|
+
:before_commit, :after_commit
|
92
|
+
]
|
93
|
+
|
94
|
+
@l.clear
|
95
|
+
tr = @r.transaction{@r['e'].child = nil}.commit
|
96
|
+
@l.events.should == [:before_delete_child,
|
97
|
+
:before_delete_parent, :after_delete_parent,
|
98
|
+
:after_delete_child,
|
99
|
+
:before_commit, :after_commit
|
100
|
+
]
|
101
|
+
|
102
|
+
updated = 0
|
103
|
+
tr.copies.size.should == 2
|
104
|
+
tr.copies.values.each do |copy|
|
105
|
+
updated += 1 if copy.updated?
|
106
|
+
end
|
107
|
+
updated.should == 2
|
108
|
+
end
|
109
|
+
|
110
|
+
it "new, delete" do
|
111
|
+
@l.clear
|
112
|
+
tr = @r.transaction{EventEntity.new 'e'}.commit
|
113
|
+
@l.events.should == [:before_new, :before_name_update, :after_name_update, :after_new, :before_commit, :after_commit]
|
114
|
+
tr.copies.values[0].new?.should be_true
|
115
|
+
|
116
|
+
@l.clear
|
117
|
+
@r.transaction{@r['e'].delete}.commit
|
118
|
+
@l.events.should == [:before_delete, :after_delete, :before_commit, :after_commit]
|
119
|
+
end
|
120
|
+
|
121
|
+
it "move" do
|
122
|
+
@r.transaction{
|
123
|
+
p1 = EventEntity.new 'p1'
|
124
|
+
EventEntity.new 'p2'
|
125
|
+
p1.child = EventEntity.new 'child'
|
126
|
+
}.commit
|
127
|
+
|
128
|
+
@l.clear
|
129
|
+
tr = @r.transaction{@r['p2'].child = @r['p1/child']}.commit
|
130
|
+
@l.events.should == [
|
131
|
+
:before_new_child,
|
132
|
+
:before_delete_child,
|
133
|
+
:before_delete_parent, :after_delete_parent,
|
134
|
+
:after_delete_child,
|
135
|
+
:before_move,
|
136
|
+
:before_new_parent, :after_new_parent,
|
137
|
+
:after_move,
|
138
|
+
:after_new_child,
|
139
|
+
:before_commit, :after_commit]
|
140
|
+
|
141
|
+
updated, moved = 0, 0
|
142
|
+
tr.copies.size.should == 3
|
143
|
+
tr.copies.values.each do |copy|
|
144
|
+
updated += 1 if copy.updated?
|
145
|
+
moved += 1 if copy.moved?
|
146
|
+
end
|
147
|
+
[updated, moved].should == [3, 1]
|
148
|
+
end
|
149
|
+
|
150
|
+
class OnEntity
|
151
|
+
inherit Entity
|
152
|
+
metadata do
|
153
|
+
attribute :before, :string
|
154
|
+
attribute :after, :string
|
155
|
+
|
156
|
+
before :new do
|
157
|
+
self.before += "before new"
|
158
|
+
end
|
159
|
+
|
160
|
+
after :new do
|
161
|
+
self.after += "after new"
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
it "Changes made to Entity during Events should be Commited." do
|
167
|
+
@r.transaction{OnEntity.new 'e'}.commit
|
168
|
+
@r['e'].before.should == "before new"
|
169
|
+
@r['e'].after.should == "after new"
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
@@ -0,0 +1,171 @@
|
|
1
|
+
require 'ObjectModel/require'
|
2
|
+
require 'spec'
|
3
|
+
|
4
|
+
module ObjectModel
|
5
|
+
module ExtendedSpec
|
6
|
+
describe "Repository Extended" do
|
7
|
+
class SimpleEntity
|
8
|
+
inherit Entity
|
9
|
+
|
10
|
+
metadata do
|
11
|
+
attribute :label, :string
|
12
|
+
attribute :value
|
13
|
+
reference :reference
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
it "Asquisition should search in Parent's methods untill found not-nil value (from error)" do
|
18
|
+
@r.transaction{
|
19
|
+
p = UpNotNil.new 'p'
|
20
|
+
p.value = "Value"
|
21
|
+
UpNotNil.new 'c'
|
22
|
+
}.commit
|
23
|
+
@r['c'].up(:value).should == nil
|
24
|
+
@r.transaction{
|
25
|
+
@r['p'].child = @r['c']
|
26
|
+
}.commit
|
27
|
+
@r['p/c'].up(:value).should == "Value"
|
28
|
+
end
|
29
|
+
|
30
|
+
it "Clearing Repository" do
|
31
|
+
@r.transaction{SimpleEntity.new("se")}.commit
|
32
|
+
@r.should include('se')
|
33
|
+
@r.clear
|
34
|
+
@r.should_not include('se')
|
35
|
+
# Should function well
|
36
|
+
@r.transaction{SimpleEntity.new("se")}.commit
|
37
|
+
@r.should include('se')
|
38
|
+
end
|
39
|
+
|
40
|
+
it "Asquisition shouldn't raise 'Not found' if Parent hasn't method returning nil" do
|
41
|
+
@r.transaction{
|
42
|
+
p = UpParent.new 'p' # Hasn't :value method
|
43
|
+
c = UpNotNil.new 'c'
|
44
|
+
p.child = c
|
45
|
+
}.commit
|
46
|
+
@r['p/c'].up(:value).should == nil
|
47
|
+
end
|
48
|
+
|
49
|
+
it "Custom Initialization" do
|
50
|
+
@r.transaction{
|
51
|
+
CustomInitialization.new 'ci'
|
52
|
+
}.commit
|
53
|
+
e = @r['ci']
|
54
|
+
[e.string, e.number, e.boolean, e.object, e.data, e.date].should ==
|
55
|
+
["ci", 1, true, 45, StreamID.new("sid"), DateTime.new(2009, 1, 1)]
|
56
|
+
end
|
57
|
+
|
58
|
+
it "Entities can be used as Hash keys (from error)" do
|
59
|
+
@r.transaction{SimpleEntity.new 'e'}.commit
|
60
|
+
@r['e'].should == @r['e']
|
61
|
+
{@r['e'] => 1}.should == {@r['e'] => 1}
|
62
|
+
[@r['e']].to_set.should == [@r['e']].to_set
|
63
|
+
end
|
64
|
+
|
65
|
+
it "Should correct restore entity_id, name and om_repository after loading" do
|
66
|
+
@r.transaction{SimpleEntity.new 'e', 'entity_id'}.commit
|
67
|
+
@r['e'].entity_id.should == "entity_id"
|
68
|
+
@r['e'].name.should == "e"
|
69
|
+
@r['e'].om_version.should_not be_nil
|
70
|
+
@r['e'].om_version.should_not == 0
|
71
|
+
@r['e'].om_repository.should == @r
|
72
|
+
end
|
73
|
+
|
74
|
+
it "Commit inside Transaction block" do
|
75
|
+
@r.transaction{|t|
|
76
|
+
SimpleEntity.new 'e'
|
77
|
+
t.commit
|
78
|
+
}
|
79
|
+
@r.should include('e')
|
80
|
+
end
|
81
|
+
|
82
|
+
it "Should correct save cycle references" do
|
83
|
+
@r.transaction{
|
84
|
+
a = SimpleEntity.new 'a'
|
85
|
+
b = SimpleEntity.new 'b'
|
86
|
+
b.reference = a
|
87
|
+
a.reference = b
|
88
|
+
}.commit
|
89
|
+
|
90
|
+
@r['a'].reference.should == @r['b']
|
91
|
+
@r['b'].reference.should == @r['a']
|
92
|
+
end
|
93
|
+
|
94
|
+
it "Should save special characters" do
|
95
|
+
@r.transaction{
|
96
|
+
e = SimpleEntity.new 'e'
|
97
|
+
e.label = "<test>\"'&"
|
98
|
+
}.commit
|
99
|
+
|
100
|
+
@r['e'].label.should == "<test>\"'&"
|
101
|
+
end
|
102
|
+
|
103
|
+
it "Shouldn't allow '/' symbol in name" do
|
104
|
+
lambda{
|
105
|
+
@r.transaction{
|
106
|
+
SimpleEntity.new 'ivalid/symbol'
|
107
|
+
}.commit
|
108
|
+
}.should raise_error(/'\/'/)
|
109
|
+
end
|
110
|
+
|
111
|
+
it %{
|
112
|
+
Tricky spec. Inside Transaction scope Entity Lookup
|
113
|
+
should use 'Transaction.resolve' not 'Repository.by_id'
|
114
|
+
} do
|
115
|
+
@r.transaction do
|
116
|
+
e1 = SimpleEntity.new
|
117
|
+
e2 = SimpleEntity.new.set :label => "e2"
|
118
|
+
e1.reference = e2
|
119
|
+
e1.reference.label.should == "e2" # <= Entity Lookup in this line shouldn't cause Error
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
it "Transaction should have default name" do
|
124
|
+
tr = @r.transaction{}
|
125
|
+
tr.name.should == "default"
|
126
|
+
end
|
127
|
+
|
128
|
+
it "Should also works with entities accessed outside Transaction scope" do
|
129
|
+
# We can use it without isolate, but we can't then guarantee integrity
|
130
|
+
# becouse if we use NoCache Cache it creates new entity each time.
|
131
|
+
# So if we first access Entity and remember it without :isolate another
|
132
|
+
# process can change this Entity.
|
133
|
+
@r.transaction{
|
134
|
+
SimpleEntity.new 'e'
|
135
|
+
}.commit
|
136
|
+
@r.isolate do
|
137
|
+
e = @r['e']
|
138
|
+
@r.transaction{
|
139
|
+
e.label = "new name"
|
140
|
+
}.commit
|
141
|
+
@r['e'].label.should == "new name"
|
142
|
+
# e.label.should == "new name" # but this will be not always true!
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
it "Shouldn't allow create Entity with empty name" do
|
147
|
+
@r.transaction{
|
148
|
+
lambda{SimpleEntity.new ""}.should raise_error(/shouldn't be Emtpy/)
|
149
|
+
}
|
150
|
+
end
|
151
|
+
|
152
|
+
it "Should be able to save some simple metadata" do
|
153
|
+
s = @r.storage
|
154
|
+
s.get("key").should be_nil
|
155
|
+
s.put("key", "value")
|
156
|
+
s.get("key").should == "value"
|
157
|
+
end
|
158
|
+
|
159
|
+
before :each do
|
160
|
+
CONFIG[:directory] = "#{File.dirname __FILE__}/data"
|
161
|
+
Repository.delete :test
|
162
|
+
@r = Repository.new :test
|
163
|
+
end
|
164
|
+
|
165
|
+
after :each do
|
166
|
+
@r.close
|
167
|
+
Repository.delete :test
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|