ripple 0.9.5 → 1.0.0.beta

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 (152) hide show
  1. data/.gitignore +32 -0
  2. data/Gemfile +10 -9
  3. data/Guardfile +15 -0
  4. data/Rakefile +11 -40
  5. data/lib/rails/generators/ripple/configuration/configuration_generator.rb +0 -13
  6. data/lib/rails/generators/ripple/configuration/templates/ripple.yml +4 -4
  7. data/lib/rails/generators/ripple/js/js_generator.rb +0 -13
  8. data/lib/rails/generators/ripple/js/templates/js/contrib.js +0 -17
  9. data/lib/rails/generators/ripple/js/templates/js/ripple.js +0 -13
  10. data/lib/rails/generators/ripple/model/model_generator.rb +0 -14
  11. data/lib/rails/generators/ripple/model/templates/model.rb +1 -1
  12. data/lib/rails/generators/ripple/observer/observer_generator.rb +0 -14
  13. data/lib/rails/generators/ripple/test/test_generator.rb +7 -19
  14. data/lib/rails/generators/ripple_generator.rb +1 -14
  15. data/lib/ripple.rb +7 -14
  16. data/lib/ripple/associations.rb +129 -26
  17. data/lib/ripple/associations/embedded.rb +1 -15
  18. data/lib/ripple/associations/instantiators.rb +0 -13
  19. data/lib/ripple/associations/linked.rb +41 -19
  20. data/lib/ripple/associations/many.rb +0 -14
  21. data/lib/ripple/associations/many_embedded_proxy.rb +0 -14
  22. data/lib/ripple/associations/many_linked_proxy.rb +39 -18
  23. data/lib/ripple/associations/many_reference_proxy.rb +93 -0
  24. data/lib/ripple/associations/many_stored_key_proxy.rb +76 -0
  25. data/lib/ripple/associations/one.rb +1 -15
  26. data/lib/ripple/associations/one_embedded_proxy.rb +0 -14
  27. data/lib/ripple/associations/one_key_proxy.rb +58 -0
  28. data/lib/ripple/associations/one_linked_proxy.rb +4 -14
  29. data/lib/ripple/associations/one_stored_key_proxy.rb +43 -0
  30. data/lib/ripple/associations/proxy.rb +8 -14
  31. data/lib/ripple/attribute_methods.rb +19 -17
  32. data/lib/ripple/attribute_methods/dirty.rb +19 -15
  33. data/lib/ripple/attribute_methods/query.rb +0 -14
  34. data/lib/ripple/attribute_methods/read.rb +0 -14
  35. data/lib/ripple/attribute_methods/write.rb +0 -14
  36. data/lib/ripple/callbacks.rb +10 -16
  37. data/lib/ripple/conflict/basic_resolver.rb +82 -0
  38. data/lib/ripple/conflict/document_hooks.rb +20 -0
  39. data/lib/ripple/conflict/resolver.rb +71 -0
  40. data/lib/ripple/conflict/test_helper.rb +33 -0
  41. data/lib/ripple/conversion.rb +0 -14
  42. data/lib/ripple/core_ext.rb +1 -14
  43. data/lib/ripple/core_ext/casting.rb +19 -19
  44. data/lib/ripple/core_ext/object.rb +8 -0
  45. data/lib/ripple/document.rb +21 -16
  46. data/lib/ripple/document/bucket_access.rb +0 -14
  47. data/lib/ripple/document/finders.rb +17 -23
  48. data/lib/ripple/document/key.rb +8 -28
  49. data/lib/ripple/document/link.rb +30 -0
  50. data/lib/ripple/document/persistence.rb +12 -20
  51. data/lib/ripple/embedded_document.rb +10 -15
  52. data/lib/ripple/embedded_document/around_callbacks.rb +18 -0
  53. data/lib/ripple/embedded_document/finders.rb +7 -18
  54. data/lib/ripple/embedded_document/persistence.rb +5 -17
  55. data/lib/ripple/i18n.rb +0 -14
  56. data/lib/ripple/inspection.rb +21 -15
  57. data/lib/ripple/locale/en.yml +9 -13
  58. data/lib/ripple/nested_attributes.rb +33 -39
  59. data/lib/ripple/observable.rb +0 -13
  60. data/lib/ripple/properties.rb +1 -14
  61. data/lib/ripple/property_type_mismatch.rb +0 -14
  62. data/lib/ripple/railtie.rb +4 -14
  63. data/lib/ripple/railties/ripple.rake +86 -0
  64. data/lib/ripple/serialization.rb +11 -11
  65. data/lib/ripple/test_server.rb +36 -0
  66. data/lib/ripple/timestamps.rb +0 -13
  67. data/lib/ripple/translation.rb +4 -14
  68. data/lib/ripple/validations.rb +1 -15
  69. data/lib/ripple/validations/associated_validator.rb +26 -17
  70. data/lib/ripple/version.rb +3 -0
  71. data/ripple.gemspec +24 -35
  72. data/spec/integration/ripple/associations_spec.rb +89 -58
  73. data/spec/integration/ripple/conflict_resolution_spec.rb +298 -0
  74. data/spec/integration/ripple/nested_attributes_spec.rb +19 -19
  75. data/spec/integration/ripple/persistence_spec.rb +15 -34
  76. data/spec/integration/ripple/search_associations_spec.rb +31 -0
  77. data/spec/ripple/associations/many_embedded_proxy_spec.rb +23 -36
  78. data/spec/ripple/associations/many_linked_proxy_spec.rb +133 -45
  79. data/spec/ripple/associations/many_reference_proxy_spec.rb +170 -0
  80. data/spec/ripple/associations/many_stored_key_proxy_spec.rb +158 -0
  81. data/spec/ripple/associations/one_embedded_proxy_spec.rb +24 -37
  82. data/spec/ripple/associations/one_key_proxy_spec.rb +82 -0
  83. data/spec/ripple/associations/one_linked_proxy_spec.rb +22 -23
  84. data/spec/ripple/associations/one_stored_key_proxy_spec.rb +72 -0
  85. data/spec/ripple/associations/proxy_spec.rb +21 -15
  86. data/spec/ripple/associations_spec.rb +54 -23
  87. data/spec/ripple/attribute_methods/dirty_spec.rb +56 -5
  88. data/spec/ripple/attribute_methods_spec.rb +47 -21
  89. data/spec/ripple/bucket_access_spec.rb +4 -17
  90. data/spec/ripple/callbacks_spec.rb +52 -15
  91. data/spec/ripple/conflict/resolver_spec.rb +42 -0
  92. data/spec/ripple/conversion_spec.rb +2 -15
  93. data/spec/ripple/core_ext_spec.rb +12 -15
  94. data/spec/ripple/document/link_spec.rb +67 -0
  95. data/spec/ripple/document_spec.rb +34 -19
  96. data/spec/ripple/embedded_document/finders_spec.rb +12 -19
  97. data/spec/ripple/embedded_document/persistence_spec.rb +20 -26
  98. data/spec/ripple/embedded_document_spec.rb +44 -34
  99. data/spec/ripple/finders_spec.rb +58 -29
  100. data/spec/ripple/inspection_spec.rb +40 -37
  101. data/spec/ripple/key_spec.rb +5 -17
  102. data/spec/ripple/observable_spec.rb +3 -16
  103. data/spec/ripple/persistence_spec.rb +134 -18
  104. data/spec/ripple/properties_spec.rb +21 -15
  105. data/spec/ripple/ripple_spec.rb +1 -14
  106. data/spec/ripple/serialization_spec.rb +16 -17
  107. data/spec/ripple/timestamps_spec.rb +73 -52
  108. data/spec/ripple/validations/associated_validator_spec.rb +69 -25
  109. data/spec/ripple/validations_spec.rb +3 -16
  110. data/spec/spec_helper.rb +17 -18
  111. data/spec/support/associations.rb +1 -1
  112. data/spec/support/associations/proxies.rb +0 -13
  113. data/spec/support/integration_setup.rb +11 -0
  114. data/spec/support/mocks.rb +0 -13
  115. data/spec/support/models.rb +33 -2
  116. data/spec/support/models/address.rb +1 -16
  117. data/spec/support/models/box.rb +7 -14
  118. data/spec/support/models/car.rb +27 -1
  119. data/spec/support/models/cardboard_box.rb +0 -14
  120. data/spec/support/models/clock.rb +6 -15
  121. data/spec/support/models/clock_observer.rb +0 -14
  122. data/spec/support/models/credit_card.rb +5 -0
  123. data/spec/support/models/customer.rb +0 -14
  124. data/spec/support/models/email.rb +0 -14
  125. data/spec/support/models/family.rb +1 -13
  126. data/spec/support/models/favorite.rb +0 -14
  127. data/spec/support/models/invoice.rb +0 -14
  128. data/spec/support/models/late_invoice.rb +0 -14
  129. data/spec/support/models/nested.rb +12 -0
  130. data/spec/support/models/ninja.rb +7 -0
  131. data/spec/support/models/note.rb +0 -14
  132. data/spec/support/models/page.rb +1 -15
  133. data/spec/support/models/paid_invoice.rb +0 -14
  134. data/spec/support/models/post.rb +12 -0
  135. data/spec/support/models/profile.rb +7 -0
  136. data/spec/support/models/subscription.rb +26 -0
  137. data/spec/support/models/tasks.rb +0 -18
  138. data/spec/support/models/team.rb +11 -0
  139. data/spec/support/models/transactions.rb +17 -0
  140. data/spec/support/models/tree.rb +2 -16
  141. data/spec/support/models/user.rb +14 -16
  142. data/spec/support/models/widget.rb +8 -14
  143. data/spec/support/search.rb +14 -0
  144. data/spec/support/test_server.rb +22 -12
  145. data/spec/support/test_server.yml.example +14 -2
  146. metadata +223 -59
  147. data/lib/rails/generators/ripple/test/templates/test_server.rb +0 -46
  148. data/spec/support/models/driver.rb +0 -5
  149. data/spec/support/models/engine.rb +0 -4
  150. data/spec/support/models/passenger.rb +0 -5
  151. data/spec/support/models/seat.rb +0 -4
  152. data/spec/support/models/wheel.rb +0 -5
@@ -0,0 +1,170 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ripple::Associations::ManyReferenceProxy do
4
+ # require 'support/models/transactions'
5
+
6
+ before :each do
7
+ @account = Account.new {|e| e.key = "accounty"}
8
+ @payment_method = PaymentMethod.new {|e| e.key = "paymadoo"}
9
+ @other_payment_method = PaymentMethod.new {|e| e.key = "otherpaym"}
10
+ Ripple.client.stub(:search => {"response" => {"docs" => []}})
11
+ end
12
+
13
+ it "should be empty before any associated documents are set" do
14
+ @account.payment_methods.should be_empty
15
+ end
16
+
17
+ it "should accept an array of documents" do
18
+ @account.payment_methods = [@payment_method]
19
+ end
20
+
21
+ it "should set the key on the sub object when assigning" do
22
+ @account.payment_methods = [@payment_method]
23
+ @payment_method.account_key.should == "accounty"
24
+ end
25
+
26
+ it "should be able to replace the entire collection of documents (even appended ones)" do
27
+ @account.payment_methods << @payment_method
28
+ @account.payment_methods = [@other_payment_method]
29
+ @account.payment_methods.should == [@other_payment_method]
30
+ end
31
+
32
+ it "should return the assigned documents when assigning" do
33
+ t = (@account.payment_methods = [@payment_method])
34
+ t.should == [@payment_method]
35
+ end
36
+
37
+ it "should find the associated documents when accessing" do
38
+ Ripple.client.should_receive(:search).with("payment_methods", "account_key: accounty").and_return({"response" => {"docs" => ["id" => "paymadoo"]}})
39
+ PaymentMethod.should_receive(:find).with(["paymadoo"]).and_return([@payment_method])
40
+ @account.payment_methods.should == [@payment_method]
41
+ end
42
+
43
+ it "should replace associated documents with a new set" do
44
+ @account.payment_methods = [@payment_method]
45
+ @account.payment_methods = [@other_payment_method]
46
+ @account.payment_methods.should == [@other_payment_method]
47
+ end
48
+
49
+ it "should return an array from to_ary" do
50
+ @account.payment_methods << @payment_method
51
+ @account.payment_methods.to_ary.should == [@payment_method]
52
+ end
53
+
54
+ it "should refuse assigning a collection of the wrong type" do
55
+ lambda { @account.payment_methods = nil }.should raise_error
56
+ lambda { @account.payment_methods = @payment_method }.should raise_error
57
+ lambda { @account.payment_methods = [@account] }.should raise_error
58
+ end
59
+
60
+ describe "#<< (when the target has not already been loaded)" do
61
+ it "avoids searching when adding a record to an unloaded association" do
62
+ PaymentMethod.should_not_receive(:search)
63
+ @account.payment_methods << @payment_method
64
+ end
65
+
66
+ it "should be able to count the associated documents" do
67
+ @account.payment_methods << @payment_method
68
+ @account.payment_methods.count.should == 1
69
+ @account.payment_methods << @other_payment_method
70
+ @account.payment_methods.count.should == 2
71
+ end
72
+
73
+ it "should be able to count without loading documents" do
74
+ Ripple.client.stub(:search => {"response" => {"docs" => [{"id" => @payment_method.key}, {"id" => @other_payment_method.key}]}})
75
+ PaymentMethod.should_not_receive(:find)
76
+ @account.payment_methods.count.should == 2
77
+ end
78
+
79
+ it "should be able to append documents to the associated set" do
80
+ @account.payment_methods << @payment_method
81
+ @account.payment_methods << @other_payment_method
82
+ @account.should have(2).payment_methods
83
+ end
84
+
85
+ it "should be able to chain calls to adding documents" do
86
+ @account.payment_methods << @payment_method << @other_payment_method
87
+ @account.should have(2).payment_methods
88
+ end
89
+
90
+ it "should assign the keys on the sub object when appending" do
91
+ @account.payment_methods << @payment_method << @other_payment_method
92
+ [@payment_method, @other_payment_method].each do |t|
93
+ t.account_key.should == "accounty"
94
+ end
95
+ end
96
+
97
+ it "does not return duplicates (for when the object has been appended and it's robject is found while walking the links)" do
98
+ @account.payment_methods.stub(:find_target => Set.new([@payment_method]))
99
+ @account.payment_methods.reset
100
+ @account.payment_methods << @payment_method
101
+ @account.payment_methods.should == [@payment_method]
102
+ end
103
+ end
104
+
105
+ describe "#reset" do
106
+ it "clears appended documents" do
107
+ @account.payment_methods << @payment_method
108
+ @account.payment_methods.reset
109
+ @account.payment_methods.should == []
110
+ end
111
+ end
112
+
113
+ describe "#keys" do
114
+ let(:ze_keys) { %w(1 2 3) }
115
+ let(:search_results) do
116
+ {"response" => {"docs" => ze_keys.map { |k| {"id" => k} }}}
117
+ end
118
+
119
+ before(:each) do
120
+ Ripple.client.stub(:search => search_results)
121
+ PaymentMethod.stub(:find => [@payment_method])
122
+ end
123
+
124
+ it "returns a set of keys" do
125
+ @account.payment_methods.keys.should be_a(Set)
126
+ @account.payment_methods.keys.to_a.should == ze_keys
127
+ end
128
+
129
+ it "is memoized between calls" do
130
+ @account.payment_methods.keys.should equal(@account.payment_methods.keys)
131
+ end
132
+
133
+ it "is cleared when the association is reset" do
134
+ orig_set = @account.payment_methods.keys
135
+ @account.payment_methods.reset
136
+ @account.payment_methods.keys.should_not equal(orig_set)
137
+ end
138
+
139
+ it "is cleared when the association is replaced" do
140
+ orig_set = @account.payment_methods.keys
141
+ @account.payment_methods.replace([@payment_method])
142
+ @account.payment_methods.keys.should_not equal(orig_set)
143
+ end
144
+
145
+ it "maintains the list of keys properly as new documents are appended" do
146
+ @account.payment_methods << @payment_method
147
+ @account.payment_methods.should have(1).key
148
+ @account.payment_methods << @other_payment_method
149
+ @account.payment_methods.should have(2).keys
150
+ end
151
+ end
152
+
153
+ describe "#include?" do
154
+ it "delegates to the set of keys so as not to unnecessarily load the associated documents" do
155
+ @account.payment_methods.keys.should_receive(:include?).with(@payment_method.key).and_return(true)
156
+ @account.payment_methods.include?(@payment_method).should be_true
157
+ end
158
+
159
+ it "short-circuits and returns false if the given object is not a ripple document" do
160
+ @account.payment_methods.keys.should_not_receive(:include?)
161
+ @account.payment_methods.include?(Object.new).should be_false
162
+ end
163
+
164
+ it "returns false if the document's bucket is different from the associations bucket, even if the keys are the same" do
165
+ @account.payment_methods << @payment_method
166
+ other_account = Account.new { |p| p.key = @payment_method.key }
167
+ @account.payment_methods.include?(other_account).should be_false
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,158 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ripple::Associations::ManyStoredKeyProxy do
4
+ # require 'support/models/transactions'
5
+
6
+ before :each do
7
+ @account = Account.new {|t| t.key = "accounty" }
8
+ @transaction_one = Transaction.new {|t| t.key = "one" }
9
+ @transaction_two = Transaction.new {|t| t.key = "two" }
10
+ @transaction_three = Transaction.new {|t| t.key = "three" }
11
+ @transaction_one.stub(:new_record?).and_return(false)
12
+ @transaction_two.stub(:new_record?).and_return(false)
13
+ @transaction_three.stub(:new_record?).and_return(false)
14
+ end
15
+
16
+ it "should be empty before any associated documents are set" do
17
+ @account.transactions.should be_empty
18
+ end
19
+
20
+ it "should allow appending" do
21
+ @account.transactions << @transaction_one
22
+ @account.transactions.should == [@transaction_one]
23
+ @account.transaction_keys.should == ["one"]
24
+ end
25
+
26
+ it "should be able to chain calls to adding documents" do
27
+ @account.transactions << @transaction_one << @transaction_two
28
+ @account.transactions.should == [@transaction_one, @transaction_two]
29
+ end
30
+
31
+ it "creates the right type of key collection" do
32
+ Object.module_eval do
33
+ class DifferentlyKeyedAccount
34
+ include Ripple::Document
35
+ property :transaction_keys, SortedSet
36
+ many :transactions, :using => :stored_key
37
+ end
38
+ end
39
+
40
+ account = DifferentlyKeyedAccount.new
41
+ account.transactions << @transaction_one
42
+ account.transaction_keys.should == SortedSet.new(["one"])
43
+ end
44
+
45
+ it "should accept an array of documents" do
46
+ @account.transactions = [@transaction_one]
47
+ @account.transactions.should == [@transaction_one]
48
+ @account.transaction_keys.should == %w(one)
49
+ end
50
+
51
+ it "should be able to replace the entire collection of documents (even appended ones)" do
52
+ @account.transactions << @transaction_one
53
+ @account.transactions = [@transaction_two]
54
+ @account.transactions.should == [@transaction_two]
55
+ @account.transaction_keys.should == %w(two)
56
+ end
57
+
58
+ it "should return the assigned documents when assigning" do
59
+ t = (@account.transactions = [@transaction_one])
60
+ t.should == [@transaction_one]
61
+ end
62
+
63
+ it "asks the keys set for the count to avoid having to unnecessarily load all documents" do
64
+ @account.transactions << @transaction_one
65
+ @account.transaction_keys.stub(:size => 17)
66
+ @account.transactions.count.should == 17
67
+ end
68
+
69
+ it "should return an array from to_ary" do
70
+ @account.transactions << @transaction_one
71
+ @account.transactions.to_ary.should == [@transaction_one]
72
+ end
73
+
74
+ it "should refuse assigning a collection of the wrong type" do
75
+ lambda { @account.transactions = nil }.should raise_error
76
+ lambda { @account.transactions = @transaction_one }.should raise_error
77
+ lambda { @account.transactions = [@account] }.should raise_error
78
+ end
79
+
80
+ it "should refuse appending a document of the wrong type" do
81
+ lambda { @account.transactions << Account.new }.should raise_error
82
+ end
83
+
84
+ describe "#reset" do
85
+ it "clears appended documents" do
86
+ @account.transactions << @transaction_one
87
+ @account.transactions.reset
88
+ @account.transactions.should == []
89
+ end
90
+
91
+ it "resets to the saved state of the proxy" do
92
+ Transaction.stub(:find).and_return([@transaction_one])
93
+ @account.transactions << @transaction_two
94
+ @account.transactions.reset
95
+ Transaction.stub(:find).and_return([@transaction_one])
96
+ @account.transactions.should == [ @transaction_one ]
97
+ end
98
+ end
99
+
100
+ describe "#include?" do
101
+ it "delegates to the set of keys so as not to unnecessarily load the associated documents" do
102
+ @account.transactions.keys.should_receive(:include?).with(@transaction_two.key).and_return(true)
103
+ @account.transactions.include?(@transaction_two).should be_true
104
+ end
105
+
106
+ it "short-circuits and returns false if the given object is not a ripple document" do
107
+ @account.transactions.keys.should_not_receive(:include?)
108
+ @account.transactions.include?(Object.new).should be_false
109
+ end
110
+
111
+ it "returns false if the document's bucket is different from the associations bucket, even if the keys are the same" do
112
+ @account.transactions << @transaction_one
113
+ other_account = Account.new { |p| p.key = @transaction_one.key }
114
+ @account.transactions.include?(other_account).should be_false
115
+ end
116
+ end
117
+
118
+ describe "#keys" do
119
+ before do
120
+ @account.transactions << @transaction_one << @transaction_two
121
+ end
122
+
123
+ it "returns a set of keys" do
124
+ @account.transactions.keys.should be_a(Array)
125
+ @account.transactions.keys.to_a.should == %w(one two)
126
+ end
127
+
128
+ it "is memoized between calls" do
129
+ @account.transactions.keys.should equal(@account.transactions.keys)
130
+ end
131
+
132
+ it "is cleared when the association is reset" do
133
+ orig_set = @account.transactions.keys
134
+ @account.transactions.reset
135
+ @account.transactions.keys.should_not equal(orig_set)
136
+ @account.transactions.keys.should == []
137
+ end
138
+
139
+ it "is cleared when the association is replaced" do
140
+ orig_set = @account.transactions.keys
141
+ @account.transactions.replace([@transaction_one])
142
+ @account.transactions.keys.should_not equal(orig_set)
143
+ @account.transactions.keys.to_a.should == %w(one)
144
+ end
145
+
146
+ it "maintains the list of keys properly as new documents are appended" do
147
+ @account.transactions.keys.size.should == 2
148
+ @account.transactions << @transaction_three
149
+ @account.transactions.keys.size.should == 3
150
+ end
151
+
152
+ end
153
+
154
+ it "temporarily bombs if the document you're appending isn't saved. This behavior shouldn't last long." do
155
+ lambda { @account.transactions << Transaction.new }.should raise_error
156
+ end
157
+
158
+ end
@@ -1,29 +1,16 @@
1
- # Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
- require File.expand_path("../../../spec_helper", __FILE__)
1
+ require 'spec_helper'
15
2
 
16
3
  describe Ripple::Associations::OneEmbeddedProxy do
17
- require 'support/models/family'
18
- require 'support/models/user'
19
- require 'support/models/address'
20
-
4
+ # require 'support/models/family'
5
+ # require 'support/models/user'
6
+ # require 'support/models/address'
7
+
21
8
  before :each do
22
9
  @parent = Parent.new
23
10
  @child = Child.new
24
11
  @gchild = Grandchild.new
25
12
  end
26
-
13
+
27
14
  it "should not have a child before one is set" do
28
15
  @parent.child.should be_nil
29
16
  end
@@ -31,27 +18,27 @@ describe Ripple::Associations::OneEmbeddedProxy do
31
18
  it "should raise NoMethodError when an undefined method is called on the unset child" do
32
19
  expect { @parent.child.some_undefined_method }.to raise_error(NoMethodError)
33
20
  end
34
-
21
+
35
22
  it "should be able to set and get its child" do
36
23
  @parent.child = @child
37
24
  @parent.child.should equal(@child)
38
25
  end
39
-
26
+
40
27
  it "should set the parent document on the child when assigning" do
41
28
  @parent.child = @child
42
29
  @child._parent_document.should == @parent
43
30
  end
44
-
31
+
45
32
  it "should return the assignment when assigning" do
46
33
  rtn = @parent.child = @child
47
34
  rtn.should == @child
48
35
  end
49
-
36
+
50
37
  it "should set the parent document on the child when accessing" do
51
38
  @parent.child = @child
52
39
  @parent.child._parent_document.should == @parent
53
40
  end
54
-
41
+
55
42
  it "should be able to replace its child with a different child" do
56
43
  @son = Child.new(:name => 'Son')
57
44
  @parent.child = @child
@@ -59,18 +46,18 @@ describe Ripple::Associations::OneEmbeddedProxy do
59
46
  @parent.child = @son
60
47
  @parent.child.name.should == 'Son'
61
48
  end
62
-
49
+
63
50
  it "should be able to build a new child" do
64
51
  Child.stub!(:new).and_return(@child)
65
52
  @parent.child.build.should == @child
66
53
  end
67
-
54
+
68
55
  it "should assign a parent to the child created with instantiate_target" do
69
56
  Child.stub!(:new).and_return(@child)
70
57
  @child._parent_document.should be_nil
71
58
  @parent.child.build._parent_document.should == @parent
72
59
  end
73
-
60
+
74
61
  it "should validate the child when saving the parent" do
75
62
  @parent.valid?.should be_true
76
63
  @child.name = ''
@@ -78,12 +65,12 @@ describe Ripple::Associations::OneEmbeddedProxy do
78
65
  @child.valid?.should be_false
79
66
  @parent.valid?.should be_false
80
67
  end
81
-
68
+
82
69
  it "should not save the root document when a child is invalid" do
83
70
  @parent.child = @child
84
71
  @parent.save.should be_false
85
72
  end
86
-
73
+
87
74
  it "should allow embedding documents in embedded documents" do
88
75
  @parent.child = @child
89
76
  @child.gchild = @gchild
@@ -95,28 +82,28 @@ describe Ripple::Associations::OneEmbeddedProxy do
95
82
  lambda { @parent.child = @gchild }.should raise_error
96
83
  lambda { @child.gchild = [] }.should raise_error
97
84
  end
98
-
85
+
99
86
  describe "callbacks" do
100
87
  before :each do
101
88
  $pinger = mock("callback verifier")
102
89
  end
103
-
90
+
104
91
  it "should run callbacks for the child and documents" do
105
92
  $pinger.should_receive(:ping).once
106
93
  Child.before_validation { $pinger.ping }
107
94
  @child = Child.new
108
95
  @child.valid?
109
- end
96
+ end
110
97
 
111
98
  # this will work using parent and child classes, but only run by itself
112
99
  # it also works using different classes, but only run in this file
113
100
  # IDK why that is, but my Yakshaver 2000 just ran out of juice
114
-
101
+
115
102
  # does this even matter? we call valid? all over the place and that
116
- # will trigger the callback anyway.
117
- # you probably shouldn't use validation callbacks and expect them to
103
+ # will trigger the callback anyway.
104
+ # you probably shouldn't use validation callbacks and expect them to
118
105
  # *only* run once
119
-
106
+
120
107
  # it "should run callbacks for the parent and child and documents respectivly" do
121
108
  # $pinger = mock("callback verifier")
122
109
  # $pinger.should_receive(:ping).once
@@ -128,7 +115,7 @@ describe Ripple::Associations::OneEmbeddedProxy do
128
115
  # @parent.child = @child
129
116
  # @parent.valid?
130
117
  # end
131
-
118
+
132
119
  after :each do
133
120
  Child.reset_callbacks(:validation)
134
121
  Parent.reset_callbacks(:validation)