dm-core 0.9.2 → 0.9.3
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/.autotest +26 -0
- data/{CHANGELOG → History.txt} +78 -77
- data/Manifest.txt +123 -0
- data/{README → README.txt} +0 -0
- data/Rakefile +29 -0
- data/SPECS +63 -0
- data/TODO +1 -0
- data/lib/dm-core.rb +6 -1
- data/lib/dm-core/adapters/data_objects_adapter.rb +29 -32
- data/lib/dm-core/adapters/mysql_adapter.rb +1 -1
- data/lib/dm-core/adapters/postgres_adapter.rb +1 -1
- data/lib/dm-core/adapters/sqlite3_adapter.rb +2 -2
- data/lib/dm-core/associations.rb +26 -0
- data/lib/dm-core/associations/many_to_many.rb +34 -25
- data/lib/dm-core/associations/many_to_one.rb +4 -4
- data/lib/dm-core/associations/one_to_many.rb +48 -13
- data/lib/dm-core/associations/one_to_one.rb +4 -4
- data/lib/dm-core/associations/relationship.rb +144 -42
- data/lib/dm-core/associations/relationship_chain.rb +31 -24
- data/lib/dm-core/auto_migrations.rb +0 -4
- data/lib/dm-core/collection.rb +40 -7
- data/lib/dm-core/dependency_queue.rb +31 -0
- data/lib/dm-core/hook.rb +2 -2
- data/lib/dm-core/is.rb +2 -2
- data/lib/dm-core/logger.rb +10 -10
- data/lib/dm-core/model.rb +94 -41
- data/lib/dm-core/property.rb +72 -41
- data/lib/dm-core/property_set.rb +8 -14
- data/lib/dm-core/query.rb +34 -9
- data/lib/dm-core/repository.rb +0 -0
- data/lib/dm-core/resource.rb +13 -13
- data/lib/dm-core/scope.rb +25 -2
- data/lib/dm-core/type.rb +3 -3
- data/lib/dm-core/types/discriminator.rb +10 -8
- data/lib/dm-core/types/object.rb +4 -0
- data/lib/dm-core/types/paranoid_boolean.rb +15 -4
- data/lib/dm-core/types/paranoid_datetime.rb +15 -4
- data/lib/dm-core/version.rb +3 -0
- data/script/all +5 -0
- data/script/performance.rb +191 -0
- data/script/profile.rb +86 -0
- data/spec/integration/association_spec.rb +288 -204
- data/spec/integration/association_through_spec.rb +9 -3
- data/spec/integration/associations/many_to_many_spec.rb +97 -31
- data/spec/integration/associations/many_to_one_spec.rb +41 -6
- data/spec/integration/associations/one_to_many_spec.rb +18 -2
- data/spec/integration/auto_migrations_spec.rb +0 -0
- data/spec/integration/collection_spec.rb +89 -42
- data/spec/integration/dependency_queue_spec.rb +58 -0
- data/spec/integration/model_spec.rb +67 -8
- data/spec/integration/postgres_adapter_spec.rb +19 -20
- data/spec/integration/property_spec.rb +17 -8
- data/spec/integration/query_spec.rb +273 -191
- data/spec/integration/resource_spec.rb +108 -10
- data/spec/integration/strategic_eager_loading_spec.rb +138 -0
- data/spec/integration/transaction_spec.rb +3 -3
- data/spec/integration/type_spec.rb +121 -0
- data/spec/lib/logging_helper.rb +18 -0
- data/spec/lib/model_loader.rb +91 -0
- data/spec/lib/publicize_methods.rb +28 -0
- data/spec/models/vehicles.rb +34 -0
- data/spec/models/zoo.rb +48 -0
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +25 -62
- data/spec/unit/adapters/data_objects_adapter_spec.rb +1 -0
- data/spec/unit/associations/many_to_many_spec.rb +3 -0
- data/spec/unit/associations/many_to_one_spec.rb +9 -1
- data/spec/unit/associations/one_to_many_spec.rb +12 -4
- data/spec/unit/associations/relationship_spec.rb +19 -15
- data/spec/unit/associations_spec.rb +37 -0
- data/spec/unit/collection_spec.rb +8 -0
- data/spec/unit/data_mapper_spec.rb +14 -0
- data/spec/unit/model_spec.rb +2 -2
- data/spec/unit/property_set_spec.rb +0 -13
- data/spec/unit/property_spec.rb +92 -21
- data/spec/unit/query_spec.rb +49 -4
- data/spec/unit/resource_spec.rb +122 -60
- data/spec/unit/scope_spec.rb +11 -0
- data/tasks/ci.rb +68 -0
- data/tasks/dm.rb +63 -0
- data/tasks/doc.rb +20 -0
- data/tasks/hoe.rb +38 -0
- data/tasks/install.rb +20 -0
- metadata +63 -22
@@ -18,7 +18,7 @@ if ADAPTER
|
|
18
18
|
has n, :taggings
|
19
19
|
|
20
20
|
has n, :relationships
|
21
|
-
has n, :related_posts, :through => :relationships, :class_name => 'Post'
|
21
|
+
has n, :related_posts, :through => :relationships, :class_name => 'Post', :child_key => [:post_id]
|
22
22
|
|
23
23
|
has n, :posts, :through => :taggings
|
24
24
|
end
|
@@ -68,7 +68,7 @@ if ADAPTER
|
|
68
68
|
|
69
69
|
property :id, Serial
|
70
70
|
belongs_to :post
|
71
|
-
belongs_to :related_post, :class_name => "Post"
|
71
|
+
belongs_to :related_post, :class_name => "Post", :child_key => [:related_post_id]
|
72
72
|
end
|
73
73
|
|
74
74
|
[Post, Tag, Tagging, Relationship].each do |descendant|
|
@@ -102,7 +102,7 @@ if ADAPTER
|
|
102
102
|
good.taggings << goody
|
103
103
|
good.save
|
104
104
|
|
105
|
-
relation = Relationship.new(:
|
105
|
+
relation = Relationship.new(:related_post_id => another_post.id)
|
106
106
|
post.relationships << relation
|
107
107
|
post.save
|
108
108
|
end
|
@@ -135,6 +135,12 @@ if ADAPTER
|
|
135
135
|
related_posts.first(10, :id => 2).map { |r| r.id }.should == [ post.id ]
|
136
136
|
end
|
137
137
|
|
138
|
+
it 'should handle get()' do
|
139
|
+
post = Post.get!(2)
|
140
|
+
related_posts = Post.first.related_posts
|
141
|
+
related_posts.get(2).should == post
|
142
|
+
end
|
143
|
+
|
138
144
|
it 'should proxy object should be frozen' do
|
139
145
|
Post.first.related_posts.should be_frozen
|
140
146
|
end
|
@@ -13,6 +13,8 @@ describe DataMapper::Associations::ManyToMany::Proxy do
|
|
13
13
|
has n, :books, :through => Resource
|
14
14
|
end
|
15
15
|
|
16
|
+
Object.send(:remove_const, :Book) if defined?(Book)
|
17
|
+
|
16
18
|
class Book
|
17
19
|
include DataMapper::Resource
|
18
20
|
|
@@ -23,7 +25,9 @@ describe DataMapper::Associations::ManyToMany::Proxy do
|
|
23
25
|
|
24
26
|
has n, :editors, :through => Resource
|
25
27
|
end
|
28
|
+
end
|
26
29
|
|
30
|
+
before do
|
27
31
|
[ Book, Editor, BookEditor ].each { |k| k.auto_migrate! }
|
28
32
|
|
29
33
|
repository(ADAPTER) do
|
@@ -37,90 +41,150 @@ describe DataMapper::Associations::ManyToMany::Proxy do
|
|
37
41
|
BookEditor.create(:book => book_1, :editor => editor_1)
|
38
42
|
BookEditor.create(:book => book_2, :editor => editor_1)
|
39
43
|
BookEditor.create(:book => book_1, :editor => editor_2)
|
44
|
+
|
45
|
+
@parent = book_3
|
46
|
+
@association = @parent.editors
|
47
|
+
@other = [ editor_1 ]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should provide #replace' do
|
52
|
+
@association.should respond_to(:replace)
|
53
|
+
end
|
54
|
+
|
55
|
+
describe '#replace' do
|
56
|
+
it 'should remove the resource from the collection' do
|
57
|
+
@association.should have(0).entries
|
58
|
+
@association.replace(@other)
|
59
|
+
@association.should == @other
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'should not automatically save that the resource was removed from the association' do
|
63
|
+
@association.replace(@other)
|
64
|
+
@parent.reload.should have(0).editors
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'should return the association' do
|
68
|
+
@association.replace(@other).object_id.should == @association.object_id
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'should add the new resources so they will be saved when saving the parent' do
|
72
|
+
@association.replace(@other)
|
73
|
+
@association.should == @other
|
74
|
+
@parent.save
|
75
|
+
@association.reload.should == @other
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should instantiate the remote model if passed an array of hashes' do
|
79
|
+
@association.replace([ { :name => 'Jim Smith' } ])
|
80
|
+
other = [ Editor.first(:name => 'Jim Smith') ]
|
81
|
+
other.first.should_not be_nil
|
82
|
+
@association.should == other
|
83
|
+
@parent.save
|
84
|
+
@association.reload.should == other
|
40
85
|
end
|
41
86
|
end
|
42
87
|
|
43
88
|
it "should correctly link records" do
|
44
|
-
|
45
|
-
|
46
|
-
Book.get(
|
47
|
-
|
89
|
+
Book.get(1).should have(2).editors
|
90
|
+
Book.get(2).should have(1).editors
|
91
|
+
Book.get(3).should have(0).editors
|
92
|
+
Editor.get(1).should have(2).books
|
93
|
+
Editor.get(2).should have(1).books
|
48
94
|
end
|
49
95
|
|
50
96
|
it "should be able to have associated objects manually added" do
|
51
97
|
book = Book.get(3)
|
52
|
-
|
98
|
+
book.should have(0).editors
|
53
99
|
|
54
100
|
be = BookEditor.new(:book_id => book.id, :editor_id => 2)
|
55
101
|
book.book_editors << be
|
56
102
|
book.save
|
57
103
|
|
58
|
-
book.reload
|
59
|
-
book.editors.size.should == 1
|
104
|
+
book.reload.should have(1).editors
|
60
105
|
end
|
61
106
|
|
62
107
|
it "should automatically added necessary through class" do
|
63
108
|
book = Book.get(3)
|
109
|
+
book.should have(0).editors
|
110
|
+
|
64
111
|
book.editors << Editor.get(1)
|
65
112
|
book.editors << Editor.new(:name => "Jimmy John")
|
66
113
|
book.save
|
67
|
-
|
114
|
+
|
115
|
+
book.reload.should have(2).editors
|
68
116
|
end
|
69
117
|
|
70
118
|
it "should react correctly to a new record" do
|
71
119
|
book = Book.new(:title => "Finnegan's Wake")
|
72
|
-
|
120
|
+
editor = Editor.get(2)
|
121
|
+
book.should have(0).editors
|
122
|
+
editor.should have(1).books
|
123
|
+
|
124
|
+
book.editors << editor
|
73
125
|
book.save
|
74
|
-
|
75
|
-
|
126
|
+
|
127
|
+
book.reload.should have(1).editors
|
128
|
+
editor.reload.should have(2).books
|
76
129
|
end
|
77
130
|
|
78
131
|
it "should be able to delete intermediate model" do
|
79
|
-
book = Book.get(
|
80
|
-
|
132
|
+
book = Book.get(1)
|
133
|
+
book.should have(2).book_editors
|
134
|
+
book.should have(2).editors
|
135
|
+
|
136
|
+
be = BookEditor.get(1,1)
|
81
137
|
book.book_editors.delete(be)
|
82
138
|
book.save
|
139
|
+
|
83
140
|
book.reload
|
84
|
-
book
|
85
|
-
book.
|
86
|
-
book.editors.size.should == 2
|
141
|
+
book.should have(1).book_editors
|
142
|
+
book.should have(1).editors
|
87
143
|
end
|
88
144
|
|
89
145
|
it "should be clearable" do
|
90
146
|
repository(ADAPTER) do
|
91
147
|
book = Book.get(2)
|
92
|
-
book.
|
148
|
+
book.should have(1).book_editors
|
149
|
+
book.should have(1).editors
|
150
|
+
|
93
151
|
book.editors.clear
|
94
152
|
book.save
|
153
|
+
|
95
154
|
book.reload
|
96
|
-
book.
|
97
|
-
book.
|
155
|
+
book.should have(0).book_editors
|
156
|
+
book.should have(0).editors
|
98
157
|
end
|
99
158
|
repository(ADAPTER) do
|
100
|
-
Book.get(2).
|
159
|
+
Book.get(2).should have(0).editors
|
101
160
|
end
|
102
161
|
end
|
103
162
|
|
104
163
|
it "should be able to delete one object" do
|
105
164
|
book = Book.get(1)
|
106
|
-
|
165
|
+
book.should have(2).book_editors
|
166
|
+
book.should have(2).editors
|
107
167
|
|
108
|
-
book.editors.
|
168
|
+
editor = book.editors.first
|
109
169
|
book.editors.delete(editor)
|
110
|
-
book.book_editors.size.should == 1
|
111
|
-
book.editors.size.should == 1
|
112
170
|
book.save
|
171
|
+
|
113
172
|
book.reload
|
114
|
-
|
173
|
+
book.should have(1).book_editors
|
174
|
+
book.should have(1).editors
|
175
|
+
editor.reload.books.should_not include(book)
|
115
176
|
end
|
116
177
|
|
117
178
|
it "should be destroyable" do
|
118
179
|
pending 'cannot destroy a collection yet' do
|
119
|
-
book = Book.get(
|
180
|
+
book = Book.get(2)
|
181
|
+
book.should have(1).editors
|
182
|
+
|
120
183
|
book.editors.destroy
|
121
184
|
book.save
|
185
|
+
|
122
186
|
book.reload
|
123
|
-
book.
|
187
|
+
book.should have(0).editors
|
124
188
|
end
|
125
189
|
end
|
126
190
|
|
@@ -139,7 +203,9 @@ describe DataMapper::Associations::ManyToMany::Proxy do
|
|
139
203
|
class Book
|
140
204
|
has n, :authors, :through => Resource
|
141
205
|
end
|
206
|
+
end
|
142
207
|
|
208
|
+
before do
|
143
209
|
[ Author, AuthorBook ].each { |k| k.auto_migrate! }
|
144
210
|
|
145
211
|
@author = Author.create(:name => 'James Joyce')
|
@@ -162,10 +228,10 @@ describe DataMapper::Associations::ManyToMany::Proxy do
|
|
162
228
|
end
|
163
229
|
|
164
230
|
it 'should correctly link records' do
|
165
|
-
@author.
|
166
|
-
@book_1.
|
167
|
-
@book_2.
|
168
|
-
@book_3.
|
231
|
+
@author.should have(3).books
|
232
|
+
@book_1.should have(1).authors
|
233
|
+
@book_2.should have(1).authors
|
234
|
+
@book_3.should have(1).authors
|
169
235
|
end
|
170
236
|
end
|
171
237
|
end
|
@@ -22,20 +22,55 @@ if ADAPTER
|
|
22
22
|
|
23
23
|
property :id, Serial
|
24
24
|
property :name, String
|
25
|
+
property :type, Discriminator
|
25
26
|
|
26
27
|
belongs_to :parent, :class_name => 'ManyToOneSpec::Parent'
|
27
28
|
end
|
29
|
+
|
30
|
+
class StepChild < Child
|
31
|
+
end
|
28
32
|
end
|
29
33
|
|
30
34
|
describe DataMapper::Associations::ManyToOne::Proxy do
|
31
35
|
before do
|
32
|
-
ManyToOneSpec::Parent.auto_migrate!
|
33
|
-
|
36
|
+
[ ManyToOneSpec::Parent, ManyToOneSpec::Child ].each { |model| model.auto_migrate! }
|
37
|
+
|
38
|
+
repository(ADAPTER) do
|
39
|
+
@parent = ManyToOneSpec::Parent.create(:name => 'parent')
|
40
|
+
@child = ManyToOneSpec::Child.create(:name => 'child', :parent => @parent)
|
41
|
+
@other = ManyToOneSpec::Parent.create(:name => 'other parent')
|
42
|
+
@step_child = ManyToOneSpec::StepChild.create(:name => 'step child', :parent => @other)
|
43
|
+
@association = @child.parent
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "#association_accessor (STI)" do
|
48
|
+
include LoggingHelper
|
49
|
+
|
50
|
+
it "should set parent" do
|
51
|
+
ManyToOneSpec::StepChild.first(:id => @step_child.id).parent.should == @other
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should use the identity map for STI" do
|
55
|
+
repository(ADAPTER) do |r|
|
56
|
+
parent = ManyToOneSpec::Parent.first(:id => @parent.id)
|
57
|
+
child = ManyToOneSpec::Child.first(:id => @child.id)
|
58
|
+
step_child = ManyToOneSpec::StepChild.first(:id => @step_child.id)
|
59
|
+
logger do |log|
|
60
|
+
# should retrieve from the IdentityMap
|
61
|
+
child.parent.object_id.should == parent.object_id
|
62
|
+
|
63
|
+
# should retrieve from the datasource
|
64
|
+
other = step_child.parent
|
34
65
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
66
|
+
# should retrieve from the IdentityMap
|
67
|
+
step_child.parent.should == @other
|
68
|
+
step_child.parent.object_id.should == other.object_id
|
69
|
+
|
70
|
+
log.readlines.size.should == 1
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
39
74
|
end
|
40
75
|
|
41
76
|
describe '#replace' do
|
@@ -9,10 +9,14 @@ describe "OneToMany" do
|
|
9
9
|
|
10
10
|
property :id, Serial
|
11
11
|
property :name, String
|
12
|
+
property :class_type, Discriminator
|
12
13
|
|
13
14
|
has n, :players
|
14
15
|
end
|
15
16
|
|
17
|
+
class BaseballTeam < Team
|
18
|
+
end
|
19
|
+
|
16
20
|
class Player
|
17
21
|
include DataMapper::Resource
|
18
22
|
|
@@ -26,7 +30,8 @@ describe "OneToMany" do
|
|
26
30
|
|
27
31
|
[Team, Player].each { |k| k.auto_migrate!(ADAPTER) }
|
28
32
|
|
29
|
-
Team.create
|
33
|
+
Team.create(:name => "Cowboys")
|
34
|
+
BaseballTeam.create(:name => "Giants")
|
30
35
|
end
|
31
36
|
|
32
37
|
it "unsaved parent model should accept array of hashes for association" do
|
@@ -42,7 +47,7 @@ describe "OneToMany" do
|
|
42
47
|
team.save
|
43
48
|
|
44
49
|
repository(ADAPTER) do
|
45
|
-
Team.get(
|
50
|
+
Team.get(3).players.should == players
|
46
51
|
end
|
47
52
|
end
|
48
53
|
|
@@ -63,4 +68,15 @@ describe "OneToMany" do
|
|
63
68
|
Team.get(1).players.should == players
|
64
69
|
end
|
65
70
|
end
|
71
|
+
|
72
|
+
describe "STI" do
|
73
|
+
it "should work" do
|
74
|
+
repository(ADAPTER) do
|
75
|
+
Player.create(:name => "Barry Bonds", :team => BaseballTeam.first)
|
76
|
+
end
|
77
|
+
repository(ADAPTER) do
|
78
|
+
Player.first.team.should == BaseballTeam.first
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
66
82
|
end
|
File without changes
|
@@ -29,6 +29,10 @@ if ADAPTER
|
|
29
29
|
property :zebra_id, Integer
|
30
30
|
|
31
31
|
belongs_to :zebra
|
32
|
+
|
33
|
+
def self.sort_by_name
|
34
|
+
all(:order => [ :name ])
|
35
|
+
end
|
32
36
|
end
|
33
37
|
|
34
38
|
class CollectionSpecParty
|
@@ -71,46 +75,6 @@ if ADAPTER
|
|
71
75
|
end
|
72
76
|
end
|
73
77
|
|
74
|
-
describe 'association proxying' do
|
75
|
-
include CollectionSpecHelper
|
76
|
-
|
77
|
-
before do
|
78
|
-
setup
|
79
|
-
end
|
80
|
-
|
81
|
-
it "should provide a Query" do
|
82
|
-
repository(ADAPTER) do
|
83
|
-
zebras = Zebra.all(:order => [ :name ])
|
84
|
-
zebras.query.order.should == [DataMapper::Query::Direction.new(Zebra.properties(ADAPTER)[:name])]
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
it "should proxy the relationships of the model" do
|
89
|
-
repository(ADAPTER) do
|
90
|
-
zebras = Zebra.all
|
91
|
-
zebras.should have(3).entries
|
92
|
-
zebras.find { |zebra| zebra.name == 'Nancy' }.stripes.should have(2).entries
|
93
|
-
zebras.stripes.should == [@babe, @snowball]
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
it "should preserve it's order on reload" do
|
98
|
-
repository(ADAPTER) do |r|
|
99
|
-
zebras = Zebra.all(:order => [ :name ])
|
100
|
-
|
101
|
-
order = %w{ Bessie Nancy Steve }
|
102
|
-
|
103
|
-
zebras.map { |z| z.name }.should == order
|
104
|
-
|
105
|
-
# Force a lazy-load call:
|
106
|
-
zebras.first.notes
|
107
|
-
|
108
|
-
# The order should be unaffected.
|
109
|
-
zebras.map { |z| z.name }.should == order
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
78
|
describe DataMapper::Collection do
|
115
79
|
include CollectionSpecHelper
|
116
80
|
|
@@ -163,6 +127,49 @@ if ADAPTER
|
|
163
127
|
results.first.should == bob
|
164
128
|
end
|
165
129
|
|
130
|
+
describe 'model proxying' do
|
131
|
+
it 'should delegate to a model method' do
|
132
|
+
stripes = @model.first.stripes
|
133
|
+
stripes.should respond_to(:sort_by_name)
|
134
|
+
stripes.sort_by_name.should == [ @babe, @snowball ]
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
describe 'association proxying' do
|
139
|
+
it "should provide a Query" do
|
140
|
+
repository(ADAPTER) do
|
141
|
+
zebras = Zebra.all(:order => [ :name ])
|
142
|
+
zebras.query.order.should == [DataMapper::Query::Direction.new(Zebra.properties(ADAPTER)[:name])]
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
it "should proxy the relationships of the model" do
|
147
|
+
repository(ADAPTER) do
|
148
|
+
zebras = Zebra.all
|
149
|
+
zebras.should have(3).entries
|
150
|
+
zebras.find { |zebra| zebra.name == 'Nancy' }.stripes.should have(2).entries
|
151
|
+
zebras.should respond_to(:stripes)
|
152
|
+
zebras.stripes.should == [@babe, @snowball]
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should preserve it's order on reload" do
|
157
|
+
repository(ADAPTER) do |r|
|
158
|
+
zebras = Zebra.all(:order => [ :name ])
|
159
|
+
|
160
|
+
order = %w{ Bessie Nancy Steve }
|
161
|
+
|
162
|
+
zebras.map { |z| z.name }.should == order
|
163
|
+
|
164
|
+
# Force a lazy-load call:
|
165
|
+
zebras.first.notes
|
166
|
+
|
167
|
+
# The order should be unaffected.
|
168
|
+
zebras.map { |z| z.name }.should == order
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
166
173
|
describe '.new' do
|
167
174
|
describe 'with non-index keys' do
|
168
175
|
it 'should instantiate read-only resources' do
|
@@ -295,6 +302,32 @@ if ADAPTER
|
|
295
302
|
end
|
296
303
|
end
|
297
304
|
|
305
|
+
describe '#build' do
|
306
|
+
it 'should build a new resource' do
|
307
|
+
resource = @collection.build(:name => 'John')
|
308
|
+
resource.should be_kind_of(@model)
|
309
|
+
resource.should be_new_record
|
310
|
+
end
|
311
|
+
|
312
|
+
it 'should append the new resource to the collection' do
|
313
|
+
resource = @collection.build(:name => 'John')
|
314
|
+
resource.should be_new_record
|
315
|
+
resource.collection.object_id.should == @collection.object_id
|
316
|
+
@collection.should include(resource)
|
317
|
+
end
|
318
|
+
|
319
|
+
it 'should use the query conditions to set default values' do
|
320
|
+
resource = @collection.build
|
321
|
+
resource.should be_new_record
|
322
|
+
resource.name.should be_nil
|
323
|
+
|
324
|
+
@collection.query.update(:name => 'John')
|
325
|
+
|
326
|
+
resource = @collection.build
|
327
|
+
resource.name.should == 'John'
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
298
331
|
describe '#clear' do
|
299
332
|
it 'should orphan the resource from the collection' do
|
300
333
|
entries = @collection.entries
|
@@ -508,6 +541,14 @@ if ADAPTER
|
|
508
541
|
end
|
509
542
|
end
|
510
543
|
|
544
|
+
describe '#freeze' do
|
545
|
+
it 'should freeze the underlying array' do
|
546
|
+
@collection.should_not be_frozen
|
547
|
+
@collection.freeze
|
548
|
+
@collection.should be_frozen
|
549
|
+
end
|
550
|
+
end
|
551
|
+
|
511
552
|
describe '#get' do
|
512
553
|
it 'should find a resource in a collection by key' do
|
513
554
|
resource = @collection.get(*@nancy.key)
|
@@ -515,9 +556,15 @@ if ADAPTER
|
|
515
556
|
resource.id.should == @nancy.id
|
516
557
|
end
|
517
558
|
|
559
|
+
it "should find a resource in a collection by typecasting the key" do
|
560
|
+
resource = @collection.get(@nancy.key.to_s)
|
561
|
+
resource.should be_kind_of(DataMapper::Resource)
|
562
|
+
resource.id.should == @nancy.id
|
563
|
+
end
|
564
|
+
|
518
565
|
it 'should not find a resource not in the collection' do
|
519
566
|
@query.update(:offset => 0, :limit => 3)
|
520
|
-
@david = Zebra.create
|
567
|
+
@david = Zebra.create(:name => 'David', :age => 15, :notes => 'Albino')
|
521
568
|
@collection.get(@david.key).should be_nil
|
522
569
|
end
|
523
570
|
end
|
@@ -531,7 +578,7 @@ if ADAPTER
|
|
531
578
|
|
532
579
|
it 'should raise an exception if the resource is not found' do
|
533
580
|
@query.update(:offset => 0, :limit => 3)
|
534
|
-
@david = Zebra.create
|
581
|
+
@david = Zebra.create(:name => 'David', :age => 15, :notes => 'Albino')
|
535
582
|
lambda {
|
536
583
|
@collection.get!(@david.key)
|
537
584
|
}.should raise_error(DataMapper::ObjectNotFoundError)
|