perpetuity 0.4.4 → 0.4.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,8 +1,4 @@
1
- require 'perpetuity'
2
-
3
- mongodb = Perpetuity::MongoDB.new db: 'perpetuity_gem_test'
4
- Perpetuity.configure { data_source mongodb }
5
-
1
+ require 'spec_helper'
6
2
  require 'support/test_classes'
7
3
 
8
4
  describe Perpetuity do
@@ -26,392 +22,6 @@ describe Perpetuity do
26
22
  end
27
23
  end
28
24
 
29
- describe 'persistence' do
30
- it "persists an object" do
31
- article = Article.new 'I have a title'
32
- expect { Perpetuity[Article].insert article }.
33
- to change { Perpetuity[Article].count }.by 1
34
- Perpetuity[Article].find(article.id).title.should eq 'I have a title'
35
- end
36
-
37
- it 'returns the id of the persisted object' do
38
- article = Article.new
39
- Perpetuity[Article].insert(article).should eq article.id
40
- end
41
-
42
- it "gives an id to objects" do
43
- article = Article.new
44
- Perpetuity[Article].give_id_to article, 1
45
-
46
- article.id.should eq 1
47
- end
48
-
49
- it 'persists referenced objects if they are not persisted' do
50
- article = Article.new
51
- article.author = User.new
52
- Perpetuity[Article].insert article
53
-
54
- Perpetuity[Article].find(article.id).author.id.should be == article.author.id
55
- end
56
-
57
- it 'persists arrays of referenced objects if they are not persisted' do
58
- authors = [User.new('Dave'), User.new('Andy')]
59
- book = Book.new
60
- book.authors = authors
61
- Perpetuity[Book].insert book
62
-
63
- Perpetuity[Book].find(book.id).authors.first.id.should be == authors.first.id
64
- end
65
-
66
- describe 'id injection' do
67
- let(:article) { Article.new }
68
-
69
- it 'assigns an id to the inserted object' do
70
- Perpetuity[Article].insert article
71
- article.should respond_to :id
72
- end
73
-
74
- it "assigns an id using Mapper.first" do
75
- Perpetuity[Article].first.should respond_to :id
76
- end
77
-
78
- it 'assigns an id using Mapper.all.first' do
79
- Perpetuity[Article].all.first.should respond_to :id
80
- end
81
- end
82
-
83
- describe 'persisting arrays' do
84
- let(:article) { Article.new }
85
-
86
- it 'persists arrays' do
87
- article.comments << 1 << 2 << 3
88
- Perpetuity[Article].insert article
89
- Perpetuity[Article].find(article.id).comments.should eq [1, 2, 3]
90
- end
91
-
92
- it 'persists arrays with unserializable objects in them' do
93
- comment = Comment.new('my comment')
94
- article.comments << comment
95
- Perpetuity[Article].insert article
96
- Perpetuity[Article].find(article.id).comments.first.tap do |persisted_comment|
97
- persisted_comment.should be_a Comment
98
- persisted_comment.body.should eq comment.body
99
- end
100
- end
101
- end
102
-
103
- it "allows mappers to set the id field" do
104
- noise = Time.now.to_f.to_s.sub('.', '')
105
- book = Book.new("My Title #{noise}")
106
-
107
- Perpetuity[Book].insert book
108
- book.id.should eq "my-title-#{noise}"
109
- end
110
- end
111
-
112
- describe "deletion" do
113
- it 'deletes an object' do
114
- 2.times { Perpetuity[Article].insert Article.new }
115
- expect { Perpetuity[Article].delete Perpetuity[Article].first }.to change { Perpetuity[Article].count }.by(-1)
116
- end
117
-
118
- it 'deletes an object with a given id' do
119
- article_id = Perpetuity[Article].insert Article.new
120
- expect {
121
- Perpetuity[Article].delete article_id
122
- }.to change { Perpetuity[Article].count }.by(-1)
123
- end
124
-
125
- describe "#delete_all" do
126
- it "should delete all objects of a certain class" do
127
- Perpetuity[Article].insert Article.new
128
- Perpetuity[Article].delete_all
129
- Perpetuity[Article].count.should eq 0
130
- end
131
- end
132
- end
133
-
134
- describe "retrieval" do
135
- it "gets all the objects of a class" do
136
- expect { Perpetuity[Article].insert Article.new }.
137
- to change { Perpetuity[Article].all.count }.by 1
138
- end
139
-
140
- it "has an ID when retrieved" do
141
- Perpetuity[Article].insert Article.new
142
- Perpetuity[Article].first.should respond_to :id
143
- end
144
-
145
- it "gets an item with a specific ID" do
146
- article = Article.new
147
- Perpetuity[Article].insert article
148
- retrieved = Perpetuity[Article].find(article.id)
149
-
150
- retrieved.id.should eq article.id
151
- retrieved.title.should eq article.title
152
- retrieved.body.should eq article.body
153
- end
154
-
155
- describe "Array-like syntax" do
156
- let(:draft) { Article.new 'Draft', 'draft content', nil, Time.now + 30 }
157
- let(:published) { Article.new 'Published', 'content', nil, Time.now - 30, 3 }
158
- before do
159
- Perpetuity[Article].insert draft
160
- Perpetuity[Article].insert published
161
- end
162
-
163
- it 'selects objects using equality' do
164
- selected = Perpetuity[Article].select { |article| article.title == 'Published' }
165
- selected.map(&:id).should include published.id
166
- selected.map(&:id).should_not include draft.id
167
- end
168
-
169
- it 'selects objects using greater-than' do
170
- selected = Perpetuity[Article].select { |article| article.published_at < Time.now }
171
- ids = selected.map(&:id)
172
- ids.should include published.id
173
- ids.should_not include draft.id
174
- end
175
-
176
- it 'selects objects using greater-than-or-equal' do
177
- selected = Perpetuity[Article].select { |article| article.views >= 3 }
178
- ids = selected.map(&:id)
179
- ids.should include published.id
180
- ids.should_not include draft.id
181
- end
182
-
183
- it 'selects objects using less-than' do
184
- selected = Perpetuity[Article].select { |article| article.views < 3 }
185
- ids = selected.map(&:id)
186
- ids.should include draft.id
187
- ids.should_not include published.id
188
- end
189
-
190
- it 'selects objects using less-than-or-equal' do
191
- selected = Perpetuity[Article].select { |article| article.views <= 0 }
192
- ids = selected.map(&:id)
193
- ids.should include draft.id
194
- ids.should_not include published.id
195
- end
196
-
197
- it 'selects objects using inequality' do
198
- selected = Perpetuity[Article].select { |article| article.title.not_equal? 'Draft' }
199
- ids = selected.map(&:id)
200
- ids.should_not include draft.id
201
- ids.should include published.id
202
- end
203
-
204
- it 'selects objects using regular expressions' do
205
- selected = Perpetuity[Article].select { |article| article.title =~ /Pub/ }
206
- ids = selected.map(&:id)
207
- ids.should include published.id
208
- ids.should_not include draft.id
209
- end
210
-
211
- it 'selects objects using inclusion' do
212
- selected = Perpetuity[Article].select { |article| article.title.in %w( Published ) }
213
- ids = selected.map(&:id)
214
- ids.should include published.id
215
- ids.should_not include draft.id
216
- end
217
- end
218
- end
219
-
220
- describe 'pagination' do
221
- it 'specifies the page we want' do
222
- Perpetuity[Article].all.should respond_to :page
223
- end
224
-
225
- it 'specify the quantity per page' do
226
- Perpetuity[Article].all.should respond_to :per_page
227
- end
228
-
229
- it 'returns an empty set when there is no data for that page' do
230
- mapper = Perpetuity[Article]
231
- mapper.delete_all
232
- data = mapper.all.page(2)
233
- data.should be_empty
234
- end
235
-
236
- it 'specifies per-page quantity' do
237
- Perpetuity[Article].delete_all
238
- 5.times { |i| Perpetuity[Article].insert Article.new i }
239
- data = Perpetuity[Article].all.page(3).per_page(2)
240
- data.should have(1).item
241
- end
242
- end
243
-
244
- describe 'associations with other objects' do
245
- let(:user) { User.new }
246
- let(:topic) { Topic.new }
247
- let(:user_mapper) { Perpetuity[User] }
248
- let(:topic_mapper) { Perpetuity[Topic] }
249
-
250
- before do
251
- user.name = 'Flump'
252
- topic.creator = user
253
- topic.title = 'Title'
254
-
255
- user_mapper.insert user
256
- topic_mapper.insert topic
257
- end
258
-
259
- describe 'referenced relationships' do
260
- let(:creator) { topic_mapper.find(topic.id).creator }
261
- subject { creator }
262
-
263
- it { should be_a Perpetuity::Reference }
264
- its(:klass) { should be User }
265
- its(:id) { should be == user.id }
266
- end
267
-
268
- it 'can retrieve a one-to-one association' do
269
- retrieved_topic = topic_mapper.find(topic.id)
270
-
271
- topic_mapper.load_association! retrieved_topic, :creator
272
- retrieved_topic.creator.name.should eq 'Flump'
273
- end
274
-
275
- describe 'associations with many objects' do
276
- let(:pragprogs) { [User.new('Dave'), User.new('Andy')] }
277
- let(:cuke_authors) { [User.new('Matt'), User.new('Aslak')] }
278
- let(:pragprog_book) { Book.new("PragProg #{Time.now.to_f}", pragprogs) }
279
- let(:cuke_book) { Book.new("Cucumber Book #{Time.now.to_f}", cuke_authors) }
280
- let(:book_mapper) { Perpetuity[Book] }
281
-
282
- before do
283
- pragprogs.each { |author| Perpetuity[User].insert author }
284
- book_mapper.insert pragprog_book
285
- end
286
-
287
- it 'can retrieve a one-to-many association' do
288
- persisted_book = book_mapper.find(pragprog_book.id)
289
- book_mapper.load_association! persisted_book, :authors
290
-
291
- persisted_book.authors.first.name.should be == 'Dave'
292
- persisted_book.authors.last.name.should be == 'Andy'
293
- end
294
-
295
- it 'can retrieve a many-to-many association' do
296
- cuke_authors.each { |author| Perpetuity[User].insert author }
297
- book_mapper.insert cuke_book
298
- book_ids = [pragprog_book, cuke_book].map(&:id)
299
-
300
- books = book_mapper.select { |book| book.id.in book_ids }.to_a
301
- book_mapper.load_association! books, :authors
302
- books.map(&:authors).flatten.map(&:name).should include *%w(Dave Andy Matt Aslak)
303
- end
304
- end
305
- end
306
-
307
- describe 'updating' do
308
- let(:article) { Article.new }
309
- let(:mapper) { Perpetuity[Article] }
310
- let(:new_title) { 'I has a new title!' }
311
-
312
- before do
313
- mapper.insert article
314
- end
315
-
316
- it 'updates an object in the database' do
317
- mapper.update article, title: new_title
318
- mapper.find(article.id).title.should eq new_title
319
- end
320
-
321
- it 'updates the object in memory' do
322
- mapper.update article, title: new_title
323
- article.title.should eq new_title
324
- end
325
-
326
- it 'resaves the object in the database' do
327
- article.title = new_title
328
- mapper.save article
329
- mapper.find(article.id).title.should eq new_title
330
- end
331
- end
332
-
333
- describe 'validations' do
334
- let(:car_mapper) { Perpetuity[Car] }
335
-
336
- it 'raises an exception when inserting an invalid object' do
337
- car = Car.new
338
- expect { car_mapper.insert car }.to raise_error
339
- end
340
-
341
- it 'does not raise an exception when validations are met' do
342
- car = Car.new
343
- car.make = "Volkswagen"
344
- expect { car_mapper.insert car }.not_to raise_error
345
- end
346
- end
347
-
348
- # The Message class stores its data members differently internally than it receives them
349
- it 'uses accessor methods to read/write data' do
350
- message = Message.new 'My Message!'
351
- Perpetuity[Message].insert message
352
- saved_message = Perpetuity[Message].find(message.id)
353
- saved_message.instance_variable_get(:@text).should eq 'My Message!'.reverse
354
- saved_message.text.should eq 'My Message!'
355
- end
356
-
357
- describe 'serialization' do
358
- let(:author) { User.new 'username' }
359
- let(:comment) { Comment.new }
360
- let(:article) { Article.new }
361
- let(:mapper) { Perpetuity[Article] }
362
- let(:serialized_value) do
363
- {
364
- 'title' => article.title,
365
- 'body' => article.body,
366
- 'author' => {
367
- '__metadata__' => {
368
- 'class' => author.class.to_s,
369
- 'id' => author.id
370
- }
371
- },
372
- 'comments' => [
373
- {
374
- '__metadata__' => {
375
- 'class' => comment.class.to_s
376
- },
377
- 'body' => comment.body,
378
- 'author' => {
379
- '__metadata__' => {
380
- 'class' => author.class.to_s,
381
- 'id' => author.id
382
- }
383
- }
384
- },
385
- ],
386
- 'published_at' => article.published_at,
387
- 'views' => article.views
388
- }
389
- end
390
-
391
- before do
392
- article.author = author
393
- article.comments = [comment]
394
- comment.author = author
395
-
396
- Perpetuity[User].insert author
397
- Perpetuity[Article].insert article
398
- end
399
-
400
- it 'serializes objects into hashes' do
401
- mapper.serialize(article).should be == serialized_value
402
- end
403
-
404
- it 'deserializes hashes into proper objects' do
405
- unserialized = mapper.find article.id
406
- unserialized.should be_a Article
407
- unserialized.title.should be == article.title
408
- unserialized.body.should be == article.body
409
- unserialized.comments.first.tap do |unserialized_comment|
410
- unserialized_comment.body.should be == comment.body
411
- end
412
- end
413
- end
414
-
415
25
  describe 'methods on mappers' do
416
26
  it 'allows methods to act as scopes' do
417
27
  published = Article.new('Published', 'I love cats', nil, Time.now - 30)
@@ -432,40 +42,4 @@ describe Perpetuity do
432
42
  unpublished_ids.should include draft.id, not_yet_published.id
433
43
  end
434
44
  end
435
-
436
- describe 'indexing' do
437
- let(:mapper_class) do
438
- Class.new(Perpetuity::Mapper) do
439
- map Object
440
- attribute :name
441
- index :name, unique: true
442
- end
443
- end
444
- let(:mapper) { mapper_class.new }
445
- let(:name_index) do
446
- mapper.indexes.find do |index|
447
- index.attribute.to_s == :name
448
- end
449
- end
450
-
451
- after { mapper.data_source.database.drop_collection 'Object' }
452
-
453
- it 'adds indexes to database collections/tables' do
454
- name_index.attribute.name.should be == :name
455
- end
456
-
457
- it 'verifies that indexes are inactive' do
458
- name_index.should be_inactive
459
- end
460
-
461
- it 'creates indexes' do
462
- mapper.reindex!
463
- name_index.should be_active
464
- mapper.remove_index! name_index
465
- end
466
-
467
- it 'specifies uniqueness of the index' do
468
- name_index.should be_unique
469
- end
470
- end
471
45
  end
@@ -0,0 +1,6 @@
1
+ require 'perpetuity'
2
+
3
+ Perpetuity.configure do
4
+ data_source Perpetuity::MongoDB.new db: 'perpetuity_gem_test'
5
+ end
6
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: perpetuity
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.4
4
+ version: 0.4.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-26 00:00:00.000000000 Z
12
+ date: 2013-02-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -44,23 +44,7 @@ dependencies:
44
44
  - !ruby/object:Gem::Version
45
45
  version: 2.8.0
46
46
  - !ruby/object:Gem::Dependency
47
- name: mongo
48
- requirement: !ruby/object:Gem::Requirement
49
- none: false
50
- requirements:
51
- - - ! '>='
52
- - !ruby/object:Gem::Version
53
- version: 1.8.0
54
- type: :runtime
55
- prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
- requirements:
59
- - - ! '>='
60
- - !ruby/object:Gem::Version
61
- version: 1.8.0
62
- - !ruby/object:Gem::Dependency
63
- name: bson_ext
47
+ name: moped
64
48
  requirement: !ruby/object:Gem::Requirement
65
49
  none: false
66
50
  requirements:
@@ -105,6 +89,7 @@ files:
105
89
  - lib/perpetuity/mongodb/query_expression.rb
106
90
  - lib/perpetuity/mongodb/query_intersection.rb
107
91
  - lib/perpetuity/mongodb/query_union.rb
92
+ - lib/perpetuity/persisted_object.rb
108
93
  - lib/perpetuity/reference.rb
109
94
  - lib/perpetuity/retrieval.rb
110
95
  - lib/perpetuity/serializer.rb
@@ -114,6 +99,15 @@ files:
114
99
  - lib/perpetuity/validations/validation_set.rb
115
100
  - lib/perpetuity/version.rb
116
101
  - perpetuity.gemspec
102
+ - spec/integration/associations_spec.rb
103
+ - spec/integration/deletion_spec.rb
104
+ - spec/integration/indexing_spec.rb
105
+ - spec/integration/pagination_spec.rb
106
+ - spec/integration/persistence_spec.rb
107
+ - spec/integration/retrieval_spec.rb
108
+ - spec/integration/serialization_spec.rb
109
+ - spec/integration/update_spec.rb
110
+ - spec/integration/validations_spec.rb
117
111
  - spec/perpetuity/attribute_set_spec.rb
118
112
  - spec/perpetuity/attribute_spec.rb
119
113
  - spec/perpetuity/config_spec.rb
@@ -127,6 +121,7 @@ files:
127
121
  - spec/perpetuity/mongodb/query_spec.rb
128
122
  - spec/perpetuity/mongodb/query_union_spec.rb
129
123
  - spec/perpetuity/mongodb_spec.rb
124
+ - spec/perpetuity/persisted_object_spec.rb
130
125
  - spec/perpetuity/reference_spec.rb
131
126
  - spec/perpetuity/retrieval_spec.rb
132
127
  - spec/perpetuity/serializer_spec.rb
@@ -134,6 +129,7 @@ files:
134
129
  - spec/perpetuity/validations/presence_spec.rb
135
130
  - spec/perpetuity/validations_spec.rb
136
131
  - spec/perpetuity_spec.rb
132
+ - spec/spec_helper.rb
137
133
  - spec/support/test_classes.rb
138
134
  - spec/support/test_classes/article.rb
139
135
  - spec/support/test_classes/book.rb
@@ -156,7 +152,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
156
152
  version: '0'
157
153
  segments:
158
154
  - 0
159
- hash: -2281292064449361967
155
+ hash: 3190074601022311513
160
156
  required_rubygems_version: !ruby/object:Gem::Requirement
161
157
  none: false
162
158
  requirements:
@@ -165,14 +161,23 @@ required_rubygems_version: !ruby/object:Gem::Requirement
165
161
  version: '0'
166
162
  segments:
167
163
  - 0
168
- hash: -2281292064449361967
164
+ hash: 3190074601022311513
169
165
  requirements: []
170
166
  rubyforge_project:
171
- rubygems_version: 1.8.24
167
+ rubygems_version: 1.8.25
172
168
  signing_key:
173
169
  specification_version: 3
174
170
  summary: Persistence library allowing serialization of Ruby objects
175
171
  test_files:
172
+ - spec/integration/associations_spec.rb
173
+ - spec/integration/deletion_spec.rb
174
+ - spec/integration/indexing_spec.rb
175
+ - spec/integration/pagination_spec.rb
176
+ - spec/integration/persistence_spec.rb
177
+ - spec/integration/retrieval_spec.rb
178
+ - spec/integration/serialization_spec.rb
179
+ - spec/integration/update_spec.rb
180
+ - spec/integration/validations_spec.rb
176
181
  - spec/perpetuity/attribute_set_spec.rb
177
182
  - spec/perpetuity/attribute_spec.rb
178
183
  - spec/perpetuity/config_spec.rb
@@ -186,6 +191,7 @@ test_files:
186
191
  - spec/perpetuity/mongodb/query_spec.rb
187
192
  - spec/perpetuity/mongodb/query_union_spec.rb
188
193
  - spec/perpetuity/mongodb_spec.rb
194
+ - spec/perpetuity/persisted_object_spec.rb
189
195
  - spec/perpetuity/reference_spec.rb
190
196
  - spec/perpetuity/retrieval_spec.rb
191
197
  - spec/perpetuity/serializer_spec.rb
@@ -193,6 +199,7 @@ test_files:
193
199
  - spec/perpetuity/validations/presence_spec.rb
194
200
  - spec/perpetuity/validations_spec.rb
195
201
  - spec/perpetuity_spec.rb
202
+ - spec/spec_helper.rb
196
203
  - spec/support/test_classes.rb
197
204
  - spec/support/test_classes/article.rb
198
205
  - spec/support/test_classes/book.rb