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
@@ -1,16 +1,11 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe ROM::Relation::Composite do
|
4
|
+
include_context 'gateway only'
|
4
5
|
include_context 'users and tasks'
|
5
6
|
|
6
|
-
let(:
|
7
|
-
|
8
|
-
|
9
|
-
let(:name_list) { proc { |r| r.map { |t| t[:name] } } }
|
10
|
-
let(:upcaser) { proc { |r| r.map(&:upcase) } }
|
11
|
-
|
12
|
-
before do
|
13
|
-
setup.relation(:users) do
|
7
|
+
let(:users_relation) do
|
8
|
+
Class.new(ROM::Memory::Relation) do
|
14
9
|
def by_name(name)
|
15
10
|
restrict(name: name)
|
16
11
|
end
|
@@ -18,30 +13,35 @@ describe ROM::Relation::Composite do
|
|
18
13
|
def sorted(other)
|
19
14
|
other.source.order(:name)
|
20
15
|
end
|
21
|
-
end
|
16
|
+
end.new(users_dataset)
|
17
|
+
end
|
22
18
|
|
23
|
-
|
19
|
+
let(:tasks_relation) do
|
20
|
+
Class.new(ROM::Memory::Relation) do
|
24
21
|
def for_users(users)
|
25
22
|
restrict(name: users.map { |u| u[:name] })
|
26
23
|
end
|
27
|
-
end
|
24
|
+
end.new(tasks_dataset)
|
28
25
|
end
|
29
26
|
|
27
|
+
let(:name_list) { proc { |r| r.map { |t| t[:name] } } }
|
28
|
+
let(:upcaser) { proc { |r| r.map(&:upcase) } }
|
29
|
+
|
30
30
|
describe '#call' do
|
31
31
|
it 'sends a relation through mappers' do
|
32
|
-
relation =
|
32
|
+
relation = users_relation >> name_list >> upcaser
|
33
33
|
loaded = relation.call
|
34
34
|
|
35
|
-
expect(loaded.source).to eql(
|
35
|
+
expect(loaded.source).to eql(users_relation)
|
36
36
|
|
37
37
|
expect(loaded).to match_array(%w(JANE JOE))
|
38
38
|
end
|
39
39
|
|
40
40
|
it 'sends a relation through another relation' do
|
41
|
-
relation =
|
41
|
+
relation = users_relation >> users_relation.sorted
|
42
42
|
loaded = relation.call
|
43
43
|
|
44
|
-
expect(loaded.source).to eql(
|
44
|
+
expect(loaded.source).to eql(users_relation.sorted(users_relation.call))
|
45
45
|
|
46
46
|
expect(loaded).to match_array([
|
47
47
|
{ name: 'Jane', email: 'jane@doe.org' },
|
@@ -50,12 +50,12 @@ describe ROM::Relation::Composite do
|
|
50
50
|
end
|
51
51
|
|
52
52
|
it 'sends a relation through another composite relation' do
|
53
|
-
task_mapper = ->
|
54
|
-
relation =
|
53
|
+
task_mapper = -> tasks_relation { tasks_relation }
|
54
|
+
relation = users_relation.by_name('Jane') >> (tasks_relation.for_users >> task_mapper)
|
55
55
|
|
56
56
|
loaded = relation.call
|
57
57
|
|
58
|
-
expect(loaded.source).to eql(
|
58
|
+
expect(loaded.source).to eql(tasks_relation.for_users(users_relation.by_name('Jane')))
|
59
59
|
|
60
60
|
expect(loaded).to match_array([
|
61
61
|
{ name: 'Jane', title: 'be cool', priority: 2 }
|
@@ -64,7 +64,7 @@ describe ROM::Relation::Composite do
|
|
64
64
|
end
|
65
65
|
|
66
66
|
describe '#each' do
|
67
|
-
let(:relation) {
|
67
|
+
let(:relation) { users_relation >> name_list >> upcaser }
|
68
68
|
|
69
69
|
it 'calls and iterates' do
|
70
70
|
result = []
|
@@ -80,7 +80,7 @@ describe ROM::Relation::Composite do
|
|
80
80
|
end
|
81
81
|
|
82
82
|
describe '#first' do
|
83
|
-
let(:relation) {
|
83
|
+
let(:relation) { users_relation >> name_list >> upcaser }
|
84
84
|
|
85
85
|
it 'calls and returns the first object' do
|
86
86
|
expect(relation.first).to eql('JOE')
|
@@ -1,12 +1,11 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
RSpec.describe ROM::Relation::Curried do
|
4
|
+
include_context 'gateway only'
|
4
5
|
include_context 'users and tasks'
|
5
6
|
|
6
|
-
let(:
|
7
|
-
|
8
|
-
before do
|
9
|
-
setup.relation(:users) do
|
7
|
+
let(:users_relation) do
|
8
|
+
Class.new(ROM::Memory::Relation) do
|
10
9
|
def by_name(name)
|
11
10
|
restrict(name: name)
|
12
11
|
end
|
@@ -14,11 +13,11 @@ RSpec.describe ROM::Relation::Curried do
|
|
14
13
|
def find(criteria)
|
15
14
|
restrict(criteria)
|
16
15
|
end
|
17
|
-
end
|
16
|
+
end.new(users_dataset)
|
18
17
|
end
|
19
18
|
|
20
19
|
describe '#call' do
|
21
|
-
let(:relation) {
|
20
|
+
let(:relation) { users_relation.by_name.call('Jane') }
|
22
21
|
|
23
22
|
it 'materializes a relation' do
|
24
23
|
expect(relation).to match_array([
|
@@ -27,27 +26,27 @@ RSpec.describe ROM::Relation::Curried do
|
|
27
26
|
end
|
28
27
|
|
29
28
|
it 'returns a loaded relation' do
|
30
|
-
expect(relation.source).to eql(
|
29
|
+
expect(relation.source).to eql(users_relation.by_name('Jane'))
|
31
30
|
end
|
32
31
|
end
|
33
32
|
|
34
33
|
describe '#respond_to?' do
|
35
34
|
it 'returns true if wrapped relation responds to a method' do
|
36
|
-
expect(
|
35
|
+
expect(users_relation.by_name).to respond_to(:dataset)
|
37
36
|
end
|
38
37
|
|
39
38
|
it 'returns false if wrapped relation does not respond to a method' do
|
40
|
-
expect(
|
39
|
+
expect(users_relation.by_name).not_to respond_to(:not_here)
|
41
40
|
end
|
42
41
|
end
|
43
42
|
|
44
43
|
describe '#method_missing' do
|
45
44
|
it 'forwards to the relation' do
|
46
|
-
expect(
|
45
|
+
expect(users_relation.by_name.dataset).to eql(users_relation.dataset)
|
47
46
|
end
|
48
47
|
|
49
48
|
it 'does not forward to the relation when method is auto-curried' do
|
50
|
-
expect {
|
49
|
+
expect { users_relation.by_name.find }.to raise_error(NoMethodError, /find/)
|
51
50
|
end
|
52
51
|
end
|
53
52
|
end
|
@@ -1,36 +1,36 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe ROM::Relation::Graph do
|
4
|
-
|
5
|
-
|
4
|
+
include_context 'gateway only'
|
6
5
|
include_context 'users and tasks'
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
T(:combine, [[:tasks, name: :name]])
|
11
|
-
end
|
12
|
-
|
13
|
-
let(:relation) do
|
14
|
-
ROM::Relation::Graph.new(users.by_name('Jane'), [tasks.for_users]) >> mapper
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
before do
|
19
|
-
setup.relation(:users) do
|
7
|
+
let(:users_relation) do
|
8
|
+
Class.new(ROM::Memory::Relation) do
|
20
9
|
def by_name(name)
|
21
10
|
restrict(name: name)
|
22
11
|
end
|
23
|
-
end
|
12
|
+
end.new(users_dataset)
|
13
|
+
end
|
24
14
|
|
25
|
-
|
15
|
+
let(:tasks_relation) do
|
16
|
+
Class.new(ROM::Memory::Relation) do
|
26
17
|
def for_users(_users)
|
27
18
|
self
|
28
19
|
end
|
29
|
-
end
|
20
|
+
end.new(tasks_dataset)
|
30
21
|
end
|
31
22
|
|
32
|
-
|
33
|
-
|
23
|
+
subject(:graph) { ROM::Relation::Graph.new(users_relation, [tasks_relation.for_users]) }
|
24
|
+
|
25
|
+
it_behaves_like 'materializable relation' do
|
26
|
+
let(:mapper) do
|
27
|
+
T(:combine, [[:tasks, name: :name]])
|
28
|
+
end
|
29
|
+
|
30
|
+
let(:relation) do
|
31
|
+
ROM::Relation::Graph.new(users_relation.by_name('Jane'), [tasks_relation.for_users]) >> mapper
|
32
|
+
end
|
33
|
+
end
|
34
34
|
|
35
35
|
describe '#method_missing' do
|
36
36
|
it 'responds to the root methods' do
|
@@ -42,11 +42,11 @@ describe ROM::Relation::Graph do
|
|
42
42
|
end
|
43
43
|
|
44
44
|
it 'forwards methods to the root and decorates curried response' do
|
45
|
-
expect((
|
45
|
+
expect((users_relation.combine(tasks_relation.for_users)).by_name).to be_instance_of(ROM::Relation::Graph)
|
46
46
|
end
|
47
47
|
|
48
48
|
it 'returns original response from the root' do
|
49
|
-
expect(graph.mappers).to eql(
|
49
|
+
expect(graph.mappers).to eql(users_relation.mappers)
|
50
50
|
end
|
51
51
|
|
52
52
|
it 'raises method error' do
|
@@ -57,8 +57,8 @@ describe ROM::Relation::Graph do
|
|
57
57
|
describe '#call' do
|
58
58
|
it 'materializes relations' do
|
59
59
|
expect(graph.call).to match_array([
|
60
|
-
|
61
|
-
[
|
60
|
+
users_relation,
|
61
|
+
[tasks_relation]
|
62
62
|
])
|
63
63
|
end
|
64
64
|
end
|
@@ -66,16 +66,16 @@ describe ROM::Relation::Graph do
|
|
66
66
|
describe '#to_a' do
|
67
67
|
it 'coerces to an array' do
|
68
68
|
expect(graph).to match_array([
|
69
|
-
|
70
|
-
[
|
69
|
+
users_relation.to_a,
|
70
|
+
[tasks_relation.for_users(users_relation).to_a]
|
71
71
|
])
|
72
72
|
end
|
73
73
|
|
74
74
|
it 'returns empty arrays when left was empty' do
|
75
|
-
graph = ROM::Relation::Graph.new(
|
75
|
+
graph = ROM::Relation::Graph.new(users_relation.by_name('Not here'), [tasks_relation.for_users])
|
76
76
|
|
77
77
|
expect(graph).to match_array([
|
78
|
-
[], [ROM::Relation::Loaded.new(
|
78
|
+
[], [ROM::Relation::Loaded.new(tasks_relation.for_users, [])]
|
79
79
|
])
|
80
80
|
end
|
81
81
|
end
|
@@ -1,23 +1,31 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe ROM::Relation, '#combine' do
|
4
|
+
include_context 'gateway only'
|
4
5
|
include_context 'users and tasks'
|
5
6
|
|
6
|
-
|
7
|
-
|
7
|
+
let(:tags_dataset) { gateway.dataset(:tags) }
|
8
|
+
|
9
|
+
let(:users_relation) do
|
10
|
+
Class.new(ROM::Memory::Relation) do
|
8
11
|
def by_name(name)
|
9
12
|
restrict(name: name)
|
10
13
|
end
|
11
|
-
end
|
14
|
+
end.new(users_dataset)
|
15
|
+
end
|
12
16
|
|
13
|
-
|
17
|
+
let(:tasks_relation) do
|
18
|
+
Class.new(ROM::Memory::Relation) do
|
14
19
|
def for_users(users)
|
15
20
|
names = users.map { |user| user[:name] }
|
16
21
|
restrict { |task| names.include?(task[:name]) }
|
17
22
|
end
|
18
|
-
end
|
23
|
+
end.new(tasks_dataset)
|
24
|
+
end
|
19
25
|
|
20
|
-
|
26
|
+
let(:tags_relation) do
|
27
|
+
Class.new(ROM::Memory::Relation) do
|
28
|
+
attr_accessor :tasks
|
21
29
|
forward :map
|
22
30
|
|
23
31
|
def for_tasks(tasks)
|
@@ -34,15 +42,13 @@ describe ROM::Relation, '#combine' do
|
|
34
42
|
} [:name])
|
35
43
|
}
|
36
44
|
end
|
37
|
-
end
|
38
|
-
|
39
|
-
setup.gateways[:default].dataset(:tags).insert(task: 'be cool', name: 'red')
|
40
|
-
setup.gateways[:default].dataset(:tags).insert(task: 'be cool', name: 'green')
|
45
|
+
end.new(tags_dataset).tap { |r| r.tasks = tasks_relation }
|
41
46
|
end
|
42
47
|
|
43
|
-
|
44
|
-
|
45
|
-
|
48
|
+
before do
|
49
|
+
tags_dataset.insert(task: 'be cool', name: 'red')
|
50
|
+
tags_dataset.insert(task: 'be cool', name: 'green')
|
51
|
+
end
|
46
52
|
|
47
53
|
let(:map_users) {
|
48
54
|
proc { |users, tasks|
|
@@ -87,7 +93,7 @@ describe ROM::Relation, '#combine' do
|
|
87
93
|
|
88
94
|
it 'raises error when composite relation is passed as a node' do
|
89
95
|
expect {
|
90
|
-
|
96
|
+
users_relation.combine(tasks_relation >> proc {})
|
91
97
|
}.to raise_error(ROM::UnsupportedRelationError)
|
92
98
|
end
|
93
99
|
|
@@ -106,8 +112,8 @@ describe ROM::Relation, '#combine' do
|
|
106
112
|
}
|
107
113
|
]
|
108
114
|
|
109
|
-
user_with_tasks_and_tags =
|
110
|
-
.combine(
|
115
|
+
user_with_tasks_and_tags = users_relation.by_name('Jane')
|
116
|
+
.combine(tasks_relation.for_users, tags_relation.for_users)
|
111
117
|
|
112
118
|
result = user_with_tasks_and_tags >> map_user_with_tasks_and_tags
|
113
119
|
|
@@ -129,8 +135,8 @@ describe ROM::Relation, '#combine' do
|
|
129
135
|
}
|
130
136
|
]
|
131
137
|
|
132
|
-
user_with_tasks_and_tags =
|
133
|
-
.combine(
|
138
|
+
user_with_tasks_and_tags = users_relation.by_name('Jane')
|
139
|
+
.combine(tasks_relation.for_users).combine(tags_relation.for_users)
|
134
140
|
|
135
141
|
result = user_with_tasks_and_tags >> map_user_with_tasks_and_tags
|
136
142
|
|
@@ -149,8 +155,8 @@ describe ROM::Relation, '#combine' do
|
|
149
155
|
}
|
150
156
|
]
|
151
157
|
|
152
|
-
user_with_tasks =
|
153
|
-
.combine(
|
158
|
+
user_with_tasks = users_relation.by_name('Jane')
|
159
|
+
.combine(tasks_relation.for_users.combine(tags_relation.for_tasks))
|
154
160
|
|
155
161
|
result = user_with_tasks >> map_user_with_tasks
|
156
162
|
|
@@ -1,13 +1,11 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe ROM::Relation do
|
4
|
+
include_context 'gateway only'
|
4
5
|
include_context 'users and tasks'
|
5
6
|
|
6
|
-
let(:
|
7
|
-
|
8
|
-
|
9
|
-
before do
|
10
|
-
setup.relation(:users) do
|
7
|
+
let(:users_relation) do
|
8
|
+
Class.new(ROM::Memory::Relation) do
|
11
9
|
def by_name(name)
|
12
10
|
restrict(name: name)
|
13
11
|
end
|
@@ -35,31 +33,33 @@ describe ROM::Relation do
|
|
35
33
|
self
|
36
34
|
end
|
37
35
|
end
|
38
|
-
end
|
36
|
+
end.new(users_dataset)
|
37
|
+
end
|
39
38
|
|
40
|
-
|
39
|
+
let(:tasks_relation) do
|
40
|
+
Class.new(ROM::Memory::Relation) do
|
41
41
|
def for_users(users)
|
42
42
|
names = users.map { |u| u[:name] }
|
43
43
|
restrict { |t| names.include?(t[:name]) }
|
44
44
|
end
|
45
|
-
end
|
45
|
+
end.new(tasks_dataset)
|
46
46
|
end
|
47
47
|
|
48
48
|
it_behaves_like 'a relation that returns one tuple' do
|
49
|
-
let(:relation) {
|
49
|
+
let(:relation) { users_relation }
|
50
50
|
end
|
51
51
|
|
52
52
|
describe '#map_with' do
|
53
53
|
it 'raises error when unknown mapper was selected' do
|
54
54
|
expect {
|
55
|
-
|
55
|
+
users_relation.as(:not_here)
|
56
56
|
}.to raise_error(ROM::MapperMissingError, /not_here/)
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
60
|
describe '#method_missing' do
|
61
61
|
it 'forwards to relation and auto-curries' do
|
62
|
-
relation =
|
62
|
+
relation = users_relation.by_name_and_email_sorted('Jane')
|
63
63
|
|
64
64
|
expect(relation.name).to eql(:by_name_and_email_sorted)
|
65
65
|
expect(relation.curry_args).to eql(['Jane'])
|
@@ -70,46 +70,46 @@ describe ROM::Relation do
|
|
70
70
|
expect(relation.curry_args).to eql(['Jane', 'jane@doe.org'])
|
71
71
|
|
72
72
|
expect(relation[:email]).to match_array(
|
73
|
-
|
73
|
+
users_relation.by_name_and_email_sorted('Jane', 'jane@doe.org', :email)
|
74
74
|
)
|
75
75
|
end
|
76
76
|
|
77
77
|
it 'forwards to relation and does not auto-curry when it is not needed' do
|
78
|
-
relation =
|
78
|
+
relation = users_relation.by_name('Jane')
|
79
79
|
|
80
80
|
expect(relation).to_not be_curried
|
81
|
-
expect(relation).to match_array(
|
81
|
+
expect(relation).to match_array(users_relation.by_name('Jane'))
|
82
82
|
end
|
83
83
|
|
84
84
|
it 'forwards to relation and return lazy when arity is unknown' do
|
85
|
-
relation =
|
85
|
+
relation = users_relation.all(name: 'Jane')
|
86
86
|
expect(relation).to_not be_curried
|
87
|
-
expect(relation).to match_array(
|
87
|
+
expect(relation).to match_array(users_relation.by_name('Jane').to_a)
|
88
88
|
end
|
89
89
|
|
90
90
|
it 'returns original response if it is not a relation' do
|
91
|
-
expect(
|
91
|
+
expect(users_relation.gateway).to be(:default)
|
92
92
|
end
|
93
93
|
|
94
94
|
it 'raises NoMethodError when relation does not respond to a method' do
|
95
|
-
expect {
|
95
|
+
expect { users_relation.not_here }.to raise_error(NoMethodError, /not_here/)
|
96
96
|
end
|
97
97
|
end
|
98
98
|
|
99
99
|
describe '#call' do
|
100
100
|
it 'auto-curries' do
|
101
|
-
relation =
|
101
|
+
relation = users_relation.by_name
|
102
102
|
|
103
103
|
expect(relation.name).to eql(:by_name)
|
104
|
-
expect(relation['Jane'].to_a).to eql(
|
104
|
+
expect(relation['Jane'].to_a).to eql(users_relation.by_name('Jane').to_a)
|
105
105
|
end
|
106
106
|
|
107
107
|
it 'returns relation' do
|
108
|
-
expect(
|
108
|
+
expect(users_relation.call.to_a).to eql(users_relation.to_a)
|
109
109
|
end
|
110
110
|
|
111
111
|
describe 'using mappers' do
|
112
|
-
subject(:users) {
|
112
|
+
subject(:users) { users_relation.with(mappers: mappers) }
|
113
113
|
|
114
114
|
let(:name_list) { proc { |r| r.map { |t| t[:name] } } }
|
115
115
|
let(:upcaser) { proc { |r| r.map(&:upcase) } }
|
@@ -125,24 +125,24 @@ describe ROM::Relation do
|
|
125
125
|
|
126
126
|
describe '#first' do
|
127
127
|
it 'return first tuple' do
|
128
|
-
expect(
|
128
|
+
expect(users_relation.first).to eql(name: 'Joe', email: 'joe@doe.org')
|
129
129
|
end
|
130
130
|
|
131
131
|
it 'raises when relation is curried and arity does not match' do
|
132
|
-
expect {
|
133
|
-
ArgumentError,
|
132
|
+
expect { users_relation.by_name.first }.to raise_error(
|
133
|
+
ArgumentError, "#{users_relation.class.to_s}#by_name arity is 1 (0 args given)"
|
134
134
|
)
|
135
135
|
end
|
136
136
|
|
137
137
|
it 'does not raise when relation is curried and arity matches' do
|
138
|
-
expect {
|
138
|
+
expect { users_relation.by_name_sorted('Joe').first }.to_not raise_error
|
139
139
|
end
|
140
140
|
end
|
141
141
|
|
142
142
|
describe '#each' do
|
143
143
|
it 'yields relation tuples' do
|
144
144
|
result = []
|
145
|
-
|
145
|
+
users_relation.each do |tuple|
|
146
146
|
result << tuple
|
147
147
|
end
|
148
148
|
expect(result).to match_array([
|
@@ -152,45 +152,45 @@ describe ROM::Relation do
|
|
152
152
|
end
|
153
153
|
|
154
154
|
it 'returns an enumerator if block is not provided' do
|
155
|
-
expect(
|
155
|
+
expect(users_relation.each.to_a).to match_array([
|
156
156
|
{ name: 'Jane', email: 'jane@doe.org' },
|
157
157
|
{ name: 'Joe', email: 'joe@doe.org' }
|
158
158
|
])
|
159
159
|
end
|
160
160
|
|
161
161
|
it 'raises when relation is curried and arity does not match' do
|
162
|
-
expect {
|
163
|
-
ArgumentError,
|
162
|
+
expect { users_relation.by_name.each {} }.to raise_error(
|
163
|
+
ArgumentError, "#{users_relation.class.to_s}#by_name arity is 1 (0 args given)"
|
164
164
|
)
|
165
165
|
end
|
166
166
|
|
167
167
|
it 'does not raise when relation is curried and arity matches' do
|
168
|
-
expect {
|
168
|
+
expect { users_relation.by_name_sorted('Jane').first }.to_not raise_error
|
169
169
|
end
|
170
170
|
end
|
171
171
|
|
172
172
|
describe '#to_ary' do
|
173
173
|
it 'returns an array with relation tuples' do
|
174
|
-
expect(
|
174
|
+
expect(users_relation.to_ary).to match_array([
|
175
175
|
{ name: 'Jane', email: 'jane@doe.org' },
|
176
176
|
{ name: 'Joe', email: 'joe@doe.org' }
|
177
177
|
])
|
178
178
|
end
|
179
179
|
|
180
180
|
it 'raises when relation is curried and arity does not match' do
|
181
|
-
expect {
|
182
|
-
ArgumentError,
|
181
|
+
expect { users_relation.by_name.to_ary }.to raise_error(
|
182
|
+
ArgumentError, "#{users_relation.class.to_s}#by_name arity is 1 (0 args given)"
|
183
183
|
)
|
184
184
|
end
|
185
185
|
|
186
186
|
it 'does not raise when relation is curried and arity matches' do
|
187
|
-
expect {
|
187
|
+
expect { users_relation.by_name_sorted('Jane').first }.to_not raise_error
|
188
188
|
end
|
189
189
|
end
|
190
190
|
|
191
191
|
describe '#>>' do
|
192
192
|
it 'composes two relations' do
|
193
|
-
other =
|
193
|
+
other = users_relation.by_name('Jane') >> tasks_relation.for_users
|
194
194
|
|
195
195
|
expect(other).to match_array([
|
196
196
|
{ name: 'Jane', title: 'be cool', priority: 2 }
|
@@ -198,12 +198,12 @@ describe ROM::Relation do
|
|
198
198
|
end
|
199
199
|
|
200
200
|
it_behaves_like 'a relation that returns one tuple' do
|
201
|
-
let(:relation) {
|
201
|
+
let(:relation) { users_relation >> proc { |r| r } }
|
202
202
|
|
203
203
|
describe 'using a mapper' do
|
204
204
|
it 'returns one mapped tuple' do
|
205
205
|
mapper = proc { |r| r.map { |t| t[:name].upcase } }
|
206
|
-
relation =
|
206
|
+
relation = users_relation.by_name('Jane') >> mapper
|
207
207
|
|
208
208
|
expect(relation.one).to eql('JANE')
|
209
209
|
expect(relation.one!).to eql('JANE')
|