ripple 0.9.5 → 1.0.0.beta
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Ripple::Associations::OneKeyProxy do
|
4
|
+
|
5
|
+
before :each do
|
6
|
+
@user = User.new
|
7
|
+
@profile = Profile.new(:color => 'blue')
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "User with a key corresponded profile" do
|
11
|
+
it "should not have a profile before it is set" do
|
12
|
+
@user.profile.should be_nil
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should be able to get and set its profile" do
|
16
|
+
@user.profile = @profile
|
17
|
+
@user.profile.should eq(@profile)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should return the assignment when assigning" do
|
21
|
+
rtn = @user.profile = @profile
|
22
|
+
rtn.should eq(@profile)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should be able to replace its profile with a new one" do
|
26
|
+
@user.profile = @profile
|
27
|
+
@user.profile = Profile.new(:color => 'red')
|
28
|
+
@user.profile.color.should eq('red')
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should be able to build a new profile" do
|
32
|
+
Profile.stub(:new).and_return(@profile)
|
33
|
+
@user.profile.build.should eq(@profile)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should assign its key to the associated profile when assigning" do
|
37
|
+
@user.key = "foo"
|
38
|
+
@user.profile = @profile
|
39
|
+
@profile.key.should eq("foo")
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should assign its key to the built profile" do
|
43
|
+
@user.key = "foo"
|
44
|
+
@user.profile.build.key.should eq("foo")
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should update the key on the profile when updating it on the user" do
|
48
|
+
@user.profile = @profile
|
49
|
+
@user.key = "foo"
|
50
|
+
@profile.key.should eq("foo")
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should not update the key of a previous profile" do
|
54
|
+
@profile2 = Profile.new
|
55
|
+
@user.profile = @profile
|
56
|
+
@user.profile = @profile2
|
57
|
+
@user.key = "foo"
|
58
|
+
@profile.key.should_not eq("foo")
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should not infinitely loop when assigning a user to the profile" do
|
62
|
+
@user2 = User.new
|
63
|
+
@user.profile = @profile
|
64
|
+
@profile.user = @user2
|
65
|
+
@profile.key = "foo"
|
66
|
+
@user2.key.should eq("foo")
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should update the user's key when being updated on the profile" do
|
70
|
+
@user.profile = @profile
|
71
|
+
@profile.key = "foo"
|
72
|
+
@user.key.should eq("foo")
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should work properly with custom key methods" do
|
76
|
+
@user = Ninja.new(:name => 'Naruto')
|
77
|
+
@user.profile = @profile
|
78
|
+
@profile.key.should eq("ninja-naruto")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
@@ -1,21 +1,8 @@
|
|
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::OneLinkedProxy do
|
17
|
-
require 'support/models/tasks'
|
18
|
-
require 'support/models/family'
|
4
|
+
# require 'support/models/tasks'
|
5
|
+
# require 'support/models/family'
|
19
6
|
|
20
7
|
before :each do
|
21
8
|
@person = Person.new {|p| p.key = "riak-user" }
|
@@ -36,7 +23,7 @@ describe Ripple::Associations::OneLinkedProxy do
|
|
36
23
|
|
37
24
|
it "should set the link on the RObject when assigning" do
|
38
25
|
@person.profile = @profile
|
39
|
-
@person.robject.links.should include(@profile.
|
26
|
+
@person.robject.links.should include(@profile.to_link("profile"))
|
40
27
|
end
|
41
28
|
|
42
29
|
it "should return the assigned document when assigning" do
|
@@ -44,18 +31,30 @@ describe Ripple::Associations::OneLinkedProxy do
|
|
44
31
|
ret.should == @profile
|
45
32
|
end
|
46
33
|
|
47
|
-
it "should save the new document when assigning" do
|
48
|
-
@profile.should_receive(:new?).and_return(true)
|
49
|
-
@profile.should_receive(:save).and_return(true)
|
50
|
-
@person.profile = @profile
|
51
|
-
end
|
52
|
-
|
53
34
|
it "should link-walk to the associated document when accessing" do
|
54
35
|
@person.robject.links << @profile.robject.to_link("profile")
|
55
36
|
@person.robject.should_receive(:walk).with(Riak::WalkSpec.new(:bucket => "profiles", :tag => "profile")).and_return([[@profile.robject]])
|
56
37
|
@person.profile.should be_present
|
57
38
|
end
|
58
39
|
|
40
|
+
it "handles conflict appropriately by selecting the linked-walk robject that matches the link" do
|
41
|
+
@person.robject.links << @profile.robject.to_link("profile")
|
42
|
+
@person.robject.
|
43
|
+
should_receive(:walk).
|
44
|
+
with(Riak::WalkSpec.new(:bucket => "profiles", :tag => "profile")).
|
45
|
+
and_return([[@other_profile.robject, @profile.robject]])
|
46
|
+
|
47
|
+
@person.profile.should == @profile
|
48
|
+
end
|
49
|
+
|
50
|
+
it "allows the links to be replaced directly" do
|
51
|
+
@person.profile = @profile
|
52
|
+
@person.profile.__send__(:should_receive, :reset)
|
53
|
+
@person.profile.__send__(:links).should == [@profile.robject.to_link("profile")]
|
54
|
+
@person.profile.replace_links(@other_profile.robject.to_link("profile"))
|
55
|
+
@person.profile.__send__(:links).should == [@other_profile.robject.to_link("profile")]
|
56
|
+
end
|
57
|
+
|
59
58
|
it "should return nil immediately if the association link is missing" do
|
60
59
|
@person.robject.links.should be_empty
|
61
60
|
@person.profile.should be_nil
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Ripple::Associations::OneStoredKeyProxy do
|
4
|
+
# require 'support/models/transactions'
|
5
|
+
# require 'support/models/family'
|
6
|
+
|
7
|
+
before :each do
|
8
|
+
@account = Account.new {|e| e.key = "accounty" }
|
9
|
+
@other_account = Account.new{|e| e.key = "ickycount" }
|
10
|
+
@transaction = Transaction.new{|e| e.key = "transacty" }
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should be blank before the associated document is set" do
|
14
|
+
@transaction.account.should_not be_present
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should accept a single document" do
|
18
|
+
lambda { @transaction.account = @account }.should_not raise_error
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should set the key when assigning" do
|
22
|
+
@transaction.account = @account
|
23
|
+
@transaction.account_key.should == "accounty"
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should return the assigned document when assigning" do
|
27
|
+
ret = (@transaction.account = @account)
|
28
|
+
ret.should == @account
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should find the associated document when accessing" do
|
32
|
+
@transaction.account_key = "accounty"
|
33
|
+
Account.should_receive(:find).with("accounty").and_return(@account)
|
34
|
+
@transaction.account.should be_present
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should return nil immediately if the association link is missing" do
|
38
|
+
@transaction.account_key.should be_nil
|
39
|
+
@transaction.account.should be_nil
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should replace associated document with a new one" do
|
43
|
+
@transaction.account = @account
|
44
|
+
@transaction.account = @other_account
|
45
|
+
@transaction.account.should == @other_account
|
46
|
+
@transaction.account_key.should == "ickycount"
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should replace the associated document with the target of the proxy" do
|
50
|
+
other_transaction = Transaction.new {|e| e.key = "ickytrans" }
|
51
|
+
other_transaction.account = @other_account
|
52
|
+
|
53
|
+
@transaction.account = other_transaction.account
|
54
|
+
@transaction.account.should == @other_account
|
55
|
+
end
|
56
|
+
|
57
|
+
it "refuses assigning a proxy if its target is the wrong type" do
|
58
|
+
parent = Parent.new{|e| e.child = Child.new}
|
59
|
+
lambda { @transaction.account = parent.child }.should raise_error
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should refuse assigning a document of the wrong type" do
|
63
|
+
lambda { @transaction.account = @transaction }.should raise_error
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should nil out the association if nil is assigned" do
|
67
|
+
@transaction.account = @account
|
68
|
+
@transaction.account = nil
|
69
|
+
@transaction.account.should be_nil
|
70
|
+
@transaction.account_key.should be_nil
|
71
|
+
end
|
72
|
+
end
|
@@ -1,17 +1,4 @@
|
|
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::Proxy do
|
17
4
|
require 'support/associations/proxies'
|
@@ -75,4 +62,23 @@ describe Ripple::Associations::Proxy do
|
|
75
62
|
it { should be_blank }
|
76
63
|
it { should_not be_present }
|
77
64
|
end
|
78
|
-
|
65
|
+
|
66
|
+
describe "#has_changed_documents?" do
|
67
|
+
before(:each) { @proxy.respond_to?(:loaded_documents).should be_true }
|
68
|
+
|
69
|
+
it "returns true if any of the loaded documents return true from #changed?" do
|
70
|
+
@proxy.stub(:loaded_documents => [stub(:changed? => false), stub(:changed? => true)])
|
71
|
+
@proxy.has_changed_documents?.should be_true
|
72
|
+
end
|
73
|
+
|
74
|
+
it "returns false if none of the loaded documents return true from #changed?" do
|
75
|
+
@proxy.stub(:loaded_documents => [stub(:changed? => false), stub(:changed? => false)])
|
76
|
+
@proxy.has_changed_documents?.should be_false
|
77
|
+
end
|
78
|
+
|
79
|
+
it "returns false if it has no loaded documents" do
|
80
|
+
@proxy.stub(:loaded_documents => [])
|
81
|
+
@proxy.has_changed_documents?.should be_false
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -1,22 +1,9 @@
|
|
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 do
|
17
|
-
require 'support/models/invoice'
|
18
|
-
require 'support/models/customer'
|
19
|
-
require 'support/models/note'
|
4
|
+
# require 'support/models/invoice'
|
5
|
+
# require 'support/models/customer'
|
6
|
+
# require 'support/models/note'
|
20
7
|
|
21
8
|
it "should provide access to the associations hash" do
|
22
9
|
Invoice.should respond_to(:associations)
|
@@ -27,6 +14,15 @@ describe Ripple::Associations do
|
|
27
14
|
Invoice.embedded_associations.should == Array(Invoice.associations[:note])
|
28
15
|
end
|
29
16
|
|
17
|
+
it "should collect the linked associations" do
|
18
|
+
Invoice.linked_associations.should == Array(Invoice.associations[:customer])
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should collect the stored_key associations" do
|
22
|
+
Account.stored_key_associations.should == Array(Account.associations[:transactions])
|
23
|
+
Transaction.stored_key_associations.should == Array(Transaction.associations[:account])
|
24
|
+
end
|
25
|
+
|
30
26
|
it "should copy associations to a subclass" do
|
31
27
|
Invoice.associations[:foo] = "bar"
|
32
28
|
class SubInvoice < Invoice; end
|
@@ -50,11 +46,16 @@ describe Ripple::Associations do
|
|
50
46
|
end
|
51
47
|
end
|
52
48
|
|
53
|
-
|
54
|
-
Invoice
|
55
|
-
|
56
|
-
|
57
|
-
|
49
|
+
before(:all) do
|
50
|
+
@orig_invoice = Invoice
|
51
|
+
Object.send(:remove_const, :Invoice)
|
52
|
+
class Invoice < @orig_invoice; end
|
53
|
+
end
|
54
|
+
|
55
|
+
after(:all) do
|
56
|
+
Object.send(:remove_const, :SubInvoice) if defined?(SubInvoice)
|
57
|
+
Object.send(:remove_const, :Invoice)
|
58
|
+
Object.send(:const_set, :Invoice, @orig_invoice)
|
58
59
|
end
|
59
60
|
end
|
60
61
|
|
@@ -81,7 +82,22 @@ describe Ripple::Association do
|
|
81
82
|
end
|
82
83
|
|
83
84
|
describe "determining the target class" do
|
84
|
-
|
85
|
+
context "when in a nested module scope" do
|
86
|
+
it "should find the target via the owner's module scope" do
|
87
|
+
@association = Ripple::Association.new(:many, :children)
|
88
|
+
@association.setup_on(Nested::Scope::Parent)
|
89
|
+
@association.klass.should == Nested::Scope::Child
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should not try to find the target in the owner's scope when the class name is fully qualified" do
|
93
|
+
@association = Ripple::Association.new(:many, :children, :class_name => "Nested::Scope::Child")
|
94
|
+
@association.setup_on(Nested::Scope::Parent)
|
95
|
+
expect {
|
96
|
+
@association.klass
|
97
|
+
}.should_not raise_error
|
98
|
+
@association.klass.should == Nested::Scope::Child
|
99
|
+
end
|
100
|
+
end
|
85
101
|
|
86
102
|
it "should default to the constantized class name" do
|
87
103
|
@association = Ripple::Association.new(:one, :t, :class_name => "Trunk")
|
@@ -110,4 +126,19 @@ describe Ripple::Association do
|
|
110
126
|
it "should determine an instance variable based on the name" do
|
111
127
|
Ripple::Association.new(:many, :pages).ivar.should == "@_pages"
|
112
128
|
end
|
129
|
+
|
130
|
+
describe "key correspondence" do
|
131
|
+
require 'support/models/profile'
|
132
|
+
require 'support/models/user'
|
133
|
+
|
134
|
+
it "should raise an exception if trying to use a many association when :using => :key" do
|
135
|
+
expect { Profile.many :user, :using => :key }.to raise_error(ArgumentError, "You cannot use a many association using :key")
|
136
|
+
end
|
137
|
+
|
138
|
+
it "should add the key_delegate attr_accessor to the model declaring the association" do
|
139
|
+
Profile.one :user, :using => :key
|
140
|
+
Profile.new.should respond_to(:key_delegate)
|
141
|
+
Profile.new.should respond_to(:key_delegate=)
|
142
|
+
end
|
143
|
+
end
|
113
144
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Ripple::AttributeMethods::Dirty do
|
4
4
|
let(:company) { Company.new }
|
@@ -12,18 +12,69 @@ describe Ripple::AttributeMethods::Dirty do
|
|
12
12
|
company.robject.stub!(:store).and_return(true)
|
13
13
|
company.name = 'Fizz Buzz, Inc.'
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
it "should capture previous changes when saving" do
|
17
17
|
company.save
|
18
18
|
company.previous_changes.should include('name')
|
19
19
|
end
|
20
20
|
|
21
21
|
it "should make previous changes available to after callbacks" do
|
22
|
-
|
22
|
+
my_class = Class.new(Company) do
|
23
23
|
after_save {|c| c['pc'] = previous_changes }
|
24
24
|
end
|
25
|
-
|
26
|
-
|
25
|
+
comp = my_class.new
|
26
|
+
comp.robject.stub!(:store).and_return(true)
|
27
|
+
comp.name = 'Fizz Buzz, Inc.'
|
28
|
+
comp.save
|
29
|
+
comp['pc'].should include('name')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#changed?" do
|
34
|
+
|
35
|
+
it "returns true if the document's attributes have changed (regardless of whether or not it has any embedded associated documents)" do
|
36
|
+
company.name = 'Fizz Buzz, Inc'
|
37
|
+
company.should be_changed
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
context "when the document's attributes have not changed" do
|
42
|
+
it 'returns false if it has no embedded associated documents' do
|
43
|
+
company.should_not be_changed
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'when the document has embedded associated documents' do
|
47
|
+
before(:each) do
|
48
|
+
company.ceo = ceo
|
49
|
+
company.invoices << invoice
|
50
|
+
company.departments << department
|
51
|
+
department.managers << manager
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'returns false if all the embedded documents are not changed' do
|
55
|
+
company.should_not be_changed
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'does not consider changes to linked associated documents' do
|
59
|
+
invoice.should_not_receive(:changed?)
|
60
|
+
company.changed?
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'returns true if a one embedded association document is changed' do
|
64
|
+
ceo.should_receive(:changed?).and_return(true)
|
65
|
+
company.should be_changed
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'returns true if a many embedded association document is changed' do
|
69
|
+
department.should_receive(:changed?).and_return(true)
|
70
|
+
company.should be_changed
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'recurses through the whole embedded document structure to find changed grandchild documents' do
|
74
|
+
manager.should_receive(:changed?).and_return(true)
|
75
|
+
company.should be_changed
|
76
|
+
end
|
77
|
+
end
|
27
78
|
end
|
28
79
|
end
|
29
80
|
end
|