rom-mapper 0.5.1 → 1.0.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -0
- data/LICENSE +1 -1
- data/README.md +1 -9
- data/lib/rom/header/attribute.rb +2 -0
- data/lib/rom/mapper/builder.rb +37 -0
- data/lib/rom/mapper/configuration_plugin.rb +26 -0
- data/lib/rom/mapper/mapper_dsl.rb +43 -0
- data/lib/rom/mapper/version.rb +1 -1
- data/lib/rom/mapper.rb +2 -2
- data/lib/rom/mapper_compiler.rb +71 -0
- data/lib/rom/open_struct.rb +35 -0
- data/lib/rom/processor/transproc.rb +6 -2
- data/lib/rom/struct.rb +113 -0
- data/lib/rom/struct_compiler.rb +104 -0
- data/lib/rom/transformer.rb +32 -0
- data/lib/rom-mapper.rb +1 -1
- metadata +17 -28
- data/.gitignore +0 -19
- data/.rspec +0 -3
- data/.ruby-gemset +0 -1
- data/.travis.yml +0 -23
- data/Gemfile +0 -31
- data/Guardfile +0 -19
- data/Rakefile +0 -16
- data/rakelib/benchmark.rake +0 -15
- data/rakelib/mutant.rake +0 -16
- data/rakelib/rubocop.rake +0 -18
- data/rom-mapper.gemspec +0 -22
- data/spec/integration/mapper_spec.rb +0 -113
- data/spec/spec_helper.rb +0 -57
- data/spec/support/constant_leak_finder.rb +0 -14
- data/spec/support/mutant.rb +0 -10
- data/spec/unit/rom/mapper/dsl_spec.rb +0 -479
- data/spec/unit/rom/mapper/model_dsl_spec.rb +0 -19
- data/spec/unit/rom/mapper_spec.rb +0 -83
- data/spec/unit/rom/processor/transproc_spec.rb +0 -506
@@ -1,479 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
RSpec.describe ROM::Mapper do
|
4
|
-
subject(:mapper) do
|
5
|
-
klass = Class.new(parent)
|
6
|
-
options.each do |k, v|
|
7
|
-
klass.send(k, v)
|
8
|
-
end
|
9
|
-
klass
|
10
|
-
end
|
11
|
-
|
12
|
-
let(:parent) { Class.new(ROM::Mapper) }
|
13
|
-
|
14
|
-
let(:options) { {} }
|
15
|
-
let(:header) { mapper.header }
|
16
|
-
|
17
|
-
let(:expected_header) { ROM::Header.coerce(attributes) }
|
18
|
-
|
19
|
-
describe '#attribute' do
|
20
|
-
context 'simple attribute' do
|
21
|
-
let(:attributes) { [[:name]] }
|
22
|
-
|
23
|
-
it 'adds an attribute for the header' do
|
24
|
-
mapper.attribute :name
|
25
|
-
|
26
|
-
expect(header).to eql(expected_header)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
context 'aliased attribute' do
|
31
|
-
let(:attributes) { [[:name, from: :user_name]] }
|
32
|
-
|
33
|
-
it 'adds an aliased attribute for the header' do
|
34
|
-
mapper.attribute :name, from: :user_name
|
35
|
-
|
36
|
-
expect(header).to eql(expected_header)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
context 'prefixed attribute' do
|
41
|
-
let(:attributes) { [[:name, from: :user_name]] }
|
42
|
-
let(:options) { { prefix: :user } }
|
43
|
-
|
44
|
-
it 'adds an aliased attribute for the header using configured :prefix' do
|
45
|
-
mapper.attribute :name
|
46
|
-
|
47
|
-
expect(header).to eql(expected_header)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
context 'prefixed attribute using custom separator' do
|
52
|
-
let(:attributes) { [[:name, from: :'u.name']] }
|
53
|
-
let(:options) { { prefix: :u, prefix_separator: '.' } }
|
54
|
-
|
55
|
-
it 'adds an aliased attribute for the header using configured :prefix' do
|
56
|
-
mapper.attribute :name
|
57
|
-
|
58
|
-
expect(header).to eql(expected_header)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
context 'symbolized attribute' do
|
63
|
-
let(:attributes) { [[:name, from: 'name']] }
|
64
|
-
let(:options) { { symbolize_keys: true } }
|
65
|
-
|
66
|
-
it 'adds an attribute with symbolized alias' do
|
67
|
-
mapper.attribute :name
|
68
|
-
|
69
|
-
expect(header).to eql(expected_header)
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
describe 'copy_keys' do
|
75
|
-
let(:attributes) { [[:name, type: :string]] }
|
76
|
-
let(:options) { { copy_keys: true } }
|
77
|
-
|
78
|
-
it 'sets copy_keys for the header' do
|
79
|
-
mapper.copy_keys true
|
80
|
-
mapper.attribute :name, type: :string
|
81
|
-
|
82
|
-
expect(header).to eql(expected_header)
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
describe 'reject_keys' do
|
87
|
-
let(:attributes) { [[:name, type: :string]] }
|
88
|
-
let(:options) { { reject_keys: true } }
|
89
|
-
|
90
|
-
it 'sets reject_keys for the header' do
|
91
|
-
mapper.reject_keys true
|
92
|
-
mapper.attribute :name, type: :string
|
93
|
-
|
94
|
-
expect(header).to eql(expected_header)
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
describe 'overriding inherited attributes' do
|
99
|
-
context 'when name matches' do
|
100
|
-
let(:attributes) { [[:name, type: :string]] }
|
101
|
-
|
102
|
-
it 'excludes the inherited attribute' do
|
103
|
-
parent.attribute :name
|
104
|
-
|
105
|
-
mapper.attribute :name, type: :string
|
106
|
-
|
107
|
-
expect(header).to eql(expected_header)
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
context 'when alias matches' do
|
112
|
-
let(:attributes) { [[:name, from: 'name', type: :string]] }
|
113
|
-
|
114
|
-
it 'excludes the inherited attribute' do
|
115
|
-
parent.attribute 'name'
|
116
|
-
|
117
|
-
mapper.attribute :name, from: 'name', type: :string
|
118
|
-
|
119
|
-
expect(header).to eql(expected_header)
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
context 'when name in a wrapped attribute matches' do
|
124
|
-
let(:attributes) do
|
125
|
-
[
|
126
|
-
[:city, type: :hash, wrap: true, header: [[:name, from: :city_name]]]
|
127
|
-
]
|
128
|
-
end
|
129
|
-
|
130
|
-
it 'excludes the inherited attribute' do
|
131
|
-
parent.attribute :city_name
|
132
|
-
|
133
|
-
mapper.wrap :city do
|
134
|
-
attribute :name, from: :city_name
|
135
|
-
end
|
136
|
-
|
137
|
-
expect(header).to eql(expected_header)
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
context 'when name in a grouped attribute matches' do
|
142
|
-
let(:attributes) do
|
143
|
-
[
|
144
|
-
[:tags, type: :array, group: true, header: [[:name, from: :tag_name]]]
|
145
|
-
]
|
146
|
-
end
|
147
|
-
|
148
|
-
it 'excludes the inherited attribute' do
|
149
|
-
parent.attribute :tag_name
|
150
|
-
|
151
|
-
mapper.group :tags do
|
152
|
-
attribute :name, from: :tag_name
|
153
|
-
end
|
154
|
-
|
155
|
-
expect(header).to eql(expected_header)
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
context 'when name in a hash attribute matches' do
|
160
|
-
let(:attributes) do
|
161
|
-
[
|
162
|
-
[:city, type: :hash, header: [[:name, from: :city_name]]]
|
163
|
-
]
|
164
|
-
end
|
165
|
-
|
166
|
-
it 'excludes the inherited attribute' do
|
167
|
-
parent.attribute :city
|
168
|
-
|
169
|
-
mapper.embedded :city, type: :hash do
|
170
|
-
attribute :name, from: :city_name
|
171
|
-
end
|
172
|
-
|
173
|
-
expect(header).to eql(expected_header)
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
context 'when name of an array attribute matches' do
|
178
|
-
let(:attributes) do
|
179
|
-
[
|
180
|
-
[:tags, type: :array, header: [[:name, from: :tag_name]]]
|
181
|
-
]
|
182
|
-
end
|
183
|
-
|
184
|
-
it 'excludes the inherited attribute' do
|
185
|
-
parent.attribute :tags
|
186
|
-
|
187
|
-
mapper.embedded :tags, type: :array do
|
188
|
-
attribute :name, from: :tag_name
|
189
|
-
end
|
190
|
-
|
191
|
-
expect(header).to eql(expected_header)
|
192
|
-
end
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
|
-
describe '#exclude' do
|
197
|
-
let(:attributes) { [[:name, from: 'name']] }
|
198
|
-
|
199
|
-
it 'removes an attribute from the inherited header' do
|
200
|
-
mapper.attribute :name, from: 'name'
|
201
|
-
expect(header).to eql(expected_header)
|
202
|
-
end
|
203
|
-
end
|
204
|
-
|
205
|
-
describe '#embedded' do
|
206
|
-
context 'when :type is set to :hash' do
|
207
|
-
let(:attributes) { [[:city, type: :hash, header: [[:name]]]] }
|
208
|
-
|
209
|
-
it 'adds an embedded hash attribute' do
|
210
|
-
mapper.embedded :city, type: :hash do
|
211
|
-
attribute :name
|
212
|
-
end
|
213
|
-
|
214
|
-
expect(header).to eql(expected_header)
|
215
|
-
end
|
216
|
-
end
|
217
|
-
|
218
|
-
context 'when :type is set to :array' do
|
219
|
-
let(:attributes) { [[:tags, type: :array, header: [[:name]]]] }
|
220
|
-
|
221
|
-
it 'adds an embedded array attribute' do
|
222
|
-
mapper.embedded :tags, type: :array do
|
223
|
-
attribute :name
|
224
|
-
end
|
225
|
-
|
226
|
-
expect(header).to eql(expected_header)
|
227
|
-
end
|
228
|
-
end
|
229
|
-
end
|
230
|
-
|
231
|
-
describe '#wrap' do
|
232
|
-
let(:attributes) { [[:city, type: :hash, wrap: true, header: [[:name]]]] }
|
233
|
-
|
234
|
-
it 'adds an wrapped hash attribute using a block to define attributes' do
|
235
|
-
mapper.wrap :city do
|
236
|
-
attribute :name
|
237
|
-
end
|
238
|
-
|
239
|
-
expect(header).to eql(expected_header)
|
240
|
-
end
|
241
|
-
|
242
|
-
it 'adds an wrapped hash attribute using a options define attributes' do
|
243
|
-
mapper.wrap city: [:name]
|
244
|
-
|
245
|
-
expect(header).to eql(expected_header)
|
246
|
-
end
|
247
|
-
|
248
|
-
it 'raises an exception when using a block and options to define attributes' do
|
249
|
-
expect {
|
250
|
-
mapper.wrap(city: [:name]) { attribute :other_name }
|
251
|
-
}.to raise_error(ROM::MapperMisconfiguredError)
|
252
|
-
end
|
253
|
-
|
254
|
-
it 'raises an exception when using options and a mapper to define attributes' do
|
255
|
-
task_mapper = Class.new(ROM::Mapper) { attribute :title }
|
256
|
-
expect {
|
257
|
-
mapper.wrap city: [:name], mapper: task_mapper
|
258
|
-
}.to raise_error(ROM::MapperMisconfiguredError)
|
259
|
-
end
|
260
|
-
end
|
261
|
-
|
262
|
-
describe '#group' do
|
263
|
-
let(:attributes) { [[:tags, type: :array, group: true, header: [[:name]]]] }
|
264
|
-
|
265
|
-
it 'adds a group attribute using a block to define attributes' do
|
266
|
-
mapper.group :tags do
|
267
|
-
attribute :name
|
268
|
-
end
|
269
|
-
|
270
|
-
expect(header).to eql(expected_header)
|
271
|
-
end
|
272
|
-
|
273
|
-
it 'adds a group attribute using a options define attributes' do
|
274
|
-
mapper.group tags: [:name]
|
275
|
-
|
276
|
-
expect(header).to eql(expected_header)
|
277
|
-
end
|
278
|
-
|
279
|
-
it 'raises an exception when using a block and options to define attributes' do
|
280
|
-
expect {
|
281
|
-
mapper.group(cities: [:name]) { attribute :other_name }
|
282
|
-
}.to raise_error(ROM::MapperMisconfiguredError)
|
283
|
-
end
|
284
|
-
|
285
|
-
it 'raises an exception when using options and a mapper to define attributes' do
|
286
|
-
task_mapper = Class.new(ROM::Mapper) { attribute :title }
|
287
|
-
expect {
|
288
|
-
mapper.group cities: [:name], mapper: task_mapper
|
289
|
-
}.to raise_error(ROM::MapperMisconfiguredError)
|
290
|
-
end
|
291
|
-
end
|
292
|
-
|
293
|
-
describe 'top-level :prefix option' do
|
294
|
-
let(:options) do
|
295
|
-
{ prefix: :user }
|
296
|
-
end
|
297
|
-
|
298
|
-
context 'when no attribute overrides top-level setting' do
|
299
|
-
let(:attributes) do
|
300
|
-
[
|
301
|
-
[:name, from: :user_name],
|
302
|
-
[:address, from: :user_address, type: :hash, header: [
|
303
|
-
[:city, from: :user_city]]
|
304
|
-
],
|
305
|
-
[:contact, type: :hash, wrap: true, header: [
|
306
|
-
[:mobile, from: :user_mobile]]
|
307
|
-
],
|
308
|
-
[:tasks, type: :array, group: true, header: [
|
309
|
-
[:title, from: :user_title]]
|
310
|
-
]
|
311
|
-
]
|
312
|
-
end
|
313
|
-
|
314
|
-
it 'sets aliased attributes using prefix automatically' do
|
315
|
-
mapper.attribute :name
|
316
|
-
|
317
|
-
mapper.embedded :address, type: :hash do
|
318
|
-
attribute :city
|
319
|
-
end
|
320
|
-
|
321
|
-
mapper.wrap :contact do
|
322
|
-
attribute :mobile
|
323
|
-
end
|
324
|
-
|
325
|
-
mapper.group :tasks do
|
326
|
-
attribute :title
|
327
|
-
end
|
328
|
-
|
329
|
-
expect(header).to eql(expected_header)
|
330
|
-
end
|
331
|
-
end
|
332
|
-
|
333
|
-
context 'when an attribute overrides top-level setting' do
|
334
|
-
let(:attributes) do
|
335
|
-
[
|
336
|
-
[:name, from: :user_name],
|
337
|
-
[:birthday, from: :user_birthday, type: :hash, header: [
|
338
|
-
[:year, from: :bd_year],
|
339
|
-
[:month, from: :bd_month],
|
340
|
-
[:day, from: :bd_day]]
|
341
|
-
],
|
342
|
-
[:address, from: :user_address, type: :hash, header: [[:city]]],
|
343
|
-
[:contact, type: :hash, wrap: true, header: [
|
344
|
-
[:mobile, from: :contact_mobile]]
|
345
|
-
],
|
346
|
-
[:tasks, type: :array, group: true, header: [
|
347
|
-
[:title, from: :task_title]]
|
348
|
-
]
|
349
|
-
]
|
350
|
-
end
|
351
|
-
|
352
|
-
it 'excludes from aliasing the ones which override it' do
|
353
|
-
mapper.attribute :name
|
354
|
-
|
355
|
-
mapper.embedded :birthday, type: :hash, prefix: :bd do
|
356
|
-
attribute :year
|
357
|
-
attribute :month
|
358
|
-
attribute :day
|
359
|
-
end
|
360
|
-
|
361
|
-
mapper.embedded :address, type: :hash, prefix: false do
|
362
|
-
attribute :city
|
363
|
-
end
|
364
|
-
|
365
|
-
mapper.wrap :contact, prefix: :contact do
|
366
|
-
attribute :mobile
|
367
|
-
end
|
368
|
-
|
369
|
-
mapper.group :tasks, prefix: :task do
|
370
|
-
attribute :title
|
371
|
-
end
|
372
|
-
|
373
|
-
expect(header).to eql(expected_header)
|
374
|
-
end
|
375
|
-
end
|
376
|
-
end
|
377
|
-
|
378
|
-
context 'reusing mappers' do
|
379
|
-
describe '#group' do
|
380
|
-
let(:task_mapper) do
|
381
|
-
Class.new(ROM::Mapper) { attribute :title }
|
382
|
-
end
|
383
|
-
|
384
|
-
let(:attributes) do
|
385
|
-
[
|
386
|
-
[:name],
|
387
|
-
[:tasks, type: :array, group: true, header: task_mapper.header]
|
388
|
-
]
|
389
|
-
end
|
390
|
-
|
391
|
-
it 'uses other mapper header' do
|
392
|
-
mapper.attribute :name
|
393
|
-
mapper.group :tasks, mapper: task_mapper
|
394
|
-
|
395
|
-
expect(header).to eql(expected_header)
|
396
|
-
end
|
397
|
-
end
|
398
|
-
|
399
|
-
describe '#wrap' do
|
400
|
-
let(:task_mapper) do
|
401
|
-
Class.new(ROM::Mapper) { attribute :title }
|
402
|
-
end
|
403
|
-
|
404
|
-
let(:attributes) do
|
405
|
-
[
|
406
|
-
[:name],
|
407
|
-
[:task, type: :hash, wrap: true, header: task_mapper.header]
|
408
|
-
]
|
409
|
-
end
|
410
|
-
|
411
|
-
it 'uses other mapper header' do
|
412
|
-
mapper.attribute :name
|
413
|
-
mapper.wrap :task, mapper: task_mapper
|
414
|
-
|
415
|
-
expect(header).to eql(expected_header)
|
416
|
-
end
|
417
|
-
end
|
418
|
-
|
419
|
-
describe '#embedded' do
|
420
|
-
let(:task_mapper) do
|
421
|
-
Class.new(ROM::Mapper) { attribute :title }
|
422
|
-
end
|
423
|
-
|
424
|
-
let(:attributes) do
|
425
|
-
[
|
426
|
-
[:name],
|
427
|
-
[:task, type: :hash, header: task_mapper.header]
|
428
|
-
]
|
429
|
-
end
|
430
|
-
|
431
|
-
it 'uses other mapper header' do
|
432
|
-
mapper.attribute :name
|
433
|
-
mapper.embedded :task, mapper: task_mapper, type: :hash
|
434
|
-
|
435
|
-
expect(header).to eql(expected_header)
|
436
|
-
end
|
437
|
-
end
|
438
|
-
end
|
439
|
-
|
440
|
-
describe '#combine' do
|
441
|
-
let(:attributes) do
|
442
|
-
[
|
443
|
-
[:title],
|
444
|
-
[:tasks, combine: true, type: :array, header: [[:title]]]
|
445
|
-
]
|
446
|
-
end
|
447
|
-
|
448
|
-
it 'adds combine attributes' do
|
449
|
-
mapper.attribute :title
|
450
|
-
|
451
|
-
mapper.combine :tasks, on: { title: :title } do
|
452
|
-
attribute :title
|
453
|
-
end
|
454
|
-
|
455
|
-
expect(header).to eql(expected_header)
|
456
|
-
end
|
457
|
-
|
458
|
-
it 'works without a block' do
|
459
|
-
expected_header = ROM::Header.coerce(
|
460
|
-
[
|
461
|
-
[:title],
|
462
|
-
[:tasks, combine: true, type: :array, header: []]
|
463
|
-
]
|
464
|
-
)
|
465
|
-
|
466
|
-
mapper.attribute :title
|
467
|
-
|
468
|
-
mapper.combine :tasks, on: { title: :title }
|
469
|
-
|
470
|
-
expect(header).to eql(expected_header)
|
471
|
-
end
|
472
|
-
end
|
473
|
-
|
474
|
-
describe '#method_missing' do
|
475
|
-
it 'responds to DSL methods' do
|
476
|
-
expect(mapper).to respond_to(:attribute)
|
477
|
-
end
|
478
|
-
end
|
479
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
RSpec.describe ROM::Mapper::ModelDSL do
|
4
|
-
describe '#model' do
|
5
|
-
it 'calls the builder with non-excluded attributes only' do
|
6
|
-
definition_class = Class.new do
|
7
|
-
include ROM::Mapper::ModelDSL
|
8
|
-
|
9
|
-
def initialize
|
10
|
-
@attributes = [[:name], [:title, { exclude: true }]]
|
11
|
-
@builder = ->(attrs) { Struct.new(*attrs) }
|
12
|
-
end
|
13
|
-
end
|
14
|
-
model_instance = definition_class.new.model.new
|
15
|
-
expect(model_instance).to respond_to(:name)
|
16
|
-
expect(model_instance).to_not respond_to(:title)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
@@ -1,83 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
require 'ostruct'
|
4
|
-
|
5
|
-
RSpec.describe ROM::Mapper do
|
6
|
-
subject(:mapper) { mapper_class.build }
|
7
|
-
|
8
|
-
let(:mapper_class) do
|
9
|
-
user_model = self.user_model
|
10
|
-
|
11
|
-
Class.new(ROM::Mapper) do
|
12
|
-
attribute :id
|
13
|
-
attribute :name
|
14
|
-
model user_model
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
let(:relation) do
|
19
|
-
[{ id: 1, name: 'Jane' }, { id: 2, name: 'Joe' }]
|
20
|
-
end
|
21
|
-
|
22
|
-
let(:user_model) do
|
23
|
-
Class.new(OpenStruct) { include Equalizer.new(:id, :name) }
|
24
|
-
end
|
25
|
-
|
26
|
-
let(:jane) { user_model.new(id: 1, name: 'Jane') }
|
27
|
-
let(:joe) { user_model.new(id: 2, name: 'Joe') }
|
28
|
-
|
29
|
-
describe '.registry' do
|
30
|
-
it 'builds mapper class registry for base and virtual relations' do
|
31
|
-
users = Class.new(ROM::Mapper) { relation(:users) }
|
32
|
-
entity = Class.new(ROM::Mapper) do
|
33
|
-
relation(:users)
|
34
|
-
register_as(:entity)
|
35
|
-
end
|
36
|
-
active = Class.new(users) { relation(:active) }
|
37
|
-
admins = Class.new(users) { relation(:admins) }
|
38
|
-
custom = Class.new(users) { register_as(:custom) }
|
39
|
-
|
40
|
-
registry = ROM::Mapper.registry([users, entity, active, admins, custom])
|
41
|
-
|
42
|
-
expect(registry).to eql(
|
43
|
-
users: {
|
44
|
-
users: users.build,
|
45
|
-
entity: entity.build,
|
46
|
-
active: active.build,
|
47
|
-
admins: admins.build,
|
48
|
-
custom: custom.build
|
49
|
-
}
|
50
|
-
)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
describe '.relation' do
|
55
|
-
it 'inherits from parent' do
|
56
|
-
base = Class.new(ROM::Mapper) { relation(:users) }
|
57
|
-
virt = Class.new(base)
|
58
|
-
|
59
|
-
expect(virt.relation).to be(:users)
|
60
|
-
expect(virt.base_relation).to be(:users)
|
61
|
-
end
|
62
|
-
|
63
|
-
it 'allows overriding' do
|
64
|
-
base = Class.new(ROM::Mapper) { relation(:users) }
|
65
|
-
virt = Class.new(base) { relation(:active) }
|
66
|
-
|
67
|
-
expect(virt.relation).to be(:active)
|
68
|
-
expect(virt.base_relation).to be(:users)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
describe "#each" do
|
73
|
-
it "yields all mapped objects" do
|
74
|
-
result = []
|
75
|
-
|
76
|
-
mapper.call(relation).each do |tuple|
|
77
|
-
result << tuple
|
78
|
-
end
|
79
|
-
|
80
|
-
expect(result).to eql([jane, joe])
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|