seomoz-ripple 1.0.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +20 -0
- data/Guardfile +15 -0
- data/Rakefile +88 -0
- data/lib/rails/generators/ripple/configuration/configuration_generator.rb +13 -0
- data/lib/rails/generators/ripple/configuration/templates/ripple.yml +24 -0
- data/lib/rails/generators/ripple/js/js_generator.rb +13 -0
- data/lib/rails/generators/ripple/js/templates/js/contrib.js +63 -0
- data/lib/rails/generators/ripple/js/templates/js/iso8601.js +76 -0
- data/lib/rails/generators/ripple/js/templates/js/ripple.js +132 -0
- data/lib/rails/generators/ripple/model/model_generator.rb +20 -0
- data/lib/rails/generators/ripple/model/templates/model.rb +10 -0
- data/lib/rails/generators/ripple/observer/observer_generator.rb +16 -0
- data/lib/rails/generators/ripple/observer/templates/observer.rb +4 -0
- data/lib/rails/generators/ripple/test/templates/test_server.rb +46 -0
- data/lib/rails/generators/ripple/test/test_generator.rb +39 -0
- data/lib/rails/generators/ripple_generator.rb +78 -0
- data/lib/ripple.rb +79 -0
- data/lib/ripple/associations.rb +356 -0
- data/lib/ripple/associations/embedded.rb +35 -0
- data/lib/ripple/associations/instantiators.rb +26 -0
- data/lib/ripple/associations/linked.rb +65 -0
- data/lib/ripple/associations/many.rb +38 -0
- data/lib/ripple/associations/many_embedded_proxy.rb +38 -0
- data/lib/ripple/associations/many_linked_proxy.rb +66 -0
- 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 +20 -0
- data/lib/ripple/associations/one_embedded_proxy.rb +35 -0
- data/lib/ripple/associations/one_key_proxy.rb +58 -0
- data/lib/ripple/associations/one_linked_proxy.rb +22 -0
- data/lib/ripple/associations/one_stored_key_proxy.rb +43 -0
- data/lib/ripple/associations/proxy.rb +118 -0
- data/lib/ripple/attribute_methods.rb +118 -0
- data/lib/ripple/attribute_methods/dirty.rb +50 -0
- data/lib/ripple/attribute_methods/query.rb +34 -0
- data/lib/ripple/attribute_methods/read.rb +26 -0
- data/lib/ripple/attribute_methods/write.rb +25 -0
- data/lib/ripple/callbacks.rb +74 -0
- 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 +28 -0
- data/lib/ripple/core_ext.rb +2 -0
- data/lib/ripple/core_ext/casting.rb +148 -0
- data/lib/ripple/core_ext/object.rb +8 -0
- data/lib/ripple/document.rb +104 -0
- data/lib/ripple/document/bucket_access.rb +25 -0
- data/lib/ripple/document/finders.rb +131 -0
- data/lib/ripple/document/key.rb +43 -0
- data/lib/ripple/document/link.rb +30 -0
- data/lib/ripple/document/persistence.rb +115 -0
- data/lib/ripple/embedded_document.rb +64 -0
- data/lib/ripple/embedded_document/around_callbacks.rb +18 -0
- data/lib/ripple/embedded_document/finders.rb +26 -0
- data/lib/ripple/embedded_document/persistence.rb +77 -0
- data/lib/ripple/i18n.rb +2 -0
- data/lib/ripple/inspection.rb +32 -0
- data/lib/ripple/locale/en.yml +21 -0
- data/lib/ripple/nested_attributes.rb +265 -0
- data/lib/ripple/observable.rb +28 -0
- data/lib/ripple/properties.rb +73 -0
- data/lib/ripple/property_type_mismatch.rb +12 -0
- data/lib/ripple/railtie.rb +13 -0
- data/lib/ripple/serialization.rb +84 -0
- data/lib/ripple/timestamps.rb +27 -0
- data/lib/ripple/translation.rb +14 -0
- data/lib/ripple/validations.rb +67 -0
- data/lib/ripple/validations/associated_validator.rb +43 -0
- data/ripple.gemspec +46 -0
- data/seomoz-ripple.gemspec +46 -0
- data/spec/fixtures/config.yml +8 -0
- data/spec/integration/ripple/associations_spec.rb +220 -0
- data/spec/integration/ripple/conflict_resolution_spec.rb +293 -0
- data/spec/integration/ripple/nested_attributes_spec.rb +264 -0
- data/spec/integration/ripple/persistence_spec.rb +57 -0
- data/spec/integration/ripple/search_associations_spec.rb +42 -0
- data/spec/ripple/associations/many_embedded_proxy_spec.rb +122 -0
- data/spec/ripple/associations/many_linked_proxy_spec.rb +191 -0
- 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 +125 -0
- data/spec/ripple/associations/one_key_proxy_spec.rb +82 -0
- data/spec/ripple/associations/one_linked_proxy_spec.rb +91 -0
- data/spec/ripple/associations/one_stored_key_proxy_spec.rb +72 -0
- data/spec/ripple/associations/proxy_spec.rb +84 -0
- data/spec/ripple/associations_spec.rb +129 -0
- data/spec/ripple/attribute_methods/dirty_spec.rb +80 -0
- data/spec/ripple/attribute_methods_spec.rb +230 -0
- data/spec/ripple/bucket_access_spec.rb +25 -0
- data/spec/ripple/callbacks_spec.rb +176 -0
- data/spec/ripple/conflict/resolver_spec.rb +42 -0
- data/spec/ripple/conversion_spec.rb +22 -0
- data/spec/ripple/core_ext_spec.rb +103 -0
- data/spec/ripple/document/link_spec.rb +67 -0
- data/spec/ripple/document_spec.rb +96 -0
- data/spec/ripple/embedded_document/finders_spec.rb +29 -0
- data/spec/ripple/embedded_document/persistence_spec.rb +80 -0
- data/spec/ripple/embedded_document_spec.rb +84 -0
- data/spec/ripple/finders_spec.rb +217 -0
- data/spec/ripple/inspection_spec.rb +51 -0
- data/spec/ripple/key_spec.rb +30 -0
- data/spec/ripple/observable_spec.rb +121 -0
- data/spec/ripple/persistence_spec.rb +326 -0
- data/spec/ripple/properties_spec.rb +262 -0
- data/spec/ripple/ripple_spec.rb +71 -0
- data/spec/ripple/serialization_spec.rb +51 -0
- data/spec/ripple/timestamps_spec.rb +76 -0
- data/spec/ripple/validations/associated_validator_spec.rb +77 -0
- data/spec/ripple/validations_spec.rb +104 -0
- data/spec/spec_helper.rb +26 -0
- data/spec/support/associations.rb +1 -0
- data/spec/support/associations/proxies.rb +17 -0
- data/spec/support/integration_setup.rb +11 -0
- data/spec/support/mocks.rb +4 -0
- data/spec/support/models.rb +4 -0
- data/spec/support/models/address.rb +12 -0
- data/spec/support/models/box.rb +13 -0
- data/spec/support/models/car.rb +16 -0
- data/spec/support/models/cardboard_box.rb +3 -0
- data/spec/support/models/clock.rb +12 -0
- data/spec/support/models/clock_observer.rb +3 -0
- data/spec/support/models/company.rb +23 -0
- data/spec/support/models/customer.rb +4 -0
- data/spec/support/models/driver.rb +6 -0
- data/spec/support/models/email.rb +4 -0
- data/spec/support/models/engine.rb +5 -0
- data/spec/support/models/family.rb +16 -0
- data/spec/support/models/favorite.rb +4 -0
- data/spec/support/models/invoice.rb +7 -0
- data/spec/support/models/late_invoice.rb +3 -0
- data/spec/support/models/ninja.rb +9 -0
- data/spec/support/models/note.rb +5 -0
- data/spec/support/models/page.rb +4 -0
- data/spec/support/models/paid_invoice.rb +4 -0
- data/spec/support/models/passenger.rb +6 -0
- data/spec/support/models/profile.rb +10 -0
- data/spec/support/models/seat.rb +5 -0
- data/spec/support/models/subscription.rb +27 -0
- data/spec/support/models/tasks.rb +14 -0
- data/spec/support/models/team.rb +11 -0
- data/spec/support/models/transactions.rb +17 -0
- data/spec/support/models/tree.rb +4 -0
- data/spec/support/models/user.rb +10 -0
- data/spec/support/models/wheel.rb +6 -0
- data/spec/support/models/widget.rb +22 -0
- data/spec/support/test_server.rb +18 -0
- data/spec/support/test_server.yml.example +2 -0
- metadata +362 -0
@@ -0,0 +1,262 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Ripple::Properties do
|
4
|
+
require 'support/models/email'
|
5
|
+
|
6
|
+
it "should make the model class have a property definition method" do
|
7
|
+
Email.should respond_to(:property)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should add properties to the class via the property method" do
|
11
|
+
Email.property :from, String
|
12
|
+
Email.properties.should include(:from)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should make the model class have a collection of properties" do
|
16
|
+
Email.should respond_to(:properties)
|
17
|
+
Email.properties.should be_kind_of(Hash)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should make subclasses inherit properties from the parent class" do
|
21
|
+
Email.properties[:foo] = "bar"
|
22
|
+
class Forward < Email; end
|
23
|
+
Forward.properties[:foo].should == "bar"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe Ripple::Property do
|
28
|
+
it "should have a key symbol" do
|
29
|
+
prop = Ripple::Property.new('foo', String)
|
30
|
+
prop.should respond_to(:key)
|
31
|
+
prop.key.should == :foo
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should have a type" do
|
35
|
+
prop = Ripple::Property.new('foo', String)
|
36
|
+
prop.should respond_to(:type)
|
37
|
+
prop.type.should == String
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should capture extra options" do
|
41
|
+
prop = Ripple::Property.new('foo', String, 'default' => "bar")
|
42
|
+
prop.should respond_to(:options)
|
43
|
+
prop.options.should == {:default => "bar"}
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should expose validation options" do
|
47
|
+
prop = Ripple::Property.new('foo', String, 'default' => "bar", :presence => true)
|
48
|
+
prop.validation_options.should == {:presence => true}
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "default value" do
|
52
|
+
it "should be nil when not specified" do
|
53
|
+
prop = Ripple::Property.new('foo', String)
|
54
|
+
prop.default.should be_nil
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should allow literal values" do
|
58
|
+
prop = Ripple::Property.new('foo', String, :default => "bar")
|
59
|
+
prop.default.should == "bar"
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should cast to the proper type" do
|
63
|
+
prop = Ripple::Property.new('foo', String, :default => :bar)
|
64
|
+
prop.default.should == "bar"
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should allow false for a Boolean" do
|
68
|
+
prop = Ripple::Property.new('foo', Boolean, :default => false)
|
69
|
+
prop.default.should == false
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should allow lambdas for deferred evaluation" do
|
73
|
+
prop = Ripple::Property.new('foo', String, :default => lambda { "bar" })
|
74
|
+
prop.default.should == "bar"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "casting a value" do
|
79
|
+
describe "when type is Boolean" do
|
80
|
+
before :each do
|
81
|
+
@prop = Ripple::Property.new('foo', Boolean)
|
82
|
+
end
|
83
|
+
|
84
|
+
[0, 0.0, "", [], false, "f", "FALSE"].each do |v|
|
85
|
+
it "should cast #{v.inspect} to false" do
|
86
|
+
@prop.type_cast(v).should == false
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
[1, 1.0, "true", "1", [1], true, "t", "TRUE"].each do |v|
|
91
|
+
it "should cast #{v.inspect} to true" do
|
92
|
+
@prop.type_cast(v).should == true
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should not cast nil" do
|
97
|
+
@prop.type_cast(nil).should be_nil
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "when type is String" do
|
102
|
+
before :each do
|
103
|
+
@prop = Ripple::Property.new('foo', String)
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should cast anything to a string using to_s" do
|
107
|
+
@prop.type_cast("s").should == "s"
|
108
|
+
@prop.type_cast(1).should == "1"
|
109
|
+
@prop.type_cast(true).should == "true"
|
110
|
+
@prop.type_cast(false).should == "false"
|
111
|
+
if RUBY_VERSION < "1.9"
|
112
|
+
@prop.type_cast([]).should == ""
|
113
|
+
else
|
114
|
+
@prop.type_cast([]).should == "[]"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should not cast nil" do
|
119
|
+
@prop.type_cast(nil).should be_nil
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
describe "when type is an Integer type" do
|
125
|
+
before :each do
|
126
|
+
@prop = Ripple::Property.new(:foo, Integer)
|
127
|
+
end
|
128
|
+
|
129
|
+
[5.0, "5", " 5", "05", Rational(10,2)].each do |v|
|
130
|
+
it "should cast #{v.inspect} to 5" do
|
131
|
+
@prop.type_cast(v).should == 5
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
[0.0, "0", " 000"].each do |v|
|
136
|
+
it "should cast #{v.inspect} to 0" do
|
137
|
+
@prop.type_cast(v).should == 0
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should not cast the blank string" do
|
142
|
+
@prop.type_cast("").should be_nil
|
143
|
+
@prop.type_cast(" ").should be_nil
|
144
|
+
end
|
145
|
+
|
146
|
+
[true, false, [], {}, :symbol, ["something else"]].each do |v|
|
147
|
+
it "should raise an error casting #{v.inspect}" do
|
148
|
+
lambda { @prop.type_cast(v) }.should raise_error(Ripple::PropertyTypeMismatch)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
describe "when type is a Float type" do
|
154
|
+
before :each do
|
155
|
+
@prop = Ripple::Property.new(:foo, Float)
|
156
|
+
end
|
157
|
+
|
158
|
+
[0, "0", "0.0", " 0.0"].each do |v|
|
159
|
+
it "should cast #{v.inspect} to 0.0" do
|
160
|
+
@prop.type_cast(v).should == 0.0
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
[5.0, "5", " 5.0", "05", Rational(10,2)].each do |v|
|
165
|
+
it "should cast #{v.inspect} to 5.0" do
|
166
|
+
@prop.type_cast(v).should == 5.0
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should not cast the blank string" do
|
171
|
+
@prop.type_cast("").should be_nil
|
172
|
+
@prop.type_cast(" ").should be_nil
|
173
|
+
end
|
174
|
+
|
175
|
+
[true, false, :symbol, [], {}].each do |v|
|
176
|
+
it "should raise an error casting #{v.inspect}" do
|
177
|
+
lambda { @prop.type_cast(v) }.should raise_error(Ripple::PropertyTypeMismatch)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
describe "when type is a Numeric type" do
|
183
|
+
before :each do
|
184
|
+
@prop = Ripple::Property.new(:foo, Numeric)
|
185
|
+
end
|
186
|
+
|
187
|
+
[5.0, "5", " 5.0", "05"].each do |v|
|
188
|
+
it "should cast #{v.inspect} to 5" do
|
189
|
+
@prop.type_cast(v).should == 5
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
[5.2, "5.2542", " 6.4", "0.5327284"].each do |v|
|
194
|
+
it "should cast #{v.inspect} to a float" do
|
195
|
+
@prop.type_cast(v).should be_kind_of(Float)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
it "should not cast the blank string" do
|
200
|
+
@prop.type_cast("").should be_nil
|
201
|
+
@prop.type_cast(" ").should be_nil
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
describe "when type is a Time type" do
|
206
|
+
before :each do
|
207
|
+
@prop = Ripple::Property.new(:foo, Time)
|
208
|
+
end
|
209
|
+
|
210
|
+
["Tue, 16 Mar 2010 12:00:00 -0000","2010/03/16 12:00:00 GMT", Time.utc(2010,03,16,12)].each do |v|
|
211
|
+
it "should cast #{v.inspect} to #{Time.utc(2010,03,16,12).inspect}" do
|
212
|
+
@prop.type_cast(v).should == Time.utc(2010,03,16,12)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
it "should not cast blank types" do
|
217
|
+
@prop.type_cast([]).should be_nil
|
218
|
+
@prop.type_cast({}).should be_nil
|
219
|
+
@prop.type_cast("").should be_nil
|
220
|
+
@prop.type_cast(" ").should be_nil
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
describe "when type is a Date type" do
|
225
|
+
before :each do
|
226
|
+
@prop = Ripple::Property.new(:foo, Date)
|
227
|
+
end
|
228
|
+
|
229
|
+
["Tue, 16 Mar 2010 00:00:00 -0000", "2010/03/16 12:00:00 GMT", Time.utc(2010,03,16,12), "2010/03/16"].each do |v|
|
230
|
+
it "should cast #{v.inspect} to 2010/03/16" do
|
231
|
+
@prop.type_cast(v).should == Date.civil(2010,3,16)
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
it "should not cast blank types" do
|
236
|
+
@prop.type_cast([]).should be_nil
|
237
|
+
@prop.type_cast({}).should be_nil
|
238
|
+
@prop.type_cast("").should be_nil
|
239
|
+
@prop.type_cast(" ").should be_nil
|
240
|
+
end
|
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
|
261
|
+
end
|
262
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Ripple do
|
4
|
+
it "should have a client" do
|
5
|
+
Ripple.client.should be_kind_of(Riak::Client)
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should have a unique client per thread" do
|
9
|
+
client = Ripple.client
|
10
|
+
th = Thread.new { Ripple.client.should_not == client }
|
11
|
+
th.join
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should be configurable" do
|
15
|
+
Ripple.should respond_to(:config)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should allow setting the client manually" do
|
19
|
+
Ripple.should respond_to(:client=)
|
20
|
+
client = Riak::Client.new(:http_port => 9000)
|
21
|
+
Ripple.client = client
|
22
|
+
Ripple.client.should == client
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should reset the client when the configuration changes" do
|
26
|
+
c = Ripple.client
|
27
|
+
Ripple.config = {:http_port => 9000}
|
28
|
+
Ripple.client.should_not == c
|
29
|
+
Ripple.client.http_port.should == 9000
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should raise No Such File or Directory when given a bad configuration file" do
|
33
|
+
lambda { Ripple.load_config('not-here') }.should raise_error(Ripple::MissingConfiguration)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should pass an empty hash into configure if the configuration file is missing the key" do
|
37
|
+
Ripple.should_receive(:config=).with({})
|
38
|
+
Ripple.load_config(File.join(File.dirname(__FILE__), '..', 'fixtures', 'config.yml'), [:ripple, 'not-here'])
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should select the configuration hash from the config keys provided" do
|
42
|
+
Ripple.load_config(File.join(File.dirname(__FILE__), '..', 'fixtures', 'config.yml'), ['ripple_rails', 'development'])
|
43
|
+
Ripple.client.http_port.should == 9001
|
44
|
+
Ripple.client.host.should == '127.0.0.1'
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should apply the configuration under the ripple key" do
|
48
|
+
Ripple.load_config(File.join(File.dirname(__FILE__), '..', 'fixtures', 'config.yml'))
|
49
|
+
Ripple.client.http_port.should == 9000
|
50
|
+
Ripple.client.host.should == 'localhost'
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "date format" do
|
54
|
+
before { @date_format = Ripple.date_format }
|
55
|
+
after { Ripple.date_format = @date_format }
|
56
|
+
|
57
|
+
it "should default to :iso8601" do
|
58
|
+
Ripple.date_format.should == :iso8601
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should allow setting via the config" do
|
62
|
+
Ripple.config = {"date_format" => "rfc822"}
|
63
|
+
Ripple.date_format.should == :rfc822
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should allow setting manually" do
|
67
|
+
Ripple.date_format = "rfc822"
|
68
|
+
Ripple.date_format.should == :rfc822
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Ripple::Serialization do
|
4
|
+
require 'support/models/invoice'
|
5
|
+
require 'support/models/note'
|
6
|
+
require 'support/models/customer'
|
7
|
+
|
8
|
+
it "should provide JSON serialization" do
|
9
|
+
Invoice.new.should respond_to(:to_json)
|
10
|
+
end
|
11
|
+
|
12
|
+
context "when serializing" do
|
13
|
+
it "should include attributes" do
|
14
|
+
Note.new(:text => "Dear Jane,...").serializable_hash.should include('text')
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should include the document key" do
|
18
|
+
doc = Invoice.new
|
19
|
+
doc.key = "1"
|
20
|
+
doc.serializable_hash['key'].should == "1"
|
21
|
+
end
|
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
|
+
|
29
|
+
it "should include embedded documents by default" do
|
30
|
+
doc = Invoice.new(:note => {:text => "Dear customer,..."}).serializable_hash
|
31
|
+
doc['note'].should eql({'text' => "Dear customer,..."})
|
32
|
+
end
|
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
|
+
|
40
|
+
it "should exclude specified attributes" do
|
41
|
+
hash = Invoice.new.serializable_hash(:except => [:created_at])
|
42
|
+
hash.should_not include('created_at')
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should limit to specified attributes" do
|
46
|
+
hash = Invoice.new.serializable_hash(:only => [:created_at])
|
47
|
+
hash.should include('created_at')
|
48
|
+
hash.should_not include('updated_at')
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,76 @@
|
|
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
|
39
|
+
|
40
|
+
describe Ripple::Timestamps do
|
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
|
76
|
+
end
|