mongoid-pre 2.0.0.beta1

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 (246) hide show
  1. data/.gitignore +6 -0
  2. data/.watchr +24 -0
  3. data/MIT_LICENSE +20 -0
  4. data/README.rdoc +49 -0
  5. data/Rakefile +52 -0
  6. data/VERSION +1 -0
  7. data/caliper.yml +4 -0
  8. data/lib/mongoid.rb +135 -0
  9. data/lib/mongoid/associations.rb +263 -0
  10. data/lib/mongoid/associations/belongs_to_related.rb +59 -0
  11. data/lib/mongoid/associations/embedded_in.rb +64 -0
  12. data/lib/mongoid/associations/embeds_many.rb +193 -0
  13. data/lib/mongoid/associations/embeds_one.rb +95 -0
  14. data/lib/mongoid/associations/has_many_related.rb +133 -0
  15. data/lib/mongoid/associations/has_one_related.rb +81 -0
  16. data/lib/mongoid/associations/meta_data.rb +28 -0
  17. data/lib/mongoid/associations/options.rb +52 -0
  18. data/lib/mongoid/associations/proxy.rb +31 -0
  19. data/lib/mongoid/attributes.rb +185 -0
  20. data/lib/mongoid/callbacks.rb +18 -0
  21. data/lib/mongoid/collection.rb +119 -0
  22. data/lib/mongoid/collections/cyclic_iterator.rb +34 -0
  23. data/lib/mongoid/collections/master.rb +28 -0
  24. data/lib/mongoid/collections/mimic.rb +46 -0
  25. data/lib/mongoid/collections/operations.rb +41 -0
  26. data/lib/mongoid/collections/slaves.rb +44 -0
  27. data/lib/mongoid/commands.rb +161 -0
  28. data/lib/mongoid/commands/create.rb +19 -0
  29. data/lib/mongoid/commands/delete.rb +16 -0
  30. data/lib/mongoid/commands/delete_all.rb +25 -0
  31. data/lib/mongoid/commands/deletion.rb +18 -0
  32. data/lib/mongoid/commands/destroy.rb +17 -0
  33. data/lib/mongoid/commands/destroy_all.rb +25 -0
  34. data/lib/mongoid/commands/save.rb +30 -0
  35. data/lib/mongoid/components.rb +31 -0
  36. data/lib/mongoid/config.rb +86 -0
  37. data/lib/mongoid/contexts.rb +25 -0
  38. data/lib/mongoid/contexts/enumerable.rb +151 -0
  39. data/lib/mongoid/contexts/ids.rb +25 -0
  40. data/lib/mongoid/contexts/mongo.rb +285 -0
  41. data/lib/mongoid/contexts/paging.rb +42 -0
  42. data/lib/mongoid/criteria.rb +239 -0
  43. data/lib/mongoid/criterion/complex.rb +21 -0
  44. data/lib/mongoid/criterion/exclusion.rb +65 -0
  45. data/lib/mongoid/criterion/inclusion.rb +93 -0
  46. data/lib/mongoid/criterion/optional.rb +136 -0
  47. data/lib/mongoid/cursor.rb +82 -0
  48. data/lib/mongoid/deprecation.rb +22 -0
  49. data/lib/mongoid/dirty.rb +203 -0
  50. data/lib/mongoid/document.rb +306 -0
  51. data/lib/mongoid/errors.rb +77 -0
  52. data/lib/mongoid/extensions.rb +99 -0
  53. data/lib/mongoid/extensions/array/accessors.rb +17 -0
  54. data/lib/mongoid/extensions/array/aliasing.rb +4 -0
  55. data/lib/mongoid/extensions/array/assimilation.rb +26 -0
  56. data/lib/mongoid/extensions/array/conversions.rb +27 -0
  57. data/lib/mongoid/extensions/array/parentization.rb +13 -0
  58. data/lib/mongoid/extensions/big_decimal/conversions.rb +19 -0
  59. data/lib/mongoid/extensions/binary/conversions.rb +17 -0
  60. data/lib/mongoid/extensions/boolean/conversions.rb +16 -0
  61. data/lib/mongoid/extensions/date/conversions.rb +15 -0
  62. data/lib/mongoid/extensions/datetime/conversions.rb +17 -0
  63. data/lib/mongoid/extensions/float/conversions.rb +16 -0
  64. data/lib/mongoid/extensions/hash/accessors.rb +38 -0
  65. data/lib/mongoid/extensions/hash/assimilation.rb +30 -0
  66. data/lib/mongoid/extensions/hash/conversions.rb +15 -0
  67. data/lib/mongoid/extensions/hash/criteria_helpers.rb +20 -0
  68. data/lib/mongoid/extensions/hash/scoping.rb +12 -0
  69. data/lib/mongoid/extensions/integer/conversions.rb +16 -0
  70. data/lib/mongoid/extensions/nil/assimilation.rb +13 -0
  71. data/lib/mongoid/extensions/object/conversions.rb +27 -0
  72. data/lib/mongoid/extensions/objectid/conversions.rb +15 -0
  73. data/lib/mongoid/extensions/proc/scoping.rb +12 -0
  74. data/lib/mongoid/extensions/string/conversions.rb +15 -0
  75. data/lib/mongoid/extensions/string/inflections.rb +97 -0
  76. data/lib/mongoid/extensions/symbol/inflections.rb +36 -0
  77. data/lib/mongoid/extensions/time/conversions.rb +18 -0
  78. data/lib/mongoid/extras.rb +61 -0
  79. data/lib/mongoid/factory.rb +19 -0
  80. data/lib/mongoid/field.rb +52 -0
  81. data/lib/mongoid/fields.rb +62 -0
  82. data/lib/mongoid/finders.rb +136 -0
  83. data/lib/mongoid/identity.rb +39 -0
  84. data/lib/mongoid/indexes.rb +27 -0
  85. data/lib/mongoid/javascript.rb +21 -0
  86. data/lib/mongoid/javascript/functions.yml +37 -0
  87. data/lib/mongoid/matchers.rb +36 -0
  88. data/lib/mongoid/matchers/all.rb +11 -0
  89. data/lib/mongoid/matchers/default.rb +26 -0
  90. data/lib/mongoid/matchers/exists.rb +13 -0
  91. data/lib/mongoid/matchers/gt.rb +11 -0
  92. data/lib/mongoid/matchers/gte.rb +11 -0
  93. data/lib/mongoid/matchers/in.rb +11 -0
  94. data/lib/mongoid/matchers/lt.rb +11 -0
  95. data/lib/mongoid/matchers/lte.rb +11 -0
  96. data/lib/mongoid/matchers/ne.rb +11 -0
  97. data/lib/mongoid/matchers/nin.rb +11 -0
  98. data/lib/mongoid/matchers/size.rb +11 -0
  99. data/lib/mongoid/memoization.rb +27 -0
  100. data/lib/mongoid/named_scope.rb +42 -0
  101. data/lib/mongoid/observable.rb +30 -0
  102. data/lib/mongoid/paths.rb +54 -0
  103. data/lib/mongoid/persistence.rb +27 -0
  104. data/lib/mongoid/persistence/command.rb +20 -0
  105. data/lib/mongoid/persistence/insert.rb +71 -0
  106. data/lib/mongoid/persistence/update.rb +78 -0
  107. data/lib/mongoid/scope.rb +75 -0
  108. data/lib/mongoid/state.rb +32 -0
  109. data/lib/mongoid/timestamps.rb +27 -0
  110. data/lib/mongoid/validations.rb +51 -0
  111. data/lib/mongoid/validations/associated.rb +32 -0
  112. data/lib/mongoid/validations/locale/en.yml +4 -0
  113. data/lib/mongoid/validations/uniqueness.rb +22 -0
  114. data/lib/mongoid/versioning.rb +26 -0
  115. data/mongoid.gemspec +413 -0
  116. data/perf/benchmark.rb +77 -0
  117. data/spec/integration/mongoid/associations_spec.rb +340 -0
  118. data/spec/integration/mongoid/attributes_spec.rb +22 -0
  119. data/spec/integration/mongoid/commands_spec.rb +230 -0
  120. data/spec/integration/mongoid/contexts/enumerable_spec.rb +33 -0
  121. data/spec/integration/mongoid/criteria_spec.rb +272 -0
  122. data/spec/integration/mongoid/dirty_spec.rb +70 -0
  123. data/spec/integration/mongoid/document_spec.rb +650 -0
  124. data/spec/integration/mongoid/extensions_spec.rb +22 -0
  125. data/spec/integration/mongoid/finders_spec.rb +119 -0
  126. data/spec/integration/mongoid/inheritance_spec.rb +137 -0
  127. data/spec/integration/mongoid/named_scope_spec.rb +46 -0
  128. data/spec/integration/mongoid/persistence/update_spec.rb +46 -0
  129. data/spec/models/address.rb +39 -0
  130. data/spec/models/animal.rb +6 -0
  131. data/spec/models/callbacks.rb +18 -0
  132. data/spec/models/comment.rb +8 -0
  133. data/spec/models/country_code.rb +6 -0
  134. data/spec/models/employer.rb +5 -0
  135. data/spec/models/game.rb +7 -0
  136. data/spec/models/inheritance.rb +56 -0
  137. data/spec/models/location.rb +5 -0
  138. data/spec/models/mixed_drink.rb +4 -0
  139. data/spec/models/name.rb +13 -0
  140. data/spec/models/namespacing.rb +11 -0
  141. data/spec/models/patient.rb +6 -0
  142. data/spec/models/person.rb +99 -0
  143. data/spec/models/pet.rb +7 -0
  144. data/spec/models/pet_owner.rb +6 -0
  145. data/spec/models/phone.rb +7 -0
  146. data/spec/models/post.rb +15 -0
  147. data/spec/models/translation.rb +5 -0
  148. data/spec/models/vet_visit.rb +5 -0
  149. data/spec/spec.opts +3 -0
  150. data/spec/spec_helper.rb +31 -0
  151. data/spec/unit/mongoid/associations/belongs_to_related_spec.rb +145 -0
  152. data/spec/unit/mongoid/associations/embedded_in_spec.rb +193 -0
  153. data/spec/unit/mongoid/associations/embeds_many_spec.rb +516 -0
  154. data/spec/unit/mongoid/associations/embeds_one_spec.rb +282 -0
  155. data/spec/unit/mongoid/associations/has_many_related_spec.rb +418 -0
  156. data/spec/unit/mongoid/associations/has_one_related_spec.rb +179 -0
  157. data/spec/unit/mongoid/associations/meta_data_spec.rb +88 -0
  158. data/spec/unit/mongoid/associations/options_spec.rb +192 -0
  159. data/spec/unit/mongoid/associations_spec.rb +595 -0
  160. data/spec/unit/mongoid/attributes_spec.rb +507 -0
  161. data/spec/unit/mongoid/callbacks_spec.rb +55 -0
  162. data/spec/unit/mongoid/collection_spec.rb +187 -0
  163. data/spec/unit/mongoid/collections/cyclic_iterator_spec.rb +75 -0
  164. data/spec/unit/mongoid/collections/master_spec.rb +41 -0
  165. data/spec/unit/mongoid/collections/mimic_spec.rb +43 -0
  166. data/spec/unit/mongoid/collections/slaves_spec.rb +81 -0
  167. data/spec/unit/mongoid/commands/create_spec.rb +31 -0
  168. data/spec/unit/mongoid/commands/delete_all_spec.rb +59 -0
  169. data/spec/unit/mongoid/commands/delete_spec.rb +38 -0
  170. data/spec/unit/mongoid/commands/destroy_all_spec.rb +21 -0
  171. data/spec/unit/mongoid/commands/destroy_spec.rb +51 -0
  172. data/spec/unit/mongoid/commands/save_spec.rb +107 -0
  173. data/spec/unit/mongoid/commands_spec.rb +270 -0
  174. data/spec/unit/mongoid/config_spec.rb +176 -0
  175. data/spec/unit/mongoid/contexts/enumerable_spec.rb +421 -0
  176. data/spec/unit/mongoid/contexts/mongo_spec.rb +682 -0
  177. data/spec/unit/mongoid/contexts_spec.rb +25 -0
  178. data/spec/unit/mongoid/criteria_spec.rb +824 -0
  179. data/spec/unit/mongoid/criterion/complex_spec.rb +19 -0
  180. data/spec/unit/mongoid/criterion/exclusion_spec.rb +91 -0
  181. data/spec/unit/mongoid/criterion/inclusion_spec.rb +219 -0
  182. data/spec/unit/mongoid/criterion/optional_spec.rb +319 -0
  183. data/spec/unit/mongoid/cursor_spec.rb +74 -0
  184. data/spec/unit/mongoid/deprecation_spec.rb +24 -0
  185. data/spec/unit/mongoid/dirty_spec.rb +286 -0
  186. data/spec/unit/mongoid/document_spec.rb +818 -0
  187. data/spec/unit/mongoid/errors_spec.rb +103 -0
  188. data/spec/unit/mongoid/extensions/array/accessors_spec.rb +50 -0
  189. data/spec/unit/mongoid/extensions/array/assimilation_spec.rb +24 -0
  190. data/spec/unit/mongoid/extensions/array/conversions_spec.rb +35 -0
  191. data/spec/unit/mongoid/extensions/array/parentization_spec.rb +20 -0
  192. data/spec/unit/mongoid/extensions/big_decimal/conversions_spec.rb +22 -0
  193. data/spec/unit/mongoid/extensions/binary/conversions_spec.rb +22 -0
  194. data/spec/unit/mongoid/extensions/boolean/conversions_spec.rb +49 -0
  195. data/spec/unit/mongoid/extensions/date/conversions_spec.rb +102 -0
  196. data/spec/unit/mongoid/extensions/datetime/conversions_spec.rb +67 -0
  197. data/spec/unit/mongoid/extensions/float/conversions_spec.rb +61 -0
  198. data/spec/unit/mongoid/extensions/hash/accessors_spec.rb +184 -0
  199. data/spec/unit/mongoid/extensions/hash/assimilation_spec.rb +46 -0
  200. data/spec/unit/mongoid/extensions/hash/conversions_spec.rb +21 -0
  201. data/spec/unit/mongoid/extensions/hash/criteria_helpers_spec.rb +17 -0
  202. data/spec/unit/mongoid/extensions/hash/scoping_spec.rb +14 -0
  203. data/spec/unit/mongoid/extensions/integer/conversions_spec.rb +61 -0
  204. data/spec/unit/mongoid/extensions/nil/assimilation_spec.rb +24 -0
  205. data/spec/unit/mongoid/extensions/object/conversions_spec.rb +57 -0
  206. data/spec/unit/mongoid/extensions/proc/scoping_spec.rb +34 -0
  207. data/spec/unit/mongoid/extensions/string/conversions_spec.rb +17 -0
  208. data/spec/unit/mongoid/extensions/string/inflections_spec.rb +208 -0
  209. data/spec/unit/mongoid/extensions/symbol/inflections_spec.rb +91 -0
  210. data/spec/unit/mongoid/extensions/time/conversions_spec.rb +70 -0
  211. data/spec/unit/mongoid/extras_spec.rb +102 -0
  212. data/spec/unit/mongoid/factory_spec.rb +31 -0
  213. data/spec/unit/mongoid/field_spec.rb +143 -0
  214. data/spec/unit/mongoid/fields_spec.rb +181 -0
  215. data/spec/unit/mongoid/finders_spec.rb +404 -0
  216. data/spec/unit/mongoid/identity_spec.rb +109 -0
  217. data/spec/unit/mongoid/indexes_spec.rb +93 -0
  218. data/spec/unit/mongoid/javascript_spec.rb +48 -0
  219. data/spec/unit/mongoid/matchers/all_spec.rb +27 -0
  220. data/spec/unit/mongoid/matchers/default_spec.rb +27 -0
  221. data/spec/unit/mongoid/matchers/exists_spec.rb +56 -0
  222. data/spec/unit/mongoid/matchers/gt_spec.rb +39 -0
  223. data/spec/unit/mongoid/matchers/gte_spec.rb +49 -0
  224. data/spec/unit/mongoid/matchers/in_spec.rb +27 -0
  225. data/spec/unit/mongoid/matchers/lt_spec.rb +39 -0
  226. data/spec/unit/mongoid/matchers/lte_spec.rb +49 -0
  227. data/spec/unit/mongoid/matchers/ne_spec.rb +27 -0
  228. data/spec/unit/mongoid/matchers/nin_spec.rb +27 -0
  229. data/spec/unit/mongoid/matchers/size_spec.rb +27 -0
  230. data/spec/unit/mongoid/matchers_spec.rb +329 -0
  231. data/spec/unit/mongoid/memoization_spec.rb +75 -0
  232. data/spec/unit/mongoid/named_scope_spec.rb +123 -0
  233. data/spec/unit/mongoid/observable_spec.rb +46 -0
  234. data/spec/unit/mongoid/paths_spec.rb +124 -0
  235. data/spec/unit/mongoid/persistence/insert_spec.rb +175 -0
  236. data/spec/unit/mongoid/persistence/update_spec.rb +148 -0
  237. data/spec/unit/mongoid/persistence_spec.rb +40 -0
  238. data/spec/unit/mongoid/scope_spec.rb +240 -0
  239. data/spec/unit/mongoid/state_spec.rb +83 -0
  240. data/spec/unit/mongoid/timestamps_spec.rb +25 -0
  241. data/spec/unit/mongoid/validations/associated_spec.rb +103 -0
  242. data/spec/unit/mongoid/validations/uniqueness_spec.rb +47 -0
  243. data/spec/unit/mongoid/validations_spec.rb +190 -0
  244. data/spec/unit/mongoid/versioning_spec.rb +41 -0
  245. data/spec/unit/mongoid_spec.rb +46 -0
  246. metadata +476 -0
@@ -0,0 +1,75 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Memoization do
4
+
5
+ let(:memo) { "Memo" }
6
+
7
+ before do
8
+ @person = Person.new
9
+ end
10
+
11
+ describe "#memoized" do
12
+
13
+ context "when variable has been defined" do
14
+
15
+ before do
16
+ @person.instance_variable_set("@memo", memo)
17
+ end
18
+
19
+ it "returns the memoized value" do
20
+ @person.memoized(:memo) { nil }.should == memo
21
+ end
22
+
23
+ end
24
+
25
+ context "when variable has not been defined" do
26
+
27
+ it "returns the new value" do
28
+ @person.memoized(:memo) { memo }.should == memo
29
+ end
30
+
31
+ it "memoizes the new value" do
32
+ @person.memoized(:memo) { memo }
33
+ @person.instance_variable_get("@memo").should == memo
34
+ end
35
+
36
+ end
37
+
38
+ end
39
+
40
+ describe "#reset" do
41
+
42
+ context "when variable has been defined" do
43
+
44
+ before do
45
+ @person.instance_variable_set("@memo", memo)
46
+ end
47
+
48
+ it "removes the memoized value" do
49
+ @person.reset(:memo) { nil }
50
+ @person.instance_variable_defined?("@memo").should be_false
51
+ end
52
+
53
+ it "returns the new value" do
54
+ @person.reset(:memo) { memo }.should == memo
55
+ end
56
+
57
+ end
58
+
59
+ context "when variable has not been defined" do
60
+
61
+ it "memoizes the new value" do
62
+ @person.reset(:memo) { memo }
63
+ @person.instance_variable_get("@memo").should == memo
64
+ end
65
+
66
+ it "returns the value" do
67
+ @person.reset(:memo) { memo }.should == memo
68
+ end
69
+
70
+ end
71
+
72
+
73
+ end
74
+
75
+ end
@@ -0,0 +1,123 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::NamedScope do
4
+
5
+ class Player
6
+ include Mongoid::Document
7
+ field :active, :type => Boolean
8
+ field :frags, :type => Integer
9
+ field :deaths, :type => Integer
10
+ field :status
11
+
12
+ named_scope :active, criteria.where(:active => true) do
13
+ def extension
14
+ "extension"
15
+ end
16
+ end
17
+ named_scope :inactive, :where => { :active => false }
18
+ named_scope :frags_over, lambda { |count| { :where => { :frags.gt => count } } }
19
+ named_scope :deaths_under, lambda { |count| criteria.where(:deaths.lt => count) }
20
+ scope :deaths_over, lambda { |count| criteria.where(:deaths.gt => count) }
21
+
22
+ class << self
23
+ def alive
24
+ criteria.where(:status => "Alive")
25
+ end
26
+ end
27
+ end
28
+
29
+ describe ".named_scope" do
30
+
31
+ it "adds a class method for the scope" do
32
+ Player.should respond_to(:active)
33
+ end
34
+
35
+ it "adds the scope to the scopes" do
36
+ Player.scopes.should include(:active)
37
+ end
38
+
39
+ context "when options are a hash" do
40
+
41
+ it "adds the selector to the scope" do
42
+ Player.inactive.selector[:active].should be_false
43
+ end
44
+
45
+ end
46
+
47
+ context "when options are a criteria" do
48
+
49
+ it "adds the selector to the scope" do
50
+ Player.active.selector[:active].should be_true
51
+ end
52
+
53
+ end
54
+
55
+ context "when options are a proc" do
56
+
57
+ context "when the proc delegates to a hash" do
58
+
59
+ it "adds the selector to the scope" do
60
+ Player.frags_over(50).selector[:frags].should == { "$gt" => 50 }
61
+ end
62
+
63
+ end
64
+
65
+ context "when the proc delegates to a criteria" do
66
+
67
+ it "adds the selector to the scope" do
68
+ Player.deaths_under(40).selector[:deaths].should == { "$lt" => 40 }
69
+ end
70
+
71
+ end
72
+
73
+ end
74
+
75
+ context "when a block is supplied" do
76
+
77
+ it "adds a class method for the scope" do
78
+ Player.should respond_to(:deaths_over)
79
+ end
80
+
81
+ it "adds the scope to the scopes" do
82
+ Player.scopes.should include(:deaths_over)
83
+ end
84
+
85
+ end
86
+
87
+ end
88
+
89
+ describe ".scope" do
90
+
91
+ it "aliases to named_scope" do
92
+ Player.should respond_to(:deaths_over)
93
+ end
94
+
95
+ end
96
+
97
+ context "chained scopes" do
98
+
99
+ context "when chaining two named scopes" do
100
+
101
+ it "merges the criteria" do
102
+ selector = Player.active.frags_over(10).selector
103
+ selector[:active].should be_true
104
+ selector[:frags].should == { "$gt" => 10 }
105
+ end
106
+
107
+ end
108
+
109
+ context "when chaining named scoped with criteria class methods" do
110
+
111
+ it "merges the criteria" do
112
+ selector = Player.active.frags_over(10).alive.selector
113
+ selector[:active].should be_true
114
+ selector[:frags].should == { "$gt" => 10 }
115
+ selector[:status].should == "Alive"
116
+ end
117
+
118
+ end
119
+
120
+ end
121
+
122
+ end
123
+
@@ -0,0 +1,46 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Observable do
4
+
5
+ let(:person) do
6
+ Person.new
7
+ end
8
+
9
+ let(:address) do
10
+ Address.new
11
+ end
12
+
13
+ describe "#add_observer" do
14
+
15
+ it "adds an observer to the observer array" do
16
+ address.add_observer(person)
17
+ address.observers.first.should == person
18
+ end
19
+ end
20
+
21
+ describe "#notify_observers" do
22
+
23
+ before do
24
+ address.add_observer(person)
25
+ end
26
+
27
+ context "when observers exist" do
28
+
29
+ it "calls update on each observer with the args" do
30
+ person.expects(:observe).with("Testing")
31
+ address.notify_observers("Testing")
32
+ end
33
+ end
34
+
35
+ context "when no observers are set up" do
36
+
37
+ before do
38
+ @name = Name.new
39
+ end
40
+
41
+ it "does notthing" do
42
+ @name.notify_observers("Testing")
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,124 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Paths do
4
+
5
+ let(:person) do
6
+ Person.new
7
+ end
8
+
9
+ let(:address) do
10
+ Address.new(:street => "testing")
11
+ end
12
+
13
+ let(:location) do
14
+ Location.new
15
+ end
16
+
17
+ describe "#path" do
18
+
19
+ context "when the document is a parent" do
20
+
21
+ it "returns an empty string" do
22
+ person.path.should == ""
23
+ end
24
+ end
25
+
26
+ context "when the document is embedded" do
27
+
28
+ before do
29
+ person.addresses << address
30
+ end
31
+
32
+ it "returns the inverse_of value of the association" do
33
+ address.path.should == "addresses"
34
+ end
35
+ end
36
+
37
+ context "when document embedded multiple levels" do
38
+
39
+ before do
40
+ address.locations << location
41
+ person.addresses << address
42
+ end
43
+
44
+ it "returns the JSON notation to the document" do
45
+ location.path.should == "addresses.locations"
46
+ end
47
+
48
+ it "sets the route class instance var" do
49
+ Location._path.should == "addresses.locations"
50
+ end
51
+ end
52
+ end
53
+
54
+ describe "#selector" do
55
+
56
+ context "when the document is a parent" do
57
+
58
+ it "returns an id selector" do
59
+ person.selector.should == { "_id" => person.id }
60
+ end
61
+ end
62
+
63
+ context "when the document is embedded" do
64
+
65
+ before do
66
+ person.addresses << address
67
+ end
68
+
69
+ it "returns the association with id selector" do
70
+ address.selector.should == { "_id" => person.id, "addresses._id" => address.id }
71
+ end
72
+ end
73
+
74
+ context "when document embedded multiple levels" do
75
+
76
+ before do
77
+ address.locations << location
78
+ person.addresses << address
79
+ end
80
+
81
+ it "returns the JSON notation to the document with ids" do
82
+ location.selector.should ==
83
+ { "_id" => person.id, "addresses._id" => address.id, "addresses.locations._id" => location.id }
84
+ end
85
+ end
86
+ end
87
+
88
+ describe "#position" do
89
+
90
+ context "when the document is a parent" do
91
+
92
+ it "returns an empty string" do
93
+ person.position.should == ""
94
+ end
95
+ end
96
+
97
+ context "when the document is embedded" do
98
+
99
+ before do
100
+ person.addresses << address
101
+ end
102
+
103
+ it "returns the path plus $" do
104
+ address.position.should == "addresses.$"
105
+ end
106
+ end
107
+
108
+ context "when document embedded multiple levels" do
109
+
110
+ before do
111
+ address.locations << location
112
+ person.addresses << address
113
+ end
114
+
115
+ it "returns the path plus $" do
116
+ location.position.should == "addresses.locations.$"
117
+ end
118
+
119
+ it "sets the matcher class instance var" do
120
+ Location._position.should == "addresses.locations.$"
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,175 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Persistence::Insert do
4
+
5
+ let(:document) do
6
+ Patient.new(:title => "Mr")
7
+ end
8
+
9
+ let(:address) do
10
+ Address.new(:street => "Oxford St")
11
+ end
12
+
13
+ let(:collection) do
14
+ stub.quacks_like(Mongoid::Collection.allocate)
15
+ end
16
+
17
+ before do
18
+ document.stubs(:collection).returns(collection)
19
+ end
20
+
21
+ describe "#initialize" do
22
+
23
+ let(:insert) do
24
+ Mongoid::Persistence::Insert.new(document)
25
+ end
26
+
27
+ it "sets the document" do
28
+ insert.document.should == document
29
+ end
30
+
31
+ it "sets the collection" do
32
+ insert.collection.should == document.collection
33
+ end
34
+
35
+ it "defaults validation to true" do
36
+ insert.validate.should == true
37
+ end
38
+
39
+ it "sets the options" do
40
+ insert.options.should ==
41
+ { :safe => Mongoid.persist_in_safe_mode }
42
+ end
43
+ end
44
+
45
+ describe "#persist" do
46
+
47
+ def root_set_expectation
48
+ lambda {
49
+ collection.expects(:insert).with(
50
+ document.raw_attributes,
51
+ :safe => true
52
+ ).returns("Object")
53
+ }
54
+ end
55
+
56
+ def root_push_expectation
57
+ lambda {
58
+ collection.expects(:update).with(
59
+ { "_id" => document.id },
60
+ { "addresses" => { "$push" => address.raw_attributes } },
61
+ :safe => true
62
+ ).returns("Object")
63
+ }
64
+ end
65
+
66
+ let(:insert) do
67
+ Mongoid::Persistence::Insert.new(document)
68
+ end
69
+
70
+ context "when the document is valid" do
71
+
72
+ it "inserts the new document" do
73
+ root_set_expectation.call
74
+ insert.persist
75
+ end
76
+
77
+ it "returns the document" do
78
+ root_set_expectation.call
79
+ insert.persist.should == document
80
+ end
81
+
82
+ it "sets new_record to false" do
83
+ root_set_expectation.call
84
+ insert.persist
85
+ document.new_record?.should == false
86
+ end
87
+ end
88
+
89
+ context "when the document is not valid" do
90
+
91
+ before do
92
+ document.stubs(:valid?).returns(false)
93
+ end
94
+
95
+ it "returns the document" do
96
+ insert.persist.should == document
97
+ end
98
+
99
+ it "leaves the document as a new record" do
100
+ insert.persist
101
+ document.new_record?.should == true
102
+ end
103
+ end
104
+
105
+ context "when not validating" do
106
+
107
+ before do
108
+ insert.instance_variable_set(:@validate, false)
109
+ document.stubs(:valid?).returns(false)
110
+ end
111
+
112
+ after do
113
+ insert.instance_variable_set(:@validate, true)
114
+ end
115
+
116
+ it "inserts the document in the database" do
117
+ root_set_expectation.call
118
+ insert.persist
119
+ document.new_record?.should == false
120
+ end
121
+ end
122
+
123
+ context "when the document is embedded" do
124
+
125
+ context "when the embedded document is an embeds_one" do
126
+
127
+ context "when the parent is new" do
128
+
129
+ it "notifies its changes to parent and inserts the parent"
130
+
131
+ end
132
+
133
+ context "when the parent is not new" do
134
+
135
+ it "performs an in place $set on the embedded document"
136
+ end
137
+ end
138
+
139
+ context "when the embedded document is an embeds_many" do
140
+
141
+ before do
142
+ document.addresses << address
143
+ end
144
+
145
+ context "when the parent is new" do
146
+
147
+ let(:insert) do
148
+ Mongoid::Persistence::Insert.new(address)
149
+ end
150
+
151
+ it "notifies its changes to the parent and inserts the parent" do
152
+ root_set_expectation.call
153
+ insert.persist.should == address
154
+ end
155
+ end
156
+
157
+ context "when the parent is not new" do
158
+
159
+ let(:insert) do
160
+ Mongoid::Persistence::Insert.new(address)
161
+ end
162
+
163
+ before do
164
+ document.instance_variable_set(:@new_record, false)
165
+ end
166
+
167
+ it "performs a $push on the embedded array" do
168
+ root_push_expectation.call
169
+ insert.persist.should == address
170
+ end
171
+ end
172
+ end
173
+ end
174
+ end
175
+ end