mongoid 0.10.6 → 0.11.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.
Files changed (42) hide show
  1. data/Rakefile +3 -3
  2. data/VERSION +1 -1
  3. data/lib/mongoid.rb +2 -2
  4. data/lib/mongoid/associations.rb +1 -1
  5. data/lib/mongoid/associations/belongs_to.rb +1 -1
  6. data/lib/mongoid/associations/has_many.rb +8 -6
  7. data/lib/mongoid/associations/has_one.rb +6 -5
  8. data/lib/mongoid/commands.rb +94 -41
  9. data/lib/mongoid/commands/delete_all.rb +2 -3
  10. data/lib/mongoid/commands/deletion.rb +1 -1
  11. data/lib/mongoid/commands/destroy_all.rb +2 -0
  12. data/lib/mongoid/commands/save.rb +1 -1
  13. data/lib/mongoid/criteria.rb +1 -1
  14. data/lib/mongoid/document.rb +43 -32
  15. data/lib/mongoid/extensions.rb +3 -3
  16. data/lib/mongoid/extensions/hash/assimilation.rb +2 -3
  17. data/lib/mongoid/extensions/string/inflections.rb +1 -0
  18. data/mongoid.gemspec +13 -9
  19. data/perf/benchmark.rb +8 -4
  20. data/spec/integration/mongoid/commands_spec.rb +103 -0
  21. data/spec/integration/mongoid/document_spec.rb +13 -1
  22. data/spec/integration/mongoid/inheritance_spec.rb +105 -0
  23. data/spec/spec_helper.rb +24 -2
  24. data/spec/unit/mongoid/associations/belongs_to_spec.rb +3 -3
  25. data/spec/unit/mongoid/associations/has_many_spec.rb +92 -31
  26. data/spec/unit/mongoid/associations/has_one_spec.rb +57 -4
  27. data/spec/unit/mongoid/associations_spec.rb +4 -4
  28. data/spec/unit/mongoid/attributes_spec.rb +2 -2
  29. data/spec/unit/mongoid/commands/delete_all_spec.rb +4 -3
  30. data/spec/unit/mongoid/commands/delete_spec.rb +1 -1
  31. data/spec/unit/mongoid/commands/destroy_all_spec.rb +3 -2
  32. data/spec/unit/mongoid/commands/destroy_spec.rb +1 -1
  33. data/spec/unit/mongoid/commands/save_spec.rb +3 -3
  34. data/spec/unit/mongoid/commands_spec.rb +6 -6
  35. data/spec/unit/mongoid/criteria_spec.rb +45 -36
  36. data/spec/unit/mongoid/document_spec.rb +198 -29
  37. data/spec/unit/mongoid/extensions/array/conversions_spec.rb +2 -2
  38. data/spec/unit/mongoid/extensions/hash/assimilation_spec.rb +33 -8
  39. data/spec/unit/mongoid/extensions/object/conversions_spec.rb +2 -2
  40. data/spec/unit/mongoid/finders_spec.rb +1 -1
  41. data/spec/unit/mongoid/timestamps_spec.rb +1 -1
  42. metadata +9 -5
@@ -54,7 +54,7 @@ describe Mongoid::Associations::BelongsTo do
54
54
 
55
55
  before do
56
56
  @parent = Name.new(:first_name => "Drexel")
57
- @document = stub(:parent => @parent)
57
+ @document = stub(:_parent => @parent)
58
58
  @options = Mongoid::Associations::Options.new(:name => :person)
59
59
  end
60
60
 
@@ -68,7 +68,7 @@ describe Mongoid::Associations::BelongsTo do
68
68
  context "when parent is nil" do
69
69
 
70
70
  before do
71
- @document = stub(:parent => nil)
71
+ @document = stub(:_parent => nil)
72
72
  @options = Mongoid::Associations::Options.new(:name => :person)
73
73
  end
74
74
 
@@ -102,7 +102,7 @@ describe Mongoid::Associations::BelongsTo do
102
102
  it "updates the parent document" do
103
103
  @person.name.should == @name
104
104
  @person.attributes[:name].except(:_id).should ==
105
- { "first_name" => "Test", "last_name" => "User" }
105
+ { "first_name" => "Test", "last_name" => "User", "_type" => "Name" }
106
106
  end
107
107
 
108
108
  end
@@ -47,7 +47,7 @@ describe Mongoid::Associations::HasMany do
47
47
  it "adds the parent document before appending to the array" do
48
48
  @association << @address
49
49
  @association.length.should == 3
50
- @address.parent.should == @document
50
+ @address._parent.should == @document
51
51
  end
52
52
 
53
53
  it "allows multiple additions" do
@@ -60,43 +60,86 @@ describe Mongoid::Associations::HasMany do
60
60
 
61
61
  describe "#build" do
62
62
 
63
- before do
64
- @association = Mongoid::Associations::HasMany.new(
65
- @document,
66
- Mongoid::Associations::Options.new(:name => :addresses)
67
- )
68
- end
63
+ context "when a type is not provided" do
64
+
65
+ before do
66
+ @association = Mongoid::Associations::HasMany.new(
67
+ @document,
68
+ Mongoid::Associations::Options.new(:name => :addresses)
69
+ )
70
+ end
71
+
72
+ it "adds a new document to the array with the suppied parameters" do
73
+ @association.build({ :street => "Street 1" })
74
+ @association.length.should == 3
75
+ @association[2].should be_a_kind_of(Address)
76
+ @association[2].street.should == "Street 1"
77
+ end
78
+
79
+ it "returns the newly built object in the association" do
80
+ address = @association.build({ :street => "Yet Another" })
81
+ address.should be_a_kind_of(Address)
82
+ address.street.should == "Yet Another"
83
+ end
69
84
 
70
- it "adds a new document to the array with the suppied parameters" do
71
- @association.build({ :street => "Street 1" })
72
- @association.length.should == 3
73
- @association[2].should be_a_kind_of(Address)
74
- @association[2].street.should == "Street 1"
75
85
  end
76
86
 
77
- it "returns the newly built object in the association" do
78
- address = @association.build({ :street => "Yet Another" })
79
- address.should be_a_kind_of(Address)
80
- address.street.should == "Yet Another"
87
+ context "when a type is provided" do
88
+
89
+ before do
90
+ @association = Mongoid::Associations::HasMany.new(
91
+ @document,
92
+ Mongoid::Associations::Options.new(:name => :shapes)
93
+ )
94
+ end
95
+
96
+ it "instantiates a class of the type" do
97
+ circle = @association.build({ :radius => 100 }, Circle)
98
+ circle.should be_a_kind_of(Circle)
99
+ circle.radius.should == 100
100
+ end
101
+
81
102
  end
82
103
 
83
104
  end
84
105
 
85
106
  describe "#create" do
86
107
 
87
- before do
88
- @association = Mongoid::Associations::HasMany.new(
89
- @document,
90
- Mongoid::Associations::Options.new(:name => :addresses)
91
- )
92
- @address = Address.new(:street => "Yet Another")
108
+ context "when a type is not provided" do
109
+
110
+ before do
111
+ @association = Mongoid::Associations::HasMany.new(
112
+ @document,
113
+ Mongoid::Associations::Options.new(:name => :addresses)
114
+ )
115
+ @address = Address.new(:street => "Yet Another")
116
+ end
117
+
118
+ it "builds and saves a new object" do
119
+ Mongoid::Commands::Save.expects(:execute).returns(true)
120
+ address = @association.create({ :street => "Yet Another" })
121
+ address.should be_a_kind_of(Address)
122
+ address.street.should == "Yet Another"
123
+ end
124
+
93
125
  end
94
126
 
95
- it "builds and saves a new object" do
96
- Mongoid::Commands::Create.expects(:execute).returns(@address)
97
- address = @association.create({ :street => "Yet Another" })
98
- address.should be_a_kind_of(Address)
99
- address.street.should == "Yet Another"
127
+ context "when a type is provided" do
128
+
129
+ before do
130
+ @association = Mongoid::Associations::HasMany.new(
131
+ @document,
132
+ Mongoid::Associations::Options.new(:name => :shapes)
133
+ )
134
+ end
135
+
136
+ it "instantiates a class of that type" do
137
+ Mongoid::Commands::Save.expects(:execute).returns(true)
138
+ circle = @association.create({ :radius => 100 }, Circle)
139
+ circle.should be_a_kind_of(Circle)
140
+ circle.radius.should == 100
141
+ end
142
+
100
143
  end
101
144
 
102
145
  end
@@ -114,7 +157,7 @@ describe Mongoid::Associations::HasMany do
114
157
  it "adds the parent document before appending to the array" do
115
158
  @association.concat [@address]
116
159
  @association.length.should == 3
117
- @address.parent.should == @document
160
+ @address._parent.should == @document
118
161
  end
119
162
 
120
163
  end
@@ -197,6 +240,24 @@ describe Mongoid::Associations::HasMany do
197
240
 
198
241
  end
199
242
 
243
+ describe "#initialize" do
244
+
245
+ before do
246
+ @canvas = stub(:attributes => { :shapes => [{ :_type => "Circle", :radius => 5 }] }, :update => true)
247
+ @association = Mongoid::Associations::HasMany.new(
248
+ @canvas,
249
+ Mongoid::Associations::Options.new(:name => :shapes)
250
+ )
251
+ end
252
+
253
+ it "creates the classes based on their types" do
254
+ circle = @association.first
255
+ circle.should be_a_kind_of(Circle)
256
+ circle.radius.should == 5
257
+ end
258
+
259
+ end
260
+
200
261
  describe ".instantiate" do
201
262
 
202
263
  it "delegates to new" do
@@ -260,7 +321,7 @@ describe Mongoid::Associations::HasMany do
260
321
  it "adds the parent document before appending to the array" do
261
322
  @association.push @address
262
323
  @association.length.should == 3
263
- @address.parent.should == @document
324
+ @address._parent.should == @document
264
325
  end
265
326
 
266
327
  it "appends the document to the end of the array" do
@@ -279,12 +340,12 @@ describe Mongoid::Associations::HasMany do
279
340
  end
280
341
 
281
342
  it "parentizes the child document" do
282
- @address.parent.should == @person
343
+ @address._parent.should == @person
283
344
  end
284
345
 
285
346
  it "sets the attributes of the child on the parent" do
286
347
  @person.attributes[:addresses].should ==
287
- [{ "_id" => "madison-ave", "street" => "Madison Ave" }]
348
+ [{ "_id" => "madison-ave", "street" => "Madison Ave", "_type" => "Address" }]
288
349
  end
289
350
 
290
351
  end
@@ -3,7 +3,10 @@ require "spec_helper"
3
3
  describe Mongoid::Associations::HasOne do
4
4
 
5
5
  before do
6
- @attributes = { :mixed_drink => { :name => "Jack and Coke" } }
6
+ @attributes = { :mixed_drink => {
7
+ :name => "Jack and Coke", :_type => "MixedDrink" },
8
+ :writer => { :speed => 50, :_type => "HtmlWriter" }
9
+ }
7
10
  @document = stub(:attributes => @attributes, :update => true)
8
11
  end
9
12
 
@@ -26,6 +29,24 @@ describe Mongoid::Associations::HasOne do
26
29
 
27
30
  end
28
31
 
32
+ context "when a type is supplied" do
33
+
34
+ before do
35
+ @association = Mongoid::Associations::HasOne.new(
36
+ @document,
37
+ @attributes[:writer],
38
+ Mongoid::Associations::Options.new(:name => :writer)
39
+ )
40
+ end
41
+
42
+ it "instantiates a class of that type" do
43
+ writer = @association.build({ :speed => 500 }, HtmlWriter)
44
+ writer.should be_a_kind_of(HtmlWriter)
45
+ writer.speed.should == 500
46
+ end
47
+
48
+ end
49
+
29
50
  end
30
51
 
31
52
  describe "#create" do
@@ -42,13 +63,45 @@ describe Mongoid::Associations::HasOne do
42
63
  end
43
64
 
44
65
  it "replaces and saves the existing has_one" do
45
- Mongoid::Commands::Create.expects(:execute).returns(@drink)
66
+ Mongoid::Commands::Save.expects(:execute).returns(true)
46
67
  drink = @association.create({ :name => "Sapphire and Tonic" })
47
68
  drink.name.should == "Sapphire and Tonic"
48
69
  end
49
70
 
50
71
  end
51
72
 
73
+ context "when a type is supplied" do
74
+
75
+ before do
76
+ @association = Mongoid::Associations::HasOne.new(
77
+ @document,
78
+ @attributes[:writer],
79
+ Mongoid::Associations::Options.new(:name => :writer)
80
+ )
81
+ end
82
+
83
+ it "instantiates a class of that type" do
84
+ Mongoid::Commands::Save.expects(:execute).returns(true)
85
+ writer = @association.create({ :speed => 500 }, HtmlWriter)
86
+ writer.should be_a_kind_of(HtmlWriter)
87
+ writer.speed.should == 500
88
+ end
89
+
90
+ end
91
+
92
+ end
93
+
94
+ describe "#initialize" do
95
+
96
+ before do
97
+ @document = stub(:attributes => { :writer => { :speed => 500, :_type => "HtmlWriter" } }, :update => true)
98
+ @options = Mongoid::Associations::Options.new(:name => :writer)
99
+ end
100
+
101
+ it "delegates to new" do
102
+ Mongoid::Associations::HasOne.new(@document, @document.attributes[:writer], @options)
103
+ end
104
+
52
105
  end
53
106
 
54
107
  describe "#method_missing" do
@@ -168,12 +221,12 @@ describe Mongoid::Associations::HasOne do
168
221
  end
169
222
 
170
223
  it "parentizes the child document" do
171
- @name.parent.should == @person
224
+ @name._parent.should == @person
172
225
  end
173
226
 
174
227
  it "sets the attributes of the child on the parent" do
175
228
  @person.attributes[:name].should ==
176
- { "_id" => "donald", "first_name" => "Donald" }
229
+ { "_id" => "donald", "first_name" => "Donald", "_type" => "Name" }
177
230
  end
178
231
 
179
232
  end
@@ -25,12 +25,12 @@ describe Mongoid::Associations do
25
25
  end
26
26
 
27
27
  it "parentizes the association" do
28
- @name.parent.should == @person
28
+ @name._parent.should == @person
29
29
  end
30
30
 
31
31
  it "sets the child attributes on the parent" do
32
32
  @person.attributes[:name].should ==
33
- { "_id" => "test-user", "first_name" => "Test", "last_name" => "User" }
33
+ { "_id" => "test-user", "first_name" => "Test", "last_name" => "User", "_type" => "Name" }
34
34
  end
35
35
 
36
36
  end
@@ -46,12 +46,12 @@ describe Mongoid::Associations do
46
46
  end
47
47
 
48
48
  it "re-parentizes the association" do
49
- @address.parent.should == @person
49
+ @address._parent.should == @person
50
50
  end
51
51
 
52
52
  it "adds the child attributes to the parent" do
53
53
  @person.attributes[:addresses].should ==
54
- [{ "_id" => "picadilly-circus", "street" => "Picadilly Circus" }]
54
+ [{ "_id" => "picadilly-circus", "street" => "Picadilly Circus", "_type" => "Address" }]
55
55
  end
56
56
 
57
57
  end
@@ -309,7 +309,7 @@ describe Mongoid::Attributes do
309
309
  it "sets the child attributes on the parent" do
310
310
  @name.write_attributes(:first_name => "Test2", :last_name => "User2")
311
311
  @person.attributes[:name].should ==
312
- { "_id" => "test-user", "first_name" => "Test2", "last_name" => "User2" }
312
+ { "_id" => "test-user", "first_name" => "Test2", "last_name" => "User2", "_type" => "Name" }
313
313
  end
314
314
 
315
315
  end
@@ -325,7 +325,7 @@ describe Mongoid::Attributes do
325
325
  it "updates the child attributes on the parent" do
326
326
  @address.write_attributes("street" => "Test2")
327
327
  @person.attributes[:addresses].should ==
328
- [ { "_id" => "test", "street" => "Test2" } ]
328
+ [ { "_id" => "test", "street" => "Test2", "_type" => "Address" } ]
329
329
  end
330
330
 
331
331
  end
@@ -7,18 +7,19 @@ describe Mongoid::Commands::DeleteAll do
7
7
  before do
8
8
  @doc = mock
9
9
  @docs = [@doc]
10
- @klass = mock
10
+ @klass = stub(:name => "Person")
11
11
  end
12
12
 
13
13
  context "when conditions supplied" do
14
14
 
15
15
  before do
16
+ @collection = mock
16
17
  @conditions = { :conditions => { :title => "Sir" } }
17
18
  end
18
19
 
19
20
  it "deletes each document that the criteria finds" do
20
- @klass.expects(:find).with(:all, @conditions).returns(@docs)
21
- Mongoid::Commands::Delete.expects(:execute).with(@doc)
21
+ @klass.expects(:collection).returns(@collection)
22
+ @collection.expects(:remove).with(@conditions[:conditions].merge(:_type => "Person"))
22
23
  Mongoid::Commands::DeleteAll.execute(@klass, @conditions)
23
24
  end
24
25
 
@@ -6,7 +6,7 @@ describe Mongoid::Commands::Delete do
6
6
 
7
7
  before do
8
8
  @collection = mock
9
- @document = stub(:collection => @collection, :id => "1", :parent => false)
9
+ @document = stub(:collection => @collection, :id => "1", :_parent => false)
10
10
  end
11
11
 
12
12
  it "removes the document from its collection" do
@@ -7,12 +7,13 @@ describe Mongoid::Commands::DestroyAll do
7
7
  before do
8
8
  @doc = mock
9
9
  @docs = [@doc]
10
- @klass = mock
10
+ @klass = stub(:name => "Person")
11
11
  @conditions = { :conditions => { :title => "Sir" } }
12
+ @expected = { :conditions => { :title => "Sir", :_type => "Person" } }
12
13
  end
13
14
 
14
15
  it "destroys each document that the criteria finds" do
15
- @klass.expects(:find).with(:all, @conditions).returns(@docs)
16
+ @klass.expects(:find).with(:all, @expected).returns(@docs)
16
17
  Mongoid::Commands::Destroy.expects(:execute).with(@doc)
17
18
  Mongoid::Commands::DestroyAll.execute(@klass, @conditions)
18
19
  end
@@ -9,7 +9,7 @@ describe Mongoid::Commands::Destroy do
9
9
  @document = stub(:run_callbacks => true,
10
10
  :collection => @collection,
11
11
  :id => "1",
12
- :parent => false)
12
+ :_parent => false)
13
13
  end
14
14
 
15
15
  it "runs the before and after destroy callbacks" do
@@ -10,12 +10,12 @@ describe Mongoid::Commands::Save do
10
10
  @parent = stub(:collection => @parent_collection,
11
11
  :valid? => true,
12
12
  :run_callbacks => true,
13
- :parent => nil,
13
+ :_parent => nil,
14
14
  :attributes => {},
15
15
  :new_record= => false)
16
16
  @document = stub(:collection => @doc_collection,
17
17
  :run_callbacks => true,
18
- :parent => @parent,
18
+ :_parent => @parent,
19
19
  :attributes => {},
20
20
  :new_record= => false)
21
21
  end
@@ -48,7 +48,7 @@ describe Mongoid::Commands::Save do
48
48
  context "when the document has no parent" do
49
49
 
50
50
  before do
51
- @document.expects(:parent).returns(nil)
51
+ @document.expects(:_parent).returns(nil)
52
52
  end
53
53
 
54
54
  it "calls save on the document collection" do
@@ -37,8 +37,8 @@ describe Mongoid::Commands do
37
37
  @person = Person.new
38
38
  end
39
39
 
40
- it "delegates to the Create command" do
41
- Mongoid::Commands::Create.expects(:execute).with(@person, true).returns(true)
40
+ it "delegates to the save command" do
41
+ Mongoid::Commands::Save.expects(:execute).with(@person, true).returns(true)
42
42
  @person.save
43
43
  end
44
44
 
@@ -51,7 +51,7 @@ describe Mongoid::Commands do
51
51
  end
52
52
 
53
53
  it "passes the validate param to the command" do
54
- Mongoid::Commands::Create.expects(:execute).with(@person, false).returns(true)
54
+ Mongoid::Commands::Save.expects(:execute).with(@person, false).returns(true)
55
55
  @person.save(false)
56
56
  end
57
57
 
@@ -85,15 +85,15 @@ describe Mongoid::Commands do
85
85
  @person = Person.new
86
86
  end
87
87
 
88
- it "delegates to the Create command" do
89
- Mongoid::Commands::Create.expects(:execute).with(@person, true).returns(true)
88
+ it "delegates to the save command" do
89
+ Mongoid::Commands::Save.expects(:execute).with(@person, true).returns(true)
90
90
  @person.save!
91
91
  end
92
92
 
93
93
  context "when validation fails" do
94
94
 
95
95
  it "it raises an error " do
96
- Mongoid::Commands::Create.expects(:execute).with(@person, true).returns(false)
96
+ Mongoid::Commands::Save.expects(:execute).with(@person, true).returns(false)
97
97
  lambda { @person.save! }.should raise_error
98
98
  end
99
99