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