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
|
@@ -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
|