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,127 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rom/memory'
|
3
|
+
|
4
|
+
describe 'Mapper definition DSL' do
|
5
|
+
let(:setup) { ROM.setup(:memory) }
|
6
|
+
let(:rom) { ROM.finalize.env }
|
7
|
+
|
8
|
+
before do
|
9
|
+
setup.relation(:users)
|
10
|
+
|
11
|
+
users = setup.default.dataset(:users)
|
12
|
+
users.insert(name: 'Joe', emails: [
|
13
|
+
{ address: 'joe@home.org', type: 'home' },
|
14
|
+
{ address: 'joe@job.com', type: 'job' },
|
15
|
+
{ address: 'joe@doe.com', type: 'job' },
|
16
|
+
{ address: 'joe@thor.org' },
|
17
|
+
{ type: 'home' },
|
18
|
+
{}
|
19
|
+
])
|
20
|
+
users.insert(name: 'Jane')
|
21
|
+
end
|
22
|
+
|
23
|
+
describe 'ungroup' do
|
24
|
+
subject(:mapped_users) { rom.relation(:users).as(:users).to_a }
|
25
|
+
|
26
|
+
it 'partially ungroups attributes' do
|
27
|
+
setup.mappers do
|
28
|
+
define(:users) { ungroup emails: [:type] }
|
29
|
+
end
|
30
|
+
|
31
|
+
expect(mapped_users).to eql [
|
32
|
+
{
|
33
|
+
name: 'Joe', type: 'home',
|
34
|
+
emails: [{ address: 'joe@home.org' }, { address: nil }]
|
35
|
+
},
|
36
|
+
{
|
37
|
+
name: 'Joe', type: 'job',
|
38
|
+
emails: [{ address: 'joe@job.com' }, { address: 'joe@doe.com' }]
|
39
|
+
},
|
40
|
+
{
|
41
|
+
name: 'Joe', type: nil,
|
42
|
+
emails: [{ address: 'joe@thor.org' }, { address: nil }]
|
43
|
+
},
|
44
|
+
{ name: 'Jane' }
|
45
|
+
]
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'removes group when all attributes extracted' do
|
49
|
+
setup.mappers do
|
50
|
+
define(:users) { ungroup emails: [:address, :type, :foo] }
|
51
|
+
end
|
52
|
+
|
53
|
+
expect(mapped_users).to eql [
|
54
|
+
{ name: 'Joe', address: 'joe@home.org', type: 'home' },
|
55
|
+
{ name: 'Joe', address: 'joe@job.com', type: 'job' },
|
56
|
+
{ name: 'Joe', address: 'joe@doe.com', type: 'job' },
|
57
|
+
{ name: 'Joe', address: 'joe@thor.org', type: nil },
|
58
|
+
{ name: 'Joe', address: nil, type: 'home' },
|
59
|
+
{ name: 'Joe', address: nil, type: nil },
|
60
|
+
{ name: 'Jane' }
|
61
|
+
]
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'accepts block syntax' do
|
65
|
+
setup.mappers do
|
66
|
+
define(:users) do
|
67
|
+
ungroup :emails do
|
68
|
+
attribute :address
|
69
|
+
attribute :type
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
expect(mapped_users).to eql [
|
75
|
+
{ name: 'Joe', address: 'joe@home.org', type: 'home' },
|
76
|
+
{ name: 'Joe', address: 'joe@job.com', type: 'job' },
|
77
|
+
{ name: 'Joe', address: 'joe@doe.com', type: 'job' },
|
78
|
+
{ name: 'Joe', address: 'joe@thor.org', type: nil },
|
79
|
+
{ name: 'Joe', address: nil, type: 'home' },
|
80
|
+
{ name: 'Joe', address: nil, type: nil },
|
81
|
+
{ name: 'Jane' }
|
82
|
+
]
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'renames ungrouped attributes' do
|
86
|
+
setup.mappers do
|
87
|
+
define(:users) do
|
88
|
+
ungroup :emails do
|
89
|
+
attribute :email, from: :address
|
90
|
+
attribute :type
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
expect(mapped_users).to eql [
|
96
|
+
{ name: 'Joe', email: 'joe@home.org', type: 'home' },
|
97
|
+
{ name: 'Joe', email: 'joe@job.com', type: 'job' },
|
98
|
+
{ name: 'Joe', email: 'joe@doe.com', type: 'job' },
|
99
|
+
{ name: 'Joe', email: 'joe@thor.org', type: nil },
|
100
|
+
{ name: 'Joe', email: nil, type: 'home' },
|
101
|
+
{ name: 'Joe', email: nil, type: nil },
|
102
|
+
{ name: 'Jane' }
|
103
|
+
]
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'skips existing attributes' do
|
107
|
+
setup.mappers do
|
108
|
+
define(:users) do
|
109
|
+
ungroup :emails do
|
110
|
+
attribute :name, from: :address
|
111
|
+
attribute :type
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
expect(mapped_users).to eql [
|
117
|
+
{ name: 'Joe', type: 'home' },
|
118
|
+
{ name: 'Joe', type: 'job' },
|
119
|
+
{ name: 'Joe', type: 'job' },
|
120
|
+
{ name: 'Joe', type: nil },
|
121
|
+
{ name: 'Joe', type: 'home' },
|
122
|
+
{ name: 'Joe', type: nil },
|
123
|
+
{ name: 'Jane' }
|
124
|
+
]
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -78,7 +78,7 @@ describe 'Mapper definition DSL' do
|
|
78
78
|
attribute :title
|
79
79
|
attribute :priority
|
80
80
|
|
81
|
-
unwrap :user do
|
81
|
+
unwrap :contact, from: :user do
|
82
82
|
attribute :task_user_name, from: :name
|
83
83
|
end
|
84
84
|
end
|
@@ -92,7 +92,7 @@ describe 'Mapper definition DSL' do
|
|
92
92
|
priority: 2,
|
93
93
|
name: 'Jane',
|
94
94
|
task_user_name: 'Jane',
|
95
|
-
|
95
|
+
contact: { email: 'jane@doe.org' })
|
96
96
|
end
|
97
97
|
end
|
98
98
|
end
|
@@ -1,24 +1,24 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'rom/memory'
|
3
3
|
|
4
|
-
describe 'Using in-memory
|
4
|
+
describe 'Using in-memory gateways for cross-repo access' do
|
5
5
|
let(:setup) do
|
6
6
|
ROM.setup(left: :memory, right: :memory, main: :memory)
|
7
7
|
end
|
8
8
|
|
9
|
-
let(:
|
9
|
+
let(:gateways) { rom.gateways }
|
10
10
|
let(:rom) { setup.finalize }
|
11
11
|
|
12
12
|
it 'works' do
|
13
|
-
setup.relation(:users,
|
13
|
+
setup.relation(:users, gateway: :left) do
|
14
14
|
def by_name(name)
|
15
15
|
restrict(name: name)
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
setup.relation(:tasks,
|
19
|
+
setup.relation(:tasks, gateway: :right)
|
20
20
|
|
21
|
-
setup.relation(:users_and_tasks,
|
21
|
+
setup.relation(:users_and_tasks, gateway: :main) do
|
22
22
|
def by_user(name)
|
23
23
|
join(users.by_name(name), tasks)
|
24
24
|
end
|
@@ -30,14 +30,14 @@ describe 'Using in-memory repositories for cross-repo access' do
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
gateways[:left][:users] << { user_id: 1, name: 'Joe' }
|
34
|
+
gateways[:left][:users] << { user_id: 2, name: 'Jane' }
|
35
|
+
gateways[:right][:tasks] << { user_id: 1, title: 'Have fun' }
|
36
|
+
gateways[:right][:tasks] << { user_id: 2, title: 'Have fun' }
|
37
37
|
|
38
38
|
user_and_tasks = rom.relation(:users_and_tasks)
|
39
|
-
|
40
|
-
|
39
|
+
.by_user('Jane')
|
40
|
+
.as(:users_and_tasks)
|
41
41
|
|
42
42
|
expect(user_and_tasks).to match_array([
|
43
43
|
{ user_id: 2, name: 'Jane', tasks: [{ title: 'Have fun' }] }
|
@@ -22,14 +22,14 @@ describe 'Repositories / Setting logger' do
|
|
22
22
|
logger_class.new
|
23
23
|
end
|
24
24
|
|
25
|
-
it 'sets up a logger for a given
|
25
|
+
it 'sets up a logger for a given gateway' do
|
26
26
|
setup = ROM.setup(:memory)
|
27
27
|
|
28
28
|
setup.default.use_logger(logger)
|
29
29
|
|
30
30
|
rom = setup.finalize
|
31
31
|
|
32
|
-
rom.
|
32
|
+
rom.gateways[:default].logger.info("test")
|
33
33
|
|
34
34
|
expect(logger.messages).to eql(["test"])
|
35
35
|
end
|
@@ -14,7 +14,7 @@ describe 'Setting up ROM' do
|
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'configures schema relations' do
|
17
|
-
expect(rom.
|
17
|
+
expect(rom.gateways[:default][:users]).to match_array([joe, jane])
|
18
18
|
end
|
19
19
|
|
20
20
|
it 'configures rom relations' do
|
@@ -48,6 +48,16 @@ describe 'Setting up ROM' do
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
+
context 'with old syntax' do
|
52
|
+
it 'warns when old repository key is used' do
|
53
|
+
setup = ROM.setup(data: :memory)
|
54
|
+
|
55
|
+
expect {
|
56
|
+
setup.relation(:users, repository: :data)
|
57
|
+
}.to output(/use `gateway: :data`/).to_stderr
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
51
61
|
describe 'defining classes' do
|
52
62
|
it 'sets up registries based on class definitions' do
|
53
63
|
ROM.setup(:memory)
|
@@ -0,0 +1,18 @@
|
|
1
|
+
shared_examples_for 'a command' do
|
2
|
+
describe '#method_missing' do
|
3
|
+
it 'forwards to relation and wraps response if it returned another relation' do
|
4
|
+
new_command = command.by_id(1)
|
5
|
+
|
6
|
+
expect(new_command).to be_instance_of(command.class)
|
7
|
+
expect(new_command.relation).to eql(command.by_id(1).relation)
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'returns original response if it was not a relation' do
|
11
|
+
expect(command.name).to eql(command.relation.name)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'raises error when message is not known' do
|
15
|
+
expect { command.not_here }.to raise_error(NoMethodError, /not_here/)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -1,10 +1,12 @@
|
|
1
1
|
shared_examples_for 'materializable relation' do
|
2
2
|
describe '#each' do
|
3
3
|
it 'yields objects' do
|
4
|
-
count = relation.to_a.
|
4
|
+
count = relation.to_a.size
|
5
5
|
result = []
|
6
6
|
|
7
|
-
relation.each
|
7
|
+
relation.each do |object|
|
8
|
+
result << object
|
9
|
+
end
|
8
10
|
|
9
11
|
expect(result.count).to eql(count)
|
10
12
|
end
|
@@ -6,10 +6,10 @@ RSpec.shared_context 'users and tasks' do
|
|
6
6
|
let(:setup) { ROM.setup(:memory) }
|
7
7
|
|
8
8
|
before do
|
9
|
-
|
9
|
+
gateway = setup.default
|
10
10
|
|
11
|
-
users =
|
12
|
-
tasks =
|
11
|
+
users = gateway.dataset(:users)
|
12
|
+
tasks = gateway.dataset(:tasks)
|
13
13
|
|
14
14
|
users.insert(name: "Joe", email: "joe@doe.org")
|
15
15
|
users.insert(name: "Jane", email: "jane@doe.org")
|
@@ -5,15 +5,15 @@ require 'rom/lint/test'
|
|
5
5
|
require 'minitest/autorun'
|
6
6
|
|
7
7
|
class MemoryRepositoryLintTest < Minitest::Test
|
8
|
-
include ROM::Lint::
|
8
|
+
include ROM::Lint::TestGateway
|
9
9
|
|
10
10
|
def setup
|
11
|
-
@
|
11
|
+
@gateway = ROM::Memory::Gateway
|
12
12
|
@identifier = :memory
|
13
13
|
end
|
14
14
|
|
15
|
-
def
|
16
|
-
ROM::Memory::
|
15
|
+
def gateway_instance
|
16
|
+
ROM::Memory::Gateway.new
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
@@ -0,0 +1,198 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ROM::Commands::Graph do
|
4
|
+
shared_examples_for 'a persisted graph' do
|
5
|
+
it 'returns nested results' do
|
6
|
+
expect(command.call).to match_array([
|
7
|
+
# parent users
|
8
|
+
[
|
9
|
+
{ name: 'Jane' },
|
10
|
+
],
|
11
|
+
[
|
12
|
+
[
|
13
|
+
# user tasks
|
14
|
+
[
|
15
|
+
{ title: 'One', user: 'Jane' }
|
16
|
+
],
|
17
|
+
[
|
18
|
+
# task tags
|
19
|
+
[
|
20
|
+
{ name: 'red', task: 'One' },
|
21
|
+
{ name: 'green', task: 'One' },
|
22
|
+
{ name: 'blue', task: 'One' }
|
23
|
+
]
|
24
|
+
]
|
25
|
+
]
|
26
|
+
]
|
27
|
+
])
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'persisted relations' do
|
31
|
+
before { command.call }
|
32
|
+
|
33
|
+
it 'inserts root' do
|
34
|
+
expect(rom.relation(:users)).to match_array([{ name: 'Jane' }])
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'inserts root nodes' do
|
38
|
+
expect(rom.relation(:tasks)).to match_array([{ user: 'Jane', title: 'One' }])
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'inserts nested graph nodes' do
|
42
|
+
expect(rom.relation(:tags)).to match_array([
|
43
|
+
{ name: 'red', task: 'One' },
|
44
|
+
{ name: 'green', task: 'One' },
|
45
|
+
{ name: 'blue', task: 'One' }
|
46
|
+
])
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
let(:rom) { setup.finalize }
|
52
|
+
let(:setup) { ROM.setup(:memory) }
|
53
|
+
|
54
|
+
let(:create_user) { rom.command(:users).create }
|
55
|
+
let(:create_task) { rom.command(:tasks).create }
|
56
|
+
|
57
|
+
let(:create_many_tasks) { rom.command(:tasks).create_many }
|
58
|
+
let(:create_many_tags) { rom.command(:tags).create_many }
|
59
|
+
|
60
|
+
let(:user) { { name: 'Jane' } }
|
61
|
+
let(:task) { { title: 'One' } }
|
62
|
+
let(:tags) { [{ name: 'red' }, { name: 'green' }, { name: 'blue' }] }
|
63
|
+
|
64
|
+
before do
|
65
|
+
setup.relation(:users)
|
66
|
+
setup.relation(:tasks)
|
67
|
+
setup.relation(:tags)
|
68
|
+
|
69
|
+
setup.commands(:users) do
|
70
|
+
define(:create) do
|
71
|
+
result :one
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
setup.commands(:tasks) do
|
76
|
+
define(:create) do
|
77
|
+
result :one
|
78
|
+
|
79
|
+
def execute(task, user)
|
80
|
+
super(task.merge(user: user[:name]))
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
define(:create) do
|
85
|
+
register_as :create_many
|
86
|
+
|
87
|
+
def execute(tasks, user)
|
88
|
+
super(tasks.map { |t| t.merge(user: user[:name]) })
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
setup.commands(:tags) do
|
94
|
+
define(:create) do
|
95
|
+
register_as :create_many
|
96
|
+
|
97
|
+
def execute(tags, tasks)
|
98
|
+
super(
|
99
|
+
Array([tasks]).flatten.map { |task|
|
100
|
+
tags.map { |tag| tag.merge(task: task[:title]) }
|
101
|
+
}.flatten
|
102
|
+
)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe '#call' do
|
109
|
+
context 'when result is :one in root and its direct children' do
|
110
|
+
it_behaves_like 'a persisted graph' do
|
111
|
+
subject(:command) do
|
112
|
+
create_user.with(user)
|
113
|
+
.combine(create_task.with(task)
|
114
|
+
.combine(create_many_tags.with(tags)))
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
context 'when result is :many for root direct children' do
|
120
|
+
it_behaves_like 'a persisted graph' do
|
121
|
+
subject(:command) do
|
122
|
+
create_user.with(user)
|
123
|
+
.combine(create_many_tasks.with([task])
|
124
|
+
.combine(create_many_tags.with(tags)))
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
context 'when error is raised' do
|
130
|
+
subject(:command) do
|
131
|
+
create_user.with(user).combine(create_many_tasks.with([task]))
|
132
|
+
end
|
133
|
+
|
134
|
+
it 're-raises the error providing proper context when root fails' do
|
135
|
+
allow(command.root).to receive(:call).and_raise(StandardError, 'ooops')
|
136
|
+
|
137
|
+
expect { command.call }.to raise_error(ROM::CommandFailure, /oops/)
|
138
|
+
end
|
139
|
+
|
140
|
+
it 're-raises the error providing proper context when a node fails' do
|
141
|
+
allow(command.nodes[0]).to receive(:call).and_raise(StandardError, 'ooops')
|
142
|
+
|
143
|
+
expect { command.call }.to raise_error(ROM::CommandFailure, /oops/)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
describe 'pipeline' do
|
149
|
+
subject(:command) do
|
150
|
+
rom.command(:users).as(:entity).create.with(user)
|
151
|
+
.combine(create_task.with(task)
|
152
|
+
.combine(create_many_tags.with(tags)))
|
153
|
+
end
|
154
|
+
|
155
|
+
before do
|
156
|
+
Test::Tag = Class.new { include Anima.new(:name) }
|
157
|
+
Test::Task = Class.new { include Anima.new(:title, :tags) }
|
158
|
+
Test::User = Class.new { include Anima.new(:name, :task) }
|
159
|
+
|
160
|
+
class Test::UserMapper < ROM::Mapper
|
161
|
+
relation :users
|
162
|
+
register_as :entity
|
163
|
+
reject_keys :true
|
164
|
+
|
165
|
+
model Test::User
|
166
|
+
|
167
|
+
attribute :name
|
168
|
+
|
169
|
+
combine :task, on: { name: :user }, type: :hash do
|
170
|
+
model Test::Task
|
171
|
+
|
172
|
+
attribute :title
|
173
|
+
|
174
|
+
combine :tags, on: { title: :task } do
|
175
|
+
model Test::Tag
|
176
|
+
attribute :name
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'sends data through the pipeline' do
|
183
|
+
expect(command.call).to eql(
|
184
|
+
Test::User.new(
|
185
|
+
name: 'Jane',
|
186
|
+
task: Test::Task.new(
|
187
|
+
title: 'One',
|
188
|
+
tags: [
|
189
|
+
Test::Tag.new(name: 'red'),
|
190
|
+
Test::Tag.new(name: 'green'),
|
191
|
+
Test::Tag.new(name: 'blue'),
|
192
|
+
]
|
193
|
+
)
|
194
|
+
)
|
195
|
+
)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|