perpetuity 1.0.0.beta3 → 1.0.0.beta5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/README.md +8 -0
- data/lib/perpetuity.rb +21 -0
- data/lib/perpetuity/config.rb +3 -7
- data/lib/perpetuity/dereferencer.rb +4 -6
- data/lib/perpetuity/dirty_tracker.rb +19 -0
- data/lib/perpetuity/identity_map.rb +6 -4
- data/lib/perpetuity/mapper.rb +24 -15
- data/lib/perpetuity/mapper_registry.rb +10 -3
- data/lib/perpetuity/version.rb +1 -1
- data/spec/integration/update_spec.rb +0 -5
- data/spec/perpetuity/dereferencer_spec.rb +5 -3
- data/spec/perpetuity/dirty_tracker_spec.rb +49 -0
- data/spec/perpetuity/identity_map_spec.rb +18 -12
- data/spec/perpetuity/mapper_registry_spec.rb +8 -1
- data/spec/perpetuity/mapper_spec.rb +21 -1
- data/spec/perpetuity_spec.rb +24 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c67c2d6a7eed0f92f1b9878069d05697405363da
|
4
|
+
data.tar.gz: 21cddf8c8f2440bea99722e28fefeca46f9ba4f6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eab30eabb92736be84697d75277242d77014f2fd71cf629fcec51b064f8a6f50a87e11643793773d49a8ca513f44cc9c9ae989d0ba1c8cebf1d4f94a6eb4edb5
|
7
|
+
data.tar.gz: b463f4b0a47ae396095b7d700b28bf3a5474a227a4ccb7b96ffa54a0175d39944d83b33012d1e0cc372d10f2df02e1a3f1623ceaf7eb3c03a9a8f6bc0c3b4004
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
## Version 1.0.0.beta5
|
2
|
+
|
3
|
+
- Don't stringify ids in `IdentityMap`. This should result in a little better performance. To be honest, I'm not even sure anymore why I put that in there.
|
4
|
+
- Use the IdentityMap when retrieving multiple objects by id.
|
5
|
+
|
6
|
+
## Version 1.0.0.beta4
|
7
|
+
|
8
|
+
- Remove in-memory updating of objects using the `Mapper#update` method.
|
9
|
+
- Separate dirty tracking from `IdentityMap` and return to a real Identity Map.
|
10
|
+
- Pass IdentityMap around when loading associations
|
11
|
+
- Add `Perpetuity.register_adapter` method to allow various data-source adapters to register without Perpetuity knowing about them.
|
12
|
+
|
1
13
|
## Version 1.0.0.beta3
|
2
14
|
|
3
15
|
- Fix title-case -> snake-case support to convert something like `UserRegistration` to `user_registration`. Previously, it would return `userregistration`.
|
data/README.md
CHANGED
@@ -248,3 +248,11 @@ This will let Rails know how to talk to your models in the way that Perpetuity h
|
|
248
248
|
## Contributing
|
249
249
|
|
250
250
|
There are plenty of opportunities to improve what's here and possibly some design decisions that need some more refinement. You can help. If you have ideas to build on this, send some love in the form of pull requests, issues or [tweets](http://twitter.com/jamie_gaskins) and I'll do what I can for them.
|
251
|
+
|
252
|
+
Please be sure that the tests run before submitting a pull request. Just run `rspec`.
|
253
|
+
|
254
|
+
The tests include integration with an adapter. By default, this is the MongoDB adapter, but you can change that to Postgres by setting the `PERPETUITY_ADAPTER` environment variable to `postgres`.
|
255
|
+
|
256
|
+
When testing with the MongoDB adapter, you'll need to have MongoDB running. On Mac OS X, you can install MongoDB via Homebrew and start it with `mongod`. No configuration is necessary.
|
257
|
+
|
258
|
+
When testing with the Postgres adapter, you'll need to have PostgreSQL running. On Mac OS X, you can install PostgreSQL via Homebrew and start it with `pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log start`. No other configuration is necessary, as long as the user has rights to create a database. NOTE: The Postgres adapter is incomplete at this time, and the tests do not yet pass with this adapter.
|
data/lib/perpetuity.rb
CHANGED
@@ -5,6 +5,7 @@ require "perpetuity/mapper_registry"
|
|
5
5
|
|
6
6
|
module Perpetuity
|
7
7
|
def self.configure &block
|
8
|
+
register_standard_adapters
|
8
9
|
detect_rails
|
9
10
|
configuration.instance_exec(&block)
|
10
11
|
end
|
@@ -31,8 +32,28 @@ module Perpetuity
|
|
31
32
|
configure { data_source *args }
|
32
33
|
end
|
33
34
|
|
35
|
+
def self.register_adapter adapters
|
36
|
+
config_adapters = Perpetuity::Configuration.adapters
|
37
|
+
adapters.each do |adapter_name, adapter_class|
|
38
|
+
if config_adapters.has_key?(adapter_name) && config_adapters[adapter_name] != adapter_class
|
39
|
+
raise "That adapter name has already been registered for #{config_adapters[adapter_name]}"
|
40
|
+
else
|
41
|
+
config_adapters[adapter_name] = adapter_class
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
34
48
|
# Necessary to be able to check whether Rails is loaded and initialized
|
35
49
|
def self.detect_rails
|
36
50
|
require File.expand_path('../perpetuity/rails.rb', __FILE__) if defined? Rails
|
37
51
|
end
|
52
|
+
|
53
|
+
# Necessary until these adapters are updated to register themselves.
|
54
|
+
def self.register_standard_adapters
|
55
|
+
Perpetuity.register_adapter :mongodb => Perpetuity::MongoDB if defined?(Perpetuity::MongoDB)
|
56
|
+
Perpetuity.register_adapter :postgres => Perpetuity::Postgres if defined?(Perpetuity::Postgres)
|
57
|
+
Perpetuity.register_adapter :dynamodb => Perpetuity::DynamoDB if defined?(Perpetuity::DynamoDB)
|
58
|
+
end
|
38
59
|
end
|
data/lib/perpetuity/config.rb
CHANGED
@@ -14,7 +14,7 @@ module Perpetuity
|
|
14
14
|
adapter = args.shift
|
15
15
|
db_name = args.shift
|
16
16
|
options = args.shift || {}
|
17
|
-
adapter_class =
|
17
|
+
adapter_class = adapter(adapter)
|
18
18
|
|
19
19
|
@db = adapter_class.new(options.merge(db: db_name))
|
20
20
|
end
|
@@ -28,7 +28,7 @@ module Perpetuity
|
|
28
28
|
options = args.shift || {}
|
29
29
|
|
30
30
|
protocol = uri.scheme
|
31
|
-
klass =
|
31
|
+
klass = adapter(protocol)
|
32
32
|
db_options = {
|
33
33
|
db: uri.path[1..-1],
|
34
34
|
username: uri.user,
|
@@ -44,11 +44,7 @@ module Perpetuity
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def self.adapters
|
47
|
-
@adapters ||= {
|
48
|
-
dynamodb: 'DynamoDB',
|
49
|
-
mongodb: 'MongoDB',
|
50
|
-
postgres: 'Postgres',
|
51
|
-
}
|
47
|
+
@adapters ||= {}
|
52
48
|
end
|
53
49
|
|
54
50
|
def adapter name
|
@@ -5,8 +5,8 @@ module Perpetuity
|
|
5
5
|
class Dereferencer
|
6
6
|
attr_reader :map, :mapper_registry
|
7
7
|
|
8
|
-
def initialize mapper_registry
|
9
|
-
@map =
|
8
|
+
def initialize mapper_registry, identity_map=IdentityMap.new
|
9
|
+
@map = identity_map
|
10
10
|
@mapper_registry = mapper_registry
|
11
11
|
end
|
12
12
|
|
@@ -37,13 +37,11 @@ module Perpetuity
|
|
37
37
|
def objects klass, ids
|
38
38
|
ids = ids.uniq
|
39
39
|
if ids.one?
|
40
|
-
mapper_registry
|
40
|
+
mapper_registry.mapper_for(klass, identity_map: map).find(ids.first)
|
41
41
|
elsif ids.none?
|
42
42
|
[]
|
43
43
|
else
|
44
|
-
mapper_registry[klass].
|
45
|
-
object.id.in ids.uniq
|
46
|
-
}.to_a
|
44
|
+
mapper_registry[klass].find(ids.uniq).to_a
|
47
45
|
end
|
48
46
|
end
|
49
47
|
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'perpetuity/duplicator'
|
2
|
+
|
3
|
+
module Perpetuity
|
4
|
+
class DirtyTracker
|
5
|
+
def initialize
|
6
|
+
@map = Hash.new { |hash, key| hash[key] = {} }
|
7
|
+
end
|
8
|
+
|
9
|
+
def [] klass, id
|
10
|
+
@map[klass][id.to_s]
|
11
|
+
end
|
12
|
+
|
13
|
+
def << object
|
14
|
+
klass = object.class
|
15
|
+
id = object.instance_variable_get(:@id)
|
16
|
+
@map[klass][id.to_s] = object.dup
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -1,19 +1,21 @@
|
|
1
1
|
module Perpetuity
|
2
2
|
class IdentityMap
|
3
|
-
attr_reader :map
|
4
|
-
|
5
3
|
def initialize
|
6
4
|
@map = Hash.new { |hash, key| hash[key] = {} }
|
7
5
|
end
|
8
6
|
|
9
7
|
def [] klass, id
|
10
|
-
map[klass][id
|
8
|
+
@map[klass][id]
|
11
9
|
end
|
12
10
|
|
13
11
|
def << object
|
14
12
|
klass = object.class
|
15
13
|
id = object.instance_variable_get(:@id)
|
16
|
-
map[klass][id
|
14
|
+
@map[klass][id] = object
|
15
|
+
end
|
16
|
+
|
17
|
+
def ids_for klass
|
18
|
+
@map[klass].keys
|
17
19
|
end
|
18
20
|
end
|
19
21
|
end
|
data/lib/perpetuity/mapper.rb
CHANGED
@@ -3,16 +3,17 @@ require 'perpetuity/attribute'
|
|
3
3
|
require 'perpetuity/data_injectable'
|
4
4
|
require 'perpetuity/dereferencer'
|
5
5
|
require 'perpetuity/retrieval'
|
6
|
-
require 'perpetuity/
|
6
|
+
require 'perpetuity/dirty_tracker'
|
7
7
|
|
8
8
|
module Perpetuity
|
9
9
|
class Mapper
|
10
10
|
include DataInjectable
|
11
|
-
attr_reader :mapper_registry, :identity_map
|
11
|
+
attr_reader :mapper_registry, :identity_map, :dirty_tracker
|
12
12
|
|
13
|
-
def initialize registry=Perpetuity.mapper_registry
|
13
|
+
def initialize registry=Perpetuity.mapper_registry, id_map=IdentityMap.new
|
14
14
|
@mapper_registry = registry
|
15
|
-
@identity_map =
|
15
|
+
@identity_map = id_map
|
16
|
+
@dirty_tracker = DirtyTracker.new
|
16
17
|
end
|
17
18
|
|
18
19
|
def self.map klass, registry=Perpetuity.mapper_registry
|
@@ -128,17 +129,27 @@ module Perpetuity
|
|
128
129
|
|
129
130
|
alias :find_all :select
|
130
131
|
|
131
|
-
def find id=nil,
|
132
|
+
def find id=nil, &block
|
132
133
|
if block_given?
|
133
134
|
select(&block).first
|
134
135
|
else
|
135
136
|
cached_value = identity_map[mapped_class, id]
|
136
137
|
return cached_value if cached_value
|
137
138
|
|
138
|
-
result =
|
139
|
-
|
140
|
-
|
141
|
-
|
139
|
+
result = if id.is_a? Array
|
140
|
+
ids = id
|
141
|
+
ids_in_map = ids & identity_map.ids_for(mapped_class)
|
142
|
+
ids_to_select = ids - ids_in_map
|
143
|
+
retrieved = select { |object| object.id.in ids_to_select }.to_a
|
144
|
+
from_map = ids_in_map.map { |id| identity_map[mapped_class, id] }
|
145
|
+
retrieved + from_map
|
146
|
+
else
|
147
|
+
select { |object| object.id == id }.first
|
148
|
+
end
|
149
|
+
|
150
|
+
Array(result).each do |r|
|
151
|
+
identity_map << r
|
152
|
+
dirty_tracker << r
|
142
153
|
end
|
143
154
|
|
144
155
|
result
|
@@ -158,7 +169,7 @@ module Perpetuity
|
|
158
169
|
|
159
170
|
def load_association! object, attribute
|
160
171
|
objects = Array(object)
|
161
|
-
dereferencer = Dereferencer.new(mapper_registry)
|
172
|
+
dereferencer = Dereferencer.new(mapper_registry, identity_map)
|
162
173
|
dereferencer.load objects.map { |obj| obj.instance_variable_get("@#{attribute}") }
|
163
174
|
|
164
175
|
objects.each do |obj|
|
@@ -185,10 +196,8 @@ module Perpetuity
|
|
185
196
|
end
|
186
197
|
end
|
187
198
|
|
188
|
-
def update object, new_data
|
199
|
+
def update object, new_data
|
189
200
|
id = object.is_a?(mapped_class) ? id_for(object) : object
|
190
|
-
|
191
|
-
inject_data object, new_data if update_in_memory
|
192
201
|
data_source.update mapped_class, id, new_data
|
193
202
|
end
|
194
203
|
|
@@ -197,7 +206,7 @@ module Perpetuity
|
|
197
206
|
if changed_attributes && changed_attributes.any?
|
198
207
|
update object, changed_attributes
|
199
208
|
else
|
200
|
-
update object, serialize(object)
|
209
|
+
update object, serialize(object)
|
201
210
|
end
|
202
211
|
end
|
203
212
|
|
@@ -237,7 +246,7 @@ module Perpetuity
|
|
237
246
|
end
|
238
247
|
|
239
248
|
def serialize_changed_attributes object
|
240
|
-
cached =
|
249
|
+
cached = dirty_tracker[object.class, id_for(object)]
|
241
250
|
if cached
|
242
251
|
data_source.serialize_changed_attributes(object, cached, self)
|
243
252
|
end
|
@@ -11,15 +11,22 @@ module Perpetuity
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def [] klass
|
14
|
-
mapper_class
|
14
|
+
mapper_class(klass).new(self)
|
15
|
+
end
|
16
|
+
|
17
|
+
def mapper_for klass, options={}
|
18
|
+
identity_map = options[:identity_map]
|
19
|
+
mapper_class(klass).new(self, *Array(identity_map))
|
20
|
+
end
|
21
|
+
|
22
|
+
def mapper_class klass
|
23
|
+
@mappers.fetch(klass) do
|
15
24
|
load_mappers
|
16
25
|
unless @mappers.has_key? klass
|
17
26
|
raise KeyError, "No mapper for #{klass}"
|
18
27
|
end
|
19
28
|
@mappers[klass]
|
20
29
|
end
|
21
|
-
|
22
|
-
mapper_class.new(self)
|
23
30
|
end
|
24
31
|
|
25
32
|
def []= klass, mapper
|
data/lib/perpetuity/version.rb
CHANGED
@@ -15,11 +15,6 @@ describe 'updating' do
|
|
15
15
|
mapper.find(mapper.id_for article).title.should eq new_title
|
16
16
|
end
|
17
17
|
|
18
|
-
it 'updates the object in memory' do
|
19
|
-
mapper.update article, title: new_title
|
20
|
-
article.title.should eq new_title
|
21
|
-
end
|
22
|
-
|
23
18
|
it 'resaves the object in the database' do
|
24
19
|
article.title = new_title
|
25
20
|
mapper.save article
|
@@ -16,6 +16,10 @@ module Perpetuity
|
|
16
16
|
it 'loads objects based on the specified objects and attribute' do
|
17
17
|
first.instance_variable_set :@id, 1
|
18
18
|
mapper.should_receive(:find).with(1) { first }
|
19
|
+
id_map = IdentityMap.new
|
20
|
+
derefer.stub(map: id_map)
|
21
|
+
registry.stub(:mapper_for)
|
22
|
+
.with(Object, identity_map: id_map) { mapper }
|
19
23
|
|
20
24
|
derefer.load first_ref
|
21
25
|
id = derefer[first_ref].instance_variable_get(:@id)
|
@@ -31,9 +35,7 @@ module Perpetuity
|
|
31
35
|
|
32
36
|
context 'with multiple references' do
|
33
37
|
it 'returns the array of dereferenced objects' do
|
34
|
-
|
35
|
-
second.instance_variable_set :@id, 2
|
36
|
-
mapper.should_receive(:select) { objects }
|
38
|
+
mapper.should_receive(:find).with([1, 2]) { objects }
|
37
39
|
derefer.load([first_ref, second_ref]).should == objects
|
38
40
|
end
|
39
41
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'perpetuity/dirty_tracker'
|
2
|
+
|
3
|
+
module Perpetuity
|
4
|
+
describe DirtyTracker do
|
5
|
+
let(:mapper) { double('ObjectMapper') }
|
6
|
+
let(:tracker) { DirtyTracker.new }
|
7
|
+
|
8
|
+
context 'when the object exists in the IdentityMap' do
|
9
|
+
let(:klass) do
|
10
|
+
Class.new do
|
11
|
+
attr_accessor :id, :name
|
12
|
+
def initialize id, name
|
13
|
+
@id = id
|
14
|
+
@name = name
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
let(:object) { klass.new(1, 'foo') }
|
19
|
+
|
20
|
+
before do
|
21
|
+
mapper.stub(:id_for).with(object) { object.id }
|
22
|
+
tracker << object
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'returns the object with the given class and id' do
|
26
|
+
object.name = 'bar'
|
27
|
+
retrieved = tracker[klass, 1]
|
28
|
+
|
29
|
+
retrieved.id.should == 1
|
30
|
+
retrieved.name.should == 'foo'
|
31
|
+
end
|
32
|
+
|
33
|
+
specify 'the object returned is a duplicate' do
|
34
|
+
tracker[klass, 1].should_not be object
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'stringifies keys when checking' do
|
38
|
+
retrieved = tracker[klass, '1']
|
39
|
+
retrieved.id.should == 1
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'when the object does not exist in the IdentityMap' do
|
44
|
+
it 'returns nil' do
|
45
|
+
tracker[Object, 1].should be_nil
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -3,28 +3,29 @@ require 'perpetuity/identity_map'
|
|
3
3
|
module Perpetuity
|
4
4
|
describe IdentityMap do
|
5
5
|
let(:id_map) { IdentityMap.new }
|
6
|
+
let(:klass) do
|
7
|
+
Class.new do
|
8
|
+
attr_reader :id
|
9
|
+
def initialize id
|
10
|
+
@id = id
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
let(:object) { klass.new(1) }
|
6
15
|
|
7
16
|
context 'when the object exists in the IdentityMap' do
|
8
|
-
let(:object) { Object.new }
|
9
|
-
|
10
17
|
before do
|
11
|
-
object.instance_variable_set :@id, 1
|
12
18
|
id_map << object
|
13
19
|
end
|
14
20
|
|
15
21
|
it 'returns the object with the given class and id' do
|
16
|
-
retrieved = id_map[
|
22
|
+
retrieved = id_map[klass, 1]
|
17
23
|
|
18
|
-
retrieved.
|
24
|
+
retrieved.id.should == 1
|
19
25
|
end
|
20
26
|
|
21
|
-
specify 'the object returned is
|
22
|
-
id_map[
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'stringifies keys when checking' do
|
26
|
-
retrieved = id_map[Object, '1']
|
27
|
-
retrieved.instance_variable_get(:@id).should == 1
|
27
|
+
specify 'the object returned is the same object' do
|
28
|
+
id_map[klass, 1].should be object
|
28
29
|
end
|
29
30
|
end
|
30
31
|
|
@@ -33,5 +34,10 @@ module Perpetuity
|
|
33
34
|
id_map[Object, 1].should be_nil
|
34
35
|
end
|
35
36
|
end
|
37
|
+
|
38
|
+
it 'returns all of the ids it contains' do
|
39
|
+
id_map << object
|
40
|
+
id_map.ids_for(klass).should == [1]
|
41
|
+
end
|
36
42
|
end
|
37
43
|
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
require 'perpetuity/mapper_registry'
|
2
|
+
require 'perpetuity/mapper'
|
2
3
|
|
3
4
|
module Perpetuity
|
4
5
|
describe MapperRegistry do
|
5
6
|
let(:registry) { MapperRegistry.new }
|
6
|
-
let(:mapper) {
|
7
|
+
let(:mapper) { Mapper }
|
7
8
|
subject { registry }
|
8
9
|
|
9
10
|
before { registry[Object] = mapper }
|
@@ -30,5 +31,11 @@ module Perpetuity
|
|
30
31
|
registry.load_mappers
|
31
32
|
end
|
32
33
|
end
|
34
|
+
|
35
|
+
it 'returns a mapper initialized with the specified identity map' do
|
36
|
+
identity_map = double('IdentityMap')
|
37
|
+
mapper = registry.mapper_for(Object, identity_map: identity_map)
|
38
|
+
mapper.identity_map.should be identity_map
|
39
|
+
end
|
33
40
|
end
|
34
41
|
end
|
@@ -71,6 +71,17 @@ module Perpetuity
|
|
71
71
|
mapper.find(1).should be == returned_object
|
72
72
|
end
|
73
73
|
|
74
|
+
it 'finds multiple objects by ID' do
|
75
|
+
first, second = double, double
|
76
|
+
criteria = data_source.query { |o| o.id.in [1, 2] }
|
77
|
+
options.merge! limit: nil
|
78
|
+
data_source.should_receive(:retrieve)
|
79
|
+
.with(Object, criteria, options)
|
80
|
+
.and_return [first, second]
|
81
|
+
|
82
|
+
mapper.find([1, 2]).to_a.should be == [first, second]
|
83
|
+
end
|
84
|
+
|
74
85
|
it 'finds multiple objects with a block' do
|
75
86
|
criteria = data_source.query { |o| o.name == 'foo' }
|
76
87
|
options = self.options.merge(limit: nil)
|
@@ -132,7 +143,7 @@ module Perpetuity
|
|
132
143
|
object.instance_variable_set :@id, 1
|
133
144
|
object.instance_variable_set :@modified, false
|
134
145
|
object.instance_variable_set :@unmodified, false
|
135
|
-
mapper.
|
146
|
+
mapper.dirty_tracker << object
|
136
147
|
|
137
148
|
object.instance_variable_set :@modified, true
|
138
149
|
|
@@ -196,5 +207,14 @@ module Perpetuity
|
|
196
207
|
end
|
197
208
|
end
|
198
209
|
end
|
210
|
+
|
211
|
+
describe 'using an existing identity map' do
|
212
|
+
it 'is initialized with an existing map' do
|
213
|
+
registry = Object.new
|
214
|
+
id_map = Object.new
|
215
|
+
mapper = Mapper.new(registry, id_map)
|
216
|
+
mapper.identity_map.should be id_map
|
217
|
+
end
|
218
|
+
end
|
199
219
|
end
|
200
220
|
end
|
data/spec/perpetuity_spec.rb
CHANGED
@@ -49,4 +49,28 @@ describe Perpetuity do
|
|
49
49
|
unpublished_ids.should include draft_id, not_yet_published_id
|
50
50
|
end
|
51
51
|
end
|
52
|
+
|
53
|
+
describe 'adapter registration' do
|
54
|
+
before do
|
55
|
+
class ExampleAdapter; end
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'registers an adapter' do
|
59
|
+
Perpetuity.register_adapter :example => ExampleAdapter
|
60
|
+
Perpetuity::Configuration.adapters[:example].should == ExampleAdapter
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'can re-register an adapter' do
|
64
|
+
Perpetuity.register_adapter :example => ExampleAdapter
|
65
|
+
Perpetuity.register_adapter :example => ExampleAdapter
|
66
|
+
Perpetuity::Configuration.adapters[:example].should == ExampleAdapter
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'cannot re-register an adapter with a different class than originally registered' do
|
70
|
+
Perpetuity.register_adapter :example => ExampleAdapter
|
71
|
+
expect { Perpetuity.register_adapter :example => TrueClass }.to raise_exception
|
72
|
+
Perpetuity::Configuration.adapters[:example].should == ExampleAdapter
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
52
76
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: perpetuity
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.
|
4
|
+
version: 1.0.0.beta5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jamie Gaskins
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-02-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -59,6 +59,7 @@ files:
|
|
59
59
|
- lib/perpetuity/config.rb
|
60
60
|
- lib/perpetuity/data_injectable.rb
|
61
61
|
- lib/perpetuity/dereferencer.rb
|
62
|
+
- lib/perpetuity/dirty_tracker.rb
|
62
63
|
- lib/perpetuity/duplicator.rb
|
63
64
|
- lib/perpetuity/exceptions/duplicate_key_error.rb
|
64
65
|
- lib/perpetuity/identity_map.rb
|
@@ -84,6 +85,7 @@ files:
|
|
84
85
|
- spec/perpetuity/config_spec.rb
|
85
86
|
- spec/perpetuity/data_injectable_spec.rb
|
86
87
|
- spec/perpetuity/dereferencer_spec.rb
|
88
|
+
- spec/perpetuity/dirty_tracker_spec.rb
|
87
89
|
- spec/perpetuity/duplicator_spec.rb
|
88
90
|
- spec/perpetuity/identity_map_spec.rb
|
89
91
|
- spec/perpetuity/mapper_registry_spec.rb
|
@@ -143,6 +145,7 @@ test_files:
|
|
143
145
|
- spec/perpetuity/config_spec.rb
|
144
146
|
- spec/perpetuity/data_injectable_spec.rb
|
145
147
|
- spec/perpetuity/dereferencer_spec.rb
|
148
|
+
- spec/perpetuity/dirty_tracker_spec.rb
|
146
149
|
- spec/perpetuity/duplicator_spec.rb
|
147
150
|
- spec/perpetuity/identity_map_spec.rb
|
148
151
|
- spec/perpetuity/mapper_registry_spec.rb
|