rom-mapper 0.5.1 → 1.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,57 +0,0 @@
1
- if RUBY_ENGINE == 'ruby' && ENV['COVERAGE'] == 'true'
2
- require 'yaml'
3
- rubies = YAML.load(File.read(File.join(__dir__, '..', '.travis.yml')))['rvm']
4
- latest_mri = rubies.select { |v| v =~ /\A\d+\.\d+.\d+\z/ }.max
5
-
6
- if RUBY_VERSION == latest_mri
7
- require 'simplecov'
8
- SimpleCov.start do
9
- add_filter '/spec/'
10
- end
11
- end
12
- end
13
-
14
- # this is needed for guard to work, not sure why :(
15
- require "bundler"
16
- Bundler.setup
17
-
18
- require 'rom-mapper'
19
-
20
- begin
21
- require 'byebug'
22
- rescue LoadError
23
- end
24
-
25
- root = Pathname(__FILE__).dirname
26
-
27
- Dir[root.join('support/*.rb').to_s].each do |f|
28
- require f
29
- end
30
- Dir[root.join('shared/*.rb').to_s].each do |f|
31
- require f
32
- end
33
-
34
- # Namespace holding all objects created during specs
35
- module Test
36
- def self.remove_constants
37
- constants.each(&method(:remove_const))
38
- end
39
- end
40
-
41
- def T(*args)
42
- ROM::Processor::Transproc::Functions[*args]
43
- end
44
-
45
- RSpec.configure do |config|
46
- config.after do
47
- Test.remove_constants
48
- end
49
-
50
- config.around do |example|
51
- ConstantLeakFinder.find(example)
52
- end
53
-
54
- config.disable_monkey_patching!
55
-
56
- config.warnings = true
57
- end
@@ -1,14 +0,0 @@
1
- # Finds leaking constants created during ROM specs
2
- module ConstantLeakFinder
3
- def self.find(example)
4
- constants = Object.constants
5
-
6
- example.run
7
-
8
- added_constants = (Object.constants - constants)
9
- added = added_constants.map(&Object.method(:const_get))
10
- if added.any? { |mod| mod.ancestors.map(&:name).grep(/\AROM/).any? }
11
- raise "Leaking constants: #{added_constants.inspect}"
12
- end
13
- end
14
- end
@@ -1,10 +0,0 @@
1
- module Mutant
2
- class Selector
3
- # Expression based test selector
4
- class Expression < self
5
- def call(_subject)
6
- integration.all_tests
7
- end
8
- end # Expression
9
- end # Selector
10
- end # Mutant
@@ -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