minimapper 0.9.0 → 0.10.0
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/Gemfile +1 -1
- data/README.md +2 -26
- data/lib/minimapper/mapper.rb +52 -23
- data/lib/minimapper/version.rb +1 -1
- data/spec/mapper_spec.rb +352 -9
- data/spec/spec_helper.rb +0 -1
- data/unit/spec_helper.rb +0 -2
- metadata +7 -9
- data/spec/support/shared_examples/mapper.rb +0 -295
data/Gemfile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
3
|
# We don't require active_record to use minimapper, only to
|
4
|
-
# use minimapper/mapper
|
4
|
+
# use minimapper/mapper. We do require it for the tests though :)
|
5
5
|
#
|
6
6
|
# Also locked to below rails 4.0 as our specs use rails 3 features. Need to look into
|
7
7
|
# if there are any issues with rails 4.
|
data/README.md
CHANGED
@@ -98,7 +98,7 @@ old_id = user.id
|
|
98
98
|
user_mapper.delete(user)
|
99
99
|
p user.id # => nil
|
100
100
|
p user_mapper.find_by_id(old_id) # => nil
|
101
|
-
# user_mapper.find(old_id) # raises
|
101
|
+
# user_mapper.find(old_id) # raises ActiveRecord::RecordNotFound
|
102
102
|
# user_mapper.delete_all
|
103
103
|
# user_mapper.delete_by_id(1)
|
104
104
|
|
@@ -285,29 +285,6 @@ When you do `mapper.delete(entity)`, it will use [ActiveRecord's `delete`](http:
|
|
285
285
|
|
286
286
|
(FIXME?: Should we support `destroy` instead or as well?)
|
287
287
|
|
288
|
-
### Exceptions and status 404
|
289
|
-
|
290
|
-
Code like `UserMapper.find(123)` will raise `Minimapper::EntityNotFound` if there's no such record.
|
291
|
-
|
292
|
-
Rails treats the similar `ActiveRecord::RecordNotFound` exception as a 404 error, using that status code with the error backtrace in development and test, and showing the 404 page in production.
|
293
|
-
|
294
|
-
If you want the same for Minimapper, you can add a `config/initializers/minimapper.rb` containing:
|
295
|
-
|
296
|
-
``` ruby
|
297
|
-
# For 404 status with the dev/test backtrace, and a 404 page in production.
|
298
|
-
ActionDispatch::ExceptionWrapper.rescue_responses.merge!(
|
299
|
-
"Minimapper::EntityNotFound" => :not_found
|
300
|
-
)
|
301
|
-
```
|
302
|
-
|
303
|
-
You may also want to ignore those errors in your error logger. With [Honeybadger](https://www.honeybadger.io), you do:
|
304
|
-
|
305
|
-
``` ruby
|
306
|
-
Honeybadger.configure do |config|
|
307
|
-
config.ignore << "Minimapper::EntityNotFound"
|
308
|
-
end
|
309
|
-
```
|
310
|
-
|
311
288
|
### Custom entity class
|
312
289
|
|
313
290
|
[Minimapper::Entity](https://github.com/joakimk/minimapper/blob/master/lib/minimapper/entity.rb) adds some convenience methods for when a model is used within a Rails application. If you don't need that you can just include the core API from the [Minimapper::Entity::Core](https://github.com/joakimk/minimapper/blob/master/lib/minimapper/entity/core.rb) module (or implement your own version that behaves like [Minimapper::Entity::Core](https://github.com/joakimk/minimapper/blob/master/lib/minimapper/entity/core.rb)).
|
@@ -327,8 +304,7 @@ Robert "Uncle Bob" Martin:
|
|
327
304
|
|
328
305
|
### Apps
|
329
306
|
|
330
|
-
*
|
331
|
-
* The deploy status app that minimapper was extracted from: [https://github.com/joakimk/deployer](https://github.com/joakimk/deployer)
|
307
|
+
* [Barsoom](http://barsoom.se/) has built an app which at the time of writing has 16 tables mapped with minimapper. Most additions to minimapper comes from this app.
|
332
308
|
|
333
309
|
## Contributing
|
334
310
|
|
data/lib/minimapper/mapper.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
1
|
module Minimapper
|
2
|
-
EntityNotFound = Class.new(StandardError)
|
3
|
-
|
4
2
|
class Mapper
|
5
3
|
attr_accessor :repository
|
6
4
|
|
@@ -9,16 +7,18 @@ module Minimapper
|
|
9
7
|
def create(entity)
|
10
8
|
record = record_class.new
|
11
9
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
10
|
+
with_save_hooks(entity, record) do
|
11
|
+
copy_attributes_to_record(record, entity)
|
12
|
+
validate_record_and_copy_errors_to_entity(record, entity)
|
13
|
+
|
14
|
+
if entity.valid?
|
15
|
+
record.save!
|
16
|
+
entity.mark_as_persisted
|
17
|
+
entity.id = record.id
|
18
|
+
entity.id
|
19
|
+
else
|
20
|
+
false
|
21
|
+
end
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
@@ -44,6 +44,10 @@ module Minimapper
|
|
44
44
|
entity_for(record_class.order("id ASC").last)
|
45
45
|
end
|
46
46
|
|
47
|
+
def reload(entity)
|
48
|
+
find(entity.id)
|
49
|
+
end
|
50
|
+
|
47
51
|
def count
|
48
52
|
record_class.count
|
49
53
|
end
|
@@ -53,14 +57,16 @@ module Minimapper
|
|
53
57
|
def update(entity)
|
54
58
|
record = record_for(entity)
|
55
59
|
|
56
|
-
|
57
|
-
|
60
|
+
with_save_hooks(entity, record) do
|
61
|
+
copy_attributes_to_record(record, entity)
|
62
|
+
validate_record_and_copy_errors_to_entity(record, entity)
|
58
63
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
+
if entity.valid?
|
65
|
+
record.save!
|
66
|
+
true
|
67
|
+
else
|
68
|
+
false
|
69
|
+
end
|
64
70
|
end
|
65
71
|
end
|
66
72
|
|
@@ -110,8 +116,7 @@ module Minimapper
|
|
110
116
|
end
|
111
117
|
|
112
118
|
def find_record_safely(id)
|
113
|
-
|
114
|
-
raise(EntityNotFound, :id => id)
|
119
|
+
record_class.find(id)
|
115
120
|
end
|
116
121
|
|
117
122
|
def find_record(id)
|
@@ -119,8 +124,7 @@ module Minimapper
|
|
119
124
|
end
|
120
125
|
|
121
126
|
def record_for(entity)
|
122
|
-
|
123
|
-
raise(EntityNotFound, entity.inspect)
|
127
|
+
record_class.find(entity.id)
|
124
128
|
end
|
125
129
|
|
126
130
|
def entities_for(records, klass = entity_class)
|
@@ -144,9 +148,34 @@ module Minimapper
|
|
144
148
|
end
|
145
149
|
end
|
146
150
|
|
151
|
+
def with_save_hooks(entity, record)
|
152
|
+
creating = record.new_record?
|
153
|
+
before_save(entity, record)
|
154
|
+
result = yield
|
155
|
+
|
156
|
+
if result
|
157
|
+
after_save(entity, record)
|
158
|
+
|
159
|
+
if creating
|
160
|
+
after_create(entity, record)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
result
|
165
|
+
end
|
166
|
+
|
147
167
|
# Hooks
|
148
168
|
|
149
169
|
def after_find(entity, record)
|
150
170
|
end
|
171
|
+
|
172
|
+
def before_save(entity, record)
|
173
|
+
end
|
174
|
+
|
175
|
+
def after_save(entity, record)
|
176
|
+
end
|
177
|
+
|
178
|
+
def after_create(entity, record)
|
179
|
+
end
|
151
180
|
end
|
152
181
|
end
|
data/lib/minimapper/version.rb
CHANGED
data/spec/mapper_spec.rb
CHANGED
@@ -25,9 +25,79 @@ describe Minimapper::Mapper do
|
|
25
25
|
let(:mapper) { ProjectMapper.new }
|
26
26
|
let(:entity_class) { Project }
|
27
27
|
|
28
|
-
|
28
|
+
it "can set and get repository" do
|
29
|
+
mapper.repository = :repository_instance
|
30
|
+
mapper.repository.should == :repository_instance
|
31
|
+
end
|
29
32
|
|
30
33
|
describe "#create" do
|
34
|
+
it "sets an id on the entity" do
|
35
|
+
entity1 = build_valid_entity
|
36
|
+
entity1.id.should be_nil
|
37
|
+
mapper.create(entity1)
|
38
|
+
entity1.id.should > 0
|
39
|
+
|
40
|
+
entity2 = build_valid_entity
|
41
|
+
mapper.create(entity2)
|
42
|
+
entity2.id.should == entity1.id + 1
|
43
|
+
end
|
44
|
+
|
45
|
+
it "marks the entity as persisted" do
|
46
|
+
entity1 = build_valid_entity
|
47
|
+
entity1.should_not be_persisted
|
48
|
+
mapper.create(entity1)
|
49
|
+
entity1.should be_persisted
|
50
|
+
end
|
51
|
+
|
52
|
+
it "returns the id" do
|
53
|
+
id = mapper.create(build_valid_entity)
|
54
|
+
id.should be_kind_of(Fixnum)
|
55
|
+
id.should > 0
|
56
|
+
end
|
57
|
+
|
58
|
+
it "does not store by reference" do
|
59
|
+
entity = build_valid_entity
|
60
|
+
mapper.create(entity)
|
61
|
+
mapper.last.object_id.should_not == entity.object_id
|
62
|
+
mapper.last.attributes[:name].should == "test"
|
63
|
+
end
|
64
|
+
|
65
|
+
it "validates the record before saving" do
|
66
|
+
entity = entity_class.new
|
67
|
+
def entity.valid?
|
68
|
+
false
|
69
|
+
end
|
70
|
+
mapper.create(entity).should be_false
|
71
|
+
end
|
72
|
+
|
73
|
+
it "calls before_save and after_save on the mapper" do
|
74
|
+
entity = build_valid_entity
|
75
|
+
record = ProjectMapper::Record.new
|
76
|
+
ProjectMapper::Record.stub(:new => record)
|
77
|
+
mapper.should_receive(:before_save).with(entity, record)
|
78
|
+
mapper.should_receive(:after_save).with(entity, record)
|
79
|
+
mapper.create(entity)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "calls after_create on the mapper" do
|
83
|
+
entity = build_valid_entity
|
84
|
+
record = ProjectMapper::Record.new
|
85
|
+
ProjectMapper::Record.stub(:new => record)
|
86
|
+
mapper.should_receive(:after_create).with(entity, record)
|
87
|
+
mapper.create(entity)
|
88
|
+
end
|
89
|
+
|
90
|
+
it "does not call after_save or after_create if the save fails" do
|
91
|
+
entity = entity_class.new
|
92
|
+
def entity.valid?
|
93
|
+
false
|
94
|
+
end
|
95
|
+
mapper.should_receive(:before_save)
|
96
|
+
mapper.should_not_receive(:after_save)
|
97
|
+
mapper.should_not_receive(:after_create)
|
98
|
+
mapper.create(entity)
|
99
|
+
end
|
100
|
+
|
31
101
|
it "does not include protected attributes" do
|
32
102
|
# because it leads to exceptions when mass_assignment_sanitizer is set to strict
|
33
103
|
entity = build_entity(:visible => true, :name => "Joe")
|
@@ -65,15 +135,226 @@ describe Minimapper::Mapper do
|
|
65
135
|
mapper.create(new_entity)
|
66
136
|
new_entity.should be_valid
|
67
137
|
end
|
138
|
+
end
|
68
139
|
|
69
|
-
|
70
|
-
|
71
|
-
entity
|
72
|
-
entity
|
140
|
+
describe "#find" do
|
141
|
+
it "returns an entity matching the id" do
|
142
|
+
entity = build_valid_entity
|
143
|
+
mapper.create(entity)
|
144
|
+
found_entity = mapper.find(entity.id)
|
145
|
+
found_entity.attributes[:name].should == "test"
|
146
|
+
found_entity.id.should == entity.id
|
147
|
+
found_entity.should be_kind_of(Minimapper::Entity::Core)
|
148
|
+
end
|
149
|
+
|
150
|
+
it "supports string ids" do
|
151
|
+
entity = build_valid_entity
|
152
|
+
mapper.create(entity)
|
153
|
+
mapper.find(entity.id.to_s)
|
154
|
+
end
|
155
|
+
|
156
|
+
it "does not return the same instance" do
|
157
|
+
entity = build_valid_entity
|
158
|
+
mapper.create(entity)
|
159
|
+
mapper.find(entity.id).object_id.should_not == entity.object_id
|
160
|
+
mapper.find(entity.id).object_id.should_not == mapper.find(entity.id).object_id
|
161
|
+
end
|
162
|
+
|
163
|
+
it "calls after_find on the mapper" do
|
164
|
+
entity = build_valid_entity
|
165
|
+
mapper.create(entity)
|
166
|
+
mapper.should_receive(:after_find)
|
167
|
+
found_entity = mapper.find(entity.id)
|
168
|
+
end
|
169
|
+
|
170
|
+
it "returns an entity marked as persisted" do
|
171
|
+
entity = build_valid_entity
|
172
|
+
mapper.create(entity)
|
173
|
+
found_entity = mapper.find(entity.id)
|
174
|
+
found_entity.should be_persisted
|
175
|
+
end
|
176
|
+
|
177
|
+
it "fails when an entity can not be found" do
|
178
|
+
lambda { mapper.find(-1) }.should raise_error(ActiveRecord::RecordNotFound)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
describe "#find_by_id" do
|
183
|
+
it "returns an entity matching the id" do
|
184
|
+
entity = build_valid_entity
|
185
|
+
mapper.create(entity)
|
186
|
+
found_entity = mapper.find_by_id(entity.id)
|
187
|
+
found_entity.attributes[:name].should == "test"
|
188
|
+
found_entity.id.should == entity.id
|
189
|
+
found_entity.should be_kind_of(Minimapper::Entity::Core)
|
190
|
+
end
|
191
|
+
|
192
|
+
it "supports string ids" do
|
193
|
+
entity = build_valid_entity
|
194
|
+
mapper.create(entity)
|
195
|
+
mapper.find_by_id(entity.id.to_s)
|
196
|
+
end
|
197
|
+
|
198
|
+
it "does not return the same instance" do
|
199
|
+
entity = build_valid_entity
|
200
|
+
mapper.create(entity)
|
201
|
+
mapper.find_by_id(entity.id).object_id.should_not == entity.object_id
|
202
|
+
mapper.find_by_id(entity.id).object_id.should_not == mapper.find_by_id(entity.id).object_id
|
203
|
+
end
|
204
|
+
|
205
|
+
it "returns nil when an entity can not be found" do
|
206
|
+
mapper.find_by_id(-1).should be_nil
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
describe "#all" do
|
211
|
+
it "returns all entities in undefined order" do
|
212
|
+
first_created_entity = build_valid_entity
|
213
|
+
second_created_entity = build_valid_entity
|
214
|
+
mapper.create(first_created_entity)
|
215
|
+
mapper.create(second_created_entity)
|
216
|
+
all_entities = mapper.all
|
217
|
+
all_entities.map(&:id).should include(first_created_entity.id)
|
218
|
+
all_entities.map(&:id).should include(second_created_entity.id)
|
219
|
+
all_entities.first.should be_kind_of(Minimapper::Entity::Core)
|
220
|
+
end
|
221
|
+
|
222
|
+
it "does not return the same instances" do
|
223
|
+
entity = build_valid_entity
|
224
|
+
mapper.create(entity)
|
225
|
+
mapper.all.first.object_id.should_not == entity.object_id
|
226
|
+
mapper.all.first.object_id.should_not == mapper.all.first.object_id
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
describe "#first" do
|
231
|
+
it "returns the first entity" do
|
232
|
+
first_created_entity = build_valid_entity
|
233
|
+
mapper.create(first_created_entity)
|
234
|
+
mapper.create(build_valid_entity)
|
235
|
+
mapper.first.id.should == first_created_entity.id
|
236
|
+
mapper.first.should be_kind_of(entity_class)
|
237
|
+
end
|
238
|
+
|
239
|
+
it "does not return the same instance" do
|
240
|
+
entity = build_valid_entity
|
241
|
+
mapper.create(entity)
|
242
|
+
mapper.first.object_id.should_not == entity.object_id
|
243
|
+
mapper.first.object_id.should_not == mapper.first.object_id
|
244
|
+
end
|
245
|
+
|
246
|
+
it "returns nil when there is no entity" do
|
247
|
+
mapper.first.should be_nil
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
describe "#last" do
|
252
|
+
it "returns the last entity" do
|
253
|
+
last_created_entity = build_valid_entity
|
254
|
+
mapper.create(build_valid_entity)
|
255
|
+
mapper.create(last_created_entity)
|
256
|
+
mapper.last.id.should == last_created_entity.id
|
257
|
+
mapper.last.should be_kind_of(entity_class)
|
258
|
+
end
|
259
|
+
|
260
|
+
it "does not return the same instance" do
|
261
|
+
entity = build_valid_entity
|
262
|
+
mapper.create(entity)
|
263
|
+
mapper.last.object_id.should_not == entity.object_id
|
264
|
+
mapper.last.object_id.should_not == mapper.last.object_id
|
265
|
+
end
|
266
|
+
|
267
|
+
it "returns nil when there is no entity" do
|
268
|
+
mapper.last.should be_nil
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
describe "#reload" do
|
273
|
+
it "reloads the given record" do
|
274
|
+
entity = build_entity(:email => "foo@example.com")
|
275
|
+
mapper.create(entity)
|
276
|
+
entity.attributes[:email] = "test@example.com"
|
277
|
+
mapper.reload(entity)
|
278
|
+
entity.attributes[:email] = "foo@example.com"
|
279
|
+
mapper.reload(entity).object_id.should_not == entity.object_id
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
describe "#count" do
|
284
|
+
it "returns the number of entities" do
|
285
|
+
mapper.create(build_valid_entity)
|
286
|
+
mapper.create(build_valid_entity)
|
287
|
+
mapper.count.should == 2
|
73
288
|
end
|
74
289
|
end
|
75
290
|
|
76
291
|
describe "#update" do
|
292
|
+
it "updates" do
|
293
|
+
entity = build_valid_entity
|
294
|
+
mapper.create(entity)
|
295
|
+
|
296
|
+
entity.attributes = { :name => "Updated" }
|
297
|
+
mapper.last.attributes[:name].should == "test"
|
298
|
+
|
299
|
+
mapper.update(entity)
|
300
|
+
mapper.last.id.should == entity.id
|
301
|
+
mapper.last.attributes[:name].should == "Updated"
|
302
|
+
end
|
303
|
+
|
304
|
+
it "does not update and returns false when the entity isn't valid" do
|
305
|
+
entity = build_valid_entity
|
306
|
+
mapper.create(entity)
|
307
|
+
|
308
|
+
def entity.valid?
|
309
|
+
false
|
310
|
+
end
|
311
|
+
|
312
|
+
mapper.update(entity).should be_false
|
313
|
+
mapper.last.attributes[:name].should == "test"
|
314
|
+
end
|
315
|
+
|
316
|
+
it "calls before_save and after_save on the mapper" do
|
317
|
+
entity = build_valid_entity
|
318
|
+
mapper.create(entity)
|
319
|
+
|
320
|
+
record = ProjectMapper::Record.last
|
321
|
+
ProjectMapper::Record.stub(:find_by_id => record)
|
322
|
+
|
323
|
+
mapper.should_receive(:before_save).with(entity, record)
|
324
|
+
mapper.should_receive(:after_save).with(entity, record)
|
325
|
+
mapper.update(entity)
|
326
|
+
end
|
327
|
+
|
328
|
+
it "does not call after_create" do
|
329
|
+
entity = build_valid_entity
|
330
|
+
mapper.create(entity)
|
331
|
+
|
332
|
+
record = ProjectMapper::Record.last
|
333
|
+
ProjectMapper::Record.stub(:find_by_id => record)
|
334
|
+
|
335
|
+
mapper.should_receive(:after_save)
|
336
|
+
mapper.should_not_receive(:after_create)
|
337
|
+
mapper.update(entity)
|
338
|
+
end
|
339
|
+
|
340
|
+
it "returns true" do
|
341
|
+
entity = build_valid_entity
|
342
|
+
mapper.create(entity)
|
343
|
+
mapper.update(entity).should == true
|
344
|
+
end
|
345
|
+
|
346
|
+
it "fails when the entity does not have an id" do
|
347
|
+
entity = build_valid_entity
|
348
|
+
lambda { mapper.update(entity) }.should raise_error(ActiveRecord::RecordNotFound)
|
349
|
+
end
|
350
|
+
|
351
|
+
it "fails when the entity no longer exists" do
|
352
|
+
entity = build_valid_entity
|
353
|
+
mapper.create(entity)
|
354
|
+
mapper.delete_all
|
355
|
+
lambda { mapper.update(entity) }.should raise_error(ActiveRecord::RecordNotFound)
|
356
|
+
end
|
357
|
+
|
77
358
|
it "does not include protected attributes" do
|
78
359
|
entity = Project.new
|
79
360
|
mapper.create(entity)
|
@@ -117,11 +398,73 @@ describe Minimapper::Mapper do
|
|
117
398
|
mapper.update(new_entity)
|
118
399
|
new_entity.should be_valid
|
119
400
|
end
|
401
|
+
end
|
120
402
|
|
121
|
-
|
122
|
-
|
123
|
-
entity
|
124
|
-
entity
|
403
|
+
describe "#delete" do
|
404
|
+
it "removes the entity" do
|
405
|
+
entity = build_valid_entity
|
406
|
+
removed_entity_id = entity.id
|
407
|
+
mapper.create(entity)
|
408
|
+
mapper.create(build_valid_entity)
|
409
|
+
mapper.delete(entity)
|
410
|
+
mapper.all.size.should == 1
|
411
|
+
mapper.first.id.should_not == removed_entity_id
|
412
|
+
end
|
413
|
+
|
414
|
+
it "marks the entity as no longer persisted" do
|
415
|
+
entity = build_valid_entity
|
416
|
+
mapper.create(entity)
|
417
|
+
entity.should be_persisted
|
418
|
+
mapper.delete(entity)
|
419
|
+
entity.should_not be_persisted
|
420
|
+
end
|
421
|
+
|
422
|
+
it "fails when the entity does not have an id" do
|
423
|
+
entity = entity_class.new
|
424
|
+
lambda { mapper.delete(entity) }.should raise_error(ActiveRecord::RecordNotFound)
|
125
425
|
end
|
426
|
+
|
427
|
+
it "fails when the entity can not be found" do
|
428
|
+
entity = entity_class.new
|
429
|
+
entity.id = -1
|
430
|
+
lambda { mapper.delete(entity) }.should raise_error(ActiveRecord::RecordNotFound)
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
describe "#delete_by_id" do
|
435
|
+
it "removes the entity" do
|
436
|
+
entity = build_valid_entity
|
437
|
+
mapper.create(entity)
|
438
|
+
mapper.create(build_valid_entity)
|
439
|
+
mapper.delete_by_id(entity.id)
|
440
|
+
mapper.all.size.should == 1
|
441
|
+
mapper.first.id.should_not == entity.id
|
442
|
+
end
|
443
|
+
|
444
|
+
it "fails when an entity can not be found" do
|
445
|
+
lambda { mapper.delete_by_id(-1) }.should raise_error(ActiveRecord::RecordNotFound)
|
446
|
+
end
|
447
|
+
end
|
448
|
+
|
449
|
+
describe "#delete_all" do
|
450
|
+
it "empties the mapper" do
|
451
|
+
mapper.create(build_valid_entity)
|
452
|
+
mapper.delete_all
|
453
|
+
mapper.all.should == []
|
454
|
+
end
|
455
|
+
end
|
456
|
+
|
457
|
+
private
|
458
|
+
|
459
|
+
def build_valid_entity
|
460
|
+
entity = entity_class.new
|
461
|
+
entity.attributes = { :name => 'test' }
|
462
|
+
entity
|
463
|
+
end
|
464
|
+
|
465
|
+
def build_entity(attributes)
|
466
|
+
entity = Project.new
|
467
|
+
entity.attributes = attributes
|
468
|
+
entity
|
126
469
|
end
|
127
470
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -2,7 +2,6 @@ require "active_record"
|
|
2
2
|
require "minimapper"
|
3
3
|
|
4
4
|
ROOT = File.expand_path(File.join(File.dirname(__FILE__), "..")) unless defined?(ROOT)
|
5
|
-
Dir[File.join(ROOT, "spec/support/shared_examples/*.rb")].each { |f| require f }
|
6
5
|
|
7
6
|
require File.join(ROOT, "spec/support/database_setup")
|
8
7
|
|
data/unit/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: minimapper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-10-
|
12
|
+
date: 2013-10-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
16
|
-
requirement: &
|
16
|
+
requirement: &70186737281960 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70186737281960
|
25
25
|
description: A minimalistic way of separating your models from ActiveRecord.
|
26
26
|
email:
|
27
27
|
- joakim.kolsjo@gmail.com
|
@@ -54,7 +54,6 @@ files:
|
|
54
54
|
- spec/mapper_spec.rb
|
55
55
|
- spec/spec_helper.rb
|
56
56
|
- spec/support/database_setup.rb
|
57
|
-
- spec/support/shared_examples/mapper.rb
|
58
57
|
- unit/entity/attributes_spec.rb
|
59
58
|
- unit/entity/convert_spec.rb
|
60
59
|
- unit/entity/core_spec.rb
|
@@ -77,7 +76,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
77
76
|
version: '0'
|
78
77
|
segments:
|
79
78
|
- 0
|
80
|
-
hash:
|
79
|
+
hash: -374043645528492869
|
81
80
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
81
|
none: false
|
83
82
|
requirements:
|
@@ -86,10 +85,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
86
85
|
version: '0'
|
87
86
|
segments:
|
88
87
|
- 0
|
89
|
-
hash:
|
88
|
+
hash: -374043645528492869
|
90
89
|
requirements: []
|
91
90
|
rubyforge_project:
|
92
|
-
rubygems_version: 1.8.
|
91
|
+
rubygems_version: 1.8.6
|
93
92
|
signing_key:
|
94
93
|
specification_version: 3
|
95
94
|
summary: A minimalistic way of separating your models from ActiveRecord.
|
@@ -97,4 +96,3 @@ test_files:
|
|
97
96
|
- spec/mapper_spec.rb
|
98
97
|
- spec/spec_helper.rb
|
99
98
|
- spec/support/database_setup.rb
|
100
|
-
- spec/support/shared_examples/mapper.rb
|
@@ -1,295 +0,0 @@
|
|
1
|
-
shared_examples :mapper do
|
2
|
-
# expects mapper and entity_class to be defined
|
3
|
-
|
4
|
-
it "can set and get repository" do
|
5
|
-
mapper.repository = :repository_instance
|
6
|
-
mapper.repository.should == :repository_instance
|
7
|
-
end
|
8
|
-
|
9
|
-
describe "#create" do
|
10
|
-
it "sets an id on the entity" do
|
11
|
-
entity1 = build_valid_entity
|
12
|
-
entity1.id.should be_nil
|
13
|
-
mapper.create(entity1)
|
14
|
-
entity1.id.should > 0
|
15
|
-
|
16
|
-
entity2 = build_valid_entity
|
17
|
-
mapper.create(entity2)
|
18
|
-
entity2.id.should == entity1.id + 1
|
19
|
-
end
|
20
|
-
|
21
|
-
it "marks the entity as persisted" do
|
22
|
-
entity1 = build_valid_entity
|
23
|
-
entity1.should_not be_persisted
|
24
|
-
mapper.create(entity1)
|
25
|
-
entity1.should be_persisted
|
26
|
-
end
|
27
|
-
|
28
|
-
it "returns the id" do
|
29
|
-
id = mapper.create(build_valid_entity)
|
30
|
-
id.should be_kind_of(Fixnum)
|
31
|
-
id.should > 0
|
32
|
-
end
|
33
|
-
|
34
|
-
it "does not store by reference" do
|
35
|
-
entity = build_valid_entity
|
36
|
-
mapper.create(entity)
|
37
|
-
mapper.last.object_id.should_not == entity.object_id
|
38
|
-
mapper.last.attributes[:name].should == "test"
|
39
|
-
end
|
40
|
-
|
41
|
-
it "validates the record before saving" do
|
42
|
-
entity = entity_class.new
|
43
|
-
def entity.valid?
|
44
|
-
false
|
45
|
-
end
|
46
|
-
mapper.create(entity).should be_false
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
describe "#find" do
|
51
|
-
it "returns an entity matching the id" do
|
52
|
-
entity = build_valid_entity
|
53
|
-
mapper.create(entity)
|
54
|
-
found_entity = mapper.find(entity.id)
|
55
|
-
found_entity.attributes[:name].should == "test"
|
56
|
-
found_entity.id.should == entity.id
|
57
|
-
found_entity.should be_kind_of(Minimapper::Entity::Core)
|
58
|
-
end
|
59
|
-
|
60
|
-
it "supports string ids" do
|
61
|
-
entity = build_valid_entity
|
62
|
-
mapper.create(entity)
|
63
|
-
mapper.find(entity.id.to_s)
|
64
|
-
end
|
65
|
-
|
66
|
-
it "does not return the same instance" do
|
67
|
-
entity = build_valid_entity
|
68
|
-
mapper.create(entity)
|
69
|
-
mapper.find(entity.id).object_id.should_not == entity.object_id
|
70
|
-
mapper.find(entity.id).object_id.should_not == mapper.find(entity.id).object_id
|
71
|
-
end
|
72
|
-
|
73
|
-
it "calls after_find on the mapper" do
|
74
|
-
entity = build_valid_entity
|
75
|
-
mapper.create(entity)
|
76
|
-
mapper.should_receive(:after_find)
|
77
|
-
found_entity = mapper.find(entity.id)
|
78
|
-
end
|
79
|
-
|
80
|
-
it "returns an entity marked as persisted" do
|
81
|
-
entity = build_valid_entity
|
82
|
-
mapper.create(entity)
|
83
|
-
found_entity = mapper.find(entity.id)
|
84
|
-
found_entity.should be_persisted
|
85
|
-
end
|
86
|
-
|
87
|
-
it "fails when an entity can not be found" do
|
88
|
-
lambda { mapper.find(-1) }.should raise_error(Minimapper::EntityNotFound)
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
describe "#find_by_id" do
|
93
|
-
it "returns an entity matching the id" do
|
94
|
-
entity = build_valid_entity
|
95
|
-
mapper.create(entity)
|
96
|
-
found_entity = mapper.find_by_id(entity.id)
|
97
|
-
found_entity.attributes[:name].should == "test"
|
98
|
-
found_entity.id.should == entity.id
|
99
|
-
found_entity.should be_kind_of(Minimapper::Entity::Core)
|
100
|
-
end
|
101
|
-
|
102
|
-
it "supports string ids" do
|
103
|
-
entity = build_valid_entity
|
104
|
-
mapper.create(entity)
|
105
|
-
mapper.find_by_id(entity.id.to_s)
|
106
|
-
end
|
107
|
-
|
108
|
-
it "does not return the same instance" do
|
109
|
-
entity = build_valid_entity
|
110
|
-
mapper.create(entity)
|
111
|
-
mapper.find_by_id(entity.id).object_id.should_not == entity.object_id
|
112
|
-
mapper.find_by_id(entity.id).object_id.should_not == mapper.find_by_id(entity.id).object_id
|
113
|
-
end
|
114
|
-
|
115
|
-
it "returns nil when an entity can not be found" do
|
116
|
-
mapper.find_by_id(-1).should be_nil
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
describe "#all" do
|
121
|
-
it "returns all entities in undefined order" do
|
122
|
-
first_created_entity = build_valid_entity
|
123
|
-
second_created_entity = build_valid_entity
|
124
|
-
mapper.create(first_created_entity)
|
125
|
-
mapper.create(second_created_entity)
|
126
|
-
all_entities = mapper.all
|
127
|
-
all_entities.map(&:id).should include(first_created_entity.id)
|
128
|
-
all_entities.map(&:id).should include(second_created_entity.id)
|
129
|
-
all_entities.first.should be_kind_of(Minimapper::Entity::Core)
|
130
|
-
end
|
131
|
-
|
132
|
-
it "does not return the same instances" do
|
133
|
-
entity = build_valid_entity
|
134
|
-
mapper.create(entity)
|
135
|
-
mapper.all.first.object_id.should_not == entity.object_id
|
136
|
-
mapper.all.first.object_id.should_not == mapper.all.first.object_id
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
describe "#first" do
|
141
|
-
it "returns the first entity" do
|
142
|
-
first_created_entity = build_valid_entity
|
143
|
-
mapper.create(first_created_entity)
|
144
|
-
mapper.create(build_valid_entity)
|
145
|
-
mapper.first.id.should == first_created_entity.id
|
146
|
-
mapper.first.should be_kind_of(entity_class)
|
147
|
-
end
|
148
|
-
|
149
|
-
it "does not return the same instance" do
|
150
|
-
entity = build_valid_entity
|
151
|
-
mapper.create(entity)
|
152
|
-
mapper.first.object_id.should_not == entity.object_id
|
153
|
-
mapper.first.object_id.should_not == mapper.first.object_id
|
154
|
-
end
|
155
|
-
|
156
|
-
it "returns nil when there is no entity" do
|
157
|
-
mapper.first.should be_nil
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
describe "#last" do
|
162
|
-
it "returns the last entity" do
|
163
|
-
last_created_entity = build_valid_entity
|
164
|
-
mapper.create(build_valid_entity)
|
165
|
-
mapper.create(last_created_entity)
|
166
|
-
mapper.last.id.should == last_created_entity.id
|
167
|
-
mapper.last.should be_kind_of(entity_class)
|
168
|
-
end
|
169
|
-
|
170
|
-
it "does not return the same instance" do
|
171
|
-
entity = build_valid_entity
|
172
|
-
mapper.create(entity)
|
173
|
-
mapper.last.object_id.should_not == entity.object_id
|
174
|
-
mapper.last.object_id.should_not == mapper.last.object_id
|
175
|
-
end
|
176
|
-
|
177
|
-
it "returns nil when there is no entity" do
|
178
|
-
mapper.last.should be_nil
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
describe "#count" do
|
183
|
-
it "returns the number of entities" do
|
184
|
-
mapper.create(build_valid_entity)
|
185
|
-
mapper.create(build_valid_entity)
|
186
|
-
mapper.count.should == 2
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
describe "#update" do
|
191
|
-
it "updates" do
|
192
|
-
entity = build_valid_entity
|
193
|
-
mapper.create(entity)
|
194
|
-
|
195
|
-
entity.attributes = { :name => "Updated" }
|
196
|
-
mapper.last.attributes[:name].should == "test"
|
197
|
-
|
198
|
-
mapper.update(entity)
|
199
|
-
mapper.last.id.should == entity.id
|
200
|
-
mapper.last.attributes[:name].should == "Updated"
|
201
|
-
end
|
202
|
-
|
203
|
-
it "does not update and returns false when the entity isn't valid" do
|
204
|
-
entity = build_valid_entity
|
205
|
-
mapper.create(entity)
|
206
|
-
|
207
|
-
def entity.valid?
|
208
|
-
false
|
209
|
-
end
|
210
|
-
|
211
|
-
mapper.update(entity).should be_false
|
212
|
-
mapper.last.attributes[:name].should == "test"
|
213
|
-
end
|
214
|
-
|
215
|
-
it "returns true" do
|
216
|
-
entity = build_valid_entity
|
217
|
-
mapper.create(entity)
|
218
|
-
mapper.update(entity).should == true
|
219
|
-
end
|
220
|
-
|
221
|
-
it "fails when the entity does not have an id" do
|
222
|
-
entity = build_valid_entity
|
223
|
-
lambda { mapper.update(entity) }.should raise_error(Minimapper::EntityNotFound)
|
224
|
-
end
|
225
|
-
|
226
|
-
it "fails when the entity no longer exists" do
|
227
|
-
entity = build_valid_entity
|
228
|
-
mapper.create(entity)
|
229
|
-
mapper.delete_all
|
230
|
-
lambda { mapper.update(entity) }.should raise_error(Minimapper::EntityNotFound)
|
231
|
-
end
|
232
|
-
end
|
233
|
-
|
234
|
-
describe "#delete" do
|
235
|
-
it "removes the entity" do
|
236
|
-
entity = build_valid_entity
|
237
|
-
removed_entity_id = entity.id
|
238
|
-
mapper.create(entity)
|
239
|
-
mapper.create(build_valid_entity)
|
240
|
-
mapper.delete(entity)
|
241
|
-
mapper.all.size.should == 1
|
242
|
-
mapper.first.id.should_not == removed_entity_id
|
243
|
-
end
|
244
|
-
|
245
|
-
it "marks the entity as no longer persisted" do
|
246
|
-
entity = build_valid_entity
|
247
|
-
mapper.create(entity)
|
248
|
-
entity.should be_persisted
|
249
|
-
mapper.delete(entity)
|
250
|
-
entity.should_not be_persisted
|
251
|
-
end
|
252
|
-
|
253
|
-
it "fails when the entity does not have an id" do
|
254
|
-
entity = entity_class.new
|
255
|
-
lambda { mapper.delete(entity) }.should raise_error(Minimapper::EntityNotFound)
|
256
|
-
end
|
257
|
-
|
258
|
-
it "fails when the entity can not be found" do
|
259
|
-
entity = entity_class.new
|
260
|
-
entity.id = -1
|
261
|
-
lambda { mapper.delete(entity) }.should raise_error(Minimapper::EntityNotFound)
|
262
|
-
end
|
263
|
-
end
|
264
|
-
|
265
|
-
describe "#delete_by_id" do
|
266
|
-
it "removes the entity" do
|
267
|
-
entity = build_valid_entity
|
268
|
-
mapper.create(entity)
|
269
|
-
mapper.create(build_valid_entity)
|
270
|
-
mapper.delete_by_id(entity.id)
|
271
|
-
mapper.all.size.should == 1
|
272
|
-
mapper.first.id.should_not == entity.id
|
273
|
-
end
|
274
|
-
|
275
|
-
it "fails when an entity can not be found" do
|
276
|
-
lambda { mapper.delete_by_id(-1) }.should raise_error(Minimapper::EntityNotFound)
|
277
|
-
end
|
278
|
-
end
|
279
|
-
|
280
|
-
describe "#delete_all" do
|
281
|
-
it "empties the mapper" do
|
282
|
-
mapper.create(build_valid_entity)
|
283
|
-
mapper.delete_all
|
284
|
-
mapper.all.should == []
|
285
|
-
end
|
286
|
-
end
|
287
|
-
|
288
|
-
private
|
289
|
-
|
290
|
-
def build_valid_entity
|
291
|
-
entity = entity_class.new
|
292
|
-
entity.attributes = { :name => 'test' }
|
293
|
-
entity
|
294
|
-
end
|
295
|
-
end
|