perpetuity 0.1 → 0.2
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.
- data/README.md +1 -3
- data/lib/perpetuity/data_injectable.rb +10 -6
- data/lib/perpetuity/mapper.rb +41 -46
- data/lib/perpetuity/mongodb.rb +9 -0
- data/lib/perpetuity/reference.rb +17 -0
- data/lib/perpetuity/retrieval.rb +32 -8
- data/lib/perpetuity/version.rb +1 -1
- data/perpetuity.gemspec +2 -2
- data/spec/perpetuity/data_injectable_spec.rb +5 -0
- data/spec/perpetuity/mapper_spec.rb +5 -9
- data/spec/perpetuity/mongodb_spec.rb +14 -2
- data/spec/perpetuity/reference_spec.rb +26 -0
- data/spec/perpetuity/retrieval_spec.rb +10 -0
- data/spec/perpetuity_spec.rb +66 -3
- data/spec/test_classes.rb +18 -14
- metadata +7 -5
data/README.md
CHANGED
@@ -15,11 +15,9 @@ In the Data Mapper pattern, the objects you work with don't understand how to pe
|
|
15
15
|
Add the following to your Gemfile and run `bundle` to install it.
|
16
16
|
|
17
17
|
```ruby
|
18
|
-
gem 'perpetuity'
|
18
|
+
gem 'perpetuity'
|
19
19
|
```
|
20
20
|
|
21
|
-
Once it's got enough functionality to release, you'll be able to remove the `github` parameter.
|
22
|
-
|
23
21
|
## Configuration
|
24
22
|
|
25
23
|
The only currently supported persistence method is MongoDB. Other schemaless solutions can probably be implemented easily.
|
@@ -1,13 +1,17 @@
|
|
1
1
|
module Perpetuity
|
2
2
|
module DataInjectable
|
3
|
+
def inject_attribute object, attribute, value
|
4
|
+
if object.respond_to?("#{attribute}=")
|
5
|
+
object.send("#{attribute}=", value)
|
6
|
+
else
|
7
|
+
attribute = "@#{attribute}" unless attribute[0] == '@'
|
8
|
+
object.instance_variable_set(attribute, value)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
3
12
|
def inject_data object, data
|
4
13
|
data.each_pair do |attribute,value|
|
5
|
-
|
6
|
-
object.send("#{attribute}=", value)
|
7
|
-
else
|
8
|
-
attribute = "@#{attribute}" unless attribute[0] == '@'
|
9
|
-
object.instance_variable_set(attribute, value)
|
10
|
-
end
|
14
|
+
inject_attribute object, attribute, value
|
11
15
|
end
|
12
16
|
give_id_to object if object.instance_variables.include?(:@id)
|
13
17
|
end
|
data/lib/perpetuity/mapper.rb
CHANGED
@@ -39,68 +39,64 @@ module Perpetuity
|
|
39
39
|
data_source.delete_all mapped_class
|
40
40
|
end
|
41
41
|
|
42
|
-
def serializable_types
|
43
|
-
@serializable_types ||= [NilClass, TrueClass, FalseClass, Fixnum, Bignum, Float, String, Array, Hash, Time, Date]
|
44
|
-
end
|
45
|
-
|
46
42
|
def insert object
|
47
43
|
raise "#{object} is invalid and cannot be persisted." unless validations.valid?(object)
|
48
|
-
serializable_attributes =
|
44
|
+
serializable_attributes = serialize(object)
|
49
45
|
if o_id = object.instance_exec(&id)
|
50
46
|
serializable_attributes[:id] = o_id
|
51
47
|
end
|
52
48
|
|
53
|
-
attributes_for(object).each_pair do |attribute, value|
|
54
|
-
if serializable_types.include? value.class
|
55
|
-
serializable_attributes[attribute] = value
|
56
|
-
elsif value.respond_to?(:id)
|
57
|
-
serializable_attributes[attribute] = value.id
|
58
|
-
else
|
59
|
-
raise "Must persist #{attribute} (#{value.inspect}) before persisting this #{object.inspect}."
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
49
|
new_id = data_source.insert mapped_class, serializable_attributes
|
64
50
|
give_id_to object, new_id
|
65
51
|
new_id
|
66
52
|
end
|
67
53
|
|
68
|
-
def
|
54
|
+
def serialize object
|
69
55
|
attrs = {}
|
70
56
|
attribute_set.each do |attrib|
|
71
57
|
value = object.send(attrib.name)
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
58
|
+
attrib_name = attrib.name.to_s
|
59
|
+
|
60
|
+
if value.respond_to? :each
|
61
|
+
attrs[attrib_name] = serialize_enumerable(value)
|
62
|
+
elsif data_source.can_serialize? value
|
63
|
+
attrs[attrib_name] = value
|
64
|
+
elsif Mapper[value.class]
|
65
|
+
if attrib.embedded?
|
66
|
+
attrs[attrib_name] = Mapper[value.class].serialize(value).merge '__metadata__' => { 'class' => value.class }
|
67
|
+
else
|
68
|
+
attrs[attrib_name] = {
|
69
|
+
'__metadata__' => {
|
70
|
+
'class' => value.class.to_s,
|
71
|
+
'id' => value.id
|
72
|
+
}
|
73
|
+
}
|
85
74
|
end
|
86
|
-
|
87
|
-
attrs[attrib.name] = new_array
|
88
75
|
else
|
89
|
-
|
76
|
+
if attrib.embedded?
|
77
|
+
attrs[attrib_name] = Marshal.dump(value)
|
78
|
+
end
|
90
79
|
end
|
91
80
|
end
|
81
|
+
|
92
82
|
attrs
|
93
83
|
end
|
94
84
|
|
95
|
-
def
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
85
|
+
def serialize_enumerable enum
|
86
|
+
enum.map do |value|
|
87
|
+
if value.respond_to? :each
|
88
|
+
serialize_enumerable(value)
|
89
|
+
elsif data_source.can_serialize? value
|
90
|
+
value
|
91
|
+
elsif Mapper[value.class]
|
92
|
+
{
|
93
|
+
'__metadata__' => {
|
94
|
+
'class' => value.class.to_s
|
95
|
+
}
|
96
|
+
}.merge Mapper[value.class].serialize(value)
|
97
|
+
else
|
98
|
+
Marshal.dump(value)
|
99
|
+
end
|
104
100
|
end
|
105
101
|
end
|
106
102
|
|
@@ -159,12 +155,11 @@ module Perpetuity
|
|
159
155
|
end
|
160
156
|
|
161
157
|
def load_association! object, attribute
|
162
|
-
|
163
|
-
|
158
|
+
reference = object.send(attribute)
|
159
|
+
klass = reference.klass
|
160
|
+
id = reference.id
|
164
161
|
|
165
|
-
|
166
|
-
associated_object = mapper.find(id)
|
167
|
-
object.send("#{attribute}=", associated_object)
|
162
|
+
inject_attribute object, attribute, Mapper[klass].find(id)
|
168
163
|
end
|
169
164
|
|
170
165
|
def id &block
|
data/lib/perpetuity/mongodb.rb
CHANGED
@@ -98,5 +98,14 @@ module Perpetuity
|
|
98
98
|
def update klass, id, new_data
|
99
99
|
collection(klass).update({ _id: id }, new_data)
|
100
100
|
end
|
101
|
+
|
102
|
+
def can_serialize? value
|
103
|
+
serializable_types.include? value.class
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
def serializable_types
|
108
|
+
@serializable_types ||= [NilClass, TrueClass, FalseClass, Fixnum, Float, String, Array, Hash, Time]
|
109
|
+
end
|
101
110
|
end
|
102
111
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Perpetuity
|
2
|
+
class Reference
|
3
|
+
attr_reader :klass, :id
|
4
|
+
def initialize klass, id
|
5
|
+
@klass = klass
|
6
|
+
@id = id
|
7
|
+
end
|
8
|
+
|
9
|
+
def == other
|
10
|
+
klass == other.klass && id == other.id
|
11
|
+
end
|
12
|
+
|
13
|
+
def eql? other
|
14
|
+
self == other
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/perpetuity/retrieval.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'perpetuity/data_injectable'
|
2
|
-
require 'perpetuity/
|
2
|
+
require 'perpetuity/reference'
|
3
3
|
|
4
4
|
module Perpetuity
|
5
5
|
class Retrieval
|
@@ -53,15 +53,39 @@ module Perpetuity
|
|
53
53
|
page: result_page
|
54
54
|
}
|
55
55
|
results = @data_source.retrieve(@class, @criteria, options)
|
56
|
-
|
57
|
-
|
58
|
-
object = @class.new
|
59
|
-
inject_data object, Mapper.new.unserialize(result)
|
56
|
+
unserialize results
|
57
|
+
end
|
60
58
|
|
61
|
-
|
62
|
-
|
59
|
+
def unserialize(data)
|
60
|
+
if data.is_a?(String) && data.start_with?("\u0004") # if it's marshaled
|
61
|
+
Marshal.load(data)
|
62
|
+
elsif data.is_a? Array
|
63
|
+
data.map { |i| unserialize i }
|
64
|
+
elsif data.is_a? Hash
|
65
|
+
metadata = data.delete('__metadata__')
|
66
|
+
if metadata
|
67
|
+
klass = Object.const_get metadata['class']
|
68
|
+
id = metadata['id']
|
69
|
+
if id
|
70
|
+
object = Reference.new(klass, id)
|
71
|
+
else
|
72
|
+
object = klass.new
|
73
|
+
data.each do |attr, value|
|
74
|
+
inject_attribute object, attr, unserialize(value)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
else
|
78
|
+
object = @class.new
|
79
|
+
data.each do |attr, value|
|
80
|
+
inject_attribute object, attr, unserialize(value)
|
81
|
+
end
|
82
|
+
end
|
63
83
|
|
64
|
-
|
84
|
+
give_id_to object
|
85
|
+
object
|
86
|
+
else
|
87
|
+
data
|
88
|
+
end
|
65
89
|
end
|
66
90
|
|
67
91
|
def [] index
|
data/lib/perpetuity/version.rb
CHANGED
data/perpetuity.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.authors = ["Jamie Gaskins"]
|
9
9
|
s.email = ["jgaskins@gmail.com"]
|
10
10
|
s.homepage = "https://github.com/jgaskins/perpetuity.git"
|
11
|
-
s.summary = %q{Persistence library allowing
|
12
|
-
s.description = %q{Persistence
|
11
|
+
s.summary = %q{Persistence library allowing serialization of Ruby objects}
|
12
|
+
s.description = %q{Persistence layer Ruby objects}
|
13
13
|
|
14
14
|
s.files = `git ls-files`.split("\n")
|
15
15
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
@@ -7,6 +7,11 @@ module Perpetuity
|
|
7
7
|
|
8
8
|
before { klass.extend DataInjectable }
|
9
9
|
|
10
|
+
it 'injects an attribute into an object' do
|
11
|
+
klass.inject_attribute object, :a, 1
|
12
|
+
object.instance_variable_get(:@a).should eq 1
|
13
|
+
end
|
14
|
+
|
10
15
|
it 'injects data into an object' do
|
11
16
|
klass.inject_data object, { a: 1, b: 2 }
|
12
17
|
object.instance_variable_get(:@a).should eq 1
|
@@ -26,7 +26,7 @@ module Perpetuity
|
|
26
26
|
|
27
27
|
its(:mapped_class) { should eq Object }
|
28
28
|
|
29
|
-
context 'with unserializable attributes' do
|
29
|
+
context 'with unserializable embedded attributes' do
|
30
30
|
let(:unserializable_object) { 1.to_c }
|
31
31
|
let(:serialized_attrs) do
|
32
32
|
[ Marshal.dump(unserializable_object) ]
|
@@ -36,15 +36,11 @@ module Perpetuity
|
|
36
36
|
object = Object.new
|
37
37
|
object.stub(sub_objects: [unserializable_object])
|
38
38
|
mapper.attribute :sub_objects, Array, embedded: true
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
describe 'unserializes attributes' do
|
43
|
-
let(:comments) { mapper.unserialize(serialized_attrs) }
|
44
|
-
subject { comments.first }
|
39
|
+
data_source = double(:data_source)
|
40
|
+
mapper.stub(data_source: data_source)
|
41
|
+
data_source.should_receive(:can_serialize?).with(unserializable_object).and_return false
|
45
42
|
|
46
|
-
|
47
|
-
it { should eq unserializable_object }
|
43
|
+
mapper.serialize(object)['sub_objects'].should eq serialized_attrs
|
48
44
|
end
|
49
45
|
end
|
50
46
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'perpetuity/mongodb'
|
2
|
+
require 'date'
|
2
3
|
|
3
4
|
module Perpetuity
|
4
5
|
describe MongoDB do
|
@@ -83,9 +84,20 @@ module Perpetuity
|
|
83
84
|
|
84
85
|
it 'retrieves by id if the id is a string' do
|
85
86
|
time = Time.now.utc
|
86
|
-
id = mongo.insert
|
87
|
-
objects = mongo.retrieve(
|
87
|
+
id = mongo.insert Object, {inserted: time}
|
88
|
+
objects = mongo.retrieve(Object, id: id.to_s).to_a
|
88
89
|
objects.map{|i| i["inserted"].to_f}.first.should be_within(0.001).of time.to_f
|
89
90
|
end
|
91
|
+
|
92
|
+
describe 'serializable objects' do
|
93
|
+
let(:serializable_values) { [nil, true, false, 1, 1.2, '', [], {}, Time.now] }
|
94
|
+
|
95
|
+
it 'can insert serializable values' do
|
96
|
+
serializable_values.each do |value|
|
97
|
+
mongo.insert(Object, {value: value}).should be_a BSON::ObjectId
|
98
|
+
mongo.can_serialize?(value).should be_true
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
90
102
|
end
|
91
103
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'perpetuity/reference'
|
2
|
+
|
3
|
+
module Perpetuity
|
4
|
+
describe Reference do
|
5
|
+
let(:reference) { Reference.new Object, 1 }
|
6
|
+
subject { reference }
|
7
|
+
|
8
|
+
its(:klass) { should be Object }
|
9
|
+
its(:id) { should be == 1 }
|
10
|
+
|
11
|
+
describe 'comparability' do
|
12
|
+
describe 'equality' do
|
13
|
+
let(:duplicate) { reference.dup }
|
14
|
+
it { should be == duplicate }
|
15
|
+
it { should eql duplicate }
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'inequality' do
|
19
|
+
it { should_not be == Reference.new(String, reference.id) }
|
20
|
+
it { should_not eql Reference.new(String, reference.id) }
|
21
|
+
it { should_not be == Reference.new(reference.klass, 2) }
|
22
|
+
it { should_not eql Reference.new(reference.klass, 2) }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -54,5 +54,15 @@ module Perpetuity
|
|
54
54
|
|
55
55
|
results.map(&:id).should == [0]
|
56
56
|
end
|
57
|
+
|
58
|
+
describe 'unserializes attributes' do
|
59
|
+
let(:unserializable_object) { 1.to_c }
|
60
|
+
let(:serialized_attrs) { [ Marshal.dump(unserializable_object) ] }
|
61
|
+
let(:comments) { retrieval.unserialize(serialized_attrs) }
|
62
|
+
subject { comments.first }
|
63
|
+
|
64
|
+
it { should be_a Complex }
|
65
|
+
it { should eq unserializable_object}
|
66
|
+
end
|
57
67
|
end
|
58
68
|
end
|
data/spec/perpetuity_spec.rb
CHANGED
@@ -243,12 +243,17 @@ describe Perpetuity do
|
|
243
243
|
topic_mapper.insert topic
|
244
244
|
end
|
245
245
|
|
246
|
-
|
247
|
-
topic_mapper.find(topic.id).creator
|
246
|
+
describe 'referenced relationships' do
|
247
|
+
let(:creator) { topic_mapper.find(topic.id).creator }
|
248
|
+
subject { creator }
|
249
|
+
|
250
|
+
it { should be_a Perpetuity::Reference }
|
251
|
+
its(:klass) { should be User }
|
252
|
+
its(:id) { should be == user.id }
|
248
253
|
end
|
249
254
|
|
250
255
|
it 'can retrieve associated objects' do
|
251
|
-
retrieved_topic = topic_mapper.
|
256
|
+
retrieved_topic = topic_mapper.find(topic.id)
|
252
257
|
|
253
258
|
topic_mapper.load_association! retrieved_topic, :creator
|
254
259
|
retrieved_topic.creator.name.should eq 'Flump'
|
@@ -290,4 +295,62 @@ describe Perpetuity do
|
|
290
295
|
saved_message.instance_variable_get(:@text).should eq 'My Message!'.reverse
|
291
296
|
saved_message.text.should eq 'My Message!'
|
292
297
|
end
|
298
|
+
|
299
|
+
describe 'serialization' do
|
300
|
+
let(:author) { User.new 'username' }
|
301
|
+
let(:comment) { Comment.new }
|
302
|
+
let(:article) { Article.new }
|
303
|
+
let(:mapper) { Perpetuity[Article] }
|
304
|
+
let(:serialized_value) do
|
305
|
+
{
|
306
|
+
'title' => article.title,
|
307
|
+
'body' => article.body,
|
308
|
+
'author' => {
|
309
|
+
'__metadata__' => {
|
310
|
+
'class' => author.class.to_s,
|
311
|
+
'id' => author.id
|
312
|
+
}
|
313
|
+
},
|
314
|
+
'comments' => [
|
315
|
+
{
|
316
|
+
'__metadata__' => {
|
317
|
+
'class' => comment.class.to_s
|
318
|
+
},
|
319
|
+
'body' => comment.body,
|
320
|
+
'author' => {
|
321
|
+
'__metadata__' => {
|
322
|
+
'class' => author.class.to_s,
|
323
|
+
'id' => author.id
|
324
|
+
}
|
325
|
+
}
|
326
|
+
},
|
327
|
+
],
|
328
|
+
'published_at' => article.published_at,
|
329
|
+
'views' => article.views
|
330
|
+
}
|
331
|
+
end
|
332
|
+
|
333
|
+
before do
|
334
|
+
article.author = author
|
335
|
+
article.comments = [comment]
|
336
|
+
comment.author = author
|
337
|
+
|
338
|
+
Perpetuity[User].insert author
|
339
|
+
Perpetuity[Article].insert article
|
340
|
+
end
|
341
|
+
|
342
|
+
it 'serializes objects into hashes' do
|
343
|
+
mapper.serialize(article).should be == serialized_value
|
344
|
+
end
|
345
|
+
|
346
|
+
it 'deserializes hashes into proper objects' do
|
347
|
+
unserialized = mapper.find article.id
|
348
|
+
unserialized.should be_a Article
|
349
|
+
unserialized.title.should be == article.title
|
350
|
+
unserialized.body.should be == article.body
|
351
|
+
unserialized.comments.first.tap do |unserialized_comment|
|
352
|
+
unserialized_comment.body.should be == comment.body
|
353
|
+
end
|
354
|
+
end
|
355
|
+
end
|
293
356
|
end
|
data/spec/test_classes.rb
CHANGED
@@ -1,8 +1,20 @@
|
|
1
|
+
class User
|
2
|
+
attr_accessor :name
|
3
|
+
def initialize name="Foo"
|
4
|
+
@name = name
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
Perpetuity.generate_mapper_for User do
|
9
|
+
attribute :name, String
|
10
|
+
end
|
11
|
+
|
1
12
|
class Article
|
2
|
-
attr_accessor :title, :body, :comments, :published_at, :views
|
13
|
+
attr_accessor :title, :body, :author, :comments, :published_at, :views
|
3
14
|
def initialize title="Title", body="Body", author=nil, published_at=Time.now, views=0
|
4
15
|
@title = title
|
5
16
|
@body = body
|
17
|
+
@author = author
|
6
18
|
@comments = []
|
7
19
|
@published_at = published_at
|
8
20
|
@views = views
|
@@ -12,31 +24,23 @@ end
|
|
12
24
|
Perpetuity.generate_mapper_for(Article) do
|
13
25
|
attribute :title, String
|
14
26
|
attribute :body, String
|
27
|
+
attribute :author, User
|
15
28
|
attribute :comments, Array, embedded: true
|
16
29
|
attribute :published_at, Time
|
17
30
|
attribute :views, Integer
|
18
31
|
end
|
19
32
|
|
20
33
|
class Comment
|
21
|
-
|
22
|
-
def initialize body='Body'
|
34
|
+
attr_accessor :body, :author
|
35
|
+
def initialize body='Body', author=nil
|
23
36
|
@body = body
|
37
|
+
@author = author
|
24
38
|
end
|
25
39
|
end
|
26
40
|
|
27
41
|
Perpetuity.generate_mapper_for(Comment) do
|
28
42
|
attribute :body, String
|
29
|
-
|
30
|
-
|
31
|
-
class User
|
32
|
-
attr_accessor :name
|
33
|
-
def initialize name="Foo"
|
34
|
-
@name = name
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
Perpetuity.generate_mapper_for User do
|
39
|
-
attribute :name, String
|
43
|
+
attribute :author, User
|
40
44
|
end
|
41
45
|
|
42
46
|
class Book
|
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
|
+
version: '0.2'
|
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: 2012-
|
12
|
+
date: 2012-11-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -91,8 +91,7 @@ dependencies:
|
|
91
91
|
- - ! '>='
|
92
92
|
- !ruby/object:Gem::Version
|
93
93
|
version: '0'
|
94
|
-
description: Persistence
|
95
|
-
persistence concerns to domain objects.
|
94
|
+
description: Persistence layer Ruby objects
|
96
95
|
email:
|
97
96
|
- jgaskins@gmail.com
|
98
97
|
executables: []
|
@@ -117,6 +116,7 @@ files:
|
|
117
116
|
- lib/perpetuity/mongodb/query.rb
|
118
117
|
- lib/perpetuity/mongodb/query_attribute.rb
|
119
118
|
- lib/perpetuity/mongodb/query_expression.rb
|
119
|
+
- lib/perpetuity/reference.rb
|
120
120
|
- lib/perpetuity/retrieval.rb
|
121
121
|
- lib/perpetuity/validations.rb
|
122
122
|
- lib/perpetuity/validations/length.rb
|
@@ -133,6 +133,7 @@ files:
|
|
133
133
|
- spec/perpetuity/mongodb/query_expression_spec.rb
|
134
134
|
- spec/perpetuity/mongodb/query_spec.rb
|
135
135
|
- spec/perpetuity/mongodb_spec.rb
|
136
|
+
- spec/perpetuity/reference_spec.rb
|
136
137
|
- spec/perpetuity/retrieval_spec.rb
|
137
138
|
- spec/perpetuity/validations/length_spec.rb
|
138
139
|
- spec/perpetuity/validations/presence_spec.rb
|
@@ -162,7 +163,7 @@ rubyforge_project:
|
|
162
163
|
rubygems_version: 1.8.24
|
163
164
|
signing_key:
|
164
165
|
specification_version: 3
|
165
|
-
summary: Persistence library allowing
|
166
|
+
summary: Persistence library allowing serialization of Ruby objects
|
166
167
|
test_files:
|
167
168
|
- spec/perpetuity/attribute_set_spec.rb
|
168
169
|
- spec/perpetuity/attribute_spec.rb
|
@@ -173,6 +174,7 @@ test_files:
|
|
173
174
|
- spec/perpetuity/mongodb/query_expression_spec.rb
|
174
175
|
- spec/perpetuity/mongodb/query_spec.rb
|
175
176
|
- spec/perpetuity/mongodb_spec.rb
|
177
|
+
- spec/perpetuity/reference_spec.rb
|
176
178
|
- spec/perpetuity/retrieval_spec.rb
|
177
179
|
- spec/perpetuity/validations/length_spec.rb
|
178
180
|
- spec/perpetuity/validations/presence_spec.rb
|