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.
Files changed (152) hide show
  1. data/.gitignore +32 -0
  2. data/Gemfile +10 -9
  3. data/Guardfile +15 -0
  4. data/Rakefile +11 -40
  5. data/lib/rails/generators/ripple/configuration/configuration_generator.rb +0 -13
  6. data/lib/rails/generators/ripple/configuration/templates/ripple.yml +4 -4
  7. data/lib/rails/generators/ripple/js/js_generator.rb +0 -13
  8. data/lib/rails/generators/ripple/js/templates/js/contrib.js +0 -17
  9. data/lib/rails/generators/ripple/js/templates/js/ripple.js +0 -13
  10. data/lib/rails/generators/ripple/model/model_generator.rb +0 -14
  11. data/lib/rails/generators/ripple/model/templates/model.rb +1 -1
  12. data/lib/rails/generators/ripple/observer/observer_generator.rb +0 -14
  13. data/lib/rails/generators/ripple/test/test_generator.rb +7 -19
  14. data/lib/rails/generators/ripple_generator.rb +1 -14
  15. data/lib/ripple.rb +7 -14
  16. data/lib/ripple/associations.rb +129 -26
  17. data/lib/ripple/associations/embedded.rb +1 -15
  18. data/lib/ripple/associations/instantiators.rb +0 -13
  19. data/lib/ripple/associations/linked.rb +41 -19
  20. data/lib/ripple/associations/many.rb +0 -14
  21. data/lib/ripple/associations/many_embedded_proxy.rb +0 -14
  22. data/lib/ripple/associations/many_linked_proxy.rb +39 -18
  23. data/lib/ripple/associations/many_reference_proxy.rb +93 -0
  24. data/lib/ripple/associations/many_stored_key_proxy.rb +76 -0
  25. data/lib/ripple/associations/one.rb +1 -15
  26. data/lib/ripple/associations/one_embedded_proxy.rb +0 -14
  27. data/lib/ripple/associations/one_key_proxy.rb +58 -0
  28. data/lib/ripple/associations/one_linked_proxy.rb +4 -14
  29. data/lib/ripple/associations/one_stored_key_proxy.rb +43 -0
  30. data/lib/ripple/associations/proxy.rb +8 -14
  31. data/lib/ripple/attribute_methods.rb +19 -17
  32. data/lib/ripple/attribute_methods/dirty.rb +19 -15
  33. data/lib/ripple/attribute_methods/query.rb +0 -14
  34. data/lib/ripple/attribute_methods/read.rb +0 -14
  35. data/lib/ripple/attribute_methods/write.rb +0 -14
  36. data/lib/ripple/callbacks.rb +10 -16
  37. data/lib/ripple/conflict/basic_resolver.rb +82 -0
  38. data/lib/ripple/conflict/document_hooks.rb +20 -0
  39. data/lib/ripple/conflict/resolver.rb +71 -0
  40. data/lib/ripple/conflict/test_helper.rb +33 -0
  41. data/lib/ripple/conversion.rb +0 -14
  42. data/lib/ripple/core_ext.rb +1 -14
  43. data/lib/ripple/core_ext/casting.rb +19 -19
  44. data/lib/ripple/core_ext/object.rb +8 -0
  45. data/lib/ripple/document.rb +21 -16
  46. data/lib/ripple/document/bucket_access.rb +0 -14
  47. data/lib/ripple/document/finders.rb +17 -23
  48. data/lib/ripple/document/key.rb +8 -28
  49. data/lib/ripple/document/link.rb +30 -0
  50. data/lib/ripple/document/persistence.rb +12 -20
  51. data/lib/ripple/embedded_document.rb +10 -15
  52. data/lib/ripple/embedded_document/around_callbacks.rb +18 -0
  53. data/lib/ripple/embedded_document/finders.rb +7 -18
  54. data/lib/ripple/embedded_document/persistence.rb +5 -17
  55. data/lib/ripple/i18n.rb +0 -14
  56. data/lib/ripple/inspection.rb +21 -15
  57. data/lib/ripple/locale/en.yml +9 -13
  58. data/lib/ripple/nested_attributes.rb +33 -39
  59. data/lib/ripple/observable.rb +0 -13
  60. data/lib/ripple/properties.rb +1 -14
  61. data/lib/ripple/property_type_mismatch.rb +0 -14
  62. data/lib/ripple/railtie.rb +4 -14
  63. data/lib/ripple/railties/ripple.rake +86 -0
  64. data/lib/ripple/serialization.rb +11 -11
  65. data/lib/ripple/test_server.rb +36 -0
  66. data/lib/ripple/timestamps.rb +0 -13
  67. data/lib/ripple/translation.rb +4 -14
  68. data/lib/ripple/validations.rb +1 -15
  69. data/lib/ripple/validations/associated_validator.rb +26 -17
  70. data/lib/ripple/version.rb +3 -0
  71. data/ripple.gemspec +24 -35
  72. data/spec/integration/ripple/associations_spec.rb +89 -58
  73. data/spec/integration/ripple/conflict_resolution_spec.rb +298 -0
  74. data/spec/integration/ripple/nested_attributes_spec.rb +19 -19
  75. data/spec/integration/ripple/persistence_spec.rb +15 -34
  76. data/spec/integration/ripple/search_associations_spec.rb +31 -0
  77. data/spec/ripple/associations/many_embedded_proxy_spec.rb +23 -36
  78. data/spec/ripple/associations/many_linked_proxy_spec.rb +133 -45
  79. data/spec/ripple/associations/many_reference_proxy_spec.rb +170 -0
  80. data/spec/ripple/associations/many_stored_key_proxy_spec.rb +158 -0
  81. data/spec/ripple/associations/one_embedded_proxy_spec.rb +24 -37
  82. data/spec/ripple/associations/one_key_proxy_spec.rb +82 -0
  83. data/spec/ripple/associations/one_linked_proxy_spec.rb +22 -23
  84. data/spec/ripple/associations/one_stored_key_proxy_spec.rb +72 -0
  85. data/spec/ripple/associations/proxy_spec.rb +21 -15
  86. data/spec/ripple/associations_spec.rb +54 -23
  87. data/spec/ripple/attribute_methods/dirty_spec.rb +56 -5
  88. data/spec/ripple/attribute_methods_spec.rb +47 -21
  89. data/spec/ripple/bucket_access_spec.rb +4 -17
  90. data/spec/ripple/callbacks_spec.rb +52 -15
  91. data/spec/ripple/conflict/resolver_spec.rb +42 -0
  92. data/spec/ripple/conversion_spec.rb +2 -15
  93. data/spec/ripple/core_ext_spec.rb +12 -15
  94. data/spec/ripple/document/link_spec.rb +67 -0
  95. data/spec/ripple/document_spec.rb +34 -19
  96. data/spec/ripple/embedded_document/finders_spec.rb +12 -19
  97. data/spec/ripple/embedded_document/persistence_spec.rb +20 -26
  98. data/spec/ripple/embedded_document_spec.rb +44 -34
  99. data/spec/ripple/finders_spec.rb +58 -29
  100. data/spec/ripple/inspection_spec.rb +40 -37
  101. data/spec/ripple/key_spec.rb +5 -17
  102. data/spec/ripple/observable_spec.rb +3 -16
  103. data/spec/ripple/persistence_spec.rb +134 -18
  104. data/spec/ripple/properties_spec.rb +21 -15
  105. data/spec/ripple/ripple_spec.rb +1 -14
  106. data/spec/ripple/serialization_spec.rb +16 -17
  107. data/spec/ripple/timestamps_spec.rb +73 -52
  108. data/spec/ripple/validations/associated_validator_spec.rb +69 -25
  109. data/spec/ripple/validations_spec.rb +3 -16
  110. data/spec/spec_helper.rb +17 -18
  111. data/spec/support/associations.rb +1 -1
  112. data/spec/support/associations/proxies.rb +0 -13
  113. data/spec/support/integration_setup.rb +11 -0
  114. data/spec/support/mocks.rb +0 -13
  115. data/spec/support/models.rb +33 -2
  116. data/spec/support/models/address.rb +1 -16
  117. data/spec/support/models/box.rb +7 -14
  118. data/spec/support/models/car.rb +27 -1
  119. data/spec/support/models/cardboard_box.rb +0 -14
  120. data/spec/support/models/clock.rb +6 -15
  121. data/spec/support/models/clock_observer.rb +0 -14
  122. data/spec/support/models/credit_card.rb +5 -0
  123. data/spec/support/models/customer.rb +0 -14
  124. data/spec/support/models/email.rb +0 -14
  125. data/spec/support/models/family.rb +1 -13
  126. data/spec/support/models/favorite.rb +0 -14
  127. data/spec/support/models/invoice.rb +0 -14
  128. data/spec/support/models/late_invoice.rb +0 -14
  129. data/spec/support/models/nested.rb +12 -0
  130. data/spec/support/models/ninja.rb +7 -0
  131. data/spec/support/models/note.rb +0 -14
  132. data/spec/support/models/page.rb +1 -15
  133. data/spec/support/models/paid_invoice.rb +0 -14
  134. data/spec/support/models/post.rb +12 -0
  135. data/spec/support/models/profile.rb +7 -0
  136. data/spec/support/models/subscription.rb +26 -0
  137. data/spec/support/models/tasks.rb +0 -18
  138. data/spec/support/models/team.rb +11 -0
  139. data/spec/support/models/transactions.rb +17 -0
  140. data/spec/support/models/tree.rb +2 -16
  141. data/spec/support/models/user.rb +14 -16
  142. data/spec/support/models/widget.rb +8 -14
  143. data/spec/support/search.rb +14 -0
  144. data/spec/support/test_server.rb +22 -12
  145. data/spec/support/test_server.yml.example +14 -2
  146. metadata +223 -59
  147. data/lib/rails/generators/ripple/test/templates/test_server.rb +0 -46
  148. data/spec/support/models/driver.rb +0 -5
  149. data/spec/support/models/engine.rb +0 -4
  150. data/spec/support/models/passenger.rb +0 -5
  151. data/spec/support/models/seat.rb +0 -4
  152. data/spec/support/models/wheel.rb +0 -5
@@ -1,24 +1,12 @@
1
- # Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
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.dirname(__FILE__))
1
+ require 'spec_helper'
15
2
 
16
3
  describe Ripple::Document::Key do
17
- require 'support/models/box'
4
+ # require 'support/models/box'
5
+
18
6
  before do
19
7
  @box = Box.new
20
8
  end
21
-
9
+
22
10
  it "should define key getter and setter" do
23
11
  @box.should respond_to(:key)
24
12
  @box.should respond_to(:key=)
@@ -39,5 +27,5 @@ describe Ripple::Document::Key do
39
27
  @box.shape.should == "square"
40
28
  @box.shape = "oblong"
41
29
  @box.key.should == "oblong"
42
- end
30
+ end
43
31
  end
@@ -1,21 +1,8 @@
1
- # Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
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::Observable do
17
- require 'support/models/clock'
18
- require 'support/models/clock_observer'
4
+ # require 'support/models/clock'
5
+ # require 'support/models/clock_observer'
19
6
 
20
7
  before :each do
21
8
  @client = Ripple.client
@@ -1,20 +1,7 @@
1
- # Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
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::Document::Persistence do
17
- require 'support/models/widget'
4
+ # require 'support/models/widget'
18
5
 
19
6
  before :each do
20
7
  @backend = mock("Backend")
@@ -24,6 +11,16 @@ describe Ripple::Document::Persistence do
24
11
  @widget = Widget.new(:size => 1000)
25
12
  end
26
13
 
14
+ it "forces the content type to 'application/json'" do
15
+ @widget.robject.content_type = 'application/not-json'
16
+
17
+ @backend.should_receive(:store_object) do |obj, *_|
18
+ obj.content_type.should == 'application/json'
19
+ end
20
+
21
+ @widget.save
22
+ end
23
+
27
24
  it "should save a new object to Riak" do
28
25
  json = @widget.attributes.merge("_type" => "Widget").to_json
29
26
  @backend.should_receive(:store_object) do |obj, _, _, _|
@@ -112,13 +109,13 @@ describe Ripple::Document::Persistence do
112
109
  end
113
110
 
114
111
  it "should allow unexpected exceptions to be raised" do
115
- robject = mock("robject", :key => @widget.key, "data=" => true)
112
+ robject = mock("robject", :key => @widget.key, "data=" => true, "content_type=" => true)
116
113
  robject.should_receive(:store).and_raise(Riak::HTTPFailedRequest.new(:post, 200, 404, {}, "404 not found"))
117
114
  @widget.stub!(:robject).and_return(robject)
118
115
  lambda { @widget.save }.should raise_error(Riak::FailedRequest)
119
116
  end
120
117
 
121
- it "should reload a saved object" do
118
+ it "should reload a saved object, including associations" do
122
119
  json = @widget.attributes.merge(:_type => "Widget").to_json
123
120
  @backend.should_receive(:store_object) do |obj, _, _, _|
124
121
  obj.raw_data.should == json
@@ -129,8 +126,12 @@ describe Ripple::Document::Persistence do
129
126
  @widget.save
130
127
  @backend.should_receive(:reload_object) do |obj, _|
131
128
  obj.key.should == "new_widget"
129
+ obj.content_type = 'application/json'
132
130
  obj.raw_data = '{"name":"spring","size":10,"shipped_at":"Sat, 01 Jan 2000 20:15:01 -0000","_type":"Widget"}'
131
+ obj
133
132
  end
133
+
134
+ @widget.widget_parts.should_receive(:reset)
134
135
  @widget.reload
135
136
  @widget.changes.should be_blank
136
137
  @widget.name.should == "spring"
@@ -150,7 +151,7 @@ describe Ripple::Document::Persistence do
150
151
 
151
152
  it "should destroy all saved objects" do
152
153
  @widget.should_receive(:destroy).and_return(true)
153
- Widget.should_receive(:all).and_yield(@widget)
154
+ Widget.should_receive(:list).and_yield(@widget)
154
155
  Widget.destroy_all.should be_true
155
156
  end
156
157
 
@@ -209,4 +210,119 @@ describe Ripple::Document::Persistence do
209
210
  widget.destroy
210
211
  end
211
212
  end
213
+
214
+ shared_examples_for "saving a parent document with linked child documents" do
215
+ before(:each) do
216
+ @backend.stub(:store_object)
217
+ end
218
+
219
+ it 'saves new children when the parent is saved' do
220
+ children.each do |child|
221
+ child.stub(:new? => true)
222
+ child.should_receive(:save)
223
+ end
224
+ parent.save
225
+ end
226
+
227
+ it 'saves children that have changes when the parent is saved' do
228
+ children.each do |child|
229
+ child.stub(:new? => false)
230
+ child.stub(:changed? => true)
231
+ child.should_receive(:save)
232
+ end
233
+ parent.save
234
+ end
235
+
236
+ it 'does not save children that have no changes and are not new when the parent is saved' do
237
+ children.each do |child|
238
+ child.stub(:new? => false)
239
+ child.stub(:changed? => false)
240
+ child.should_not_receive(:save)
241
+ end
242
+ parent.save
243
+ end
244
+ end
245
+
246
+ context "for a document with a many linked association" do
247
+ before(:all) do
248
+ # check assumptions of these examples
249
+ Widget.associations[:widget_parts].should be_many
250
+ Widget.associations[:widget_parts].should be_linked
251
+ end
252
+
253
+ it_behaves_like "saving a parent document with linked child documents" do
254
+ let(:parent) { Widget.new(:name => 'fizzbuzz') }
255
+ let(:children) { %w[ fizz buzz ].map { |n| WidgetPart.new(:name => n) } }
256
+
257
+ before(:each) do
258
+ children.each { |c| parent.widget_parts << c }
259
+ end
260
+ end
261
+ end
262
+
263
+ describe "for a document with a one linked association" do
264
+ before(:all) do
265
+ # check assumptions of these examples
266
+ Invoice.associations[:customer].should be_one
267
+ Invoice.associations[:customer].should be_linked
268
+ end
269
+
270
+ it_behaves_like "saving a parent document with linked child documents" do
271
+ let(:parent) { Invoice.new }
272
+ let(:children) { [Customer.new] }
273
+
274
+ before(:each) do
275
+ parent.customer = children.first
276
+ end
277
+ end
278
+ end
279
+
280
+ shared_examples_for "embedded association persistence logic" do
281
+ before(:each) do
282
+ @backend.stub(:store_object)
283
+ end
284
+
285
+ it "does not save children when the parent is saved" do
286
+ children.each do |child|
287
+ child.stub(:new? => true, :changed? => true)
288
+ child.should_not_receive(:save)
289
+ end
290
+
291
+ parent.save
292
+ end
293
+ end
294
+
295
+ describe "for a document with a many embedded association" do
296
+ before(:all) do
297
+ # check assumptions of these examples
298
+ Clock.associations[:modes].should be_many
299
+ Clock.associations[:modes].should be_embedded
300
+ end
301
+
302
+ it_behaves_like "embedded association persistence logic" do
303
+ let(:parent) { Clock.new }
304
+ let(:children) { [1, 2].map { |i| Mode.new } }
305
+
306
+ before(:each) do
307
+ children.each { |c| parent.modes << c }
308
+ end
309
+ end
310
+ end
311
+
312
+ describe "for a document with a one embedded association" do
313
+ before(:all) do
314
+ # check assumptions of these examples
315
+ Parent.associations[:child].should be_one
316
+ Parent.associations[:child].should be_embedded
317
+ end
318
+
319
+ it_behaves_like "embedded association persistence logic" do
320
+ let(:parent) { Parent.new }
321
+ let(:children) { [Child.new(:name => 'Bobby', :age => 9)] }
322
+
323
+ before(:each) do
324
+ parent.child = children.first
325
+ end
326
+ end
327
+ end
212
328
  end
@@ -1,20 +1,7 @@
1
- # Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
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::Properties do
17
- require 'support/models/email'
4
+ # require 'support/models/email'
18
5
 
19
6
  it "should make the model class have a property definition method" do
20
7
  Email.should respond_to(:property)
@@ -252,5 +239,24 @@ describe Ripple::Property do
252
239
  @prop.type_cast(" ").should be_nil
253
240
  end
254
241
  end
242
+
243
+ describe "when type is a Set type" do
244
+ let(:prop) { Ripple::Property.new(:foo, Set) }
245
+
246
+ it "casts an array to a a set" do
247
+ prop.type_cast([1]).should be_a(Set)
248
+ prop.type_cast([1]).to_a.should == [1]
249
+ end
250
+
251
+ it "does not cast nil" do
252
+ prop.type_cast(nil).should be_nil
253
+ end
254
+
255
+ it "raises an error when casting a non-enumerable" do
256
+ expect {
257
+ prop.type_cast(1)
258
+ }.to raise_error(Ripple::PropertyTypeMismatch)
259
+ end
260
+ end
255
261
  end
256
262
  end
@@ -1,17 +1,4 @@
1
- # Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
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.dirname(__FILE__))
1
+ require 'spec_helper'
15
2
 
16
3
  describe Ripple do
17
4
  it "should have a client" do
@@ -1,22 +1,9 @@
1
- # Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
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::Serialization do
17
- require 'support/models/invoice'
18
- require 'support/models/note'
19
- require 'support/models/customer'
4
+ # require 'support/models/invoice'
5
+ # require 'support/models/note'
6
+ # require 'support/models/customer'
20
7
 
21
8
  it "should provide JSON serialization" do
22
9
  Invoice.new.should respond_to(:to_json)
@@ -33,11 +20,23 @@ describe Ripple::Serialization do
33
20
  doc.serializable_hash['key'].should == "1"
34
21
  end
35
22
 
23
+ it "should be able to exclude the document key" do
24
+ doc = Invoice.new
25
+ doc.key = "1"
26
+ doc.serializable_hash(:except => [:key]).should_not include("key")
27
+ end
28
+
36
29
  it "should include embedded documents by default" do
37
30
  doc = Invoice.new(:note => {:text => "Dear customer,..."}).serializable_hash
38
31
  doc['note'].should eql({'text' => "Dear customer,..."})
39
32
  end
40
33
 
34
+ it "should exclude the _type field from embedded documents" do
35
+ doc = Invoice.new
36
+ doc.note = Note.new :text => "Dear customer,..."
37
+ doc.serializable_hash['note'].should_not include("_type")
38
+ end
39
+
41
40
  it "should exclude specified attributes" do
42
41
  hash = Invoice.new.serializable_hash(:except => [:created_at])
43
42
  hash.should_not include('created_at')
@@ -1,55 +1,76 @@
1
- # Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
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
-
15
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
1
+ require 'spec_helper'
2
+
3
+ shared_examples_for "a timestamped model" do
4
+ it "adds a created_at property" do
5
+ subject.should respond_to(:created_at)
6
+ end
7
+
8
+ it "adds an updated_at property" do
9
+ subject.should respond_to(:updated_at)
10
+ end
11
+
12
+ it "sets the created_at timestamp when the object is initialized" do
13
+ subject.created_at.should_not be_nil
14
+ end
15
+
16
+ it "does not set the updated_at timestamp when the object is initialized" do
17
+ subject.updated_at.should be_nil
18
+ end
19
+
20
+ it "sets the updated_at timestamp when the object is saved" do
21
+ record_to_save.save
22
+ subject.updated_at.should_not be_nil
23
+ end
24
+
25
+ it "updates the updated_at timestamp when the object is updated" do
26
+ record_to_save.save
27
+ start = subject.updated_at
28
+ record_to_save.save
29
+ subject.updated_at.should > start
30
+ end
31
+
32
+ it "does not update the created_at timestamp when the object is updated" do
33
+ record_to_save.save
34
+ start = subject.created_at
35
+ record_to_save.save
36
+ subject.created_at.should == start
37
+ end
38
+ end
16
39
 
17
40
  describe Ripple::Timestamps do
18
- require 'support/models/clock'
19
-
20
- before :each do
21
- response = {:headers => {"content-type" => ["application/json"]}, :body => "{}"}
22
- @client = Ripple.client
23
- @backend = mock("Backend", :store_object => true)
24
- @client.stub!(:backend).and_return(@backend)
25
- @clock = Clock.new
26
- end
27
-
28
- it "should add a created_at property" do
29
- @clock.should respond_to(:created_at)
30
- end
31
-
32
- it "should add an updated_at property" do
33
- @clock.should respond_to(:updated_at)
34
- end
35
-
36
- it "should set the created_at timestamp when the object is initialized" do
37
- @clock.created_at.should_not be_nil
38
- end
39
-
40
- it "should not set the updated_at timestamp when the object is initialized" do
41
- @clock.updated_at.should be_nil
42
- end
43
-
44
- it "should set the updated_at timestamp when the object is created" do
45
- @clock.save
46
- @clock.updated_at.should_not be_nil
47
- end
48
-
49
- it "should update the updated_at timestamp when the object is updated" do
50
- @clock.save
51
- start = @clock.updated_at
52
- @clock.save
53
- @clock.updated_at.should > start
54
- end
41
+ # require 'support/models/clock'
42
+
43
+ let(:backend) { mock("Backend", :store_object => true) }
44
+ before(:each) { Ripple.client.stub!(:backend).and_return(backend) }
45
+
46
+ context "for a Ripple::Document" do
47
+ it_behaves_like "a timestamped model" do
48
+ subject { Clock.new }
49
+ let(:record_to_save) { subject }
50
+ end
51
+ end
52
+
53
+ context "for a Ripple::EmbeddedDocument when directly saved" do
54
+ it_behaves_like "a timestamped model" do
55
+ let(:clock) { Clock.new }
56
+ subject { Mode.new }
57
+ let(:record_to_save) { subject }
58
+
59
+ before(:each) do
60
+ clock.modes << subject
61
+ end
62
+ end
63
+ end
64
+
65
+ context "for a Ripple::EmbeddedDocument when the parent is saved" do
66
+ it_behaves_like "a timestamped model" do
67
+ let(:clock) { Clock.new }
68
+ subject { Mode.new }
69
+ let(:record_to_save) { clock }
70
+
71
+ before(:each) do
72
+ clock.modes << subject
73
+ end
74
+ end
75
+ end
55
76
  end