couchobject 0.5.0 → 0.6.0

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 (63) hide show
  1. data/History.txt +10 -0
  2. data/Manifest.txt +30 -6
  3. data/README.txt +580 -42
  4. data/TODO +2 -2
  5. data/config/hoe.rb +1 -1
  6. data/lib/couch_object.rb +7 -2
  7. data/lib/couch_object/database.rb +19 -34
  8. data/lib/couch_object/document.rb +13 -6
  9. data/lib/couch_object/error_classes.rb +110 -0
  10. data/lib/couch_object/persistable.rb +954 -36
  11. data/lib/couch_object/persistable/has_many_relations_array.rb +91 -0
  12. data/lib/couch_object/persistable/meta_classes.rb +568 -0
  13. data/lib/couch_object/persistable/overloaded_methods.rb +209 -0
  14. data/lib/couch_object/server.rb +1 -1
  15. data/lib/couch_object/utils.rb +44 -0
  16. data/lib/couch_object/version.rb +1 -1
  17. data/lib/couch_object/view.rb +129 -6
  18. data/script/console +0 -0
  19. data/script/destroy +0 -0
  20. data/script/generate +0 -0
  21. data/script/txt2html +0 -0
  22. data/spec/database_spec.rb +23 -31
  23. data/spec/database_spec.rb.orig +173 -0
  24. data/spec/document_spec.rb +21 -3
  25. data/spec/integration/database_integration_spec.rb +46 -15
  26. data/spec/integration/integration_helper.rb +3 -3
  27. data/spec/persistable/callback.rb +44 -0
  28. data/spec/persistable/callback_spec.rb +44 -0
  29. data/spec/persistable/cloning.rb +77 -0
  30. data/spec/persistable/cloning_spec.rb +77 -0
  31. data/spec/persistable/comparing_objects.rb +350 -0
  32. data/spec/persistable/comparing_objects_spec.rb +350 -0
  33. data/spec/persistable/deleting.rb +113 -0
  34. data/spec/persistable/deleting_spec.rb +113 -0
  35. data/spec/persistable/error_messages.rb +32 -0
  36. data/spec/persistable/error_messages_spec.rb +32 -0
  37. data/spec/persistable/loading.rb +339 -0
  38. data/spec/persistable/loading_spec.rb +339 -0
  39. data/spec/persistable/new_methods.rb +70 -0
  40. data/spec/persistable/new_methods_spec.rb +70 -0
  41. data/spec/persistable/persistable_helper.rb +194 -0
  42. data/spec/persistable/relations.rb +470 -0
  43. data/spec/persistable/relations_spec.rb +470 -0
  44. data/spec/persistable/saving.rb +137 -0
  45. data/spec/persistable/saving_spec.rb +137 -0
  46. data/spec/persistable/setting_storage_location.rb +65 -0
  47. data/spec/persistable/setting_storage_location_spec.rb +65 -0
  48. data/spec/persistable/timestamps.rb +76 -0
  49. data/spec/persistable/timestamps_spec.rb +76 -0
  50. data/spec/persistable/unsaved_changes.rb +211 -0
  51. data/spec/persistable/unsaved_changes_spec.rb +211 -0
  52. data/spec/server_spec.rb +5 -5
  53. data/spec/utils_spec.rb +60 -0
  54. data/spec/view_spec.rb +40 -7
  55. data/website/index.html +22 -7
  56. data/website/index.txt +13 -5
  57. metadata +93 -61
  58. data/bin/couch_ruby_view_requestor +0 -81
  59. data/lib/couch_object/model.rb +0 -5
  60. data/lib/couch_object/proc_condition.rb +0 -14
  61. data/spec/model_spec.rb +0 -5
  62. data/spec/persistable_spec.rb +0 -91
  63. data/spec/proc_condition_spec.rb +0 -26
@@ -0,0 +1,77 @@
1
+ require File.dirname(__FILE__) + '/persistable_helper.rb'
2
+
3
+ describe CouchObject::Persistable, "behaviour related to cloning and copying:" do
4
+ before(:each) do
5
+ @bike = Bike.new
6
+
7
+ @db = mock("mock db")
8
+
9
+ content = HTTPResponse.new(JSON.unparse({
10
+ "_id" => "123BAC",
11
+ "_rev" => "946B7D1C",
12
+ "created_at" => Time.new,
13
+ "updated_at" => Time.new,
14
+ "attributes" => {
15
+ "wheels" => 3
16
+ }
17
+ }))
18
+
19
+ @empty_response = {}
20
+ @ok_response = {"ok" => true}
21
+ @document_response = CouchObject::Response.new(content)
22
+ end
23
+
24
+ it "clones and dupes should not have an ID and a revision number" do
25
+ CouchObject::Database.should_receive(:open).and_return(@db)
26
+ @db.should_receive(:post).
27
+ with("", @bike.to_json).and_return(@document_response)
28
+ @bike.set_location = "foo"
29
+ @bike.save
30
+
31
+ new_bike = @bike.clone
32
+ second_new_bike = @bike.dup
33
+
34
+ # clone
35
+ new_bike.id.should_not == @bike.id
36
+ new_bike.revision.should_not == @bike.revision
37
+
38
+ # dup
39
+ second_new_bike.id.should_not == @bike.id
40
+ second_new_bike.revision.should_not == @bike.revision
41
+ end
42
+
43
+ it "clones and dupes should share the same location" do
44
+ CouchObject::Database.should_receive(:open).and_return(@db)
45
+ @db.should_receive(:post).
46
+ with("", @bike.to_json).and_return(@document_response)
47
+ @bike.set_location = "foo"
48
+ @bike.save
49
+
50
+ new_bike = @bike.clone
51
+ second_new_bike = @bike.dup
52
+
53
+ # clone
54
+ new_bike.location.should == @bike.location
55
+
56
+ # dup
57
+ second_new_bike.location.should == @bike.location
58
+ end
59
+
60
+ it "clones should share attributes" do
61
+ CouchObject::Database.should_receive(:open).and_return(@db)
62
+ @db.should_receive(:post).
63
+ with("", @bike.to_json).and_return(@document_response)
64
+ @bike.set_location = "foo"
65
+ @bike.save
66
+
67
+ new_bike = @bike.clone
68
+ second_new_bike = @bike.dup
69
+
70
+ # clone
71
+ new_bike.wheels.should == @bike.wheels
72
+
73
+ # dup
74
+ second_new_bike.wheels.should == @bike.wheels
75
+ end
76
+
77
+ end
@@ -0,0 +1,350 @@
1
+ require File.dirname(__FILE__) + '/persistable_helper.rb'
2
+
3
+ describe CouchObject::Persistable, "comparing objects: == :" do
4
+ before(:each) do
5
+ @bike = Bike.new
6
+
7
+ @db = mock("mock db")
8
+
9
+ @content = HTTPResponse.new(JSON.unparse({
10
+ "_id" => "123BAC",
11
+ "_rev" => "946B7D1C",
12
+ "class" => Bike,
13
+ "created_at" => Time.new,
14
+ "updated_at" => Time.new,
15
+ "attributes" => {
16
+ "wheels" => 3
17
+ }
18
+ }))
19
+
20
+ @document_response = CouchObject::Response.new(@content)
21
+ end
22
+
23
+ it "two objects with the same object_id should be ==" do
24
+ CouchObject::Database.should_receive(:open).and_return(@db)
25
+ @db.should_receive(:post).
26
+ with("", @bike.to_json).and_return(@document_response)
27
+
28
+ new_bike = @bike
29
+
30
+ @bike.set_location = "foo"
31
+ @bike.save
32
+
33
+ new_bike.should == @bike
34
+
35
+ end
36
+
37
+ it "two objects loaded from the database with the same ID should be equal if the instance variables and the revision number are equal" do
38
+ CouchObject::Database.should_receive(:open).twice.and_return(@db)
39
+ @db.should_receive(:get).with("123BAC").twice.
40
+ and_return(@content)
41
+
42
+ bike1 = Bike.get_by_id("123BAC", "foo")
43
+ bike2 = Bike.get_by_id("123BAC", "foo")
44
+
45
+ bike1.should == bike2
46
+
47
+ end
48
+
49
+ it "two objects loaded from the database with the same ID should not be equal once the value of one of them has changed" do
50
+ CouchObject::Database.should_receive(:open).twice.and_return(@db)
51
+ @db.should_receive(:get).with("123BAC").twice.
52
+ and_return(@content)
53
+
54
+ bike1 = Bike.get_by_id("123BAC", "foo")
55
+ bike2 = Bike.get_by_id("123BAC", "foo")
56
+
57
+ bike1.wheels = 5
58
+
59
+ bike1.wheels.should == 5
60
+ bike2.wheels.should_not == 5
61
+ bike1.should_not == bike2
62
+ end
63
+
64
+ it "two new object of the same type should not equal the same, because they will be saved to different locations!" do
65
+ bike2 = Bike.new
66
+ @bike.should_not == bike2
67
+
68
+ bike3 = bike2
69
+ bike3.should == bike2
70
+ end
71
+
72
+ end
73
+
74
+ describe CouchObject::Persistable, "comparing objects: < and > :" do
75
+ before(:each) do
76
+ @with_time_stamp = WithTimeStamp.new
77
+ @bike = Bike.new
78
+
79
+ @db = mock("mock db")
80
+
81
+ @content = HTTPResponse.new(JSON.unparse({
82
+ "_id" => "123BAC",
83
+ "_rev" => "946B7D1C",
84
+ "class" => Bike,
85
+ "created_at" => Time.new,
86
+ "updated_at" => Time.new,
87
+ "attributes" => {
88
+ "wheels" => 3
89
+ }
90
+ }))
91
+
92
+ @content2 = HTTPResponse.new(JSON.unparse({
93
+ "_id" => "123BACB",
94
+ "_rev" => "946B7D1Cas",
95
+ "class" => Bike,
96
+ "created_at" => Time.new,
97
+ "updated_at" => Time.new + 50,
98
+ "attributes" => {
99
+ "wheels" => 3
100
+ }
101
+ }))
102
+
103
+ @document_response = CouchObject::Response.new(@content)
104
+ @document_response2 = CouchObject::Response.new(@content2)
105
+ end
106
+
107
+ it "two objects with the same object_id should return false for < and >" do
108
+ CouchObject::Database.should_receive(:open).and_return(@db)
109
+ @db.should_receive(:post).and_return(@document_response)
110
+
111
+ new_with_time_stamps = @with_time_stamp
112
+
113
+ @with_time_stamp.set_location = "foo"
114
+ @with_time_stamp.save
115
+
116
+ new_with_time_stamps.>(@with_time_stamp).should == false
117
+ new_with_time_stamps.<(@with_time_stamp).should == false
118
+ end
119
+
120
+ it "> == true and < == false if the other object has not been saved while self has, and both have timestamps." do
121
+ CouchObject::Database.should_receive(:open).twice.and_return(@db)
122
+ @db.should_receive(:post).twice.and_return(@document_response)
123
+
124
+ new_with_time_stamps = @with_time_stamp.clone
125
+
126
+ @with_time_stamp.set_location = "foo"
127
+ @with_time_stamp.save
128
+
129
+ new_with_time_stamps.>(@with_time_stamp).should == false
130
+ new_with_time_stamps.<(@with_time_stamp).should == true
131
+
132
+ with_time_stamp_on_create = WithTimeStampCreatedOn.new
133
+ new_with_time_stamp_on_create = with_time_stamp_on_create.clone
134
+
135
+ with_time_stamp_on_create.set_location = "foo"
136
+ with_time_stamp_on_create.save
137
+
138
+ new_with_time_stamp_on_create.>(with_time_stamp_on_create).should == false
139
+ new_with_time_stamp_on_create.<(with_time_stamp_on_create).should == true
140
+ end
141
+
142
+ it "if both have been saved the one saved at last returns as bigger" do
143
+ CouchObject::Database.should_receive(:open).and_return(@db)
144
+ @db.should_receive(:post).and_return(@document_response)
145
+
146
+ with_time_stamp_1 = WithTimeStamp.new
147
+ with_time_stamp_1.set_location = "foo"
148
+ with_time_stamp_1.save
149
+
150
+ with_time_stamp_2 = with_time_stamp_1.couch_object_origianl_clone
151
+ with_time_stamp_2.instance_variable_set("@updated_at", Time.now + 100)
152
+
153
+ with_time_stamp_1.<(with_time_stamp_2).should == true
154
+ with_time_stamp_1.>(with_time_stamp_2).should == false
155
+ end
156
+
157
+ it "two object loaded from the database should raise an error when compared sizewise if they don't have timestamps" do
158
+ CouchObject::Database.should_receive(:open).twice.and_return(@db)
159
+
160
+ @db.should_receive(:get).with("123BACA").
161
+ and_return(@document_response)
162
+ @db.should_receive(:get).with("123BACB").
163
+ and_return(@document_response2)
164
+
165
+ bike_1 = Bike.get_by_id("123BACA", "foo")
166
+ bike_2 = Bike.get_by_id("123BACB", "foo")
167
+
168
+ lambda{ bike_1.>(bike_2) }.
169
+ should raise_error(CouchObject::Errors::CantCompareSize)
170
+ lambda{ bike_1.<(bike_2) }.
171
+ should raise_error(CouchObject::Errors::CantCompareSize)
172
+ end
173
+
174
+ it "two object loaded from the database where one has been updated more recently should make the recently updated > == true" do
175
+ CouchObject::Database.should_receive(:open).twice.and_return(@db)
176
+
177
+ content = CouchObject::Response.new(HTTPResponse.new(JSON.unparse({
178
+ "_id" => "123BAC",
179
+ "_rev" => "946B7D1C",
180
+ "class" => WithTimeStamp,
181
+ "created_at" => Time.new,
182
+ "updated_at" => Time.new,
183
+ "attributes" => {
184
+ "wheels" => 3
185
+ }
186
+ })))
187
+
188
+ content2 = CouchObject::Response.new(HTTPResponse.new(JSON.unparse({
189
+ "_id" => "123BACB",
190
+ "_rev" => "946B7D1Cas",
191
+ "class" => WithTimeStamp,
192
+ "created_at" => Time.new,
193
+ "updated_at" => Time.new + 50,
194
+ "attributes" => {
195
+ "wheels" => 3
196
+ }
197
+ })))
198
+
199
+ @db.should_receive(:get).with("123BACA").
200
+ and_return(content)
201
+ @db.should_receive(:get).with("123BACB").
202
+ and_return(content2)
203
+
204
+ time_stamp = WithTimeStamp.get_by_id("123BACA", "foo")
205
+ time_stamp_2 = WithTimeStamp.get_by_id("123BACB", "foo")
206
+
207
+ time_stamp.>(time_stamp_2).should == false
208
+ time_stamp.<(time_stamp_2).should == true
209
+ end
210
+
211
+ it "comparing two unsaved object should raise an error" do
212
+ w1 = WithTimeStamp.new
213
+ w2 = WithTimeStamp.new
214
+ lambda{ w1 < w2 }.should \
215
+ raise_error(CouchObject::Errors::CantCompareSize)
216
+ lambda{ w1 > w2 }.should \
217
+ raise_error(CouchObject::Errors::CantCompareSize)
218
+ end
219
+
220
+ end
221
+
222
+ describe CouchObject::Persistable, "comparing objects: <= and >= :" do
223
+ before(:each) do
224
+ @with_time_stamp = WithTimeStamp.new
225
+ @bike = Bike.new
226
+
227
+ @db = mock("mock db")
228
+
229
+ content = HTTPResponse.new(JSON.unparse({
230
+ "_id" => "123BAC",
231
+ "_rev" => "946B7D1C",
232
+ "class" => Bike,
233
+ "created_at" => Time.new,
234
+ "updated_at" => Time.new,
235
+ "attributes" => {
236
+ "wheels" => 3
237
+ }
238
+ }))
239
+
240
+ content2 = HTTPResponse.new(JSON.unparse({
241
+ "_id" => "123BACB",
242
+ "_rev" => "946B7D1Cas",
243
+ "class" => Bike,
244
+ "created_at" => Time.new,
245
+ "updated_at" => Time.new + 50,
246
+ "attributes" => {
247
+ "wheels" => 3
248
+ }
249
+ }))
250
+
251
+ @document_response = CouchObject::Response.new(content)
252
+ @document_response2 = CouchObject::Response.new(content2)
253
+ end
254
+
255
+
256
+ it "two objects with the same object_id should true because they are equal" do
257
+ CouchObject::Database.should_receive(:open).and_return(@db)
258
+ @db.should_receive(:post).and_return(@document_response)
259
+
260
+ new_with_time_stamps = @with_time_stamp
261
+
262
+ @with_time_stamp.set_location = "foo"
263
+ @with_time_stamp.save
264
+
265
+ new_with_time_stamps.>=(@with_time_stamp).should == true
266
+ new_with_time_stamps.<=(@with_time_stamp).should == true
267
+ end
268
+
269
+ it ">= == true and <= == false if the other object has not been saved while self has, and both have timestamps." do
270
+ CouchObject::Database.should_receive(:open).and_return(@db)
271
+ @db.should_receive(:post).and_return(@document_response)
272
+
273
+ new_with_time_stamps = @with_time_stamp.clone
274
+
275
+ @with_time_stamp.set_location = "foo"
276
+ @with_time_stamp.save
277
+
278
+ new_with_time_stamps.>=(@with_time_stamp).should == false
279
+ new_with_time_stamps.<=(@with_time_stamp).should == true
280
+ end
281
+
282
+ it "if both have been saved the one saved at last returns as bigger" do
283
+ CouchObject::Database.should_receive(:open).and_return(@db)
284
+ @db.should_receive(:post).and_return(@document_response)
285
+
286
+ with_time_stamp_1 = WithTimeStamp.new
287
+ with_time_stamp_1.set_location = "foo"
288
+ with_time_stamp_1.save
289
+
290
+ with_time_stamp_2 = with_time_stamp_1.couch_object_origianl_clone
291
+ with_time_stamp_2.instance_variable_set("@updated_at", Time.now + 100)
292
+
293
+ with_time_stamp_1.<=(with_time_stamp_2).should == true
294
+ with_time_stamp_1.>=(with_time_stamp_2).should == false
295
+ end
296
+
297
+ it "two object loaded from the database should NOT raise an error when compared sizewise even though they don't have timestamps because they are equal!" do
298
+ CouchObject::Database.should_receive(:open).twice.and_return(@db)
299
+ @db.should_receive(:get).twice.with("123BACA").
300
+ and_return(@document_response)
301
+
302
+ bike_1 = Bike.get_by_id("123BACA", "foo")
303
+ bike_2 = Bike.get_by_id("123BACA", "foo")
304
+
305
+ lambda{ bike_1.>=(bike_2) }.
306
+ should_not raise_error(CouchObject::Errors::CantCompareSize)
307
+ lambda{ bike_1.<=(bike_2) }.
308
+ should_not raise_error(CouchObject::Errors::CantCompareSize)
309
+ end
310
+
311
+ it "two object loaded from the database where one has been updated more recently should make the recently updated >= == true" do
312
+ CouchObject::Database.should_receive(:open).twice.and_return(@db)
313
+
314
+ content = CouchObject::Response.new(HTTPResponse.new(JSON.unparse({
315
+ "_id" => "123BAC",
316
+ "_rev" => "946B7D1C",
317
+ "class" => WithTimeStamp,
318
+ "created_at" => Time.new,
319
+ "updated_at" => Time.new,
320
+ "attributes" => {
321
+ "wheels" => 3
322
+ }
323
+ })))
324
+
325
+ content2 = CouchObject::Response.new(HTTPResponse.new(JSON.unparse({
326
+ "_id" => "123BACB",
327
+ "_rev" => "946B7D1Cas",
328
+ "class" => WithTimeStamp,
329
+ "created_at" => Time.new,
330
+ "updated_at" => Time.new + 50,
331
+ "attributes" => {
332
+ "wheels" => 3
333
+ }
334
+ })))
335
+
336
+
337
+ @db.should_receive(:get).with("123BACA").
338
+ and_return(content)
339
+ @db.should_receive(:get).with("123BACB").
340
+ and_return(content2)
341
+
342
+ time_stamp = WithTimeStamp.get_by_id("123BACA", "foo")
343
+ time_stamp_2 = WithTimeStamp.get_by_id("123BACB", "foo")
344
+
345
+ time_stamp.>=(time_stamp_2).should == false
346
+ time_stamp.<=(time_stamp_2).should == true
347
+ end
348
+
349
+
350
+ end
@@ -0,0 +1,350 @@
1
+ require File.dirname(__FILE__) + '/persistable_helper.rb'
2
+
3
+ describe CouchObject::Persistable, "comparing objects: == :" do
4
+ before(:each) do
5
+ @bike = Bike.new
6
+
7
+ @db = mock("mock db")
8
+
9
+ @content = HTTPResponse.new(JSON.unparse({
10
+ "_id" => "123BAC",
11
+ "_rev" => "946B7D1C",
12
+ "class" => Bike,
13
+ "created_at" => Time.new,
14
+ "updated_at" => Time.new,
15
+ "attributes" => {
16
+ "wheels" => 3
17
+ }
18
+ }))
19
+
20
+ @document_response = CouchObject::Response.new(@content)
21
+ end
22
+
23
+ it "two objects with the same object_id should be ==" do
24
+ CouchObject::Database.should_receive(:open).and_return(@db)
25
+ @db.should_receive(:post).
26
+ with("", @bike.to_json).and_return(@document_response)
27
+
28
+ new_bike = @bike
29
+
30
+ @bike.set_location = "foo"
31
+ @bike.save
32
+
33
+ new_bike.should == @bike
34
+
35
+ end
36
+
37
+ it "two objects loaded from the database with the same ID should be equal if the instance variables and the revision number are equal" do
38
+ CouchObject::Database.should_receive(:open).twice.and_return(@db)
39
+ @db.should_receive(:get).with("123BAC").twice.
40
+ and_return(@content)
41
+
42
+ bike1 = Bike.get_by_id("123BAC", "foo")
43
+ bike2 = Bike.get_by_id("123BAC", "foo")
44
+
45
+ bike1.should == bike2
46
+
47
+ end
48
+
49
+ it "two objects loaded from the database with the same ID should not be equal once the value of one of them has changed" do
50
+ CouchObject::Database.should_receive(:open).twice.and_return(@db)
51
+ @db.should_receive(:get).with("123BAC").twice.
52
+ and_return(@content)
53
+
54
+ bike1 = Bike.get_by_id("123BAC", "foo")
55
+ bike2 = Bike.get_by_id("123BAC", "foo")
56
+
57
+ bike1.wheels = 5
58
+
59
+ bike1.wheels.should == 5
60
+ bike2.wheels.should_not == 5
61
+ bike1.should_not == bike2
62
+ end
63
+
64
+ it "two new object of the same type should not equal the same, because they will be saved to different locations!" do
65
+ bike2 = Bike.new
66
+ @bike.should_not == bike2
67
+
68
+ bike3 = bike2
69
+ bike3.should == bike2
70
+ end
71
+
72
+ end
73
+
74
+ describe CouchObject::Persistable, "comparing objects: < and > :" do
75
+ before(:each) do
76
+ @with_time_stamp = WithTimeStamp.new
77
+ @bike = Bike.new
78
+
79
+ @db = mock("mock db")
80
+
81
+ @content = HTTPResponse.new(JSON.unparse({
82
+ "_id" => "123BAC",
83
+ "_rev" => "946B7D1C",
84
+ "class" => Bike,
85
+ "created_at" => Time.new,
86
+ "updated_at" => Time.new,
87
+ "attributes" => {
88
+ "wheels" => 3
89
+ }
90
+ }))
91
+
92
+ @content2 = HTTPResponse.new(JSON.unparse({
93
+ "_id" => "123BACB",
94
+ "_rev" => "946B7D1Cas",
95
+ "class" => Bike,
96
+ "created_at" => Time.new,
97
+ "updated_at" => Time.new + 50,
98
+ "attributes" => {
99
+ "wheels" => 3
100
+ }
101
+ }))
102
+
103
+ @document_response = CouchObject::Response.new(@content)
104
+ @document_response2 = CouchObject::Response.new(@content2)
105
+ end
106
+
107
+ it "two objects with the same object_id should return false for < and >" do
108
+ CouchObject::Database.should_receive(:open).and_return(@db)
109
+ @db.should_receive(:post).and_return(@document_response)
110
+
111
+ new_with_time_stamps = @with_time_stamp
112
+
113
+ @with_time_stamp.set_location = "foo"
114
+ @with_time_stamp.save
115
+
116
+ new_with_time_stamps.>(@with_time_stamp).should == false
117
+ new_with_time_stamps.<(@with_time_stamp).should == false
118
+ end
119
+
120
+ it "> == true and < == false if the other object has not been saved while self has, and both have timestamps." do
121
+ CouchObject::Database.should_receive(:open).twice.and_return(@db)
122
+ @db.should_receive(:post).twice.and_return(@document_response)
123
+
124
+ new_with_time_stamps = @with_time_stamp.clone
125
+
126
+ @with_time_stamp.set_location = "foo"
127
+ @with_time_stamp.save
128
+
129
+ new_with_time_stamps.>(@with_time_stamp).should == false
130
+ new_with_time_stamps.<(@with_time_stamp).should == true
131
+
132
+ with_time_stamp_on_create = WithTimeStampCreatedOn.new
133
+ new_with_time_stamp_on_create = with_time_stamp_on_create.clone
134
+
135
+ with_time_stamp_on_create.set_location = "foo"
136
+ with_time_stamp_on_create.save
137
+
138
+ new_with_time_stamp_on_create.>(with_time_stamp_on_create).should == false
139
+ new_with_time_stamp_on_create.<(with_time_stamp_on_create).should == true
140
+ end
141
+
142
+ it "if both have been saved the one saved at last returns as bigger" do
143
+ CouchObject::Database.should_receive(:open).and_return(@db)
144
+ @db.should_receive(:post).and_return(@document_response)
145
+
146
+ with_time_stamp_1 = WithTimeStamp.new
147
+ with_time_stamp_1.set_location = "foo"
148
+ with_time_stamp_1.save
149
+
150
+ with_time_stamp_2 = with_time_stamp_1.couch_object_origianl_clone
151
+ with_time_stamp_2.instance_variable_set("@updated_at", Time.now + 100)
152
+
153
+ with_time_stamp_1.<(with_time_stamp_2).should == true
154
+ with_time_stamp_1.>(with_time_stamp_2).should == false
155
+ end
156
+
157
+ it "two object loaded from the database should raise an error when compared sizewise if they don't have timestamps" do
158
+ CouchObject::Database.should_receive(:open).twice.and_return(@db)
159
+
160
+ @db.should_receive(:get).with("123BACA").
161
+ and_return(@document_response)
162
+ @db.should_receive(:get).with("123BACB").
163
+ and_return(@document_response2)
164
+
165
+ bike_1 = Bike.get_by_id("123BACA", "foo")
166
+ bike_2 = Bike.get_by_id("123BACB", "foo")
167
+
168
+ lambda{ bike_1.>(bike_2) }.
169
+ should raise_error(CouchObject::Errors::CantCompareSize)
170
+ lambda{ bike_1.<(bike_2) }.
171
+ should raise_error(CouchObject::Errors::CantCompareSize)
172
+ end
173
+
174
+ it "two object loaded from the database where one has been updated more recently should make the recently updated > == true" do
175
+ CouchObject::Database.should_receive(:open).twice.and_return(@db)
176
+
177
+ content = CouchObject::Response.new(HTTPResponse.new(JSON.unparse({
178
+ "_id" => "123BAC",
179
+ "_rev" => "946B7D1C",
180
+ "class" => WithTimeStamp,
181
+ "created_at" => Time.new,
182
+ "updated_at" => Time.new,
183
+ "attributes" => {
184
+ "wheels" => 3
185
+ }
186
+ })))
187
+
188
+ content2 = CouchObject::Response.new(HTTPResponse.new(JSON.unparse({
189
+ "_id" => "123BACB",
190
+ "_rev" => "946B7D1Cas",
191
+ "class" => WithTimeStamp,
192
+ "created_at" => Time.new,
193
+ "updated_at" => Time.new + 50,
194
+ "attributes" => {
195
+ "wheels" => 3
196
+ }
197
+ })))
198
+
199
+ @db.should_receive(:get).with("123BACA").
200
+ and_return(content)
201
+ @db.should_receive(:get).with("123BACB").
202
+ and_return(content2)
203
+
204
+ time_stamp = WithTimeStamp.get_by_id("123BACA", "foo")
205
+ time_stamp_2 = WithTimeStamp.get_by_id("123BACB", "foo")
206
+
207
+ time_stamp.>(time_stamp_2).should == false
208
+ time_stamp.<(time_stamp_2).should == true
209
+ end
210
+
211
+ it "comparing two unsaved object should raise an error" do
212
+ w1 = WithTimeStamp.new
213
+ w2 = WithTimeStamp.new
214
+ lambda{ w1 < w2 }.should \
215
+ raise_error(CouchObject::Errors::CantCompareSize)
216
+ lambda{ w1 > w2 }.should \
217
+ raise_error(CouchObject::Errors::CantCompareSize)
218
+ end
219
+
220
+ end
221
+
222
+ describe CouchObject::Persistable, "comparing objects: <= and >= :" do
223
+ before(:each) do
224
+ @with_time_stamp = WithTimeStamp.new
225
+ @bike = Bike.new
226
+
227
+ @db = mock("mock db")
228
+
229
+ content = HTTPResponse.new(JSON.unparse({
230
+ "_id" => "123BAC",
231
+ "_rev" => "946B7D1C",
232
+ "class" => Bike,
233
+ "created_at" => Time.new,
234
+ "updated_at" => Time.new,
235
+ "attributes" => {
236
+ "wheels" => 3
237
+ }
238
+ }))
239
+
240
+ content2 = HTTPResponse.new(JSON.unparse({
241
+ "_id" => "123BACB",
242
+ "_rev" => "946B7D1Cas",
243
+ "class" => Bike,
244
+ "created_at" => Time.new,
245
+ "updated_at" => Time.new + 50,
246
+ "attributes" => {
247
+ "wheels" => 3
248
+ }
249
+ }))
250
+
251
+ @document_response = CouchObject::Response.new(content)
252
+ @document_response2 = CouchObject::Response.new(content2)
253
+ end
254
+
255
+
256
+ it "two objects with the same object_id should true because they are equal" do
257
+ CouchObject::Database.should_receive(:open).and_return(@db)
258
+ @db.should_receive(:post).and_return(@document_response)
259
+
260
+ new_with_time_stamps = @with_time_stamp
261
+
262
+ @with_time_stamp.set_location = "foo"
263
+ @with_time_stamp.save
264
+
265
+ new_with_time_stamps.>=(@with_time_stamp).should == true
266
+ new_with_time_stamps.<=(@with_time_stamp).should == true
267
+ end
268
+
269
+ it ">= == true and <= == false if the other object has not been saved while self has, and both have timestamps." do
270
+ CouchObject::Database.should_receive(:open).and_return(@db)
271
+ @db.should_receive(:post).and_return(@document_response)
272
+
273
+ new_with_time_stamps = @with_time_stamp.clone
274
+
275
+ @with_time_stamp.set_location = "foo"
276
+ @with_time_stamp.save
277
+
278
+ new_with_time_stamps.>=(@with_time_stamp).should == false
279
+ new_with_time_stamps.<=(@with_time_stamp).should == true
280
+ end
281
+
282
+ it "if both have been saved the one saved at last returns as bigger" do
283
+ CouchObject::Database.should_receive(:open).and_return(@db)
284
+ @db.should_receive(:post).and_return(@document_response)
285
+
286
+ with_time_stamp_1 = WithTimeStamp.new
287
+ with_time_stamp_1.set_location = "foo"
288
+ with_time_stamp_1.save
289
+
290
+ with_time_stamp_2 = with_time_stamp_1.couch_object_origianl_clone
291
+ with_time_stamp_2.instance_variable_set("@updated_at", Time.now + 100)
292
+
293
+ with_time_stamp_1.<=(with_time_stamp_2).should == true
294
+ with_time_stamp_1.>=(with_time_stamp_2).should == false
295
+ end
296
+
297
+ it "two object loaded from the database should NOT raise an error when compared sizewise even though they don't have timestamps because they are equal!" do
298
+ CouchObject::Database.should_receive(:open).twice.and_return(@db)
299
+ @db.should_receive(:get).twice.with("123BACA").
300
+ and_return(@document_response)
301
+
302
+ bike_1 = Bike.get_by_id("123BACA", "foo")
303
+ bike_2 = Bike.get_by_id("123BACA", "foo")
304
+
305
+ lambda{ bike_1.>=(bike_2) }.
306
+ should_not raise_error(CouchObject::Errors::CantCompareSize)
307
+ lambda{ bike_1.<=(bike_2) }.
308
+ should_not raise_error(CouchObject::Errors::CantCompareSize)
309
+ end
310
+
311
+ it "two object loaded from the database where one has been updated more recently should make the recently updated >= == true" do
312
+ CouchObject::Database.should_receive(:open).twice.and_return(@db)
313
+
314
+ content = CouchObject::Response.new(HTTPResponse.new(JSON.unparse({
315
+ "_id" => "123BAC",
316
+ "_rev" => "946B7D1C",
317
+ "class" => WithTimeStamp,
318
+ "created_at" => Time.new,
319
+ "updated_at" => Time.new,
320
+ "attributes" => {
321
+ "wheels" => 3
322
+ }
323
+ })))
324
+
325
+ content2 = CouchObject::Response.new(HTTPResponse.new(JSON.unparse({
326
+ "_id" => "123BACB",
327
+ "_rev" => "946B7D1Cas",
328
+ "class" => WithTimeStamp,
329
+ "created_at" => Time.new,
330
+ "updated_at" => Time.new + 50,
331
+ "attributes" => {
332
+ "wheels" => 3
333
+ }
334
+ })))
335
+
336
+
337
+ @db.should_receive(:get).with("123BACA").
338
+ and_return(content)
339
+ @db.should_receive(:get).with("123BACB").
340
+ and_return(content2)
341
+
342
+ time_stamp = WithTimeStamp.get_by_id("123BACA", "foo")
343
+ time_stamp_2 = WithTimeStamp.get_by_id("123BACB", "foo")
344
+
345
+ time_stamp.>=(time_stamp_2).should == false
346
+ time_stamp.<=(time_stamp_2).should == true
347
+ end
348
+
349
+
350
+ end