seomoz-ripple 1.0.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +20 -0
- data/Guardfile +15 -0
- data/Rakefile +88 -0
- data/lib/rails/generators/ripple/configuration/configuration_generator.rb +13 -0
- data/lib/rails/generators/ripple/configuration/templates/ripple.yml +24 -0
- data/lib/rails/generators/ripple/js/js_generator.rb +13 -0
- data/lib/rails/generators/ripple/js/templates/js/contrib.js +63 -0
- data/lib/rails/generators/ripple/js/templates/js/iso8601.js +76 -0
- data/lib/rails/generators/ripple/js/templates/js/ripple.js +132 -0
- data/lib/rails/generators/ripple/model/model_generator.rb +20 -0
- data/lib/rails/generators/ripple/model/templates/model.rb +10 -0
- data/lib/rails/generators/ripple/observer/observer_generator.rb +16 -0
- data/lib/rails/generators/ripple/observer/templates/observer.rb +4 -0
- data/lib/rails/generators/ripple/test/templates/test_server.rb +46 -0
- data/lib/rails/generators/ripple/test/test_generator.rb +39 -0
- data/lib/rails/generators/ripple_generator.rb +78 -0
- data/lib/ripple.rb +79 -0
- data/lib/ripple/associations.rb +356 -0
- data/lib/ripple/associations/embedded.rb +35 -0
- data/lib/ripple/associations/instantiators.rb +26 -0
- data/lib/ripple/associations/linked.rb +65 -0
- data/lib/ripple/associations/many.rb +38 -0
- data/lib/ripple/associations/many_embedded_proxy.rb +38 -0
- data/lib/ripple/associations/many_linked_proxy.rb +66 -0
- data/lib/ripple/associations/many_reference_proxy.rb +93 -0
- data/lib/ripple/associations/many_stored_key_proxy.rb +76 -0
- data/lib/ripple/associations/one.rb +20 -0
- data/lib/ripple/associations/one_embedded_proxy.rb +35 -0
- data/lib/ripple/associations/one_key_proxy.rb +58 -0
- data/lib/ripple/associations/one_linked_proxy.rb +22 -0
- data/lib/ripple/associations/one_stored_key_proxy.rb +43 -0
- data/lib/ripple/associations/proxy.rb +118 -0
- data/lib/ripple/attribute_methods.rb +118 -0
- data/lib/ripple/attribute_methods/dirty.rb +50 -0
- data/lib/ripple/attribute_methods/query.rb +34 -0
- data/lib/ripple/attribute_methods/read.rb +26 -0
- data/lib/ripple/attribute_methods/write.rb +25 -0
- data/lib/ripple/callbacks.rb +74 -0
- data/lib/ripple/conflict/basic_resolver.rb +82 -0
- data/lib/ripple/conflict/document_hooks.rb +20 -0
- data/lib/ripple/conflict/resolver.rb +71 -0
- data/lib/ripple/conflict/test_helper.rb +33 -0
- data/lib/ripple/conversion.rb +28 -0
- data/lib/ripple/core_ext.rb +2 -0
- data/lib/ripple/core_ext/casting.rb +148 -0
- data/lib/ripple/core_ext/object.rb +8 -0
- data/lib/ripple/document.rb +104 -0
- data/lib/ripple/document/bucket_access.rb +25 -0
- data/lib/ripple/document/finders.rb +131 -0
- data/lib/ripple/document/key.rb +43 -0
- data/lib/ripple/document/link.rb +30 -0
- data/lib/ripple/document/persistence.rb +115 -0
- data/lib/ripple/embedded_document.rb +64 -0
- data/lib/ripple/embedded_document/around_callbacks.rb +18 -0
- data/lib/ripple/embedded_document/finders.rb +26 -0
- data/lib/ripple/embedded_document/persistence.rb +77 -0
- data/lib/ripple/i18n.rb +2 -0
- data/lib/ripple/inspection.rb +32 -0
- data/lib/ripple/locale/en.yml +21 -0
- data/lib/ripple/nested_attributes.rb +265 -0
- data/lib/ripple/observable.rb +28 -0
- data/lib/ripple/properties.rb +73 -0
- data/lib/ripple/property_type_mismatch.rb +12 -0
- data/lib/ripple/railtie.rb +13 -0
- data/lib/ripple/serialization.rb +84 -0
- data/lib/ripple/timestamps.rb +27 -0
- data/lib/ripple/translation.rb +14 -0
- data/lib/ripple/validations.rb +67 -0
- data/lib/ripple/validations/associated_validator.rb +43 -0
- data/ripple.gemspec +46 -0
- data/seomoz-ripple.gemspec +46 -0
- data/spec/fixtures/config.yml +8 -0
- data/spec/integration/ripple/associations_spec.rb +220 -0
- data/spec/integration/ripple/conflict_resolution_spec.rb +293 -0
- data/spec/integration/ripple/nested_attributes_spec.rb +264 -0
- data/spec/integration/ripple/persistence_spec.rb +57 -0
- data/spec/integration/ripple/search_associations_spec.rb +42 -0
- data/spec/ripple/associations/many_embedded_proxy_spec.rb +122 -0
- data/spec/ripple/associations/many_linked_proxy_spec.rb +191 -0
- data/spec/ripple/associations/many_reference_proxy_spec.rb +170 -0
- data/spec/ripple/associations/many_stored_key_proxy_spec.rb +158 -0
- data/spec/ripple/associations/one_embedded_proxy_spec.rb +125 -0
- data/spec/ripple/associations/one_key_proxy_spec.rb +82 -0
- data/spec/ripple/associations/one_linked_proxy_spec.rb +91 -0
- data/spec/ripple/associations/one_stored_key_proxy_spec.rb +72 -0
- data/spec/ripple/associations/proxy_spec.rb +84 -0
- data/spec/ripple/associations_spec.rb +129 -0
- data/spec/ripple/attribute_methods/dirty_spec.rb +80 -0
- data/spec/ripple/attribute_methods_spec.rb +230 -0
- data/spec/ripple/bucket_access_spec.rb +25 -0
- data/spec/ripple/callbacks_spec.rb +176 -0
- data/spec/ripple/conflict/resolver_spec.rb +42 -0
- data/spec/ripple/conversion_spec.rb +22 -0
- data/spec/ripple/core_ext_spec.rb +103 -0
- data/spec/ripple/document/link_spec.rb +67 -0
- data/spec/ripple/document_spec.rb +96 -0
- data/spec/ripple/embedded_document/finders_spec.rb +29 -0
- data/spec/ripple/embedded_document/persistence_spec.rb +80 -0
- data/spec/ripple/embedded_document_spec.rb +84 -0
- data/spec/ripple/finders_spec.rb +217 -0
- data/spec/ripple/inspection_spec.rb +51 -0
- data/spec/ripple/key_spec.rb +30 -0
- data/spec/ripple/observable_spec.rb +121 -0
- data/spec/ripple/persistence_spec.rb +326 -0
- data/spec/ripple/properties_spec.rb +262 -0
- data/spec/ripple/ripple_spec.rb +71 -0
- data/spec/ripple/serialization_spec.rb +51 -0
- data/spec/ripple/timestamps_spec.rb +76 -0
- data/spec/ripple/validations/associated_validator_spec.rb +77 -0
- data/spec/ripple/validations_spec.rb +104 -0
- data/spec/spec_helper.rb +26 -0
- data/spec/support/associations.rb +1 -0
- data/spec/support/associations/proxies.rb +17 -0
- data/spec/support/integration_setup.rb +11 -0
- data/spec/support/mocks.rb +4 -0
- data/spec/support/models.rb +4 -0
- data/spec/support/models/address.rb +12 -0
- data/spec/support/models/box.rb +13 -0
- data/spec/support/models/car.rb +16 -0
- data/spec/support/models/cardboard_box.rb +3 -0
- data/spec/support/models/clock.rb +12 -0
- data/spec/support/models/clock_observer.rb +3 -0
- data/spec/support/models/company.rb +23 -0
- data/spec/support/models/customer.rb +4 -0
- data/spec/support/models/driver.rb +6 -0
- data/spec/support/models/email.rb +4 -0
- data/spec/support/models/engine.rb +5 -0
- data/spec/support/models/family.rb +16 -0
- data/spec/support/models/favorite.rb +4 -0
- data/spec/support/models/invoice.rb +7 -0
- data/spec/support/models/late_invoice.rb +3 -0
- data/spec/support/models/ninja.rb +9 -0
- data/spec/support/models/note.rb +5 -0
- data/spec/support/models/page.rb +4 -0
- data/spec/support/models/paid_invoice.rb +4 -0
- data/spec/support/models/passenger.rb +6 -0
- data/spec/support/models/profile.rb +10 -0
- data/spec/support/models/seat.rb +5 -0
- data/spec/support/models/subscription.rb +27 -0
- data/spec/support/models/tasks.rb +14 -0
- data/spec/support/models/team.rb +11 -0
- data/spec/support/models/transactions.rb +17 -0
- data/spec/support/models/tree.rb +4 -0
- data/spec/support/models/user.rb +10 -0
- data/spec/support/models/wheel.rb +6 -0
- data/spec/support/models/widget.rb +22 -0
- data/spec/support/test_server.rb +18 -0
- data/spec/support/test_server.yml.example +2 -0
- metadata +362 -0
@@ -0,0 +1,264 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'active_support/core_ext/array'
|
3
|
+
|
4
|
+
describe Ripple::NestedAttributes do
|
5
|
+
require 'support/models/car'
|
6
|
+
require 'support/models/driver'
|
7
|
+
require 'support/models/passenger'
|
8
|
+
require 'support/models/engine'
|
9
|
+
require 'support/models/seat'
|
10
|
+
require 'support/models/wheel'
|
11
|
+
require 'support/test_server'
|
12
|
+
|
13
|
+
context "one :driver (link)" do
|
14
|
+
subject { Car.new }
|
15
|
+
|
16
|
+
it { should respond_to(:driver_attributes=) }
|
17
|
+
|
18
|
+
it "should not have a driver" do
|
19
|
+
subject.driver.should be_nil
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "creation" do
|
23
|
+
subject { Car.new(:make => 'VW', :model => 'Rabbit', :driver_attributes => { :name => 'Speed Racer' }) }
|
24
|
+
|
25
|
+
it "should have a driver of class Driver" do
|
26
|
+
subject.driver.should be_a(Driver)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should have a driver with name 'Speed Racer'" do
|
30
|
+
subject.driver.name.should == 'Speed Racer'
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should save the child when saving the parent" do
|
34
|
+
subject.driver.should_receive(:save)
|
35
|
+
subject.save
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "update" do
|
40
|
+
let(:driver) { Driver.create(:name => 'Slow Racer') }
|
41
|
+
|
42
|
+
before do
|
43
|
+
subject.driver = driver
|
44
|
+
subject.save
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should have a driver" do
|
48
|
+
subject.driver.should == driver
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should update attributes" do
|
52
|
+
subject.driver_attributes = { :name => 'Speed Racer' }
|
53
|
+
subject.driver.name.should == 'Speed Racer'
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should not save the child if attributes haven't been updated" do
|
57
|
+
subject.driver.should_not_receive(:save)
|
58
|
+
subject.save
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should save the child when saving the parent" do
|
62
|
+
subject.driver_attributes = { :name => 'Speed Racer' }
|
63
|
+
subject.driver.should_receive(:save)
|
64
|
+
subject.save
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "many :passengers (link)" do
|
70
|
+
subject { Car.new }
|
71
|
+
|
72
|
+
it { should respond_to(:passengers_attributes=) }
|
73
|
+
|
74
|
+
it "should not have passengers" do
|
75
|
+
subject.passengers.should == []
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "creation" do
|
79
|
+
subject { Car.new(:make => 'VW',
|
80
|
+
:model => 'Rabbit',
|
81
|
+
:passengers_attributes => [ { :name => 'Joe' },
|
82
|
+
{ :name => 'Sue' },
|
83
|
+
{ :name => 'Pat' } ] ) }
|
84
|
+
|
85
|
+
it "should have 3 passengers" do
|
86
|
+
subject.passengers.size.should == 3
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should have 3 passengers with specified names" do
|
90
|
+
subject.passengers.first.name.should == 'Joe'
|
91
|
+
subject.passengers.second.name.should == 'Sue'
|
92
|
+
subject.passengers.third.name.should == 'Pat'
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should save the children when saving the parent" do
|
96
|
+
subject.save
|
97
|
+
found_subject = Car.find(subject.key)
|
98
|
+
found_subject.passengers.map(&:name).should =~ %w[ Joe Sue Pat ]
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe "update" do
|
103
|
+
let(:passenger1) { Passenger.create(:name => 'One') }
|
104
|
+
let(:passenger2) { Passenger.create(:name => 'Two') }
|
105
|
+
let(:passenger3) { Passenger.create(:name => 'Three') }
|
106
|
+
|
107
|
+
before do
|
108
|
+
subject.passengers << passenger1
|
109
|
+
subject.passengers << passenger2
|
110
|
+
subject.passengers << passenger3
|
111
|
+
subject.save
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should have 3 passengers" do
|
115
|
+
subject.passengers.size.should == 3
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should update attributes" do
|
119
|
+
subject.passengers_attributes = [ { :key => passenger1.key, :name => 'UPDATED One' },
|
120
|
+
{ :key => passenger2.key, :name => 'UPDATED Two' },
|
121
|
+
{ :key => passenger3.key, :name => 'UPDATED Three' } ]
|
122
|
+
subject.passengers.first.name.should == 'UPDATED One'
|
123
|
+
subject.passengers.second.name.should == 'UPDATED Two'
|
124
|
+
subject.passengers.third.name.should == 'UPDATED Three'
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should not save the child if attributes haven't been updated" do
|
128
|
+
subject.passengers.each do |passenger|
|
129
|
+
passenger.should_not_receive(:save)
|
130
|
+
end
|
131
|
+
subject.save
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should save the child when saving the parent" do
|
135
|
+
subject.passengers_attributes = [ { :key => passenger1.key, :name => 'UPDATED One' },
|
136
|
+
{ :key => passenger2.key, :name => 'UPDATED Two' },
|
137
|
+
{ :key => passenger3.key, :name => 'UPDATED Three' } ]
|
138
|
+
subject.save
|
139
|
+
|
140
|
+
found_subject = Car.find(subject.key)
|
141
|
+
found_subject.passengers.map(&:name).should =~ [
|
142
|
+
'UPDATED One',
|
143
|
+
'UPDATED Two',
|
144
|
+
'UPDATED Three'
|
145
|
+
]
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
context "one :engine (embedded)" do
|
151
|
+
subject { Car.new }
|
152
|
+
|
153
|
+
it { should respond_to(:engine_attributes=) }
|
154
|
+
|
155
|
+
it "should not have an engine" do
|
156
|
+
subject.engine.should be_nil
|
157
|
+
end
|
158
|
+
|
159
|
+
describe "creation" do
|
160
|
+
subject { Car.new(:make => 'VW', :model => 'Rabbit', :engine_attributes => { :displacement => '2.5L' }) }
|
161
|
+
|
162
|
+
it "should have an engine of class Engine" do
|
163
|
+
subject.engine.should be_a(Engine)
|
164
|
+
end
|
165
|
+
|
166
|
+
it "should have a engine with displacement '2.5L'" do
|
167
|
+
subject.engine.displacement.should == '2.5L'
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should save the child when saving the parent" do
|
171
|
+
subject.engine.should_not_receive(:save)
|
172
|
+
subject.save
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
describe "update" do
|
177
|
+
before do
|
178
|
+
subject.engine.build(:displacement => '3.6L')
|
179
|
+
subject.save
|
180
|
+
end
|
181
|
+
|
182
|
+
it "should have a specified engine" do
|
183
|
+
subject.engine.displacement.should == '3.6L'
|
184
|
+
end
|
185
|
+
|
186
|
+
it "should update attributes" do
|
187
|
+
subject.engine_attributes = { :displacement => 'UPDATED 3.6L' }
|
188
|
+
subject.engine.displacement.should == 'UPDATED 3.6L'
|
189
|
+
end
|
190
|
+
|
191
|
+
it "should not save the child if attributes haven't been updated" do
|
192
|
+
subject.engine.should_not_receive(:save)
|
193
|
+
subject.save
|
194
|
+
end
|
195
|
+
|
196
|
+
it "should not save the child when saving the parent" do
|
197
|
+
subject.engine_attributes = { :displacement => 'UPDATED 3.6L' }
|
198
|
+
subject.engine.should_not_receive(:save)
|
199
|
+
subject.save
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
context "many :seats (embedded)" do
|
205
|
+
subject { Car.new }
|
206
|
+
|
207
|
+
it { should respond_to(:seats_attributes=) }
|
208
|
+
|
209
|
+
it "should not have passengers" do
|
210
|
+
subject.seats.should == []
|
211
|
+
end
|
212
|
+
|
213
|
+
describe "creation" do
|
214
|
+
subject { Car.new(:make => 'VW',
|
215
|
+
:model => 'Rabbit',
|
216
|
+
:seats_attributes => [ { :color => 'red' },
|
217
|
+
{ :color => 'blue' },
|
218
|
+
{ :color => 'brown' } ] ) }
|
219
|
+
|
220
|
+
it "should have 3 seats" do
|
221
|
+
subject.seats.size.should == 3
|
222
|
+
end
|
223
|
+
|
224
|
+
it "should have 3 passengers with specified names" do
|
225
|
+
subject.seats.first.color.should == 'red'
|
226
|
+
subject.seats.second.color.should == 'blue'
|
227
|
+
subject.seats.third.color.should == 'brown'
|
228
|
+
end
|
229
|
+
|
230
|
+
specify "replace/clobber" do
|
231
|
+
subject.seats_attributes = [ { :color => 'orange' } ]
|
232
|
+
subject.seats.size.should == 1
|
233
|
+
subject.seats.first.color.should == 'orange'
|
234
|
+
end
|
235
|
+
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
context ":reject_if" do
|
240
|
+
it "should not create a wheel" do
|
241
|
+
car = Car.new(:wheels_attributes => [ { :diameter => 10 } ])
|
242
|
+
car.wheels.should == []
|
243
|
+
end
|
244
|
+
|
245
|
+
it "should create a wheel" do
|
246
|
+
car = Car.new(:wheels_attributes => [ { :diameter => 16 } ])
|
247
|
+
car.wheels.size.should == 1
|
248
|
+
car.wheels.first.diameter.should == 16
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
context ":allow_delete" do
|
253
|
+
let(:wheel) { Wheel.create(:diameter => 17) }
|
254
|
+
subject { Car.create(:wheels => [ wheel ] ) }
|
255
|
+
|
256
|
+
it "should allow us to delete the wheel" do
|
257
|
+
subject.wheels_attributes = [ { :key => wheel.key, :_destroy => "1" } ]
|
258
|
+
subject.save
|
259
|
+
subject.wheels.should == []
|
260
|
+
end
|
261
|
+
|
262
|
+
end
|
263
|
+
|
264
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Ripple Persistence" do
|
4
|
+
require 'support/test_server'
|
5
|
+
|
6
|
+
before :all do
|
7
|
+
Object.module_eval do
|
8
|
+
class Widget
|
9
|
+
include Ripple::Document
|
10
|
+
property :name, String
|
11
|
+
property :size, Integer
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
before :each do
|
17
|
+
@widget = Widget.new
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should save an object to the riak database" do
|
21
|
+
@widget.save
|
22
|
+
@found = Widget.find(@widget.key)
|
23
|
+
@found.should be_a(Widget)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should save attributes properly to riak" do
|
27
|
+
@widget.attributes = {:name => 'Sprocket', :size => 10}
|
28
|
+
@widget.save
|
29
|
+
@found = Widget.find(@widget.key)
|
30
|
+
@found.name.should == 'Sprocket'
|
31
|
+
@found.size.should == 10
|
32
|
+
end
|
33
|
+
|
34
|
+
after :each do
|
35
|
+
Widget.destroy_all
|
36
|
+
end
|
37
|
+
|
38
|
+
after :all do
|
39
|
+
Object.send(:remove_const, :Widget)
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
describe Ripple::Document do
|
45
|
+
let(:custom_data) { Subscription::MyCustomType.new('bar') }
|
46
|
+
let(:days_of_month) { Set.new([1, 7, 15, 23]) }
|
47
|
+
let(:subscription) { Subscription.create!(:custom_data => custom_data, :days_of_month => days_of_month) }
|
48
|
+
let(:found_subscription) { Subscription.find(subscription.key) }
|
49
|
+
|
50
|
+
it 'allows properties with custom types to be saved and restored from riak' do
|
51
|
+
found_subscription.custom_data.should == custom_data
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'allows Set properties to be saved and restored from riak' do
|
55
|
+
found_subscription.days_of_month.should == days_of_month
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Ripple Search Associations" do
|
4
|
+
require 'support/test_server'
|
5
|
+
|
6
|
+
before :all do
|
7
|
+
Object.module_eval do
|
8
|
+
class Transaction
|
9
|
+
include Ripple::Document
|
10
|
+
property :account_key, String
|
11
|
+
property :name, String
|
12
|
+
end
|
13
|
+
class Account
|
14
|
+
include Ripple::Document
|
15
|
+
many :transactions, :using => :reference
|
16
|
+
property :email, String
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
before :each do
|
22
|
+
pending("depends upon riak search, which is not available") unless $test_server.riak_search?
|
23
|
+
@account = Account.new(:email => 'riak@ripple.com')
|
24
|
+
@transaction1 = Transaction.new(:name => 'One')
|
25
|
+
@transaction2 = Transaction.new(:name => 'Two')
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should save a many referenced association" do
|
29
|
+
@account.save!
|
30
|
+
@account.transactions << @transaction1 << @transaction2
|
31
|
+
@transaction1.save!
|
32
|
+
@transaction2.save!
|
33
|
+
@found = Account.find(@account.key)
|
34
|
+
@found.transactions.map(&:key).should include(@transaction1.key)
|
35
|
+
@found.transactions.map(&:key).should include(@transaction2.key)
|
36
|
+
end
|
37
|
+
|
38
|
+
after :all do
|
39
|
+
Object.send(:remove_const, :Account)
|
40
|
+
Object.send(:remove_const, :Transaction)
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Ripple::Associations::ManyEmbeddedProxy do
|
4
|
+
require 'support/models/user'
|
5
|
+
require 'support/models/address'
|
6
|
+
require 'support/models/note'
|
7
|
+
|
8
|
+
before :each do
|
9
|
+
@user = User.new
|
10
|
+
@address = Address.new
|
11
|
+
@addr = Address.new(:street => '123 Somewhere')
|
12
|
+
@note = Note.new
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should not have children before any are set" do
|
16
|
+
@user.addresses.should == []
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should be able to set and get its children" do
|
20
|
+
Address.stub!(:instantiate).and_return(@address)
|
21
|
+
@user.addresses = [@address]
|
22
|
+
@user.addresses.should == [@address]
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should set the parent document on the children when assigning" do
|
26
|
+
@user.addresses = [@address]
|
27
|
+
@address._parent_document.should == @user
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should return the assignment when assigning" do
|
31
|
+
rtn = @user.addresses = [@address]
|
32
|
+
rtn.should == [@address]
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should set the parent document on the children when accessing" do
|
36
|
+
@user.addresses = [@address]
|
37
|
+
@user.addresses.first._parent_document.should == @user
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should be able to replace its children with different children" do
|
41
|
+
@user.addresses = [@address]
|
42
|
+
@user.addresses.first.street.should be_blank
|
43
|
+
@user.addresses = [@addr]
|
44
|
+
@user.addresses.first.street.should == '123 Somewhere'
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should be able to add to its children" do
|
48
|
+
Address.stub!(:instantiate).and_return(@address)
|
49
|
+
@user.addresses = [@address]
|
50
|
+
@user.addresses << @address
|
51
|
+
@user.addresses.should == [@address, @address]
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should be able to chain calls to adding children" do
|
55
|
+
Address.stub!(:instantiate).and_return(@address)
|
56
|
+
@user.addresses = [@address]
|
57
|
+
@user.addresses << @address << @address << @address
|
58
|
+
@user.addresses.should == [@address, @address, @address, @address]
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should set the parent document when adding to its children" do
|
62
|
+
@user.addresses << @address
|
63
|
+
@user.addresses.first._parent_document.should == @user
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should be able to count its children" do
|
67
|
+
@user.addresses = [@address, @address]
|
68
|
+
@user.addresses.count.should == 2
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should be able to build a new child" do
|
72
|
+
Address.stub!(:new).and_return(@address)
|
73
|
+
@user.addresses.build.should == @address
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should assign a parent to the children created with instantiate_target" do
|
77
|
+
Address.stub!(:new).and_return(@address)
|
78
|
+
@address._parent_document.should be_nil
|
79
|
+
@user.addresses.build._parent_document.should == @user
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should validate the children when saving the parent" do
|
83
|
+
@user.valid?.should be_true
|
84
|
+
@user.addresses << @address
|
85
|
+
@address.valid?.should be_false
|
86
|
+
@user.valid?.should be_false
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should not save the root document when a child is invalid" do
|
90
|
+
@user.addresses << @address
|
91
|
+
@user.save.should be_false
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should allow embedding documents in embedded documents" do
|
95
|
+
@user.addresses << @address
|
96
|
+
@address.notes << @note
|
97
|
+
@note._root_document.should == @user
|
98
|
+
@note._parent_document.should == @address
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should allow assiging child documents as an array of hashes" do
|
102
|
+
@user.attributes = {'addresses' => [{'street' => '123 Somewhere'}]}
|
103
|
+
@user.addresses.first.street.should == '123 Somewhere'
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should return an array from to_ary" do
|
107
|
+
Address.stub!(:instantiate).and_return(@address)
|
108
|
+
@user.addresses << @address
|
109
|
+
@user.addresses.to_ary.should == [@address]
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should refuse assigning documents of the wrong type" do
|
113
|
+
lambda { @user.addresses = nil }.should raise_error
|
114
|
+
lambda { @user.addresses = @address }.should raise_error
|
115
|
+
lambda { @user.addresses = [@note] }.should raise_error
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should not add the associated validator multiple times" do
|
119
|
+
#$stderr.puts User.validators.collect(&:inspect)
|
120
|
+
User.validators_on(:addresses).count.should eq(1)
|
121
|
+
end
|
122
|
+
end
|