rom 0.9.1 → 1.0.0.beta1
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_todo.yml +30 -12
- data/.travis.yml +1 -1
- data/CHANGELOG.md +24 -0
- data/Gemfile +7 -3
- data/README.md +24 -11
- data/lib/rom.rb +9 -26
- data/lib/rom/command.rb +113 -75
- data/lib/rom/commands/class_interface.rb +115 -0
- data/lib/rom/commands/graph.rb +17 -23
- data/lib/rom/commands/graph/builder.rb +176 -0
- data/lib/rom/commands/graph/class_interface.rb +8 -2
- data/lib/rom/commands/graph/input_evaluator.rb +13 -9
- data/lib/rom/commands/lazy.rb +23 -17
- data/lib/rom/commands/lazy/create.rb +23 -0
- data/lib/rom/commands/lazy/delete.rb +27 -0
- data/lib/rom/commands/lazy/update.rb +34 -0
- data/lib/rom/commands/result.rb +14 -0
- data/lib/rom/commands/update.rb +0 -4
- data/lib/rom/configuration.rb +86 -0
- data/lib/rom/{setup_dsl/setup.rb → configuration_dsl.rb} +9 -7
- data/lib/rom/configuration_dsl/command.rb +43 -0
- data/lib/rom/{setup_dsl → configuration_dsl}/command_dsl.rb +5 -4
- data/lib/rom/configuration_dsl/mapper.rb +37 -0
- data/lib/rom/{setup_dsl → configuration_dsl}/mapper_dsl.rb +11 -5
- data/lib/rom/configuration_dsl/relation.rb +26 -0
- data/lib/rom/configuration_plugin.rb +17 -0
- data/lib/rom/constants.rb +5 -12
- data/lib/rom/container.rb +11 -8
- data/lib/rom/create_container.rb +61 -0
- data/lib/rom/environment.rb +27 -241
- data/lib/rom/gateway.rb +18 -2
- data/lib/rom/global.rb +24 -0
- data/lib/rom/global/plugin_dsl.rb +2 -0
- data/lib/rom/lint/spec.rb +0 -12
- data/lib/rom/lint/test.rb +0 -31
- data/lib/rom/memory/commands.rb +2 -2
- data/lib/rom/memory/gateway.rb +2 -0
- data/lib/rom/pipeline.rb +1 -1
- data/lib/rom/plugin_base.rb +1 -1
- data/lib/rom/plugin_registry.rb +12 -10
- data/lib/rom/plugins/configuration/configuration_dsl.rb +16 -0
- data/lib/rom/plugins/relation/key_inference.rb +31 -0
- data/lib/rom/plugins/relation/view.rb +90 -0
- data/lib/rom/plugins/relation/view/dsl.rb +32 -0
- data/lib/rom/relation.rb +1 -11
- data/lib/rom/relation/class_interface.rb +37 -50
- data/lib/rom/setup.rb +13 -104
- data/lib/rom/setup/auto_registration.rb +55 -0
- data/lib/rom/setup/finalize.rb +113 -127
- data/lib/rom/setup/finalize/commands.rb +67 -0
- data/lib/rom/setup/finalize/mappers.rb +36 -0
- data/lib/rom/setup/finalize/relations.rb +53 -0
- data/lib/rom/support/configurable.rb +21 -7
- data/lib/rom/version.rb +1 -1
- data/rakelib/mutant.rake +4 -1
- data/rom.gemspec +3 -4
- data/spec/fixtures/app/commands/create_user.rb +2 -0
- data/spec/fixtures/app/mappers/user_list.rb +2 -0
- data/spec/fixtures/app/relations/users.rb +2 -0
- data/spec/fixtures/lib/persistence/commands/create_user.rb +6 -0
- data/spec/fixtures/lib/persistence/mappers/user_list.rb +6 -0
- data/spec/fixtures/lib/persistence/relations/users.rb +6 -0
- data/spec/{unit/rom → integration}/command_registry_spec.rb +8 -9
- data/spec/integration/commands/create_spec.rb +17 -13
- data/spec/integration/commands/delete_spec.rb +12 -11
- data/spec/integration/commands/error_handling_spec.rb +5 -4
- data/spec/integration/commands/graph_builder_spec.rb +213 -0
- data/spec/integration/commands/graph_spec.rb +112 -49
- data/spec/integration/commands/update_spec.rb +14 -11
- data/spec/integration/commands_spec.rb +60 -0
- data/spec/integration/mappers/combine_spec.rb +7 -6
- data/spec/integration/mappers/deep_embedded_spec.rb +5 -6
- data/spec/integration/mappers/definition_dsl_spec.rb +19 -18
- data/spec/integration/mappers/embedded_spec.rb +11 -12
- data/spec/integration/mappers/exclude_spec.rb +5 -6
- data/spec/integration/mappers/fold_spec.rb +8 -7
- data/spec/integration/mappers/group_spec.rb +16 -15
- data/spec/integration/mappers/overwrite_attributes_value_spec.rb +5 -5
- data/spec/integration/mappers/prefix_separator_spec.rb +5 -7
- data/spec/integration/mappers/prefix_spec.rb +5 -7
- data/spec/integration/mappers/prefixing_attributes_spec.rb +7 -7
- data/spec/integration/mappers/registering_custom_mappers_spec.rb +4 -5
- data/spec/integration/mappers/renaming_attributes_spec.rb +18 -18
- data/spec/integration/mappers/step_spec.rb +11 -12
- data/spec/integration/mappers/symbolizing_attributes_spec.rb +11 -8
- data/spec/integration/mappers/unfold_spec.rb +9 -10
- data/spec/integration/mappers/ungroup_spec.rb +10 -11
- data/spec/integration/mappers/unwrap_spec.rb +10 -15
- data/spec/integration/mappers/wrap_spec.rb +16 -15
- data/spec/{unit/rom → integration}/memory/commands/create_spec.rb +7 -5
- data/spec/{unit/rom → integration}/memory/commands/delete_spec.rb +7 -5
- data/spec/{unit/rom → integration}/memory/commands/update_spec.rb +7 -5
- data/spec/integration/multi_env_spec.rb +16 -124
- data/spec/integration/multi_repo_spec.rb +9 -9
- data/spec/integration/relations/default_dataset_spec.rb +15 -0
- data/spec/integration/relations/inheritance_spec.rb +5 -7
- data/spec/integration/relations/reading_spec.rb +32 -65
- data/spec/integration/relations/registry_dsl_spec.rb +5 -4
- data/spec/integration/repositories/extending_relations_spec.rb +6 -7
- data/spec/integration/repositories/setting_logger_spec.rb +5 -7
- data/spec/integration/setup_spec.rb +49 -61
- data/spec/shared/command_graph.rb +50 -0
- data/spec/shared/container.rb +9 -0
- data/spec/shared/gateway_only.rb +6 -0
- data/spec/shared/no_container.rb +16 -0
- data/spec/shared/one_behavior.rb +4 -4
- data/spec/shared/users_and_tasks.rb +5 -17
- data/spec/spec_helper.rb +5 -3
- data/spec/test/memory_repository_lint_test.rb +1 -1
- data/spec/unit/rom/auto_registration_spec.rb +54 -0
- data/spec/unit/rom/commands/graph_spec.rb +18 -44
- data/spec/unit/rom/commands/lazy_spec.rb +246 -35
- data/spec/unit/rom/commands/result_spec.rb +56 -0
- data/spec/unit/rom/commands_spec.rb +9 -73
- data/spec/unit/rom/configurable_spec.rb +49 -0
- data/spec/unit/rom/configuration_spec.rb +61 -0
- data/spec/unit/rom/container_spec.rb +39 -33
- data/spec/unit/rom/create_container_spec.rb +151 -0
- data/spec/unit/rom/environment_spec.rb +123 -0
- data/spec/unit/rom/gateway_spec.rb +58 -2
- data/spec/unit/rom/global_spec.rb +10 -7
- data/spec/unit/rom/plugin_spec.rb +44 -25
- data/spec/unit/rom/plugins/relation/key_inference_spec.rb +27 -0
- data/spec/unit/rom/plugins/relation/view_spec.rb +47 -0
- data/spec/unit/rom/relation/composite_spec.rb +20 -20
- data/spec/unit/rom/relation/curried_spec.rb +10 -11
- data/spec/unit/rom/relation/graph_spec.rb +27 -27
- data/spec/unit/rom/relation/lazy/combine_spec.rb +26 -20
- data/spec/unit/rom/relation/lazy_spec.rb +38 -38
- data/spec/unit/rom/relation/loaded_spec.rb +2 -3
- data/spec/unit/rom/relation_spec.rb +39 -2
- metadata +58 -66
- data/lib/rom/commands/abstract.rb +0 -184
- data/lib/rom/environment_plugin.rb +0 -17
- data/lib/rom/environment_plugins/auto_registration.rb +0 -38
- data/lib/rom/repository.rb +0 -16
- data/lib/rom/setup_dsl/command.rb +0 -36
- data/lib/rom/setup_dsl/mapper.rb +0 -32
- data/lib/rom/setup_dsl/relation.rb +0 -30
- data/spec/integration/inline_setup_spec.rb +0 -65
- data/spec/unit/rom/repository_spec.rb +0 -12
- data/spec/unit/rom/setup_spec.rb +0 -253
@@ -21,7 +21,7 @@ class MemoryDatasetLintTest < Minitest::Test
|
|
21
21
|
include ROM::Lint::TestEnumerableDataset
|
22
22
|
|
23
23
|
def setup
|
24
|
-
@data
|
24
|
+
@data = [{ name: 'Jane', age: 24 }, { name: 'Joe', age: 25 }]
|
25
25
|
@dataset = ROM::Memory::Dataset.new(@data)
|
26
26
|
end
|
27
27
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rom/setup/auto_registration'
|
3
|
+
|
4
|
+
RSpec.describe ROM::Setup, '#auto_registration' do
|
5
|
+
let(:setup) { ROM::Setup.new }
|
6
|
+
|
7
|
+
context 'with namespace turned on' do
|
8
|
+
before do
|
9
|
+
setup.auto_registration(SPEC_ROOT.join('fixtures/lib/persistence'))
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#relations' do
|
13
|
+
it 'loads files and returns constants' do
|
14
|
+
expect(setup.relation_classes).to eql([Persistence::Relations::Users])
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#commands' do
|
19
|
+
it 'loads files and returns constants' do
|
20
|
+
expect(setup.command_classes).to eql([Persistence::Commands::CreateUser])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#mappers' do
|
25
|
+
it 'loads files and returns constants' do
|
26
|
+
expect(setup.mapper_classes).to eql([Persistence::Mappers::UserList])
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'with namespace turned off' do
|
32
|
+
before do
|
33
|
+
setup.auto_registration(SPEC_ROOT.join('fixtures/app'), namespace: false)
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#relations' do
|
37
|
+
it 'loads files and returns constants' do
|
38
|
+
expect(setup.relation_classes).to eql([Users])
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe '#commands' do
|
43
|
+
it 'loads files and returns constants' do
|
44
|
+
expect(setup.command_classes).to eql([CreateUser])
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '#mappers' do
|
49
|
+
it 'loads files and returns constants' do
|
50
|
+
expect(setup.mapper_classes).to eql([UserList])
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -6,7 +6,7 @@ describe ROM::Commands::Graph do
|
|
6
6
|
expect(command.call).to match_array([
|
7
7
|
# parent users
|
8
8
|
[
|
9
|
-
{ name: 'Jane' }
|
9
|
+
{ name: 'Jane' }
|
10
10
|
],
|
11
11
|
[
|
12
12
|
[
|
@@ -31,15 +31,15 @@ describe ROM::Commands::Graph do
|
|
31
31
|
before { command.call }
|
32
32
|
|
33
33
|
it 'inserts root' do
|
34
|
-
expect(
|
34
|
+
expect(container.relation(:users)).to match_array([{ name: 'Jane' }])
|
35
35
|
end
|
36
36
|
|
37
37
|
it 'inserts root nodes' do
|
38
|
-
expect(
|
38
|
+
expect(container.relation(:tasks)).to match_array([{ user: 'Jane', title: 'One' }])
|
39
39
|
end
|
40
40
|
|
41
41
|
it 'inserts nested graph nodes' do
|
42
|
-
expect(
|
42
|
+
expect(container.relation(:tags)).to match_array([
|
43
43
|
{ name: 'red', task: 'One' },
|
44
44
|
{ name: 'green', task: 'One' },
|
45
45
|
{ name: 'blue', task: 'One' }
|
@@ -48,31 +48,30 @@ describe ROM::Commands::Graph do
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
-
|
52
|
-
let(:setup) { ROM.setup(:memory) }
|
51
|
+
include_context 'container'
|
53
52
|
|
54
|
-
let(:create_user) {
|
55
|
-
let(:create_task) {
|
53
|
+
let(:create_user) { container.command(:users).create }
|
54
|
+
let(:create_task) { container.command(:tasks).create }
|
56
55
|
|
57
|
-
let(:create_many_tasks) {
|
58
|
-
let(:create_many_tags) {
|
56
|
+
let(:create_many_tasks) { container.command(:tasks).create_many }
|
57
|
+
let(:create_many_tags) { container.command(:tags).create_many }
|
59
58
|
|
60
59
|
let(:user) { { name: 'Jane' } }
|
61
60
|
let(:task) { { title: 'One' } }
|
62
61
|
let(:tags) { [{ name: 'red' }, { name: 'green' }, { name: 'blue' }] }
|
63
62
|
|
64
63
|
before do
|
65
|
-
|
66
|
-
|
67
|
-
|
64
|
+
configuration.relation(:users)
|
65
|
+
configuration.relation(:tasks)
|
66
|
+
configuration.relation(:tags)
|
68
67
|
|
69
|
-
|
68
|
+
configuration.commands(:users) do
|
70
69
|
define(:create) do
|
71
70
|
result :one
|
72
71
|
end
|
73
72
|
end
|
74
73
|
|
75
|
-
|
74
|
+
configuration.commands(:tasks) do
|
76
75
|
define(:create) do
|
77
76
|
result :one
|
78
77
|
|
@@ -90,7 +89,7 @@ describe ROM::Commands::Graph do
|
|
90
89
|
end
|
91
90
|
end
|
92
91
|
|
93
|
-
|
92
|
+
configuration.commands(:tags) do
|
94
93
|
define(:create) do
|
95
94
|
register_as :create_many
|
96
95
|
|
@@ -125,37 +124,11 @@ describe ROM::Commands::Graph do
|
|
125
124
|
end
|
126
125
|
end
|
127
126
|
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
|
-
|
145
|
-
begin
|
146
|
-
command.call
|
147
|
-
rescue ROM::CommandFailure => e
|
148
|
-
expect(e.original_error).to be_a(ROM::CommandFailure)
|
149
|
-
expect(e.original_error.message).to include('ooops')
|
150
|
-
expect(e.backtrace).to eql(e.original_error.backtrace)
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
154
127
|
end
|
155
128
|
|
156
129
|
describe 'pipeline' do
|
157
130
|
subject(:command) do
|
158
|
-
|
131
|
+
container.command(:users).as(:entity).create.with(user)
|
159
132
|
.combine(create_task.with(task)
|
160
133
|
.combine(create_many_tags.with(tags)))
|
161
134
|
end
|
@@ -185,6 +158,7 @@ describe ROM::Commands::Graph do
|
|
185
158
|
end
|
186
159
|
end
|
187
160
|
end
|
161
|
+
configuration.register_mapper(Test::UserMapper)
|
188
162
|
end
|
189
163
|
|
190
164
|
it 'sends data through the pipeline' do
|
@@ -196,7 +170,7 @@ describe ROM::Commands::Graph do
|
|
196
170
|
tags: [
|
197
171
|
Test::Tag.new(name: 'red'),
|
198
172
|
Test::Tag.new(name: 'green'),
|
199
|
-
Test::Tag.new(name: 'blue')
|
173
|
+
Test::Tag.new(name: 'blue')
|
200
174
|
]
|
201
175
|
)
|
202
176
|
)
|
@@ -1,52 +1,275 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe ROM::Commands::Lazy do
|
4
|
-
|
5
|
-
let(:setup) { ROM.setup(:memory) }
|
4
|
+
include_context 'container'
|
6
5
|
|
7
|
-
let(:create_user) {
|
8
|
-
let(:update_user) {
|
9
|
-
let(:
|
6
|
+
let(:create_user) { container.command(:users).create }
|
7
|
+
let(:update_user) { container.command(:users).update }
|
8
|
+
let(:delete_user) { container.command(:users).delete }
|
10
9
|
|
11
|
-
let(:
|
10
|
+
let(:create_task) { container.command(:tasks).create }
|
11
|
+
let(:create_tasks) { container.command(:tasks).create_many }
|
12
|
+
let(:update_task) { container.command(:tasks).update }
|
13
|
+
|
14
|
+
let(:input) { { user: { name: 'Jane', email: 'jane@doe.org' } } }
|
15
|
+
let(:jane) { input[:user] }
|
12
16
|
let(:evaluator) { -> input { input[:user] } }
|
13
17
|
|
14
18
|
before do
|
15
|
-
|
19
|
+
configuration.relation(:tasks) do
|
20
|
+
def by_user_and_title(user, title)
|
21
|
+
by_user(user).by_title(title)
|
22
|
+
end
|
23
|
+
|
24
|
+
def by_user(user)
|
25
|
+
restrict(user: user)
|
26
|
+
end
|
16
27
|
|
17
|
-
|
28
|
+
def by_title(title)
|
29
|
+
restrict(title: title)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
configuration.relation(:users) do
|
18
34
|
def by_name(name)
|
19
35
|
restrict(name: name)
|
20
36
|
end
|
21
37
|
end
|
22
38
|
|
23
|
-
|
39
|
+
configuration.commands(:users) do
|
24
40
|
define(:create) do
|
25
41
|
result :one
|
26
42
|
end
|
27
43
|
|
28
|
-
define(:update)
|
44
|
+
define(:update) do
|
45
|
+
result :one
|
46
|
+
end
|
47
|
+
|
48
|
+
define(:delete) do
|
49
|
+
result :one
|
50
|
+
end
|
29
51
|
end
|
30
52
|
|
31
|
-
|
32
|
-
define(:create)
|
53
|
+
configuration.commands(:tasks) do
|
54
|
+
define(:create) do
|
55
|
+
result :one
|
56
|
+
end
|
57
|
+
|
58
|
+
define(:create_many, type: :create) do
|
59
|
+
def execute(tuples, user)
|
60
|
+
super(tuples.map { |tuple| tuple.merge(user: user[:name]) })
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
define(:update) do
|
65
|
+
result :one
|
66
|
+
|
67
|
+
def execute(tuple, user)
|
68
|
+
super(tuple.merge(user: user[:name]))
|
69
|
+
end
|
70
|
+
end
|
33
71
|
end
|
34
72
|
end
|
35
73
|
|
36
74
|
describe '#call' do
|
37
|
-
|
75
|
+
context 'with a create command' do
|
76
|
+
subject(:command) { ROM::Commands::Lazy[create_user].new(create_user, evaluator) }
|
77
|
+
|
78
|
+
it 'evaluates the input and calls command' do
|
79
|
+
command.call(input)
|
80
|
+
|
81
|
+
expect(container.relation(:users)).to match_array([jane])
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context 'with a create command for many child tuples' do
|
86
|
+
subject(:command) do
|
87
|
+
ROM::Commands::Lazy[create_tasks].new(create_tasks, evaluator)
|
88
|
+
end
|
89
|
+
|
90
|
+
let(:evaluator) { -> input, index { input[:users][index][:tasks] } }
|
91
|
+
|
92
|
+
let(:input) do
|
93
|
+
{ users: [
|
94
|
+
{
|
95
|
+
name: 'Jane',
|
96
|
+
tasks: [{ title: 'Jane Task One' }, { title: 'Jane Task Two' }]
|
97
|
+
},
|
98
|
+
{
|
99
|
+
name: 'Joe',
|
100
|
+
tasks: [{ title: 'Joe Task One' }]
|
101
|
+
}
|
102
|
+
]}
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'evaluates the input and calls command' do
|
106
|
+
command.call(input, input[:users])
|
107
|
+
|
108
|
+
expect(container.relation(:tasks)).to match_array([
|
109
|
+
{ user: 'Jane', title: 'Jane Task One' },
|
110
|
+
{ user: 'Jane', title: 'Jane Task Two' },
|
111
|
+
{ user: 'Joe', title: 'Joe Task One' }
|
112
|
+
])
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
context 'with an update command' do
|
117
|
+
subject(:command) do
|
118
|
+
ROM::Commands::Lazy[update_user].new(
|
119
|
+
update_user, evaluator, -> cmd, user { cmd.by_name(user[:name]) })
|
120
|
+
end
|
121
|
+
|
122
|
+
before do
|
123
|
+
create_user[jane]
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'evaluates the input, restricts the relation and calls its command' do
|
127
|
+
input = { user: { name: 'Jane', email: 'jane.doe@rom-rb.org' } }
|
128
|
+
command.call(input)
|
129
|
+
|
130
|
+
expect(container.relation(:users)).to match_array([input[:user]])
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
context 'with an update command for a child tuple' do
|
135
|
+
subject(:command) do
|
136
|
+
ROM::Commands::Lazy[update_task].new(
|
137
|
+
update_task,
|
138
|
+
evaluator,
|
139
|
+
-> cmd, user, task { cmd.by_user(user[:name]).by_title(task[:title]) }
|
140
|
+
)
|
141
|
+
end
|
38
142
|
|
39
|
-
|
40
|
-
command.call(user)
|
143
|
+
let(:evaluator) { -> input { input[:user][:task] } }
|
41
144
|
|
42
|
-
|
43
|
-
|
44
|
-
|
145
|
+
let(:jane) { { name: 'Jane' } }
|
146
|
+
let(:jane_task) { { user: 'Jane', title: 'Jane Task', priority: 1 } }
|
147
|
+
|
148
|
+
let(:input) { { user: jane.merge(task: jane_task) } }
|
149
|
+
|
150
|
+
before do
|
151
|
+
create_user[jane]
|
152
|
+
create_task[user: 'Jane', title: 'Jane Task', priority: 2]
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'evaluates the input, restricts the relation and calls its command' do
|
156
|
+
command.call(input, input[:user])
|
157
|
+
|
158
|
+
expect(container.relation(:users)).to match_array([jane])
|
159
|
+
|
160
|
+
expect(container.relation(:tasks)).to match_array([jane_task])
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
context 'with an update command for child tuples' do
|
165
|
+
subject(:command) do
|
166
|
+
ROM::Commands::Lazy[update_task].new(
|
167
|
+
update_task,
|
168
|
+
evaluator,
|
169
|
+
-> cmd, user, task { cmd.by_user(user[:name]).by_title(task[:title]) }
|
170
|
+
)
|
171
|
+
end
|
172
|
+
|
173
|
+
let(:evaluator) { -> input { input[:user][:tasks] } }
|
174
|
+
|
175
|
+
let(:jane) { { name: 'Jane' } }
|
176
|
+
let(:jane_tasks) {
|
177
|
+
[
|
178
|
+
{ user: 'Jane', title: 'Jane Task One', priority: 2 },
|
179
|
+
{ user: 'Jane', title: 'Jane Task Two', priority: 3 }
|
180
|
+
]
|
181
|
+
}
|
182
|
+
|
183
|
+
let(:input) { { user: jane.merge(tasks: jane_tasks) } }
|
184
|
+
|
185
|
+
before do
|
186
|
+
create_user[jane]
|
187
|
+
create_task[user: 'Jane', title: 'Jane Task One', priority: 3]
|
188
|
+
create_task[user: 'Jane', title: 'Jane Task Two', priority: 4]
|
189
|
+
end
|
190
|
+
|
191
|
+
it 'evaluates the input, restricts the relation and calls its command' do
|
192
|
+
command.call(input, input[:user])
|
193
|
+
|
194
|
+
expect(container.relation(:users)).to match_array([jane])
|
195
|
+
|
196
|
+
expect(container.relation(:tasks)).to match_array(jane_tasks)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
context 'with an update command for many parents and their children' do
|
201
|
+
subject(:command) do
|
202
|
+
ROM::Commands::Lazy[update_task].new(
|
203
|
+
update_task,
|
204
|
+
evaluator,
|
205
|
+
-> cmd, user, task { cmd.by_user(user[:name]).by_title(task[:title]) }
|
206
|
+
)
|
207
|
+
end
|
208
|
+
|
209
|
+
let(:evaluator) { -> input, index { input[:users][index][:tasks] } }
|
210
|
+
|
211
|
+
let(:input) do
|
212
|
+
{ users: [
|
213
|
+
{
|
214
|
+
name: 'Jane',
|
215
|
+
tasks: [
|
216
|
+
{ title: 'Jane Task One', priority: 1 },
|
217
|
+
{ title: 'Jane Task Two', priority: 2 }
|
218
|
+
]
|
219
|
+
},
|
220
|
+
{
|
221
|
+
name: 'Joe',
|
222
|
+
tasks: [{ title: 'Joe Task One', priority: 1 }]
|
223
|
+
}
|
224
|
+
]}
|
225
|
+
end
|
226
|
+
|
227
|
+
before do
|
228
|
+
create_user[name: 'Jane']
|
229
|
+
create_user[name: 'Joe']
|
230
|
+
|
231
|
+
create_task[user: 'Jane', title: 'Jane Task One']
|
232
|
+
create_task[user: 'Jane', title: 'Jane Task Two']
|
233
|
+
create_task[user: 'Joe', title: 'Joe Task One']
|
234
|
+
end
|
235
|
+
|
236
|
+
it 'evaluates the input and calls its command' do
|
237
|
+
command.call(input, input[:users])
|
238
|
+
|
239
|
+
expect(container.relation(:tasks)).to match_array([
|
240
|
+
{ user: 'Jane', title: 'Jane Task One', priority: 1 },
|
241
|
+
{ user: 'Jane', title: 'Jane Task Two', priority: 2 },
|
242
|
+
{ user: 'Joe', title: 'Joe Task One', priority: 1 }
|
243
|
+
])
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
context 'with a delete command' do
|
248
|
+
subject(:command) do
|
249
|
+
ROM::Commands::Lazy[delete_user].new(
|
250
|
+
delete_user,
|
251
|
+
evaluator,
|
252
|
+
-> cmd, user { cmd.by_name(user[:name]) }
|
253
|
+
)
|
254
|
+
end
|
255
|
+
|
256
|
+
let(:joe) { { name: 'Joe' } }
|
257
|
+
|
258
|
+
before do
|
259
|
+
create_user[jane]
|
260
|
+
create_user[joe]
|
261
|
+
end
|
262
|
+
|
263
|
+
it 'restricts the relation and calls its command' do
|
264
|
+
command.call(input)
|
265
|
+
|
266
|
+
expect(container.relation(:users)).to match_array([joe])
|
267
|
+
end
|
45
268
|
end
|
46
269
|
end
|
47
270
|
|
48
271
|
describe '#>>' do
|
49
|
-
subject(:command) { ROM::Commands::Lazy.new(create_user, evaluator) }
|
272
|
+
subject(:command) { ROM::Commands::Lazy[create_user].new(create_user, evaluator) }
|
50
273
|
|
51
274
|
it 'composes with another command' do
|
52
275
|
expect(command >> create_task).to be_instance_of(ROM::Commands::Composite)
|
@@ -54,7 +277,7 @@ describe ROM::Commands::Lazy do
|
|
54
277
|
end
|
55
278
|
|
56
279
|
describe '#combine' do
|
57
|
-
subject(:command) { ROM::Commands::Lazy.new(create_user, evaluator) }
|
280
|
+
subject(:command) { ROM::Commands::Lazy[create_user].new(create_user, evaluator) }
|
58
281
|
|
59
282
|
it 'combines with another command' do
|
60
283
|
expect(command.combine(create_task)).to be_instance_of(ROM::Commands::Graph)
|
@@ -62,23 +285,11 @@ describe ROM::Commands::Lazy do
|
|
62
285
|
end
|
63
286
|
|
64
287
|
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
|
288
|
+
subject(:command) { ROM::Commands::Lazy[update_user].new(update_user, evaluator) }
|
78
289
|
|
79
|
-
it '
|
290
|
+
it 'returns original response if it was not a command' do
|
80
291
|
response = command.result
|
81
|
-
expect(response).to be(:
|
292
|
+
expect(response).to be(:one)
|
82
293
|
end
|
83
294
|
|
84
295
|
it 'raises error when message is unknown' do
|