perpetuity 0.1 → 0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|