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.
- data/.gitignore +32 -0
- data/Gemfile +10 -9
- data/Guardfile +15 -0
- data/Rakefile +11 -40
- data/lib/rails/generators/ripple/configuration/configuration_generator.rb +0 -13
- data/lib/rails/generators/ripple/configuration/templates/ripple.yml +4 -4
- data/lib/rails/generators/ripple/js/js_generator.rb +0 -13
- data/lib/rails/generators/ripple/js/templates/js/contrib.js +0 -17
- data/lib/rails/generators/ripple/js/templates/js/ripple.js +0 -13
- data/lib/rails/generators/ripple/model/model_generator.rb +0 -14
- data/lib/rails/generators/ripple/model/templates/model.rb +1 -1
- data/lib/rails/generators/ripple/observer/observer_generator.rb +0 -14
- data/lib/rails/generators/ripple/test/test_generator.rb +7 -19
- data/lib/rails/generators/ripple_generator.rb +1 -14
- data/lib/ripple.rb +7 -14
- data/lib/ripple/associations.rb +129 -26
- data/lib/ripple/associations/embedded.rb +1 -15
- data/lib/ripple/associations/instantiators.rb +0 -13
- data/lib/ripple/associations/linked.rb +41 -19
- data/lib/ripple/associations/many.rb +0 -14
- data/lib/ripple/associations/many_embedded_proxy.rb +0 -14
- data/lib/ripple/associations/many_linked_proxy.rb +39 -18
- 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 +1 -15
- data/lib/ripple/associations/one_embedded_proxy.rb +0 -14
- data/lib/ripple/associations/one_key_proxy.rb +58 -0
- data/lib/ripple/associations/one_linked_proxy.rb +4 -14
- data/lib/ripple/associations/one_stored_key_proxy.rb +43 -0
- data/lib/ripple/associations/proxy.rb +8 -14
- data/lib/ripple/attribute_methods.rb +19 -17
- data/lib/ripple/attribute_methods/dirty.rb +19 -15
- data/lib/ripple/attribute_methods/query.rb +0 -14
- data/lib/ripple/attribute_methods/read.rb +0 -14
- data/lib/ripple/attribute_methods/write.rb +0 -14
- data/lib/ripple/callbacks.rb +10 -16
- 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 +0 -14
- data/lib/ripple/core_ext.rb +1 -14
- data/lib/ripple/core_ext/casting.rb +19 -19
- data/lib/ripple/core_ext/object.rb +8 -0
- data/lib/ripple/document.rb +21 -16
- data/lib/ripple/document/bucket_access.rb +0 -14
- data/lib/ripple/document/finders.rb +17 -23
- data/lib/ripple/document/key.rb +8 -28
- data/lib/ripple/document/link.rb +30 -0
- data/lib/ripple/document/persistence.rb +12 -20
- data/lib/ripple/embedded_document.rb +10 -15
- data/lib/ripple/embedded_document/around_callbacks.rb +18 -0
- data/lib/ripple/embedded_document/finders.rb +7 -18
- data/lib/ripple/embedded_document/persistence.rb +5 -17
- data/lib/ripple/i18n.rb +0 -14
- data/lib/ripple/inspection.rb +21 -15
- data/lib/ripple/locale/en.yml +9 -13
- data/lib/ripple/nested_attributes.rb +33 -39
- data/lib/ripple/observable.rb +0 -13
- data/lib/ripple/properties.rb +1 -14
- data/lib/ripple/property_type_mismatch.rb +0 -14
- data/lib/ripple/railtie.rb +4 -14
- data/lib/ripple/railties/ripple.rake +86 -0
- data/lib/ripple/serialization.rb +11 -11
- data/lib/ripple/test_server.rb +36 -0
- data/lib/ripple/timestamps.rb +0 -13
- data/lib/ripple/translation.rb +4 -14
- data/lib/ripple/validations.rb +1 -15
- data/lib/ripple/validations/associated_validator.rb +26 -17
- data/lib/ripple/version.rb +3 -0
- data/ripple.gemspec +24 -35
- data/spec/integration/ripple/associations_spec.rb +89 -58
- data/spec/integration/ripple/conflict_resolution_spec.rb +298 -0
- data/spec/integration/ripple/nested_attributes_spec.rb +19 -19
- data/spec/integration/ripple/persistence_spec.rb +15 -34
- data/spec/integration/ripple/search_associations_spec.rb +31 -0
- data/spec/ripple/associations/many_embedded_proxy_spec.rb +23 -36
- data/spec/ripple/associations/many_linked_proxy_spec.rb +133 -45
- 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 +24 -37
- data/spec/ripple/associations/one_key_proxy_spec.rb +82 -0
- data/spec/ripple/associations/one_linked_proxy_spec.rb +22 -23
- data/spec/ripple/associations/one_stored_key_proxy_spec.rb +72 -0
- data/spec/ripple/associations/proxy_spec.rb +21 -15
- data/spec/ripple/associations_spec.rb +54 -23
- data/spec/ripple/attribute_methods/dirty_spec.rb +56 -5
- data/spec/ripple/attribute_methods_spec.rb +47 -21
- data/spec/ripple/bucket_access_spec.rb +4 -17
- data/spec/ripple/callbacks_spec.rb +52 -15
- data/spec/ripple/conflict/resolver_spec.rb +42 -0
- data/spec/ripple/conversion_spec.rb +2 -15
- data/spec/ripple/core_ext_spec.rb +12 -15
- data/spec/ripple/document/link_spec.rb +67 -0
- data/spec/ripple/document_spec.rb +34 -19
- data/spec/ripple/embedded_document/finders_spec.rb +12 -19
- data/spec/ripple/embedded_document/persistence_spec.rb +20 -26
- data/spec/ripple/embedded_document_spec.rb +44 -34
- data/spec/ripple/finders_spec.rb +58 -29
- data/spec/ripple/inspection_spec.rb +40 -37
- data/spec/ripple/key_spec.rb +5 -17
- data/spec/ripple/observable_spec.rb +3 -16
- data/spec/ripple/persistence_spec.rb +134 -18
- data/spec/ripple/properties_spec.rb +21 -15
- data/spec/ripple/ripple_spec.rb +1 -14
- data/spec/ripple/serialization_spec.rb +16 -17
- data/spec/ripple/timestamps_spec.rb +73 -52
- data/spec/ripple/validations/associated_validator_spec.rb +69 -25
- data/spec/ripple/validations_spec.rb +3 -16
- data/spec/spec_helper.rb +17 -18
- data/spec/support/associations.rb +1 -1
- data/spec/support/associations/proxies.rb +0 -13
- data/spec/support/integration_setup.rb +11 -0
- data/spec/support/mocks.rb +0 -13
- data/spec/support/models.rb +33 -2
- data/spec/support/models/address.rb +1 -16
- data/spec/support/models/box.rb +7 -14
- data/spec/support/models/car.rb +27 -1
- data/spec/support/models/cardboard_box.rb +0 -14
- data/spec/support/models/clock.rb +6 -15
- data/spec/support/models/clock_observer.rb +0 -14
- data/spec/support/models/credit_card.rb +5 -0
- data/spec/support/models/customer.rb +0 -14
- data/spec/support/models/email.rb +0 -14
- data/spec/support/models/family.rb +1 -13
- data/spec/support/models/favorite.rb +0 -14
- data/spec/support/models/invoice.rb +0 -14
- data/spec/support/models/late_invoice.rb +0 -14
- data/spec/support/models/nested.rb +12 -0
- data/spec/support/models/ninja.rb +7 -0
- data/spec/support/models/note.rb +0 -14
- data/spec/support/models/page.rb +1 -15
- data/spec/support/models/paid_invoice.rb +0 -14
- data/spec/support/models/post.rb +12 -0
- data/spec/support/models/profile.rb +7 -0
- data/spec/support/models/subscription.rb +26 -0
- data/spec/support/models/tasks.rb +0 -18
- data/spec/support/models/team.rb +11 -0
- data/spec/support/models/transactions.rb +17 -0
- data/spec/support/models/tree.rb +2 -16
- data/spec/support/models/user.rb +14 -16
- data/spec/support/models/widget.rb +8 -14
- data/spec/support/search.rb +14 -0
- data/spec/support/test_server.rb +22 -12
- data/spec/support/test_server.yml.example +14 -2
- metadata +223 -59
- data/lib/rails/generators/ripple/test/templates/test_server.rb +0 -46
- data/spec/support/models/driver.rb +0 -5
- data/spec/support/models/engine.rb +0 -4
- data/spec/support/models/passenger.rb +0 -5
- data/spec/support/models/seat.rb +0 -4
- data/spec/support/models/wheel.rb +0 -5
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
require
|
|
1
|
+
require 'spec_helper'
|
|
2
2
|
require 'active_support/core_ext/array'
|
|
3
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'
|
|
4
|
+
describe Ripple::NestedAttributes, :integration => true 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'
|
|
12
11
|
|
|
13
12
|
context "one :driver (link)" do
|
|
14
13
|
subject { Car.new }
|
|
@@ -93,10 +92,9 @@ describe Ripple::NestedAttributes do
|
|
|
93
92
|
end
|
|
94
93
|
|
|
95
94
|
it "should save the children when saving the parent" do
|
|
96
|
-
subject.passengers.each do |passenger|
|
|
97
|
-
passenger.should_receive(:save)
|
|
98
|
-
end
|
|
99
95
|
subject.save
|
|
96
|
+
found_subject = Car.find(subject.key)
|
|
97
|
+
found_subject.passengers.map(&:name).should =~ %w[ Joe Sue Pat ]
|
|
100
98
|
end
|
|
101
99
|
end
|
|
102
100
|
|
|
@@ -134,12 +132,16 @@ describe Ripple::NestedAttributes do
|
|
|
134
132
|
|
|
135
133
|
it "should save the child when saving the parent" do
|
|
136
134
|
subject.passengers_attributes = [ { :key => passenger1.key, :name => 'UPDATED One' },
|
|
137
|
-
{ :key =>
|
|
138
|
-
{ :key =>
|
|
139
|
-
subject.passengers.each do |passenger|
|
|
140
|
-
passenger.should_receive(:save)
|
|
141
|
-
end
|
|
135
|
+
{ :key => passenger2.key, :name => 'UPDATED Two' },
|
|
136
|
+
{ :key => passenger3.key, :name => 'UPDATED Three' } ]
|
|
142
137
|
subject.save
|
|
138
|
+
|
|
139
|
+
found_subject = Car.find(subject.key)
|
|
140
|
+
found_subject.passengers.map(&:name).should =~ [
|
|
141
|
+
'UPDATED One',
|
|
142
|
+
'UPDATED Two',
|
|
143
|
+
'UPDATED Three'
|
|
144
|
+
]
|
|
143
145
|
end
|
|
144
146
|
end
|
|
145
147
|
end
|
|
@@ -255,7 +257,5 @@ describe Ripple::NestedAttributes do
|
|
|
255
257
|
subject.save
|
|
256
258
|
subject.wheels.should == []
|
|
257
259
|
end
|
|
258
|
-
|
|
259
260
|
end
|
|
260
|
-
|
|
261
261
|
end
|
|
@@ -1,41 +1,16 @@
|
|
|
1
|
-
|
|
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 Persistence" do
|
|
17
|
-
require 'support/test_server'
|
|
18
|
-
|
|
19
|
-
before :all do
|
|
20
|
-
Object.module_eval do
|
|
21
|
-
class Widget
|
|
22
|
-
include Ripple::Document
|
|
23
|
-
property :name, String
|
|
24
|
-
property :size, Integer
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
4
|
before :each do
|
|
30
5
|
@widget = Widget.new
|
|
31
6
|
end
|
|
32
|
-
|
|
7
|
+
|
|
33
8
|
it "should save an object to the riak database" do
|
|
34
9
|
@widget.save
|
|
35
10
|
@found = Widget.find(@widget.key)
|
|
36
11
|
@found.should be_a(Widget)
|
|
37
12
|
end
|
|
38
|
-
|
|
13
|
+
|
|
39
14
|
it "should save attributes properly to riak" do
|
|
40
15
|
@widget.attributes = {:name => 'Sprocket', :size => 10}
|
|
41
16
|
@widget.save
|
|
@@ -43,13 +18,19 @@ describe "Ripple Persistence" do
|
|
|
43
18
|
@found.name.should == 'Sprocket'
|
|
44
19
|
@found.size.should == 10
|
|
45
20
|
end
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe Ripple::Document do
|
|
24
|
+
let(:custom_data) { Subscription::MyCustomType.new('bar') }
|
|
25
|
+
let(:days_of_month) { Set.new([1, 7, 15, 23]) }
|
|
26
|
+
let(:subscription) { Subscription.create!(:custom_data => custom_data, :days_of_month => days_of_month) }
|
|
27
|
+
let(:found_subscription) { Subscription.find(subscription.key) }
|
|
28
|
+
|
|
29
|
+
it 'allows properties with custom types to be saved and restored from riak' do
|
|
30
|
+
found_subscription.custom_data.should == custom_data
|
|
49
31
|
end
|
|
50
32
|
|
|
51
|
-
|
|
52
|
-
|
|
33
|
+
it 'allows Set properties to be saved and restored from riak' do
|
|
34
|
+
found_subscription.days_of_month.should == days_of_month
|
|
53
35
|
end
|
|
54
|
-
|
|
55
36
|
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "Ripple Search Associations", :integration => true, :search => true do
|
|
4
|
+
class SearchTransaction
|
|
5
|
+
include Ripple::Document
|
|
6
|
+
property :search_account_key, String
|
|
7
|
+
property :name, String
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
class SearchAccount
|
|
11
|
+
include Ripple::Document
|
|
12
|
+
many :search_transactions, :using => :reference
|
|
13
|
+
property :email, String
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
before :each do
|
|
17
|
+
@account = SearchAccount.new(:email => 'riak@ripple.com')
|
|
18
|
+
@transaction1 = SearchTransaction.new(:name => 'One')
|
|
19
|
+
@transaction2 = SearchTransaction.new(:name => 'Two')
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "should save a many referenced association" do
|
|
23
|
+
@account.save!
|
|
24
|
+
@account.search_transactions << @transaction1 << @transaction2
|
|
25
|
+
@transaction1.save!
|
|
26
|
+
@transaction2.save!
|
|
27
|
+
@found = SearchAccount.find(@account.key)
|
|
28
|
+
@found.search_transactions.map(&:key).should include(@transaction1.key)
|
|
29
|
+
@found.search_transactions.map(&:key).should include(@transaction2.key)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -1,81 +1,68 @@
|
|
|
1
|
-
|
|
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::ManyEmbeddedProxy do
|
|
17
|
-
require 'support/models/user'
|
|
18
|
-
require 'support/models/address'
|
|
19
|
-
require 'support/models/note'
|
|
20
|
-
|
|
4
|
+
# require 'support/models/user'
|
|
5
|
+
# require 'support/models/address'
|
|
6
|
+
# require 'support/models/note'
|
|
7
|
+
|
|
21
8
|
before :each do
|
|
22
|
-
@user = User.new
|
|
9
|
+
@user = User.new(:email => "riak@ripple.com")
|
|
23
10
|
@address = Address.new
|
|
24
11
|
@addr = Address.new(:street => '123 Somewhere')
|
|
25
12
|
@note = Note.new
|
|
26
13
|
end
|
|
27
|
-
|
|
14
|
+
|
|
28
15
|
it "should not have children before any are set" do
|
|
29
16
|
@user.addresses.should == []
|
|
30
17
|
end
|
|
31
|
-
|
|
18
|
+
|
|
32
19
|
it "should be able to set and get its children" do
|
|
33
20
|
Address.stub!(:instantiate).and_return(@address)
|
|
34
21
|
@user.addresses = [@address]
|
|
35
22
|
@user.addresses.should == [@address]
|
|
36
23
|
end
|
|
37
|
-
|
|
24
|
+
|
|
38
25
|
it "should set the parent document on the children when assigning" do
|
|
39
26
|
@user.addresses = [@address]
|
|
40
27
|
@address._parent_document.should == @user
|
|
41
28
|
end
|
|
42
|
-
|
|
29
|
+
|
|
43
30
|
it "should return the assignment when assigning" do
|
|
44
31
|
rtn = @user.addresses = [@address]
|
|
45
32
|
rtn.should == [@address]
|
|
46
33
|
end
|
|
47
|
-
|
|
34
|
+
|
|
48
35
|
it "should set the parent document on the children when accessing" do
|
|
49
36
|
@user.addresses = [@address]
|
|
50
37
|
@user.addresses.first._parent_document.should == @user
|
|
51
38
|
end
|
|
52
|
-
|
|
39
|
+
|
|
53
40
|
it "should be able to replace its children with different children" do
|
|
54
41
|
@user.addresses = [@address]
|
|
55
42
|
@user.addresses.first.street.should be_blank
|
|
56
43
|
@user.addresses = [@addr]
|
|
57
44
|
@user.addresses.first.street.should == '123 Somewhere'
|
|
58
45
|
end
|
|
59
|
-
|
|
46
|
+
|
|
60
47
|
it "should be able to add to its children" do
|
|
61
48
|
Address.stub!(:instantiate).and_return(@address)
|
|
62
49
|
@user.addresses = [@address]
|
|
63
50
|
@user.addresses << @address
|
|
64
51
|
@user.addresses.should == [@address, @address]
|
|
65
52
|
end
|
|
66
|
-
|
|
53
|
+
|
|
67
54
|
it "should be able to chain calls to adding children" do
|
|
68
55
|
Address.stub!(:instantiate).and_return(@address)
|
|
69
56
|
@user.addresses = [@address]
|
|
70
57
|
@user.addresses << @address << @address << @address
|
|
71
58
|
@user.addresses.should == [@address, @address, @address, @address]
|
|
72
59
|
end
|
|
73
|
-
|
|
60
|
+
|
|
74
61
|
it "should set the parent document when adding to its children" do
|
|
75
62
|
@user.addresses << @address
|
|
76
63
|
@user.addresses.first._parent_document.should == @user
|
|
77
64
|
end
|
|
78
|
-
|
|
65
|
+
|
|
79
66
|
it "should be able to count its children" do
|
|
80
67
|
@user.addresses = [@address, @address]
|
|
81
68
|
@user.addresses.count.should == 2
|
|
@@ -85,37 +72,37 @@ describe Ripple::Associations::ManyEmbeddedProxy do
|
|
|
85
72
|
Address.stub!(:new).and_return(@address)
|
|
86
73
|
@user.addresses.build.should == @address
|
|
87
74
|
end
|
|
88
|
-
|
|
75
|
+
|
|
89
76
|
it "should assign a parent to the children created with instantiate_target" do
|
|
90
77
|
Address.stub!(:new).and_return(@address)
|
|
91
78
|
@address._parent_document.should be_nil
|
|
92
79
|
@user.addresses.build._parent_document.should == @user
|
|
93
80
|
end
|
|
94
|
-
|
|
81
|
+
|
|
95
82
|
it "should validate the children when saving the parent" do
|
|
96
83
|
@user.valid?.should be_true
|
|
97
84
|
@user.addresses << @address
|
|
98
85
|
@address.valid?.should be_false
|
|
99
86
|
@user.valid?.should be_false
|
|
100
87
|
end
|
|
101
|
-
|
|
88
|
+
|
|
102
89
|
it "should not save the root document when a child is invalid" do
|
|
103
90
|
@user.addresses << @address
|
|
104
91
|
@user.save.should be_false
|
|
105
92
|
end
|
|
106
|
-
|
|
93
|
+
|
|
107
94
|
it "should allow embedding documents in embedded documents" do
|
|
108
95
|
@user.addresses << @address
|
|
109
96
|
@address.notes << @note
|
|
110
97
|
@note._root_document.should == @user
|
|
111
98
|
@note._parent_document.should == @address
|
|
112
99
|
end
|
|
113
|
-
|
|
100
|
+
|
|
114
101
|
it "should allow assiging child documents as an array of hashes" do
|
|
115
102
|
@user.attributes = {'addresses' => [{'street' => '123 Somewhere'}]}
|
|
116
103
|
@user.addresses.first.street.should == '123 Somewhere'
|
|
117
104
|
end
|
|
118
|
-
|
|
105
|
+
|
|
119
106
|
it "should return an array from to_ary" do
|
|
120
107
|
Address.stub!(:instantiate).and_return(@address)
|
|
121
108
|
@user.addresses << @address
|
|
@@ -127,7 +114,7 @@ describe Ripple::Associations::ManyEmbeddedProxy do
|
|
|
127
114
|
lambda { @user.addresses = @address }.should raise_error
|
|
128
115
|
lambda { @user.addresses = [@note] }.should raise_error
|
|
129
116
|
end
|
|
130
|
-
|
|
117
|
+
|
|
131
118
|
it "should not add the associated validator multiple times" do
|
|
132
119
|
#$stderr.puts User.validators.collect(&:inspect)
|
|
133
120
|
User.validators_on(:addresses).count.should eq(1)
|
|
@@ -1,25 +1,13 @@
|
|
|
1
|
-
|
|
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::ManyLinkedProxy do
|
|
17
|
-
require 'support/models/tasks'
|
|
4
|
+
# require 'support/models/tasks'
|
|
18
5
|
|
|
19
6
|
before :each do
|
|
20
7
|
@person = Person.new {|p| p.key = "riak-user" }
|
|
21
8
|
@task = Task.new {|t| t.key = "one" }
|
|
22
9
|
@other_task = Task.new {|t| t.key = "two" }
|
|
10
|
+
@third_task = Task.new {|t| t.key = "three" }
|
|
23
11
|
[@person, @task, @other_task].each do |doc|
|
|
24
12
|
doc.stub!(:new?).and_return(false)
|
|
25
13
|
end
|
|
@@ -35,7 +23,13 @@ describe Ripple::Associations::ManyLinkedProxy do
|
|
|
35
23
|
|
|
36
24
|
it "should set the links on the RObject when assigning" do
|
|
37
25
|
@person.tasks = [@task]
|
|
38
|
-
@person.robject.links.should include(@task.
|
|
26
|
+
@person.robject.links.should include(@task.to_link("tasks"))
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "should be able to replace the entire collection of documents (even appended ones)" do
|
|
30
|
+
@person.tasks << @task
|
|
31
|
+
@person.tasks = [@other_task]
|
|
32
|
+
@person.tasks.should == [@other_task]
|
|
39
33
|
end
|
|
40
34
|
|
|
41
35
|
it "should return the assigned documents when assigning" do
|
|
@@ -43,47 +37,39 @@ describe Ripple::Associations::ManyLinkedProxy do
|
|
|
43
37
|
t.should == [@task]
|
|
44
38
|
end
|
|
45
39
|
|
|
46
|
-
it "should save unsaved documents when assigning" do
|
|
47
|
-
@task.should_receive(:new?).and_return(true)
|
|
48
|
-
@task.should_receive(:save).and_return(true)
|
|
49
|
-
@person.tasks = [@task]
|
|
50
|
-
end
|
|
51
|
-
|
|
52
40
|
it "should link-walk to the associated documents when accessing" do
|
|
53
|
-
@person.robject.links << @task.
|
|
41
|
+
@person.robject.links << @task.to_link("tasks")
|
|
54
42
|
@person.robject.should_receive(:walk).with(Riak::WalkSpec.new(:bucket => "tasks", :tag => "tasks")).and_return([])
|
|
55
43
|
@person.tasks.should == []
|
|
56
44
|
end
|
|
57
45
|
|
|
58
|
-
it "
|
|
59
|
-
@person.tasks
|
|
60
|
-
@person.
|
|
61
|
-
|
|
62
|
-
|
|
46
|
+
it "handles conflict appropriately by selecting the linked-walk robjects that match the links" do
|
|
47
|
+
@person.robject.links << @task.to_link("tasks") << @other_task.to_link("tasks")
|
|
48
|
+
@person.robject.
|
|
49
|
+
should_receive(:walk).
|
|
50
|
+
with(Riak::WalkSpec.new(:bucket => "tasks", :tag => "tasks")).
|
|
51
|
+
and_return([[@task.robject, @other_task.robject, @third_task.robject]])
|
|
63
52
|
|
|
64
|
-
|
|
65
|
-
@person.tasks << @task
|
|
66
|
-
@person.tasks << @other_task
|
|
67
|
-
@person.should have(2).tasks
|
|
53
|
+
@person.tasks.should == [@task, @other_task]
|
|
68
54
|
end
|
|
69
55
|
|
|
70
|
-
it "
|
|
71
|
-
@person.tasks
|
|
72
|
-
@person.
|
|
56
|
+
it "allows the links to be replaced directly" do
|
|
57
|
+
@person.tasks = [@task]
|
|
58
|
+
@person.tasks.__send__(:should_receive, :reset)
|
|
59
|
+
@person.tasks.__send__(:links).should == [@task.robject.to_link("tasks")]
|
|
60
|
+
@person.tasks.replace_links([@other_task, @third_task].map { |t| t.robject.to_link("tasks") })
|
|
61
|
+
@person.tasks.__send__(:links).should == [@other_task, @third_task].map { |t| t.robject.to_link("tasks") }
|
|
73
62
|
end
|
|
74
63
|
|
|
75
|
-
it "should
|
|
76
|
-
@person.tasks
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
end
|
|
64
|
+
it "should replace associated documents with a new set" do
|
|
65
|
+
@person.tasks = [@task]
|
|
66
|
+
@person.tasks = [@other_task]
|
|
67
|
+
@person.tasks.should == [@other_task]
|
|
80
68
|
end
|
|
81
69
|
|
|
82
|
-
it "
|
|
83
|
-
@person.tasks
|
|
84
|
-
@person.tasks.count.should ==
|
|
85
|
-
@person.tasks << @other_task
|
|
86
|
-
@person.tasks.count.should == 2
|
|
70
|
+
it "asks the keys set for the count to avoid having to unnecessarily load all documents" do
|
|
71
|
+
@person.tasks.keys.stub(:size => 17)
|
|
72
|
+
@person.tasks.count.should == 17
|
|
87
73
|
end
|
|
88
74
|
|
|
89
75
|
# it "should be able to build a new associated document" do
|
|
@@ -100,4 +86,106 @@ describe Ripple::Associations::ManyLinkedProxy do
|
|
|
100
86
|
lambda { @person.tasks = @task }.should raise_error
|
|
101
87
|
lambda { @person.tasks = [@person] }.should raise_error
|
|
102
88
|
end
|
|
89
|
+
|
|
90
|
+
describe "#<< (when the target has not already been loaded)" do
|
|
91
|
+
it "avoids link-walking when adding a record to an unloaded association" do
|
|
92
|
+
@person.robject.should_not_receive(:walk)
|
|
93
|
+
@person.tasks << @task
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it "should be able to count the associated documents" do
|
|
97
|
+
@person.tasks << @task
|
|
98
|
+
@person.tasks.count.should == 1
|
|
99
|
+
@person.tasks << @other_task
|
|
100
|
+
@person.tasks.count.should == 2
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it "maintains the list of keys properly as new documents are appended" do
|
|
104
|
+
@person.tasks << @task
|
|
105
|
+
@person.tasks.should have(1).key
|
|
106
|
+
@person.tasks << @other_task
|
|
107
|
+
@person.tasks.should have(2).keys
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it "should be able to append documents to the associated set" do
|
|
111
|
+
@person.tasks << @task
|
|
112
|
+
@person.tasks << @other_task
|
|
113
|
+
@person.should have(2).tasks
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
it "should be able to chain calls to adding documents" do
|
|
117
|
+
@person.tasks << @task << @other_task
|
|
118
|
+
@person.should have(2).tasks
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
it "should set the links on the RObject when appending" do
|
|
122
|
+
@person.tasks << @task << @other_task
|
|
123
|
+
[@task, @other_task].each do |t|
|
|
124
|
+
@person.robject.links.should include(t.to_link("tasks"))
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
it "does not return duplicates (for when the object has been appended and it's robject is found while walking the links)" do
|
|
129
|
+
@person.tasks.stub(:robjects => [@task.robject])
|
|
130
|
+
@person.tasks.reset
|
|
131
|
+
@person.tasks << @task
|
|
132
|
+
@person.tasks.should == [@task]
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
describe "#reset" do
|
|
137
|
+
it "clears appended documents" do
|
|
138
|
+
@person.tasks << @task
|
|
139
|
+
@person.tasks.reset
|
|
140
|
+
@person.tasks.should == []
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
describe "#keys" do
|
|
145
|
+
let(:link_keys) { %w[ 1 2 3 ] }
|
|
146
|
+
let(:links) { link_keys.map { |k| Riak::Link.new('tasks', k, 'task') } }
|
|
147
|
+
|
|
148
|
+
before(:each) do
|
|
149
|
+
@person.tasks.stub(:links => links)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
it "returns a set of keys" do
|
|
153
|
+
@person.tasks.keys.should be_a(Set)
|
|
154
|
+
@person.tasks.keys.to_a.should == link_keys
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
it "is memoized between calls" do
|
|
158
|
+
@person.tasks.keys.should equal(@person.tasks.keys)
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
it "is cleared when the association is reset" do
|
|
162
|
+
orig_set = @person.tasks.keys
|
|
163
|
+
@person.tasks.reset
|
|
164
|
+
@person.tasks.keys.should_not equal(orig_set)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
it "is cleared when the association is replaced" do
|
|
168
|
+
orig_set = @person.tasks.keys
|
|
169
|
+
@person.tasks.replace([@task])
|
|
170
|
+
@person.tasks.keys.should_not equal(orig_set)
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
describe "#include?" do
|
|
175
|
+
it "delegates to the set of keys so as not to unnecessarily load the associated documents" do
|
|
176
|
+
@person.tasks.keys.should_receive(:include?).with(@task.key).and_return(true)
|
|
177
|
+
@person.tasks.include?(@task).should be_true
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
it "short-circuits and returns false if the given object is not a ripple document" do
|
|
181
|
+
@person.tasks.keys.should_not_receive(:include?)
|
|
182
|
+
@person.tasks.include?(Object.new).should be_false
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
it "returns false if the document's bucket is different from the associations bucket, even if the keys are the same" do
|
|
186
|
+
@person.tasks << @task
|
|
187
|
+
other_person = Person.new { |p| p.key = @task.key }
|
|
188
|
+
@person.tasks.include?(other_person).should be_false
|
|
189
|
+
end
|
|
190
|
+
end
|
|
103
191
|
end
|