rom 0.7.1 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|