store 0.0.5 → 0.0.6
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +6 -0
- data/README.md +6 -1
- data/example.rb +29 -10
- data/lib/store.rb +28 -62
- data/lib/store/entity_references.rb +17 -0
- data/lib/store/repo.rb +7 -2
- data/lib/store/resolver.rb +18 -0
- data/lib/store/resolver/data_mapper.rb +22 -0
- data/lib/store/resolver/entity_mapper.rb +23 -0
- data/lib/store/version.rb +1 -1
- data/spec/entity_references_spec.rb +39 -0
- data/spec/helper.rb +14 -0
- data/spec/resolver/data_mapper_spec.rb +50 -0
- data/spec/resolver/entity_mapper_spec.rb +51 -0
- data/spec/resolver/resolver_spec.rb +30 -0
- data/spec/store_repo_spec.rb +34 -5
- data/store.gemspec +1 -0
- metadata +29 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f95b1ab0e7baa12a07c3b53d297f42da47440ac
|
4
|
+
data.tar.gz: 0dcaa59a8fe5af7d4678bb9ab714c335cd95894d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a224bbb8c5330b40ae561c85e65c3fc05669afd2eb2b026acc40eddc2b099ca0719fde7e9acad7227afbc309ae3840beb4d559d82ffc0fc881c3145776e4334d
|
7
|
+
data.tar.gz: 4c9595417be360e5b12d35bb6bbcc4f8c36037071027d32af0bdefd513775a4d932198aceeda1f55fdbd2914dce12dea8d92ba8191813eb2f8b32cd8666228c1
|
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,7 +1,12 @@
|
|
1
|
-
# Store
|
1
|
+
# Store
|
2
|
+
|
3
|
+
[](http://badge.fury.io/rb/store) [](https://travis-ci.org/holderbaum/store)
|
2
4
|
|
3
5
|
Implementations for using the Repository- and Data Mapper Pattern in ruby
|
4
6
|
|
7
|
+
**Important:** We are still ignoring dirty tracking, so this is not for
|
8
|
+
heavy-load environments! [Issue](https://github.com/holderbaum/store/issues/1)
|
9
|
+
|
5
10
|
## Installation
|
6
11
|
|
7
12
|
Add this line to your application's Gemfile:
|
data/example.rb
CHANGED
@@ -18,7 +18,15 @@ class Catalog
|
|
18
18
|
end
|
19
19
|
|
20
20
|
class Product
|
21
|
-
attr_accessor :name, :price
|
21
|
+
attr_accessor :name, :price, :discount
|
22
|
+
|
23
|
+
def discounted_price
|
24
|
+
price * (1 - discount)
|
25
|
+
end
|
26
|
+
|
27
|
+
def discount
|
28
|
+
@discount || 0
|
29
|
+
end
|
22
30
|
end
|
23
31
|
|
24
32
|
# EntityMappers ################################################################
|
@@ -59,15 +67,17 @@ class ProductEntityMapper < Store::EntityMapper
|
|
59
67
|
def map(product)
|
60
68
|
{
|
61
69
|
'name' => product.name,
|
62
|
-
'price' => product.price
|
70
|
+
'price' => product.price,
|
71
|
+
'discount' => product.discount
|
63
72
|
}
|
64
73
|
end
|
65
74
|
|
66
75
|
def unmap(cls, mapped)
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
76
|
+
product = cls.new
|
77
|
+
product.name = mapped['name']
|
78
|
+
product.price = mapped['price']
|
79
|
+
product.discount = mapped['discount']
|
80
|
+
product
|
71
81
|
end
|
72
82
|
end
|
73
83
|
|
@@ -95,12 +105,12 @@ class MemoryDataMapper < Store::DataMapper
|
|
95
105
|
id
|
96
106
|
end
|
97
107
|
|
98
|
-
def single_find(
|
99
|
-
dup(@items[
|
108
|
+
def single_find(id)
|
109
|
+
dup(@items[id])
|
100
110
|
end
|
101
111
|
|
102
|
-
def bulk_find(
|
103
|
-
@items.values_at(*
|
112
|
+
def bulk_find(ids)
|
113
|
+
@items.values_at(*ids).map do |data|
|
104
114
|
dup data
|
105
115
|
end
|
106
116
|
end
|
@@ -171,6 +181,12 @@ class Repo < Store::Repo
|
|
171
181
|
end
|
172
182
|
end
|
173
183
|
|
184
|
+
class DiscountedProductFactory < Struct.new(:repo)
|
185
|
+
def build(name, price = 100)
|
186
|
+
repo.build 'Product', :name => name, :price => price, :discount => 0.25
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
174
190
|
repo = Repo.new(entities, data_mappers, entity_mappers)
|
175
191
|
|
176
192
|
# Usage ########################################################################
|
@@ -179,8 +195,11 @@ editor = repo.build 'User', :name => 'Mr. Repo'
|
|
179
195
|
|
180
196
|
catalog = repo.build 'Catalog', :name => 'Catalog 1', :editor => editor
|
181
197
|
|
198
|
+
factory = DiscountedProductFactory.new(repo)
|
199
|
+
|
182
200
|
catalog.add_product repo.build('Product', :name => 'Pickaxe', :price => 100)
|
183
201
|
catalog.add_product repo.build('Product', :name => 'Scredriver', :price => 400)
|
202
|
+
catalog.add_product factory.build('Pair of shoes')
|
184
203
|
|
185
204
|
p 'save call'
|
186
205
|
repo.save(catalog)
|
data/lib/store.rb
CHANGED
@@ -2,14 +2,15 @@ require 'store/repo'
|
|
2
2
|
require 'store/ref'
|
3
3
|
require 'store/entity_mapper'
|
4
4
|
require 'store/data_mapper'
|
5
|
+
require 'store/resolver'
|
6
|
+
require 'store/entity_references'
|
5
7
|
|
6
8
|
class Store
|
7
9
|
def initialize(entity_classes, data_mapping, entity_mapping)
|
8
|
-
@entity_classes
|
9
|
-
@
|
10
|
-
@
|
11
|
-
|
12
|
-
@entity_references = Hash.new
|
10
|
+
@entity_classes = entity_classes
|
11
|
+
@resolver_data_mapper = Resolver::DataMapper.new(data_mapping)
|
12
|
+
@resolver_entity_mapper = Resolver::EntityMapper.new(self, entity_mapping)
|
13
|
+
@entity_references = EntityReferences.new
|
13
14
|
end
|
14
15
|
|
15
16
|
def build(entity_class_name, attributes = {})
|
@@ -34,7 +35,7 @@ class Store
|
|
34
35
|
end
|
35
36
|
|
36
37
|
def remove(entity)
|
37
|
-
data_mapper =
|
38
|
+
data_mapper = data_mapper(entity)
|
38
39
|
raise_unless_data_mapper_found(entity, data_mapper)
|
39
40
|
|
40
41
|
reference = find_entity_reference(entity)
|
@@ -44,8 +45,7 @@ class Store
|
|
44
45
|
end
|
45
46
|
|
46
47
|
def query(query)
|
47
|
-
data_mapper =
|
48
|
-
entity_mapper = entity_mapper_for_query(query)
|
48
|
+
data_mapper = data_mapper(query)
|
49
49
|
entity_class = @entity_classes[query.entity]
|
50
50
|
|
51
51
|
raise_unless_data_mapper_found(query, data_mapper)
|
@@ -53,7 +53,7 @@ class Store
|
|
53
53
|
mapped_entities_with_references = data_mapper.select(query) || {}
|
54
54
|
|
55
55
|
mapped_entities_with_references.map do |reference, mapped_entity|
|
56
|
-
entity = entity_mapper
|
56
|
+
entity = entity_mapper(query).unmap(entity_class, mapped_entity)
|
57
57
|
save_entity_reference reference, entity
|
58
58
|
entity
|
59
59
|
end
|
@@ -68,21 +68,19 @@ class Store
|
|
68
68
|
end
|
69
69
|
|
70
70
|
def single_load(ref)
|
71
|
-
data_mapper =
|
72
|
-
entity_mapper = entity_mapper_for_ref(ref)
|
71
|
+
data_mapper = data_mapper(ref)
|
73
72
|
entity_class = @entity_classes[ref.entity_type]
|
74
73
|
reference = ref.reference
|
75
74
|
|
76
75
|
mapped_entity = data_mapper.single_find(reference)
|
77
76
|
|
78
|
-
entity = entity_mapper
|
77
|
+
entity = entity_mapper(ref).unmap(entity_class, mapped_entity)
|
79
78
|
save_entity_reference reference, entity
|
80
79
|
entity
|
81
80
|
end
|
82
81
|
|
83
82
|
def bulk_load(refs)
|
84
|
-
data_mapper =
|
85
|
-
entity_mapper = entity_mapper_for_ref(refs.first)
|
83
|
+
data_mapper = data_mapper(refs.first)
|
86
84
|
entity_class = @entity_classes[refs.first.entity_type]
|
87
85
|
|
88
86
|
references = refs.map(&:reference)
|
@@ -93,7 +91,7 @@ class Store
|
|
93
91
|
references.each_with_index do |reference, i|
|
94
92
|
mapped_entity = mapped_entities[i]
|
95
93
|
|
96
|
-
entity = entity_mapper.
|
94
|
+
entity = entity_mapper(refs.first).unmap(entity_class, mapped_entity)
|
97
95
|
save_entity_reference reference, entity
|
98
96
|
entities << entity
|
99
97
|
end
|
@@ -105,82 +103,50 @@ class Store
|
|
105
103
|
def save_entity(entity)
|
106
104
|
return nil unless entity
|
107
105
|
|
108
|
-
data_mapper =
|
106
|
+
data_mapper = data_mapper(entity)
|
109
107
|
raise_unless_data_mapper_found(entity, data_mapper)
|
110
108
|
|
111
109
|
reference = find_entity_reference(entity)
|
112
110
|
if reference.nil?
|
113
|
-
reference = data_mapper.insert(
|
111
|
+
reference = data_mapper.insert(extract_entity_attributes(entity))
|
114
112
|
save_entity_reference(reference, entity)
|
115
113
|
else
|
116
|
-
data_mapper.update(reference,
|
114
|
+
data_mapper.update(reference, extract_entity_attributes(entity))
|
117
115
|
end
|
118
116
|
|
119
|
-
Ref.new(
|
117
|
+
Ref.new(extract_entity_class_name(entity), reference)
|
120
118
|
end
|
121
119
|
|
122
120
|
def raise_unless_data_mapper_found(source, data_mapper)
|
123
121
|
raise "No data_mapper for #{source.inspect} found" unless data_mapper
|
124
122
|
end
|
125
123
|
|
126
|
-
def
|
127
|
-
|
128
|
-
entity_mapper.new(self).map(entity)
|
129
|
-
end
|
130
|
-
|
131
|
-
def entity_mapper_for_entity(entity)
|
132
|
-
type = entity_type(entity)
|
133
|
-
entity_mapper_for_type(type)
|
134
|
-
end
|
135
|
-
|
136
|
-
def entity_mapper_for_query(query)
|
137
|
-
type = query.entity
|
138
|
-
entity_mapper_for_type(type)
|
139
|
-
end
|
140
|
-
|
141
|
-
def entity_mapper_for_ref(ref)
|
142
|
-
type = ref.entity_type
|
143
|
-
entity_mapper_for_type(type)
|
144
|
-
end
|
145
|
-
|
146
|
-
def entity_mapper_for_type(type)
|
147
|
-
@entity_mapping[type]
|
148
|
-
end
|
149
|
-
|
150
|
-
def entity_type(entity)
|
151
|
-
entity_class = entity.class
|
152
|
-
entity_class.name.split('::').last
|
153
|
-
end
|
154
|
-
|
155
|
-
def data_mapper_for_entity(entity)
|
156
|
-
type = entity_type(entity)
|
157
|
-
data_mapper_for_type type
|
124
|
+
def data_mapper(obj)
|
125
|
+
@resolver_data_mapper.resolve_data_mapper(obj)
|
158
126
|
end
|
159
127
|
|
160
|
-
def
|
161
|
-
|
162
|
-
data_mapper_for_type type
|
128
|
+
def entity_mapper(obj)
|
129
|
+
@resolver_entity_mapper.resolve_entity_mapper(obj)
|
163
130
|
end
|
164
131
|
|
165
|
-
def
|
166
|
-
|
167
|
-
data_mapper_for_type type
|
132
|
+
def extract_entity_attributes(entity)
|
133
|
+
entity_mapper(entity).map(entity)
|
168
134
|
end
|
169
135
|
|
170
|
-
def
|
171
|
-
@
|
136
|
+
def extract_entity_class_name(obj)
|
137
|
+
@resolver_entity_mapper.extract_entity_class_name_from_object(obj)
|
172
138
|
end
|
173
139
|
|
174
140
|
def find_entity_reference(entity)
|
175
|
-
@entity_references
|
141
|
+
@entity_references.find(entity)
|
176
142
|
end
|
177
143
|
|
178
144
|
def save_entity_reference(reference, entity)
|
179
|
-
@entity_references
|
145
|
+
@entity_references.save(reference, entity)
|
180
146
|
end
|
181
147
|
|
182
148
|
def remove_entity_reference(entity)
|
183
|
-
@entity_references.
|
149
|
+
@entity_references.remove entity
|
184
150
|
end
|
185
151
|
|
186
152
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class EntityReferences
|
2
|
+
def initialize
|
3
|
+
@hash = Hash.new
|
4
|
+
end
|
5
|
+
|
6
|
+
def save(id, entity)
|
7
|
+
@hash[entity.object_id] = id
|
8
|
+
end
|
9
|
+
|
10
|
+
def find(entity)
|
11
|
+
@hash[entity.object_id]
|
12
|
+
end
|
13
|
+
|
14
|
+
def remove(entity)
|
15
|
+
@hash.delete entity.object_id
|
16
|
+
end
|
17
|
+
end
|
data/lib/store/repo.rb
CHANGED
@@ -10,11 +10,16 @@ class Store
|
|
10
10
|
@store.build(entity, *args)
|
11
11
|
end
|
12
12
|
|
13
|
-
def save(
|
14
|
-
@store.save(
|
13
|
+
def save(entities)
|
14
|
+
@store.save(entities)
|
15
15
|
true
|
16
16
|
end
|
17
17
|
|
18
|
+
def save_and_load(entities)
|
19
|
+
refs = @store.save(entities)
|
20
|
+
@store.load(refs)
|
21
|
+
end
|
22
|
+
|
18
23
|
def remove(entity)
|
19
24
|
@store.remove(entity)
|
20
25
|
true
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'store/resolver/entity_mapper'
|
2
|
+
require 'store/resolver/data_mapper'
|
3
|
+
|
4
|
+
module Resolver
|
5
|
+
|
6
|
+
def extract_entity_class_name_from_ref(ref)
|
7
|
+
ref.entity_type
|
8
|
+
end
|
9
|
+
|
10
|
+
def extract_entity_class_name_from_query(query)
|
11
|
+
query.entity
|
12
|
+
end
|
13
|
+
|
14
|
+
def extract_entity_class_name_from_object(obj)
|
15
|
+
obj.class.name.split('::').last
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Resolver
|
2
|
+
class DataMapper
|
3
|
+
include Resolver
|
4
|
+
|
5
|
+
def initialize(mapping)
|
6
|
+
@mapping = mapping
|
7
|
+
end
|
8
|
+
|
9
|
+
def resolve_data_mapper(obj)
|
10
|
+
@mapping[
|
11
|
+
if obj.kind_of? Store::Ref
|
12
|
+
extract_entity_class_name_from_ref(obj)
|
13
|
+
elsif obj.kind_of? Store::Query
|
14
|
+
extract_entity_class_name_from_query(obj)
|
15
|
+
else
|
16
|
+
extract_entity_class_name_from_object(obj)
|
17
|
+
end
|
18
|
+
]
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Resolver
|
2
|
+
class EntityMapper
|
3
|
+
include Resolver
|
4
|
+
|
5
|
+
def initialize(store, mapping)
|
6
|
+
@store = store
|
7
|
+
@mapping = mapping
|
8
|
+
end
|
9
|
+
|
10
|
+
def resolve_entity_mapper(obj)
|
11
|
+
@mapping[
|
12
|
+
if obj.kind_of? Store::Ref
|
13
|
+
extract_entity_class_name_from_ref(obj)
|
14
|
+
elsif obj.kind_of? Store::Query
|
15
|
+
extract_entity_class_name_from_query(obj)
|
16
|
+
else
|
17
|
+
extract_entity_class_name_from_object(obj)
|
18
|
+
end
|
19
|
+
].new(@store)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
data/lib/store/version.rb
CHANGED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe 'entity references' do
|
4
|
+
|
5
|
+
subject { EntityReferences.new }
|
6
|
+
let(:id) { 43 }
|
7
|
+
let(:object_id) { 42 }
|
8
|
+
let(:entity) { Struct.new(:object_id).new(object_id) }
|
9
|
+
|
10
|
+
describe 'save' do
|
11
|
+
it 'returns the passed id' do
|
12
|
+
assert_equal id, subject.save(id, entity)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe 'find' do
|
17
|
+
it 'returns the passed id' do
|
18
|
+
subject.save(id, entity)
|
19
|
+
assert_equal id, subject.find(entity)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe 'remove' do
|
24
|
+
it 'returns the passed id' do
|
25
|
+
subject.save(id, entity)
|
26
|
+
assert_equal id, subject.remove(entity)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe 'integration' do
|
31
|
+
it 'saves an entity, finds it and removes it after that' do
|
32
|
+
subject.save(id, entity)
|
33
|
+
assert_equal id, subject.find(entity)
|
34
|
+
subject.remove(entity)
|
35
|
+
assert_nil subject.find(entity)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
data/spec/helper.rb
CHANGED
@@ -10,3 +10,17 @@ require 'ostruct'
|
|
10
10
|
|
11
11
|
require 'store'
|
12
12
|
|
13
|
+
class MiniTest::Spec
|
14
|
+
|
15
|
+
def faked_class(class_name)
|
16
|
+
faked_class = Class.new do
|
17
|
+
class << self
|
18
|
+
attr_accessor :name
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
faked_class.name = class_name
|
23
|
+
faked_class
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe Resolver::DataMapper do
|
4
|
+
|
5
|
+
subject { Resolver::DataMapper.new(mapping) }
|
6
|
+
|
7
|
+
# entites
|
8
|
+
let(:foo) { faked_class('Foo').new }
|
9
|
+
let(:bar) { faked_class('Nested::Bar').new }
|
10
|
+
|
11
|
+
# data mapper
|
12
|
+
FooDataMapper = Class.new(Store::DataMapper)
|
13
|
+
BarDataMapper = Class.new(Store::DataMapper)
|
14
|
+
|
15
|
+
let(:mapping) do
|
16
|
+
{
|
17
|
+
'Foo' => FooDataMapper,
|
18
|
+
'Bar' => BarDataMapper,
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'validates the subject' do
|
23
|
+
assert_instance_of Resolver::DataMapper, subject
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'resolves data mapper class from Store::Ref' do
|
27
|
+
ref = Store::Ref.new('Foo', 42)
|
28
|
+
assert_equal FooDataMapper, subject.resolve_data_mapper(ref)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'resolves data mapper class from Store::Query' do
|
32
|
+
query = Store::Query.new('Foo', :query_name, :some, :args)
|
33
|
+
assert_equal FooDataMapper, subject.resolve_data_mapper(query)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'resolves data mapper class from object' do
|
37
|
+
assert_equal FooDataMapper, subject.resolve_data_mapper(foo)
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'resolves data mapper class from namespaced object' do
|
41
|
+
assert_equal BarDataMapper, subject.resolve_data_mapper(bar)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'includes Resolver module' do
|
45
|
+
assert subject.respond_to? :extract_entity_class_name_from_ref
|
46
|
+
assert subject.respond_to? :extract_entity_class_name_from_query
|
47
|
+
assert subject.respond_to? :extract_entity_class_name_from_object
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe Resolver::EntityMapper do
|
4
|
+
subject { Resolver::EntityMapper.new(store, mapping) }
|
5
|
+
|
6
|
+
# entites
|
7
|
+
let(:foo) { faked_class('Foo').new }
|
8
|
+
let(:bar) { faked_class('Nested::Bar').new }
|
9
|
+
|
10
|
+
# entity mapper
|
11
|
+
FooEntityMapper = Class.new(Store::EntityMapper)
|
12
|
+
BarEntityMapper = Class.new(Store::EntityMapper)
|
13
|
+
|
14
|
+
let(:mapping) do
|
15
|
+
{
|
16
|
+
'Foo' => FooEntityMapper,
|
17
|
+
'Bar' => BarEntityMapper,
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:store) { Object.new }
|
22
|
+
|
23
|
+
it 'validates the subject' do
|
24
|
+
assert_instance_of Resolver::EntityMapper, subject
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'resolves entity mapper instance from Store::Ref' do
|
28
|
+
ref = Store::Ref.new('Foo', 42)
|
29
|
+
assert_instance_of FooEntityMapper, subject.resolve_entity_mapper(ref)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'resolves entity mapper instance from Store::Query' do
|
33
|
+
query = Store::Query.new('Foo', :query_name, :some, :args)
|
34
|
+
assert_instance_of FooEntityMapper, subject.resolve_entity_mapper(query)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'resolves entity mapper instance from object' do
|
38
|
+
assert_instance_of FooEntityMapper, subject.resolve_entity_mapper(foo)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'resolves entity mapper instance from namespaced object' do
|
42
|
+
assert_instance_of BarEntityMapper, subject.resolve_entity_mapper(bar)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'includes Resolver module' do
|
46
|
+
assert subject.respond_to? :extract_entity_class_name_from_ref
|
47
|
+
assert subject.respond_to? :extract_entity_class_name_from_query
|
48
|
+
assert subject.respond_to? :extract_entity_class_name_from_object
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe Resolver do
|
4
|
+
|
5
|
+
let(:subject_class) { Class.new { include Resolver } }
|
6
|
+
subject { subject_class.new }
|
7
|
+
|
8
|
+
# entites
|
9
|
+
let(:foo) { faked_class('Foo').new }
|
10
|
+
let(:bar) { faked_class('Nested::Bar').new }
|
11
|
+
|
12
|
+
it 'extracts entity class name from Store::Ref' do
|
13
|
+
ref = Store::Ref.new('Foo', 42)
|
14
|
+
assert_equal 'Foo', subject.extract_entity_class_name_from_ref(ref)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'extracts entity class name from Store::Query' do
|
18
|
+
query = Store::Query.new('Foo', :query_name, :some, :args)
|
19
|
+
assert_equal 'Foo', subject.extract_entity_class_name_from_query(query)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'extracts entity class name from Object' do
|
23
|
+
assert_equal 'Foo', subject.extract_entity_class_name_from_object(foo)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'extracts entity class from Nested::Object' do
|
27
|
+
assert_equal 'Bar', subject.extract_entity_class_name_from_object(bar)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
data/spec/store_repo_spec.rb
CHANGED
@@ -15,19 +15,48 @@ describe 'Store::Repo' do
|
|
15
15
|
|
16
16
|
it 'delegeates save to @store and swallows result' do
|
17
17
|
store.expect :save, :result, [:arg]
|
18
|
-
|
18
|
+
|
19
|
+
result = repo.save(:arg)
|
20
|
+
|
21
|
+
assert store.verify
|
22
|
+
assert_equal true, result
|
19
23
|
end
|
20
24
|
|
21
25
|
it 'delegates remove to @store and swallows result' do
|
22
26
|
store.expect :remove, :result, [:arg]
|
23
|
-
|
27
|
+
|
28
|
+
result = repo.remove(:arg)
|
29
|
+
|
30
|
+
assert store.verify
|
31
|
+
assert_equal true, result
|
24
32
|
end
|
25
33
|
|
26
|
-
it 'delegates build to @store and returns result' do
|
34
|
+
it 'delegates build to @store and returns result without args' do
|
27
35
|
store.expect :build, :result, [:arg]
|
28
|
-
assert_equal :result, repo.build(:arg)
|
29
36
|
|
37
|
+
result = repo.build(:arg)
|
38
|
+
|
39
|
+
assert store.verify
|
40
|
+
assert_equal :result, result
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'delegates build to @store and returns result with args' do
|
30
44
|
store.expect :build, :result, [:arg, :a, :b]
|
31
|
-
|
45
|
+
|
46
|
+
result = repo.build(:arg, :a, :b)
|
47
|
+
|
48
|
+
assert store.verify
|
49
|
+
assert_equal :result, result
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'delegates save_and_load to @store' do
|
53
|
+
store.expect :save, :refs, [:arg]
|
54
|
+
store.expect :load, :entities, [:refs]
|
55
|
+
|
56
|
+
result = repo.save_and_load(:arg)
|
57
|
+
|
58
|
+
assert store.verify
|
59
|
+
assert_equal :entities, result
|
32
60
|
end
|
61
|
+
|
33
62
|
end
|
data/store.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: store
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jakob Holderbaum
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-07-
|
11
|
+
date: 2013-07-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - '>='
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '5.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '5.0'
|
55
69
|
description:
|
56
70
|
email:
|
57
71
|
- jakob@featurefabrik.de
|
@@ -60,6 +74,7 @@ extensions: []
|
|
60
74
|
extra_rdoc_files: []
|
61
75
|
files:
|
62
76
|
- .gitignore
|
77
|
+
- .travis.yml
|
63
78
|
- Gemfile
|
64
79
|
- README.md
|
65
80
|
- Rakefile
|
@@ -67,11 +82,19 @@ files:
|
|
67
82
|
- lib/store.rb
|
68
83
|
- lib/store/data_mapper.rb
|
69
84
|
- lib/store/entity_mapper.rb
|
85
|
+
- lib/store/entity_references.rb
|
70
86
|
- lib/store/query.rb
|
71
87
|
- lib/store/ref.rb
|
72
88
|
- lib/store/repo.rb
|
89
|
+
- lib/store/resolver.rb
|
90
|
+
- lib/store/resolver/data_mapper.rb
|
91
|
+
- lib/store/resolver/entity_mapper.rb
|
73
92
|
- lib/store/version.rb
|
93
|
+
- spec/entity_references_spec.rb
|
74
94
|
- spec/helper.rb
|
95
|
+
- spec/resolver/data_mapper_spec.rb
|
96
|
+
- spec/resolver/entity_mapper_spec.rb
|
97
|
+
- spec/resolver/resolver_spec.rb
|
75
98
|
- spec/store_query_spec.rb
|
76
99
|
- spec/store_ref_spec.rb
|
77
100
|
- spec/store_repo_spec.rb
|
@@ -102,7 +125,11 @@ signing_key:
|
|
102
125
|
specification_version: 4
|
103
126
|
summary: Repository Pattern and Data-Mapper Pattern
|
104
127
|
test_files:
|
128
|
+
- spec/entity_references_spec.rb
|
105
129
|
- spec/helper.rb
|
130
|
+
- spec/resolver/data_mapper_spec.rb
|
131
|
+
- spec/resolver/entity_mapper_spec.rb
|
132
|
+
- spec/resolver/resolver_spec.rb
|
106
133
|
- spec/store_query_spec.rb
|
107
134
|
- spec/store_ref_spec.rb
|
108
135
|
- spec/store_repo_spec.rb
|