ObjectModel 0.3.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.
- 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
|