rom 0.7.1 → 0.8.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/.gitignore +1 -0
- data/.rubocop.yml +5 -8
- data/CHANGELOG.md +28 -1
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +2 -2
- data/lib/rom.rb +1 -1
- data/lib/rom/command.rb +7 -5
- data/lib/rom/command_registry.rb +1 -1
- data/lib/rom/commands.rb +0 -2
- data/lib/rom/commands/abstract.rb +55 -25
- data/lib/rom/commands/composite.rb +13 -1
- data/lib/rom/commands/delete.rb +0 -8
- data/lib/rom/commands/graph.rb +102 -0
- data/lib/rom/commands/graph/class_interface.rb +69 -0
- data/lib/rom/commands/lazy.rb +87 -0
- data/lib/rom/constants.rb +22 -0
- data/lib/rom/env.rb +48 -18
- data/lib/rom/gateway.rb +132 -0
- data/lib/rom/global.rb +19 -19
- data/lib/rom/header.rb +42 -16
- data/lib/rom/header/attribute.rb +37 -15
- data/lib/rom/lint/gateway.rb +94 -0
- data/lib/rom/lint/spec.rb +15 -3
- data/lib/rom/lint/test.rb +45 -14
- data/lib/rom/mapper.rb +23 -10
- data/lib/rom/mapper/attribute_dsl.rb +157 -18
- data/lib/rom/memory.rb +1 -1
- data/lib/rom/memory/commands.rb +10 -8
- data/lib/rom/memory/dataset.rb +22 -2
- data/lib/rom/memory/{repository.rb → gateway.rb} +10 -10
- data/lib/rom/pipeline.rb +2 -1
- data/lib/rom/processor/transproc.rb +105 -14
- data/lib/rom/relation.rb +4 -4
- data/lib/rom/relation/class_interface.rb +19 -13
- data/lib/rom/relation/graph.rb +22 -0
- data/lib/rom/relation/lazy.rb +5 -3
- data/lib/rom/repository.rb +9 -118
- data/lib/rom/setup.rb +21 -14
- data/lib/rom/setup/finalize.rb +19 -19
- data/lib/rom/setup_dsl/relation.rb +10 -1
- data/lib/rom/support/deprecations.rb +21 -3
- data/lib/rom/support/enumerable_dataset.rb +1 -1
- data/lib/rom/version.rb +1 -1
- data/rom.gemspec +2 -4
- data/spec/integration/commands/delete_spec.rb +6 -0
- data/spec/integration/commands/graph_spec.rb +235 -0
- data/spec/integration/mappers/combine_spec.rb +14 -5
- data/spec/integration/mappers/definition_dsl_spec.rb +6 -1
- data/spec/integration/mappers/exclude_spec.rb +28 -0
- data/spec/integration/mappers/fold_spec.rb +16 -0
- data/spec/integration/mappers/group_spec.rb +0 -22
- data/spec/integration/mappers/prefix_separator_spec.rb +54 -0
- data/spec/integration/mappers/prefix_spec.rb +50 -0
- data/spec/integration/mappers/reusing_mappers_spec.rb +21 -0
- data/spec/integration/mappers/step_spec.rb +120 -0
- data/spec/integration/mappers/unfold_spec.rb +93 -0
- data/spec/integration/mappers/ungroup_spec.rb +127 -0
- data/spec/integration/mappers/unwrap_spec.rb +2 -2
- data/spec/integration/multi_repo_spec.rb +11 -11
- data/spec/integration/repositories/setting_logger_spec.rb +2 -2
- data/spec/integration/setup_spec.rb +11 -1
- data/spec/shared/command_behavior.rb +18 -0
- data/spec/shared/materializable.rb +4 -2
- data/spec/shared/users_and_tasks.rb +3 -3
- data/spec/test/memory_repository_lint_test.rb +4 -4
- data/spec/unit/rom/commands/graph_spec.rb +198 -0
- data/spec/unit/rom/commands/lazy_spec.rb +88 -0
- data/spec/unit/rom/commands_spec.rb +2 -2
- data/spec/unit/rom/env_spec.rb +26 -0
- data/spec/unit/rom/gateway_spec.rb +90 -0
- data/spec/unit/rom/global_spec.rb +4 -3
- data/spec/unit/rom/mapper/dsl_spec.rb +42 -1
- data/spec/unit/rom/mapper_spec.rb +4 -1
- data/spec/unit/rom/memory/commands/create_spec.rb +21 -0
- data/spec/unit/rom/memory/commands/delete_spec.rb +21 -0
- data/spec/unit/rom/memory/commands/update_spec.rb +21 -0
- data/spec/unit/rom/memory/relation_spec.rb +42 -10
- data/spec/unit/rom/memory/repository_spec.rb +3 -3
- data/spec/unit/rom/processor/transproc_spec.rb +75 -0
- data/spec/unit/rom/relation/lazy/combine_spec.rb +33 -4
- data/spec/unit/rom/relation/lazy_spec.rb +9 -1
- data/spec/unit/rom/repository_spec.rb +4 -63
- data/spec/unit/rom/setup_spec.rb +19 -5
- metadata +28 -38
- data/.ruby-version +0 -1
- data/lib/rom/lint/repository.rb +0 -94
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ROM::Commands::Lazy do
|
4
|
+
let(:rom) { setup.finalize }
|
5
|
+
let(:setup) { ROM.setup(:memory) }
|
6
|
+
|
7
|
+
let(:create_user) { rom.command(:users).create }
|
8
|
+
let(:update_user) { rom.command(:users).update }
|
9
|
+
let(:create_task) { rom.command(:tasks).create }
|
10
|
+
|
11
|
+
let(:user) { { user: { name: 'Jane' } } }
|
12
|
+
let(:evaluator) { -> input { input[:user] } }
|
13
|
+
|
14
|
+
before do
|
15
|
+
setup.relation(:tasks)
|
16
|
+
|
17
|
+
setup.relation(:users) do
|
18
|
+
def by_name(name)
|
19
|
+
restrict(name: name)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
setup.commands(:users) do
|
24
|
+
define(:create) do
|
25
|
+
result :one
|
26
|
+
end
|
27
|
+
|
28
|
+
define(:update)
|
29
|
+
end
|
30
|
+
|
31
|
+
setup.commands(:tasks) do
|
32
|
+
define(:create)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#call' do
|
37
|
+
subject(:command) { ROM::Commands::Lazy.new(create_user, evaluator) }
|
38
|
+
|
39
|
+
it 'evaluates the input and calls command' do
|
40
|
+
command.call(user)
|
41
|
+
|
42
|
+
expect(rom.relation(:users)).to match_array([
|
43
|
+
{ name: 'Jane' }
|
44
|
+
])
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '#>>' do
|
49
|
+
subject(:command) { ROM::Commands::Lazy.new(create_user, evaluator) }
|
50
|
+
|
51
|
+
it 'composes with another command' do
|
52
|
+
expect(command >> create_task).to be_instance_of(ROM::Commands::Composite)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '#combine' do
|
57
|
+
subject(:command) { ROM::Commands::Lazy.new(create_user, evaluator) }
|
58
|
+
|
59
|
+
it 'combines with another command' do
|
60
|
+
expect(command.combine(create_task)).to be_instance_of(ROM::Commands::Graph)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe '#method_missing' do
|
65
|
+
subject(:command) { ROM::Commands::Lazy.new(update_user, evaluator) }
|
66
|
+
|
67
|
+
it 'forwards to command' do
|
68
|
+
rom.relations[:users] << { name: 'Jane' } << { name: 'Joe' }
|
69
|
+
|
70
|
+
new_command = command.by_name('Jane')
|
71
|
+
new_command.call(user: { name: 'Jane Doe' })
|
72
|
+
|
73
|
+
expect(rom.relation(:users)).to match_array([
|
74
|
+
{ name: 'Jane Doe' },
|
75
|
+
{ name: 'Joe' }
|
76
|
+
])
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'return original response if it was not a command' do
|
80
|
+
response = command.result
|
81
|
+
expect(response).to be(:many)
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'raises error when message is unknown' do
|
85
|
+
expect { command.not_here }.to raise_error(NoMethodError, /not_here/)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -64,7 +64,7 @@ describe 'Commands' do
|
|
64
64
|
|
65
65
|
describe 'extending command with a db-specific behavior' do
|
66
66
|
before do
|
67
|
-
setup.
|
67
|
+
setup.gateways[:default].instance_exec do
|
68
68
|
def extend_command_class(klass, _)
|
69
69
|
klass.class_eval do
|
70
70
|
def super_command?
|
@@ -103,7 +103,7 @@ describe 'Commands' do
|
|
103
103
|
end
|
104
104
|
|
105
105
|
registry = ROM::Command.registry(
|
106
|
-
rom.relations, setup.
|
106
|
+
rom.relations, setup.gateways, commands.values
|
107
107
|
)
|
108
108
|
|
109
109
|
expect(registry).to eql(
|
data/spec/unit/rom/env_spec.rb
CHANGED
@@ -12,6 +12,14 @@ describe ROM::Env do
|
|
12
12
|
|
13
13
|
setup.relation(:tasks)
|
14
14
|
|
15
|
+
setup.commands(:users) do
|
16
|
+
define(:create)
|
17
|
+
end
|
18
|
+
|
19
|
+
setup.commands(:tasks) do
|
20
|
+
define(:create)
|
21
|
+
end
|
22
|
+
|
15
23
|
setup.mappers do
|
16
24
|
define(:users) do
|
17
25
|
attribute :name
|
@@ -25,6 +33,24 @@ describe ROM::Env do
|
|
25
33
|
end
|
26
34
|
end
|
27
35
|
|
36
|
+
describe '#command' do
|
37
|
+
it 'returns registered command registry' do
|
38
|
+
expect(rom.command(:users)).to be_instance_of(ROM::CommandRegistry)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'returns registered command' do
|
42
|
+
expect(rom.command(:users).create).to be_kind_of(ROM::Commands::Create)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'accepts an array with graph options and input' do
|
46
|
+
expect(rom.command([:users, [:create]])).to be_kind_of(ROM::Commands::Lazy)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'raises ArgumentError when unsupported arg was passed' do
|
50
|
+
expect { rom.command({ oops: 'sorry' }) }.to raise_error(ArgumentError)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
28
54
|
describe '#relation' do
|
29
55
|
it 'yields selected relation to the block and returns a loaded relation' do
|
30
56
|
result = rom.relation(:users) { |r| r.by_name('Jane') }.as(:name_list)
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ROM::Gateway do
|
4
|
+
describe '.setup' do
|
5
|
+
it 'sets up a gateway based on a type' do
|
6
|
+
gateway_class = Class.new(ROM::Gateway) do
|
7
|
+
attr_reader :args
|
8
|
+
|
9
|
+
def initialize(*args)
|
10
|
+
@args = args
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
allow(ROM::Gateway).to receive(:class_from_symbol)
|
15
|
+
.with(:wormhole).and_return(gateway_class)
|
16
|
+
|
17
|
+
args = %w(hello world)
|
18
|
+
gateway = ROM::Gateway.setup(:wormhole, *args)
|
19
|
+
|
20
|
+
expect(gateway).to be_instance_of(gateway_class)
|
21
|
+
expect(gateway.args).to eq(args)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'raises an exception if the type is not supported' do
|
25
|
+
expect {
|
26
|
+
ROM::Gateway.setup(:bogus, "memory://test")
|
27
|
+
}.to raise_error(ROM::AdapterLoadError, /bogus/)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'accepts a gateway instance' do
|
31
|
+
gateway = ROM::Gateway.new
|
32
|
+
expect(ROM::Gateway.setup(gateway)).to be(gateway)
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'raises an exception if instance and arguments are passed' do
|
36
|
+
gateway = ROM::Gateway.new
|
37
|
+
|
38
|
+
expect { ROM::Gateway.setup(gateway, 'foo://bar') }.to raise_error(
|
39
|
+
ArgumentError,
|
40
|
+
"Can't accept arguments when passing an instance"
|
41
|
+
)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'raises an exception if a URI string is passed' do
|
45
|
+
expect { ROM::Gateway.setup('memory://test') }.to raise_error(
|
46
|
+
ArgumentError,
|
47
|
+
/URIs without an explicit scheme are not supported anymore/
|
48
|
+
)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '.class_from_symbol' do
|
53
|
+
context 'when adapter is already present' do
|
54
|
+
before do
|
55
|
+
module Test
|
56
|
+
module Adapter
|
57
|
+
class Gateway
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
ROM.register_adapter(:test_adapter, Test::Adapter)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'does not try to require an adapter if it is already present' do
|
66
|
+
klass = ROM::Gateway.class_from_symbol(:test_adapter)
|
67
|
+
|
68
|
+
expect(klass).to be(Test::Adapter::Gateway)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'instantiates a gateway based on type' do
|
73
|
+
klass = ROM::Gateway.class_from_symbol(:memory)
|
74
|
+
expect(klass).to be(ROM::Memory::Gateway)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'raises an exception if the type is not supported' do
|
78
|
+
expect { ROM::Gateway.class_from_symbol(:bogus) }
|
79
|
+
.to raise_error(ROM::AdapterLoadError, /bogus/)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe '#disconnect' do
|
84
|
+
it 'does nothing' do
|
85
|
+
gateway_class = Class.new(ROM::Gateway)
|
86
|
+
gateway = gateway_class.new
|
87
|
+
expect(gateway.disconnect).to be(nil)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -2,13 +2,14 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe ROM do
|
4
4
|
describe '.setup' do
|
5
|
-
it 'allows passing in
|
6
|
-
klass = Class.new(ROM::
|
5
|
+
it 'allows passing in gateway instances' do
|
6
|
+
klass = Class.new(ROM::Gateway)
|
7
7
|
repo = klass.new
|
8
8
|
|
9
9
|
setup = ROM.setup(test: repo)
|
10
10
|
|
11
|
-
expect(setup.
|
11
|
+
expect(setup.gateways[:test]).to be(repo)
|
12
12
|
end
|
13
13
|
end
|
14
|
+
|
14
15
|
end
|
@@ -232,6 +232,19 @@ describe ROM::Mapper do
|
|
232
232
|
|
233
233
|
expect(header).to eql(expected_header)
|
234
234
|
end
|
235
|
+
|
236
|
+
it 'raises an exception when using a block and options to define attributes' do
|
237
|
+
expect {
|
238
|
+
mapper.wrap(city: [:name]) { attribute :other_name }
|
239
|
+
}.to raise_error(ROM::MapperMisconfiguredError)
|
240
|
+
end
|
241
|
+
|
242
|
+
it 'raises an exception when using options and a mapper to define attributes' do
|
243
|
+
task_mapper = Class.new(ROM::Mapper) { attribute :title }
|
244
|
+
expect {
|
245
|
+
mapper.wrap city: [:name], mapper: task_mapper
|
246
|
+
}.to raise_error(ROM::MapperMisconfiguredError)
|
247
|
+
end
|
235
248
|
end
|
236
249
|
|
237
250
|
describe '#group' do
|
@@ -250,6 +263,19 @@ describe ROM::Mapper do
|
|
250
263
|
|
251
264
|
expect(header).to eql(expected_header)
|
252
265
|
end
|
266
|
+
|
267
|
+
it 'raises an exception when using a block and options to define attributes' do
|
268
|
+
expect {
|
269
|
+
mapper.group(cities: [:name]) { attribute :other_name }
|
270
|
+
}.to raise_error(ROM::MapperMisconfiguredError)
|
271
|
+
end
|
272
|
+
|
273
|
+
it 'raises an exception when using options and a mapper to define attributes' do
|
274
|
+
task_mapper = Class.new(ROM::Mapper) { attribute :title }
|
275
|
+
expect {
|
276
|
+
mapper.group cities: [:name], mapper: task_mapper
|
277
|
+
}.to raise_error(ROM::MapperMisconfiguredError)
|
278
|
+
end
|
253
279
|
end
|
254
280
|
|
255
281
|
describe 'top-level :prefix option' do
|
@@ -386,7 +412,7 @@ describe ROM::Mapper do
|
|
386
412
|
let(:attributes) do
|
387
413
|
[
|
388
414
|
[:name],
|
389
|
-
[:task, type: :
|
415
|
+
[:task, type: :hash, header: task_mapper.header]
|
390
416
|
]
|
391
417
|
end
|
392
418
|
|
@@ -416,6 +442,21 @@ describe ROM::Mapper do
|
|
416
442
|
|
417
443
|
expect(header).to eql(expected_header)
|
418
444
|
end
|
445
|
+
|
446
|
+
it 'works without a block' do
|
447
|
+
expected_header = ROM::Header.coerce(
|
448
|
+
[
|
449
|
+
[:title],
|
450
|
+
[:tasks, combine: true, type: :array, header: []]
|
451
|
+
]
|
452
|
+
)
|
453
|
+
|
454
|
+
mapper.attribute :title
|
455
|
+
|
456
|
+
mapper.combine :tasks, on: { title: :title }
|
457
|
+
|
458
|
+
expect(header).to eql(expected_header)
|
459
|
+
end
|
419
460
|
end
|
420
461
|
|
421
462
|
describe '#method_missing' do
|
@@ -30,7 +30,10 @@ describe ROM::Mapper do
|
|
30
30
|
describe '.registry' do
|
31
31
|
it 'builds mapper class registry for base and virtual relations' do
|
32
32
|
users = Class.new(ROM::Mapper) { relation(:users) }
|
33
|
-
entity = Class.new(ROM::Mapper)
|
33
|
+
entity = Class.new(ROM::Mapper) do
|
34
|
+
relation(:users)
|
35
|
+
register_as(:entity)
|
36
|
+
end
|
34
37
|
active = Class.new(users) { relation(:active) }
|
35
38
|
admins = Class.new(users) { relation(:admins) }
|
36
39
|
custom = Class.new(users) { register_as(:custom) }
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'rom/memory'
|
4
|
+
|
5
|
+
describe ROM::Memory::Commands::Delete do
|
6
|
+
include_context 'users and tasks'
|
7
|
+
|
8
|
+
subject(:command) { ROM::Memory::Commands::Delete.build(users) }
|
9
|
+
|
10
|
+
let(:users) { rom.relations[:users] }
|
11
|
+
|
12
|
+
before do
|
13
|
+
setup.relation(:users) do
|
14
|
+
def by_id(id)
|
15
|
+
restrict(id: id)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it_behaves_like 'a command'
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'rom/memory'
|
4
|
+
|
5
|
+
describe ROM::Memory::Commands::Create do
|
6
|
+
include_context 'users and tasks'
|
7
|
+
|
8
|
+
subject(:command) { ROM::Memory::Commands::Create.build(users) }
|
9
|
+
|
10
|
+
let(:users) { rom.relations[:users] }
|
11
|
+
|
12
|
+
before do
|
13
|
+
setup.relation(:users) do
|
14
|
+
def by_id(id)
|
15
|
+
restrict(id: id)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it_behaves_like 'a command'
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'rom/memory'
|
4
|
+
|
5
|
+
describe ROM::Memory::Commands::Update do
|
6
|
+
include_context 'users and tasks'
|
7
|
+
|
8
|
+
subject(:command) { ROM::Memory::Commands::Update.build(users) }
|
9
|
+
|
10
|
+
let(:users) { rom.relations[:users] }
|
11
|
+
|
12
|
+
before do
|
13
|
+
setup.relation(:users) do
|
14
|
+
def by_id(id)
|
15
|
+
restrict(id: id)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it_behaves_like 'a command'
|
21
|
+
end
|
@@ -11,7 +11,11 @@ describe ROM::Memory::Relation do
|
|
11
11
|
ROM::Memory::Dataset.new([
|
12
12
|
{ name: 'Jane', email: 'jane@doe.org', age: 10 },
|
13
13
|
{ name: 'Jade', email: 'jade@doe.org', age: 11 },
|
14
|
-
{ name: 'Joe',
|
14
|
+
{ name: 'Joe', email: 'joe@doe.org', age: 12 },
|
15
|
+
{ name: 'Jack', age: 11 },
|
16
|
+
{ name: 'Jill', email: 'jill@doe.org' },
|
17
|
+
{ name: 'John' },
|
18
|
+
{ name: 'Judy', email: 'judy@doe.org', age: 11 }
|
15
19
|
])
|
16
20
|
end
|
17
21
|
|
@@ -29,7 +33,11 @@ describe ROM::Memory::Relation do
|
|
29
33
|
expect(relation.project(:name, :age)).to match_array([
|
30
34
|
{ name: 'Jane', age: 10 },
|
31
35
|
{ name: 'Jade', age: 11 },
|
32
|
-
{ name: 'Joe',
|
36
|
+
{ name: 'Joe', age: 12 },
|
37
|
+
{ name: 'Jack', age: 11 },
|
38
|
+
{ name: 'Jill' },
|
39
|
+
{ name: 'John' },
|
40
|
+
{ name: 'Judy', age: 11 }
|
33
41
|
])
|
34
42
|
end
|
35
43
|
end
|
@@ -44,33 +52,57 @@ describe ROM::Memory::Relation do
|
|
44
52
|
end
|
45
53
|
|
46
54
|
it 'restricts data using block' do
|
47
|
-
expect(relation.restrict { |tuple| tuple[:age] > 10 }).to match_array([
|
55
|
+
expect(relation.restrict { |tuple| tuple[:age].to_i > 10 }).to match_array([
|
48
56
|
{ name: 'Jade', email: 'jade@doe.org', age: 11 },
|
49
|
-
{ name: 'Joe',
|
57
|
+
{ name: 'Joe', email: 'joe@doe.org', age: 12 },
|
58
|
+
{ name: 'Jack', age: 11 },
|
59
|
+
{ name: 'Judy', email: 'judy@doe.org', age: 11 }
|
50
60
|
])
|
51
61
|
end
|
52
62
|
|
53
63
|
it 'allows to use array as a value' do
|
54
64
|
expect(relation.restrict(age: [10, 11])).to match_array([
|
55
65
|
{ name: 'Jane', email: 'jane@doe.org', age: 10 },
|
56
|
-
{ name: 'Jade', email: 'jade@doe.org', age: 11 }
|
66
|
+
{ name: 'Jade', email: 'jade@doe.org', age: 11 },
|
67
|
+
{ name: 'Jack', age: 11 },
|
68
|
+
{ name: 'Judy', email: 'judy@doe.org', age: 11 }
|
57
69
|
])
|
58
70
|
end
|
59
71
|
|
60
72
|
it 'allows to use regexp as a value' do
|
61
73
|
expect(relation.restrict(name: /\w{4}/)).to match_array([
|
62
74
|
{ name: 'Jane', email: 'jane@doe.org', age: 10 },
|
63
|
-
{ name: 'Jade', email: 'jade@doe.org', age: 11 }
|
75
|
+
{ name: 'Jade', email: 'jade@doe.org', age: 11 },
|
76
|
+
{ name: 'Jack', age: 11 },
|
77
|
+
{ name: 'Jill', email: 'jill@doe.org' },
|
78
|
+
{ name: 'John' },
|
79
|
+
{ name: 'Judy', email: 'judy@doe.org', age: 11 }
|
64
80
|
])
|
65
81
|
end
|
66
82
|
end
|
67
83
|
|
68
84
|
describe '#order' do
|
69
85
|
it 'sorts data using provided attribute names' do
|
70
|
-
expect(relation.order(:
|
71
|
-
{ name: '
|
72
|
-
{ name: '
|
73
|
-
{ name: '
|
86
|
+
expect(relation.order(:age, :email).to_a).to eq([
|
87
|
+
{ name: 'Jane', age: 10, email: 'jane@doe.org' },
|
88
|
+
{ name: 'Jade', age: 11, email: 'jade@doe.org' },
|
89
|
+
{ name: 'Judy', age: 11, email: 'judy@doe.org' },
|
90
|
+
{ name: 'Jack', age: 11 },
|
91
|
+
{ name: 'Joe', age: 12, email: 'joe@doe.org' },
|
92
|
+
{ name: 'Jill', email: 'jill@doe.org' },
|
93
|
+
{ name: 'John' }
|
94
|
+
])
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'places nil before other values when required' do
|
98
|
+
expect(relation.order(:age, :email, nils_first: true).to_a).to eq([
|
99
|
+
{ name: 'John' },
|
100
|
+
{ name: 'Jill', email: 'jill@doe.org' },
|
101
|
+
{ name: 'Jane', age: 10, email: 'jane@doe.org' },
|
102
|
+
{ name: 'Jack', age: 11 },
|
103
|
+
{ name: 'Jade', age: 11, email: 'jade@doe.org' },
|
104
|
+
{ name: 'Judy', age: 11, email: 'judy@doe.org' },
|
105
|
+
{ name: 'Joe', age: 12, email: 'joe@doe.org' }
|
74
106
|
])
|
75
107
|
end
|
76
108
|
end
|