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,170 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Ripple::Associations::ManyReferenceProxy do
|
|
4
|
+
# require 'support/models/transactions'
|
|
5
|
+
|
|
6
|
+
before :each do
|
|
7
|
+
@account = Account.new {|e| e.key = "accounty"}
|
|
8
|
+
@payment_method = PaymentMethod.new {|e| e.key = "paymadoo"}
|
|
9
|
+
@other_payment_method = PaymentMethod.new {|e| e.key = "otherpaym"}
|
|
10
|
+
Ripple.client.stub(:search => {"response" => {"docs" => []}})
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "should be empty before any associated documents are set" do
|
|
14
|
+
@account.payment_methods.should be_empty
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "should accept an array of documents" do
|
|
18
|
+
@account.payment_methods = [@payment_method]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "should set the key on the sub object when assigning" do
|
|
22
|
+
@account.payment_methods = [@payment_method]
|
|
23
|
+
@payment_method.account_key.should == "accounty"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "should be able to replace the entire collection of documents (even appended ones)" do
|
|
27
|
+
@account.payment_methods << @payment_method
|
|
28
|
+
@account.payment_methods = [@other_payment_method]
|
|
29
|
+
@account.payment_methods.should == [@other_payment_method]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "should return the assigned documents when assigning" do
|
|
33
|
+
t = (@account.payment_methods = [@payment_method])
|
|
34
|
+
t.should == [@payment_method]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "should find the associated documents when accessing" do
|
|
38
|
+
Ripple.client.should_receive(:search).with("payment_methods", "account_key: accounty").and_return({"response" => {"docs" => ["id" => "paymadoo"]}})
|
|
39
|
+
PaymentMethod.should_receive(:find).with(["paymadoo"]).and_return([@payment_method])
|
|
40
|
+
@account.payment_methods.should == [@payment_method]
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "should replace associated documents with a new set" do
|
|
44
|
+
@account.payment_methods = [@payment_method]
|
|
45
|
+
@account.payment_methods = [@other_payment_method]
|
|
46
|
+
@account.payment_methods.should == [@other_payment_method]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "should return an array from to_ary" do
|
|
50
|
+
@account.payment_methods << @payment_method
|
|
51
|
+
@account.payment_methods.to_ary.should == [@payment_method]
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it "should refuse assigning a collection of the wrong type" do
|
|
55
|
+
lambda { @account.payment_methods = nil }.should raise_error
|
|
56
|
+
lambda { @account.payment_methods = @payment_method }.should raise_error
|
|
57
|
+
lambda { @account.payment_methods = [@account] }.should raise_error
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
describe "#<< (when the target has not already been loaded)" do
|
|
61
|
+
it "avoids searching when adding a record to an unloaded association" do
|
|
62
|
+
PaymentMethod.should_not_receive(:search)
|
|
63
|
+
@account.payment_methods << @payment_method
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it "should be able to count the associated documents" do
|
|
67
|
+
@account.payment_methods << @payment_method
|
|
68
|
+
@account.payment_methods.count.should == 1
|
|
69
|
+
@account.payment_methods << @other_payment_method
|
|
70
|
+
@account.payment_methods.count.should == 2
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it "should be able to count without loading documents" do
|
|
74
|
+
Ripple.client.stub(:search => {"response" => {"docs" => [{"id" => @payment_method.key}, {"id" => @other_payment_method.key}]}})
|
|
75
|
+
PaymentMethod.should_not_receive(:find)
|
|
76
|
+
@account.payment_methods.count.should == 2
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it "should be able to append documents to the associated set" do
|
|
80
|
+
@account.payment_methods << @payment_method
|
|
81
|
+
@account.payment_methods << @other_payment_method
|
|
82
|
+
@account.should have(2).payment_methods
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it "should be able to chain calls to adding documents" do
|
|
86
|
+
@account.payment_methods << @payment_method << @other_payment_method
|
|
87
|
+
@account.should have(2).payment_methods
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it "should assign the keys on the sub object when appending" do
|
|
91
|
+
@account.payment_methods << @payment_method << @other_payment_method
|
|
92
|
+
[@payment_method, @other_payment_method].each do |t|
|
|
93
|
+
t.account_key.should == "accounty"
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it "does not return duplicates (for when the object has been appended and it's robject is found while walking the links)" do
|
|
98
|
+
@account.payment_methods.stub(:find_target => Set.new([@payment_method]))
|
|
99
|
+
@account.payment_methods.reset
|
|
100
|
+
@account.payment_methods << @payment_method
|
|
101
|
+
@account.payment_methods.should == [@payment_method]
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
describe "#reset" do
|
|
106
|
+
it "clears appended documents" do
|
|
107
|
+
@account.payment_methods << @payment_method
|
|
108
|
+
@account.payment_methods.reset
|
|
109
|
+
@account.payment_methods.should == []
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
describe "#keys" do
|
|
114
|
+
let(:ze_keys) { %w(1 2 3) }
|
|
115
|
+
let(:search_results) do
|
|
116
|
+
{"response" => {"docs" => ze_keys.map { |k| {"id" => k} }}}
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
before(:each) do
|
|
120
|
+
Ripple.client.stub(:search => search_results)
|
|
121
|
+
PaymentMethod.stub(:find => [@payment_method])
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it "returns a set of keys" do
|
|
125
|
+
@account.payment_methods.keys.should be_a(Set)
|
|
126
|
+
@account.payment_methods.keys.to_a.should == ze_keys
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
it "is memoized between calls" do
|
|
130
|
+
@account.payment_methods.keys.should equal(@account.payment_methods.keys)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it "is cleared when the association is reset" do
|
|
134
|
+
orig_set = @account.payment_methods.keys
|
|
135
|
+
@account.payment_methods.reset
|
|
136
|
+
@account.payment_methods.keys.should_not equal(orig_set)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
it "is cleared when the association is replaced" do
|
|
140
|
+
orig_set = @account.payment_methods.keys
|
|
141
|
+
@account.payment_methods.replace([@payment_method])
|
|
142
|
+
@account.payment_methods.keys.should_not equal(orig_set)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
it "maintains the list of keys properly as new documents are appended" do
|
|
146
|
+
@account.payment_methods << @payment_method
|
|
147
|
+
@account.payment_methods.should have(1).key
|
|
148
|
+
@account.payment_methods << @other_payment_method
|
|
149
|
+
@account.payment_methods.should have(2).keys
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
describe "#include?" do
|
|
154
|
+
it "delegates to the set of keys so as not to unnecessarily load the associated documents" do
|
|
155
|
+
@account.payment_methods.keys.should_receive(:include?).with(@payment_method.key).and_return(true)
|
|
156
|
+
@account.payment_methods.include?(@payment_method).should be_true
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
it "short-circuits and returns false if the given object is not a ripple document" do
|
|
160
|
+
@account.payment_methods.keys.should_not_receive(:include?)
|
|
161
|
+
@account.payment_methods.include?(Object.new).should be_false
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
it "returns false if the document's bucket is different from the associations bucket, even if the keys are the same" do
|
|
165
|
+
@account.payment_methods << @payment_method
|
|
166
|
+
other_account = Account.new { |p| p.key = @payment_method.key }
|
|
167
|
+
@account.payment_methods.include?(other_account).should be_false
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
end
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Ripple::Associations::ManyStoredKeyProxy do
|
|
4
|
+
# require 'support/models/transactions'
|
|
5
|
+
|
|
6
|
+
before :each do
|
|
7
|
+
@account = Account.new {|t| t.key = "accounty" }
|
|
8
|
+
@transaction_one = Transaction.new {|t| t.key = "one" }
|
|
9
|
+
@transaction_two = Transaction.new {|t| t.key = "two" }
|
|
10
|
+
@transaction_three = Transaction.new {|t| t.key = "three" }
|
|
11
|
+
@transaction_one.stub(:new_record?).and_return(false)
|
|
12
|
+
@transaction_two.stub(:new_record?).and_return(false)
|
|
13
|
+
@transaction_three.stub(:new_record?).and_return(false)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "should be empty before any associated documents are set" do
|
|
17
|
+
@account.transactions.should be_empty
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "should allow appending" do
|
|
21
|
+
@account.transactions << @transaction_one
|
|
22
|
+
@account.transactions.should == [@transaction_one]
|
|
23
|
+
@account.transaction_keys.should == ["one"]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "should be able to chain calls to adding documents" do
|
|
27
|
+
@account.transactions << @transaction_one << @transaction_two
|
|
28
|
+
@account.transactions.should == [@transaction_one, @transaction_two]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "creates the right type of key collection" do
|
|
32
|
+
Object.module_eval do
|
|
33
|
+
class DifferentlyKeyedAccount
|
|
34
|
+
include Ripple::Document
|
|
35
|
+
property :transaction_keys, SortedSet
|
|
36
|
+
many :transactions, :using => :stored_key
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
account = DifferentlyKeyedAccount.new
|
|
41
|
+
account.transactions << @transaction_one
|
|
42
|
+
account.transaction_keys.should == SortedSet.new(["one"])
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "should accept an array of documents" do
|
|
46
|
+
@account.transactions = [@transaction_one]
|
|
47
|
+
@account.transactions.should == [@transaction_one]
|
|
48
|
+
@account.transaction_keys.should == %w(one)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "should be able to replace the entire collection of documents (even appended ones)" do
|
|
52
|
+
@account.transactions << @transaction_one
|
|
53
|
+
@account.transactions = [@transaction_two]
|
|
54
|
+
@account.transactions.should == [@transaction_two]
|
|
55
|
+
@account.transaction_keys.should == %w(two)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "should return the assigned documents when assigning" do
|
|
59
|
+
t = (@account.transactions = [@transaction_one])
|
|
60
|
+
t.should == [@transaction_one]
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "asks the keys set for the count to avoid having to unnecessarily load all documents" do
|
|
64
|
+
@account.transactions << @transaction_one
|
|
65
|
+
@account.transaction_keys.stub(:size => 17)
|
|
66
|
+
@account.transactions.count.should == 17
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it "should return an array from to_ary" do
|
|
70
|
+
@account.transactions << @transaction_one
|
|
71
|
+
@account.transactions.to_ary.should == [@transaction_one]
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it "should refuse assigning a collection of the wrong type" do
|
|
75
|
+
lambda { @account.transactions = nil }.should raise_error
|
|
76
|
+
lambda { @account.transactions = @transaction_one }.should raise_error
|
|
77
|
+
lambda { @account.transactions = [@account] }.should raise_error
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it "should refuse appending a document of the wrong type" do
|
|
81
|
+
lambda { @account.transactions << Account.new }.should raise_error
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
describe "#reset" do
|
|
85
|
+
it "clears appended documents" do
|
|
86
|
+
@account.transactions << @transaction_one
|
|
87
|
+
@account.transactions.reset
|
|
88
|
+
@account.transactions.should == []
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it "resets to the saved state of the proxy" do
|
|
92
|
+
Transaction.stub(:find).and_return([@transaction_one])
|
|
93
|
+
@account.transactions << @transaction_two
|
|
94
|
+
@account.transactions.reset
|
|
95
|
+
Transaction.stub(:find).and_return([@transaction_one])
|
|
96
|
+
@account.transactions.should == [ @transaction_one ]
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
describe "#include?" do
|
|
101
|
+
it "delegates to the set of keys so as not to unnecessarily load the associated documents" do
|
|
102
|
+
@account.transactions.keys.should_receive(:include?).with(@transaction_two.key).and_return(true)
|
|
103
|
+
@account.transactions.include?(@transaction_two).should be_true
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it "short-circuits and returns false if the given object is not a ripple document" do
|
|
107
|
+
@account.transactions.keys.should_not_receive(:include?)
|
|
108
|
+
@account.transactions.include?(Object.new).should be_false
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it "returns false if the document's bucket is different from the associations bucket, even if the keys are the same" do
|
|
112
|
+
@account.transactions << @transaction_one
|
|
113
|
+
other_account = Account.new { |p| p.key = @transaction_one.key }
|
|
114
|
+
@account.transactions.include?(other_account).should be_false
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
describe "#keys" do
|
|
119
|
+
before do
|
|
120
|
+
@account.transactions << @transaction_one << @transaction_two
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "returns a set of keys" do
|
|
124
|
+
@account.transactions.keys.should be_a(Array)
|
|
125
|
+
@account.transactions.keys.to_a.should == %w(one two)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
it "is memoized between calls" do
|
|
129
|
+
@account.transactions.keys.should equal(@account.transactions.keys)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
it "is cleared when the association is reset" do
|
|
133
|
+
orig_set = @account.transactions.keys
|
|
134
|
+
@account.transactions.reset
|
|
135
|
+
@account.transactions.keys.should_not equal(orig_set)
|
|
136
|
+
@account.transactions.keys.should == []
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
it "is cleared when the association is replaced" do
|
|
140
|
+
orig_set = @account.transactions.keys
|
|
141
|
+
@account.transactions.replace([@transaction_one])
|
|
142
|
+
@account.transactions.keys.should_not equal(orig_set)
|
|
143
|
+
@account.transactions.keys.to_a.should == %w(one)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
it "maintains the list of keys properly as new documents are appended" do
|
|
147
|
+
@account.transactions.keys.size.should == 2
|
|
148
|
+
@account.transactions << @transaction_three
|
|
149
|
+
@account.transactions.keys.size.should == 3
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
it "temporarily bombs if the document you're appending isn't saved. This behavior shouldn't last long." do
|
|
155
|
+
lambda { @account.transactions << Transaction.new }.should raise_error
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
end
|
|
@@ -1,29 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
#
|
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
# you may not use this file except in compliance with the License.
|
|
5
|
-
# You may obtain a copy of the License at
|
|
6
|
-
#
|
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
#
|
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
# See the License for the specific language governing permissions and
|
|
13
|
-
# limitations under the License.
|
|
14
|
-
require File.expand_path("../../../spec_helper", __FILE__)
|
|
1
|
+
require 'spec_helper'
|
|
15
2
|
|
|
16
3
|
describe Ripple::Associations::OneEmbeddedProxy do
|
|
17
|
-
require 'support/models/family'
|
|
18
|
-
require 'support/models/user'
|
|
19
|
-
require 'support/models/address'
|
|
20
|
-
|
|
4
|
+
# require 'support/models/family'
|
|
5
|
+
# require 'support/models/user'
|
|
6
|
+
# require 'support/models/address'
|
|
7
|
+
|
|
21
8
|
before :each do
|
|
22
9
|
@parent = Parent.new
|
|
23
10
|
@child = Child.new
|
|
24
11
|
@gchild = Grandchild.new
|
|
25
12
|
end
|
|
26
|
-
|
|
13
|
+
|
|
27
14
|
it "should not have a child before one is set" do
|
|
28
15
|
@parent.child.should be_nil
|
|
29
16
|
end
|
|
@@ -31,27 +18,27 @@ describe Ripple::Associations::OneEmbeddedProxy do
|
|
|
31
18
|
it "should raise NoMethodError when an undefined method is called on the unset child" do
|
|
32
19
|
expect { @parent.child.some_undefined_method }.to raise_error(NoMethodError)
|
|
33
20
|
end
|
|
34
|
-
|
|
21
|
+
|
|
35
22
|
it "should be able to set and get its child" do
|
|
36
23
|
@parent.child = @child
|
|
37
24
|
@parent.child.should equal(@child)
|
|
38
25
|
end
|
|
39
|
-
|
|
26
|
+
|
|
40
27
|
it "should set the parent document on the child when assigning" do
|
|
41
28
|
@parent.child = @child
|
|
42
29
|
@child._parent_document.should == @parent
|
|
43
30
|
end
|
|
44
|
-
|
|
31
|
+
|
|
45
32
|
it "should return the assignment when assigning" do
|
|
46
33
|
rtn = @parent.child = @child
|
|
47
34
|
rtn.should == @child
|
|
48
35
|
end
|
|
49
|
-
|
|
36
|
+
|
|
50
37
|
it "should set the parent document on the child when accessing" do
|
|
51
38
|
@parent.child = @child
|
|
52
39
|
@parent.child._parent_document.should == @parent
|
|
53
40
|
end
|
|
54
|
-
|
|
41
|
+
|
|
55
42
|
it "should be able to replace its child with a different child" do
|
|
56
43
|
@son = Child.new(:name => 'Son')
|
|
57
44
|
@parent.child = @child
|
|
@@ -59,18 +46,18 @@ describe Ripple::Associations::OneEmbeddedProxy do
|
|
|
59
46
|
@parent.child = @son
|
|
60
47
|
@parent.child.name.should == 'Son'
|
|
61
48
|
end
|
|
62
|
-
|
|
49
|
+
|
|
63
50
|
it "should be able to build a new child" do
|
|
64
51
|
Child.stub!(:new).and_return(@child)
|
|
65
52
|
@parent.child.build.should == @child
|
|
66
53
|
end
|
|
67
|
-
|
|
54
|
+
|
|
68
55
|
it "should assign a parent to the child created with instantiate_target" do
|
|
69
56
|
Child.stub!(:new).and_return(@child)
|
|
70
57
|
@child._parent_document.should be_nil
|
|
71
58
|
@parent.child.build._parent_document.should == @parent
|
|
72
59
|
end
|
|
73
|
-
|
|
60
|
+
|
|
74
61
|
it "should validate the child when saving the parent" do
|
|
75
62
|
@parent.valid?.should be_true
|
|
76
63
|
@child.name = ''
|
|
@@ -78,12 +65,12 @@ describe Ripple::Associations::OneEmbeddedProxy do
|
|
|
78
65
|
@child.valid?.should be_false
|
|
79
66
|
@parent.valid?.should be_false
|
|
80
67
|
end
|
|
81
|
-
|
|
68
|
+
|
|
82
69
|
it "should not save the root document when a child is invalid" do
|
|
83
70
|
@parent.child = @child
|
|
84
71
|
@parent.save.should be_false
|
|
85
72
|
end
|
|
86
|
-
|
|
73
|
+
|
|
87
74
|
it "should allow embedding documents in embedded documents" do
|
|
88
75
|
@parent.child = @child
|
|
89
76
|
@child.gchild = @gchild
|
|
@@ -95,28 +82,28 @@ describe Ripple::Associations::OneEmbeddedProxy do
|
|
|
95
82
|
lambda { @parent.child = @gchild }.should raise_error
|
|
96
83
|
lambda { @child.gchild = [] }.should raise_error
|
|
97
84
|
end
|
|
98
|
-
|
|
85
|
+
|
|
99
86
|
describe "callbacks" do
|
|
100
87
|
before :each do
|
|
101
88
|
$pinger = mock("callback verifier")
|
|
102
89
|
end
|
|
103
|
-
|
|
90
|
+
|
|
104
91
|
it "should run callbacks for the child and documents" do
|
|
105
92
|
$pinger.should_receive(:ping).once
|
|
106
93
|
Child.before_validation { $pinger.ping }
|
|
107
94
|
@child = Child.new
|
|
108
95
|
@child.valid?
|
|
109
|
-
end
|
|
96
|
+
end
|
|
110
97
|
|
|
111
98
|
# this will work using parent and child classes, but only run by itself
|
|
112
99
|
# it also works using different classes, but only run in this file
|
|
113
100
|
# IDK why that is, but my Yakshaver 2000 just ran out of juice
|
|
114
|
-
|
|
101
|
+
|
|
115
102
|
# does this even matter? we call valid? all over the place and that
|
|
116
|
-
# will trigger the callback anyway.
|
|
117
|
-
# you probably shouldn't use validation callbacks and expect them to
|
|
103
|
+
# will trigger the callback anyway.
|
|
104
|
+
# you probably shouldn't use validation callbacks and expect them to
|
|
118
105
|
# *only* run once
|
|
119
|
-
|
|
106
|
+
|
|
120
107
|
# it "should run callbacks for the parent and child and documents respectivly" do
|
|
121
108
|
# $pinger = mock("callback verifier")
|
|
122
109
|
# $pinger.should_receive(:ping).once
|
|
@@ -128,7 +115,7 @@ describe Ripple::Associations::OneEmbeddedProxy do
|
|
|
128
115
|
# @parent.child = @child
|
|
129
116
|
# @parent.valid?
|
|
130
117
|
# end
|
|
131
|
-
|
|
118
|
+
|
|
132
119
|
after :each do
|
|
133
120
|
Child.reset_callbacks(:validation)
|
|
134
121
|
Parent.reset_callbacks(:validation)
|