rom 0.4.2 → 0.5.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/.rubocop.yml +81 -0
- data/.travis.yml +2 -1
- data/CHANGELOG.md +41 -0
- data/Gemfile +12 -8
- data/Guardfile +17 -11
- data/README.md +7 -7
- data/Rakefile +29 -0
- data/lib/rom.rb +9 -66
- data/lib/rom/adapter.rb +45 -12
- data/lib/rom/adapter/memory.rb +0 -4
- data/lib/rom/adapter/memory/commands.rb +0 -10
- data/lib/rom/adapter/memory/dataset.rb +18 -6
- data/lib/rom/adapter/memory/storage.rb +0 -3
- data/lib/rom/command_registry.rb +24 -43
- data/lib/rom/commands.rb +5 -6
- data/lib/rom/commands/create.rb +5 -5
- data/lib/rom/commands/delete.rb +8 -6
- data/lib/rom/commands/result.rb +82 -0
- data/lib/rom/commands/update.rb +5 -4
- data/lib/rom/commands/with_options.rb +1 -4
- data/lib/rom/config.rb +70 -0
- data/lib/rom/env.rb +11 -3
- data/lib/rom/global.rb +107 -0
- data/lib/rom/header.rb +122 -89
- data/lib/rom/header/attribute.rb +148 -0
- data/lib/rom/mapper.rb +46 -67
- data/lib/rom/mapper_builder.rb +20 -73
- data/lib/rom/mapper_builder/mapper_dsl.rb +114 -0
- data/lib/rom/mapper_builder/model_dsl.rb +29 -0
- data/lib/rom/mapper_registry.rb +21 -0
- data/lib/rom/model_builder.rb +11 -17
- data/lib/rom/processor.rb +28 -0
- data/lib/rom/processor/transproc.rb +105 -0
- data/lib/rom/reader.rb +81 -21
- data/lib/rom/reader_builder.rb +14 -4
- data/lib/rom/relation.rb +19 -5
- data/lib/rom/relation_builder.rb +20 -6
- data/lib/rom/repository.rb +0 -2
- data/lib/rom/setup.rb +156 -0
- data/lib/rom/{boot → setup}/base_relation_dsl.rb +4 -8
- data/lib/rom/setup/command_dsl.rb +46 -0
- data/lib/rom/setup/finalize.rb +125 -0
- data/lib/rom/setup/mapper_dsl.rb +19 -0
- data/lib/rom/{boot → setup}/relation_dsl.rb +1 -4
- data/lib/rom/setup/schema_dsl.rb +33 -0
- data/lib/rom/support/registry.rb +10 -6
- data/lib/rom/version.rb +1 -1
- data/rom.gemspec +3 -1
- data/spec/integration/adapters/extending_relations_spec.rb +0 -2
- data/spec/integration/commands/create_spec.rb +2 -9
- data/spec/integration/commands/delete_spec.rb +4 -5
- data/spec/integration/commands/error_handling_spec.rb +4 -3
- data/spec/integration/commands/update_spec.rb +3 -8
- data/spec/integration/mappers/deep_embedded_spec.rb +52 -0
- data/spec/integration/mappers/definition_dsl_spec.rb +0 -118
- data/spec/integration/mappers/embedded_spec.rb +82 -0
- data/spec/integration/mappers/group_spec.rb +170 -0
- data/spec/integration/mappers/prefixing_attributes_spec.rb +2 -2
- data/spec/integration/mappers/renaming_attributes_spec.rb +8 -6
- data/spec/integration/mappers/symbolizing_attributes_spec.rb +80 -0
- data/spec/integration/mappers/wrap_spec.rb +162 -0
- data/spec/integration/multi_repo_spec.rb +64 -0
- data/spec/integration/relations/reading_spec.rb +12 -8
- data/spec/integration/relations/registry_dsl_spec.rb +1 -3
- data/spec/integration/schema_spec.rb +10 -0
- data/spec/integration/setup_spec.rb +57 -6
- data/spec/spec_helper.rb +2 -1
- data/spec/unit/config_spec.rb +60 -0
- data/spec/unit/rom/adapter/memory/dataset_spec.rb +52 -0
- data/spec/unit/rom/adapter_spec.rb +31 -11
- data/spec/unit/rom/header_spec.rb +60 -16
- data/spec/unit/rom/mapper_builder_spec.rb +311 -0
- data/spec/unit/rom/mapper_registry_spec.rb +25 -0
- data/spec/unit/rom/mapper_spec.rb +4 -5
- data/spec/unit/rom/model_builder_spec.rb +15 -13
- data/spec/unit/rom/processor/transproc_spec.rb +331 -0
- data/spec/unit/rom/reader_spec.rb +73 -0
- data/spec/unit/rom/registry_spec.rb +38 -0
- data/spec/unit/rom/relation_spec.rb +0 -1
- data/spec/unit/rom/setup_spec.rb +55 -0
- data/spec/unit/rom_spec.rb +14 -0
- metadata +62 -22
- data/Gemfile.devtools +0 -71
- data/lib/rom/boot.rb +0 -197
- data/lib/rom/boot/command_dsl.rb +0 -48
- data/lib/rom/boot/dsl.rb +0 -37
- data/lib/rom/boot/mapper_dsl.rb +0 -23
- data/lib/rom/boot/schema_dsl.rb +0 -27
- data/lib/rom/ra.rb +0 -172
- data/lib/rom/ra/operation/group.rb +0 -47
- data/lib/rom/ra/operation/join.rb +0 -39
- data/lib/rom/ra/operation/wrap.rb +0 -45
- data/lib/rom/transformer.rb +0 -77
- data/spec/integration/ra/group_spec.rb +0 -46
- data/spec/integration/ra/join_spec.rb +0 -50
- data/spec/integration/ra/wrap_spec.rb +0 -37
- data/spec/unit/rom/ra/operation/group_spec.rb +0 -55
- data/spec/unit/rom/ra/operation/wrap_spec.rb +0 -29
- data/spec/unit/rom/transformer_spec.rb +0 -41
@@ -4,55 +4,99 @@ describe ROM::Header do
|
|
4
4
|
describe '.coerce' do
|
5
5
|
subject(:header) { ROM::Header.coerce(input) }
|
6
6
|
|
7
|
-
|
8
7
|
context 'with a primitive type' do
|
9
|
-
let(:input) { [[:name, type:
|
8
|
+
let(:input) { [[:name, type: :string]] }
|
10
9
|
|
11
|
-
let(:expected)
|
10
|
+
let(:expected) do
|
11
|
+
ROM::Header.new(name: ROM::Header::Attribute.coerce(input.first))
|
12
|
+
end
|
12
13
|
|
13
14
|
it 'returns a header with coerced attributes' do
|
14
15
|
expect(header).to eql(expected)
|
15
16
|
|
16
|
-
expect(header[:name].type).to be(
|
17
|
+
expect(header[:name].type).to be(:string)
|
17
18
|
end
|
18
19
|
end
|
19
20
|
|
20
21
|
context 'with a collection type' do
|
21
|
-
let(:input) { [[:tasks, header: [[:title]], type:
|
22
|
+
let(:input) { [[:tasks, header: [[:title]], type: :array, model: model]] }
|
22
23
|
let(:model) { Class.new }
|
23
24
|
|
24
|
-
let(:expected)
|
25
|
+
let(:expected) do
|
26
|
+
ROM::Header.new(tasks: ROM::Header::Attribute.coerce(input.first))
|
27
|
+
end
|
25
28
|
|
26
29
|
it 'returns a header with coerced attributes' do
|
27
30
|
expect(header).to eql(expected)
|
28
31
|
|
29
32
|
tasks = header[:tasks]
|
30
33
|
|
31
|
-
expect(tasks.type).to be(
|
32
|
-
expect(tasks.model).to be(model)
|
33
|
-
expect(tasks.header).to eql(ROM::Header.coerce([[:title]]))
|
34
|
+
expect(tasks.type).to be(:array)
|
35
|
+
expect(tasks.header.model).to be(model)
|
36
|
+
expect(tasks.header).to eql(ROM::Header.coerce([[:title]], model))
|
34
37
|
|
35
|
-
expect(input.first[1])
|
38
|
+
expect(input.first[1])
|
39
|
+
.to eql(header: [[:title]], type: :array, model: model)
|
36
40
|
end
|
37
41
|
end
|
38
42
|
|
39
43
|
context 'with a hash type' do
|
40
|
-
let(:input) { [[:task, header: [[:title]], type:
|
44
|
+
let(:input) { [[:task, header: [[:title]], type: :hash, model: model]] }
|
41
45
|
let(:model) { Class.new }
|
42
46
|
|
43
|
-
let(:expected)
|
47
|
+
let(:expected) do
|
48
|
+
ROM::Header.new(task: ROM::Header::Attribute.coerce(input.first))
|
49
|
+
end
|
44
50
|
|
45
51
|
it 'returns a header with coerced attributes' do
|
46
52
|
expect(header).to eql(expected)
|
47
53
|
|
48
54
|
tasks = header[:task]
|
49
55
|
|
50
|
-
expect(tasks.type).to be(
|
51
|
-
expect(tasks.model).to be(model)
|
52
|
-
expect(tasks.header).to eql(ROM::Header.coerce([[:title]]))
|
56
|
+
expect(tasks.type).to be(:hash)
|
57
|
+
expect(tasks.header.model).to be(model)
|
58
|
+
expect(tasks.header).to eql(ROM::Header.coerce([[:title]], model))
|
53
59
|
|
54
|
-
expect(input.first[1])
|
60
|
+
expect(input.first[1])
|
61
|
+
.to eql(header: [[:title]], type: :hash, model: model)
|
55
62
|
end
|
56
63
|
end
|
57
64
|
end
|
65
|
+
|
66
|
+
describe '#mapping' do
|
67
|
+
it 'return mapping hash for primitive attributes' do
|
68
|
+
header = ROM::Header.coerce([[:title], [:name, from: :user_name]])
|
69
|
+
|
70
|
+
expect(header.mapping).to eql(title: :title, user_name: :name)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'returns an empty hash when there are no primitive attributes' do
|
74
|
+
header = ROM::Header.coerce([
|
75
|
+
[:city, type: :hash, wrap: true, header: [[:name]]]
|
76
|
+
])
|
77
|
+
|
78
|
+
expect(header.mapping).to eql({})
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe '#tuple_keys' do
|
83
|
+
it 'return primitive attribute keys' do
|
84
|
+
header = ROM::Header.coerce([[:title], [:name, from: :user_name]])
|
85
|
+
expect(header.tuple_keys).to eql([:title, :user_name])
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'return primitive attribute, wrap and group keys' do
|
89
|
+
header = ROM::Header.coerce([
|
90
|
+
[:title],
|
91
|
+
[:comments, type: :array, header: [[:author], [:text]]],
|
92
|
+
[:location, type: :hash, header: [[:lat], [:lng]]],
|
93
|
+
[:city, type: :hash, wrap: true, header: [[:name, from: :city_name]]],
|
94
|
+
[:tags, type: :array, group: true, header: [[:name, from: :tag_name]]]
|
95
|
+
])
|
96
|
+
|
97
|
+
expect(header.tuple_keys).to match_array([
|
98
|
+
:title, :comments, :location, :city_name, :tag_name
|
99
|
+
])
|
100
|
+
end
|
101
|
+
end
|
58
102
|
end
|
@@ -0,0 +1,311 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ROM::MapperBuilder do
|
4
|
+
subject(:builder) { ROM::MapperBuilder.new(:users, relation, options) }
|
5
|
+
|
6
|
+
let(:options) { {} }
|
7
|
+
let(:relation) { double('relation', header: []) }
|
8
|
+
let(:header) { mapper.header }
|
9
|
+
let(:mapper) { builder.call }
|
10
|
+
|
11
|
+
let(:expected_header) { ROM::Header.coerce(attributes) }
|
12
|
+
|
13
|
+
describe '#attribute' do
|
14
|
+
context 'simple attribute' do
|
15
|
+
let(:attributes) { [[:name]] }
|
16
|
+
|
17
|
+
it 'adds an attribute for the header' do
|
18
|
+
builder.attribute :name
|
19
|
+
|
20
|
+
expect(header).to eql(expected_header)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'aliased attribute' do
|
25
|
+
let(:attributes) { [[:name, from: :user_name]] }
|
26
|
+
|
27
|
+
it 'adds an aliased attribute for the header' do
|
28
|
+
builder.attribute :name, from: :user_name
|
29
|
+
|
30
|
+
expect(header).to eql(expected_header)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'prefixed attribute' do
|
35
|
+
let(:attributes) { [[:name, from: :user_name]] }
|
36
|
+
let(:options) { { prefix: :user } }
|
37
|
+
|
38
|
+
it 'adds an aliased attribute for the header using configured :prefix' do
|
39
|
+
builder.attribute :name
|
40
|
+
|
41
|
+
expect(header).to eql(expected_header)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'symbolized attribute' do
|
46
|
+
let(:attributes) { [[:name, from: 'name']] }
|
47
|
+
let(:options) { { symbolize_keys: true } }
|
48
|
+
|
49
|
+
it 'adds an attribute with symbolized alias' do
|
50
|
+
builder.attribute :name
|
51
|
+
|
52
|
+
expect(header).to eql(expected_header)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe 'overriding inherited attributes from the relation header' do
|
58
|
+
context 'when name matches' do
|
59
|
+
let(:attributes) { [[:name, type: :string]] }
|
60
|
+
|
61
|
+
it 'excludes the inherited attribute' do
|
62
|
+
allow(relation).to receive(:header).and_return([:name])
|
63
|
+
|
64
|
+
builder.attribute :name, type: :string
|
65
|
+
|
66
|
+
expect(header).to eql(expected_header)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'when alias matches' do
|
71
|
+
let(:attributes) { [[:name, from: 'name', type: :string]] }
|
72
|
+
|
73
|
+
it 'excludes the inherited attribute' do
|
74
|
+
allow(relation).to receive(:header).and_return(['name'])
|
75
|
+
|
76
|
+
builder.attribute :name, from: 'name', type: :string
|
77
|
+
|
78
|
+
expect(header).to eql(expected_header)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context 'when name in a wrapped attribute matches' do
|
83
|
+
let(:attributes) do
|
84
|
+
[
|
85
|
+
[:city, type: :hash, wrap: true, header: [[:name, from: :city_name]]]
|
86
|
+
]
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'excludes the inherited attribute' do
|
90
|
+
allow(relation).to receive(:header).and_return([:city_name])
|
91
|
+
|
92
|
+
builder.wrap :city do
|
93
|
+
attribute :name, from: :city_name
|
94
|
+
end
|
95
|
+
|
96
|
+
expect(header).to eql(expected_header)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context 'when name in a grouped attribute matches' do
|
101
|
+
let(:attributes) do
|
102
|
+
[
|
103
|
+
[:tags, type: :array, group: true, header: [[:name, from: :tag_name]]]
|
104
|
+
]
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'excludes the inherited attribute' do
|
108
|
+
allow(relation).to receive(:header).and_return([:tag_name])
|
109
|
+
|
110
|
+
builder.group :tags do
|
111
|
+
attribute :name, from: :tag_name
|
112
|
+
end
|
113
|
+
|
114
|
+
expect(header).to eql(expected_header)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
context 'when name in a hash attribute matches' do
|
119
|
+
let(:attributes) do
|
120
|
+
[
|
121
|
+
[:city, type: :hash, header: [[:name, from: :city_name]]]
|
122
|
+
]
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'excludes the inherited attribute' do
|
126
|
+
allow(relation).to receive(:header).and_return([:city])
|
127
|
+
|
128
|
+
builder.embedded :city, type: :hash do
|
129
|
+
attribute :name, from: :city_name
|
130
|
+
end
|
131
|
+
|
132
|
+
expect(header).to eql(expected_header)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
context 'when name of an array attribute matches' do
|
137
|
+
let(:attributes) do
|
138
|
+
[
|
139
|
+
[:tags, type: :array, header: [[:name, from: :tag_name]]]
|
140
|
+
]
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'excludes the inherited attribute' do
|
144
|
+
allow(relation).to receive(:header).and_return([:tags])
|
145
|
+
|
146
|
+
builder.embedded :tags, type: :array do
|
147
|
+
attribute :name, from: :tag_name
|
148
|
+
end
|
149
|
+
|
150
|
+
expect(header).to eql(expected_header)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
describe '#exclude' do
|
156
|
+
let(:attributes) { [[:name, from: 'name']] }
|
157
|
+
|
158
|
+
it 'removes an attribute from the inherited header' do
|
159
|
+
allow(relation).to receive(:header).and_return(['name'])
|
160
|
+
builder.attribute :name, from: 'name'
|
161
|
+
expect(header).to eql(expected_header)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
describe '#embedded' do
|
166
|
+
context 'when :type is set to :hash' do
|
167
|
+
let(:attributes) { [[:city, type: :hash, header: [[:name]]]] }
|
168
|
+
|
169
|
+
it 'adds an embedded hash attribute' do
|
170
|
+
builder.embedded :city, type: :hash do
|
171
|
+
attribute :name
|
172
|
+
end
|
173
|
+
|
174
|
+
expect(header).to eql(expected_header)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
context 'when :type is set to :array' do
|
179
|
+
let(:attributes) { [[:tags, type: :array, header: [[:name]]]] }
|
180
|
+
|
181
|
+
it 'adds an embedded array attribute' do
|
182
|
+
builder.embedded :tags, type: :array do
|
183
|
+
attribute :name
|
184
|
+
end
|
185
|
+
|
186
|
+
expect(header).to eql(expected_header)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
describe '#wrap' do
|
192
|
+
let(:attributes) { [[:city, type: :hash, wrap: true, header: [[:name]]]] }
|
193
|
+
|
194
|
+
it 'adds an wrapped hash attribute using a block to define attributes' do
|
195
|
+
builder.wrap :city do
|
196
|
+
attribute :name
|
197
|
+
end
|
198
|
+
|
199
|
+
expect(header).to eql(expected_header)
|
200
|
+
end
|
201
|
+
|
202
|
+
it 'adds an wrapped hash attribute using a options define attributes' do
|
203
|
+
builder.wrap city: [:name]
|
204
|
+
|
205
|
+
expect(header).to eql(expected_header)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
describe '#group' do
|
210
|
+
let(:attributes) { [[:tags, type: :array, group: true, header: [[:name]]]] }
|
211
|
+
|
212
|
+
it 'adds a group attribute using a block to define attributes' do
|
213
|
+
builder.group :tags do
|
214
|
+
attribute :name
|
215
|
+
end
|
216
|
+
|
217
|
+
expect(header).to eql(expected_header)
|
218
|
+
end
|
219
|
+
|
220
|
+
it 'adds a group attribute using a options define attributes' do
|
221
|
+
builder.group tags: [:name]
|
222
|
+
|
223
|
+
expect(header).to eql(expected_header)
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
describe 'top-level :prefix option' do
|
228
|
+
let(:options) do
|
229
|
+
{ prefix: :user }
|
230
|
+
end
|
231
|
+
|
232
|
+
context 'when no attribute overrides top-level setting' do
|
233
|
+
let(:attributes) do
|
234
|
+
[
|
235
|
+
[:name, from: :user_name],
|
236
|
+
[:address, from: :user_address, type: :hash, header: [
|
237
|
+
[:city, from: :user_city]]
|
238
|
+
],
|
239
|
+
[:contact, type: :hash, wrap: true, header: [
|
240
|
+
[:mobile, from: :user_mobile]]
|
241
|
+
],
|
242
|
+
[:tasks, type: :array, group: true, header: [
|
243
|
+
[:title, from: :user_title]]
|
244
|
+
]
|
245
|
+
]
|
246
|
+
end
|
247
|
+
|
248
|
+
it 'sets aliased attributes using prefix automatically' do
|
249
|
+
builder.attribute :name
|
250
|
+
|
251
|
+
builder.embedded :address, type: :hash do
|
252
|
+
attribute :city
|
253
|
+
end
|
254
|
+
|
255
|
+
builder.wrap :contact do
|
256
|
+
attribute :mobile
|
257
|
+
end
|
258
|
+
|
259
|
+
builder.group :tasks do
|
260
|
+
attribute :title
|
261
|
+
end
|
262
|
+
|
263
|
+
expect(header).to eql(expected_header)
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
context 'when an attribute overrides top-level setting' do
|
268
|
+
let(:attributes) do
|
269
|
+
[
|
270
|
+
[:name, from: :user_name],
|
271
|
+
[:birthday, from: :user_birthday, type: :hash, header: [
|
272
|
+
[:year, from: :bd_year],
|
273
|
+
[:month, from: :bd_month],
|
274
|
+
[:day, from: :bd_day]]
|
275
|
+
],
|
276
|
+
[:address, from: :user_address, type: :hash, header: [[:city]]],
|
277
|
+
[:contact, type: :hash, wrap: true, header: [
|
278
|
+
[:mobile, from: :contact_mobile]]
|
279
|
+
],
|
280
|
+
[:tasks, type: :array, group: true, header: [
|
281
|
+
[:title, from: :task_title]]
|
282
|
+
]
|
283
|
+
]
|
284
|
+
end
|
285
|
+
|
286
|
+
it 'excludes from aliasing the ones which override it' do
|
287
|
+
builder.attribute :name
|
288
|
+
|
289
|
+
builder.embedded :birthday, type: :hash, prefix: :bd do
|
290
|
+
attribute :year
|
291
|
+
attribute :month
|
292
|
+
attribute :day
|
293
|
+
end
|
294
|
+
|
295
|
+
builder.embedded :address, type: :hash, prefix: false do
|
296
|
+
attribute :city
|
297
|
+
end
|
298
|
+
|
299
|
+
builder.wrap :contact, prefix: :contact do
|
300
|
+
attribute :mobile
|
301
|
+
end
|
302
|
+
|
303
|
+
builder.group :tasks, prefix: :task do
|
304
|
+
attribute :title
|
305
|
+
end
|
306
|
+
|
307
|
+
expect(header).to eql(expected_header)
|
308
|
+
end
|
309
|
+
end
|
310
|
+
end
|
311
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ROM::MapperRegistry do
|
4
|
+
subject(:registry) { ROM::MapperRegistry.new }
|
5
|
+
|
6
|
+
let(:user_mapper) { double('user_mapper') }
|
7
|
+
let(:index_mapper) { double('index_mapper') }
|
8
|
+
|
9
|
+
before do
|
10
|
+
registry[:users] = user_mapper
|
11
|
+
registry[:index] = index_mapper
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#by_path' do
|
15
|
+
it 'returns first matching mapper' do
|
16
|
+
mapper = registry.by_path('users')
|
17
|
+
|
18
|
+
expect(mapper).to be(user_mapper)
|
19
|
+
|
20
|
+
mapper = registry.by_path('users.index')
|
21
|
+
|
22
|
+
expect(mapper).to be(index_mapper)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|