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
@@ -11,4 +11,60 @@ describe ROM::Commands::Result do
|
|
11
11
|
expect(r.value).to eq(data)
|
12
12
|
end
|
13
13
|
end
|
14
|
+
|
15
|
+
describe '#success?' do
|
16
|
+
context 'not launched command' do
|
17
|
+
subject(:command) { ROM::Commands::Result }
|
18
|
+
|
19
|
+
it 'returns false' do
|
20
|
+
expect(command.new.success?).to eq(false)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'successful command' do
|
25
|
+
subject(:result) { ROM::Commands::Result::Success }
|
26
|
+
|
27
|
+
it 'returns true' do
|
28
|
+
data = double(to_ary: ['foo'])
|
29
|
+
expect(result.new(data).success?).to eq(true)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'failed command' do
|
34
|
+
subject(:result) { ROM::Commands::Result::Failure }
|
35
|
+
|
36
|
+
it 'returns false' do
|
37
|
+
error = double(:error)
|
38
|
+
expect(result.new(error).success?).to eq(false)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '#failure?' do
|
44
|
+
context 'not launched command' do
|
45
|
+
subject(:command) { ROM::Commands::Result }
|
46
|
+
|
47
|
+
it 'returns false' do
|
48
|
+
expect(command.new.success?).to eq(false)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'successful command' do
|
53
|
+
subject(:result) { ROM::Commands::Result::Success }
|
54
|
+
|
55
|
+
it 'returns false' do
|
56
|
+
data = double(to_ary: ['foo'])
|
57
|
+
expect(result.new(data).failure?).to eq(false)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'failed command' do
|
62
|
+
subject(:result) { ROM::Commands::Result::Failure }
|
63
|
+
|
64
|
+
it 'returns true' do
|
65
|
+
error = double(:error)
|
66
|
+
expect(result.new(error).failure?).to eq(true)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
14
70
|
end
|
@@ -1,21 +1,20 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe 'Commands' 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_id(id)
|
11
10
|
restrict(id: id)
|
12
11
|
end
|
13
|
-
end
|
12
|
+
end.new(users_dataset)
|
14
13
|
end
|
15
14
|
|
16
15
|
describe '.build_class' do
|
17
16
|
it 'creates a command class constant' do
|
18
|
-
klass = ROM::Command.build_class(:create, :users, adapter: :memory) {
|
17
|
+
klass = ROM::ConfigurationDSL::Command.build_class(:create, :users, adapter: :memory) {
|
19
18
|
def super?
|
20
19
|
true
|
21
20
|
end
|
@@ -24,7 +23,7 @@ describe 'Commands' do
|
|
24
23
|
expect(klass.name).to eql('ROM::Memory::Commands::Create[Users]')
|
25
24
|
expect(klass.register_as).to eql(:create)
|
26
25
|
|
27
|
-
command = klass.build(
|
26
|
+
command = klass.build(users_relation)
|
28
27
|
|
29
28
|
expect(command).to be_a(ROM::Memory::Commands::Create)
|
30
29
|
expect(command).to be_super
|
@@ -37,7 +36,7 @@ describe 'Commands' do
|
|
37
36
|
relation :users
|
38
37
|
end
|
39
38
|
|
40
|
-
command = klass.build(
|
39
|
+
command = klass.build(users_relation)
|
41
40
|
|
42
41
|
expect(command).to be_kind_of(ROM::Memory::Commands::Create)
|
43
42
|
end
|
@@ -47,7 +46,7 @@ describe 'Commands' do
|
|
47
46
|
relation :users
|
48
47
|
end
|
49
48
|
|
50
|
-
command = klass.build(
|
49
|
+
command = klass.build(users_relation)
|
51
50
|
|
52
51
|
expect(command).to be_kind_of(ROM::Memory::Commands::Update)
|
53
52
|
end
|
@@ -57,63 +56,10 @@ describe 'Commands' do
|
|
57
56
|
relation :users
|
58
57
|
end
|
59
58
|
|
60
|
-
command = klass.build(
|
59
|
+
command = klass.build(users_relation)
|
61
60
|
|
62
61
|
expect(command).to be_kind_of(ROM::Memory::Commands::Delete)
|
63
62
|
end
|
64
|
-
|
65
|
-
describe 'extending command with a db-specific behavior' do
|
66
|
-
before do
|
67
|
-
setup.gateways[:default].instance_exec do
|
68
|
-
def extend_command_class(klass, _)
|
69
|
-
klass.class_eval do
|
70
|
-
def super_command?
|
71
|
-
true
|
72
|
-
end
|
73
|
-
end
|
74
|
-
klass
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
it 'applies to defined classes' do
|
80
|
-
klass = Class.new(ROM::Commands::Create[:memory]) { relation :users }
|
81
|
-
command = klass.build(users)
|
82
|
-
expect(command).to be_super_command
|
83
|
-
end
|
84
|
-
|
85
|
-
it 'applies to generated classes' do
|
86
|
-
klass = ROM::Command.build_class(:create, :users, adapter: :memory)
|
87
|
-
command = klass.build(users)
|
88
|
-
expect(command).to be_super_command
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
describe '.registry' do
|
94
|
-
it 'builds a hash with commands grouped by relations' do
|
95
|
-
commands = {}
|
96
|
-
|
97
|
-
[:Create, :Update, :Delete].each do |command_type|
|
98
|
-
klass = Class.new(ROM::Commands.const_get(command_type)) do
|
99
|
-
relation :users
|
100
|
-
end
|
101
|
-
klass.class_eval "def self.name; 'Test::#{command_type}'; end"
|
102
|
-
commands[command_type] = klass
|
103
|
-
end
|
104
|
-
|
105
|
-
registry = ROM::Command.registry(
|
106
|
-
rom.relations, setup.gateways, commands.values
|
107
|
-
)
|
108
|
-
|
109
|
-
expect(registry).to eql(
|
110
|
-
users: {
|
111
|
-
create: commands[:Create].build(users),
|
112
|
-
update: commands[:Update].build(users),
|
113
|
-
delete: commands[:Delete].build(users)
|
114
|
-
}
|
115
|
-
)
|
116
|
-
end
|
117
63
|
end
|
118
64
|
|
119
65
|
describe '#>>' do
|
@@ -178,14 +124,4 @@ describe 'Commands' do
|
|
178
124
|
command.with(user_input).call
|
179
125
|
end
|
180
126
|
end
|
181
|
-
|
182
|
-
describe 'access to exposed relations' do
|
183
|
-
it 'exposes relation' do
|
184
|
-
command = ROM::Commands::Update[:memory].build(users)
|
185
|
-
|
186
|
-
users.insert(id: 1, name: 'Jane')
|
187
|
-
|
188
|
-
expect(command.by_id(1).relation).to eql(users.by_id(1))
|
189
|
-
end
|
190
|
-
end
|
191
127
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe ROM::Configurable do
|
4
|
+
let (:klass) { Class.new { include ROM::Configurable } }
|
5
|
+
let (:object) { klass.new }
|
6
|
+
let (:config) { object.config }
|
7
|
+
|
8
|
+
it 'exposes the config property' do
|
9
|
+
expect { config }.not_to raise_error
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'is configurable via block' do
|
13
|
+
object.configure do |config|
|
14
|
+
config.sql.infer_relations = false
|
15
|
+
end
|
16
|
+
|
17
|
+
expect(config.sql.infer_relations).to be(false)
|
18
|
+
end
|
19
|
+
|
20
|
+
context ROM::Configurable::Config do
|
21
|
+
it 'can be traversed via dot syntax' do
|
22
|
+
config.sql.infer_relations = false
|
23
|
+
expect(config.sql.infer_relations).to be(false)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'can be traversed via bracket syntax' do
|
27
|
+
config[:sql].infer_relations = false
|
28
|
+
|
29
|
+
expect(config[:sql][:infer_relations]).to be(false)
|
30
|
+
expect(config).to respond_to(:sql)
|
31
|
+
expect(config.sql.infer_relations).to be(false)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'freezes properly' do
|
35
|
+
config.freeze
|
36
|
+
|
37
|
+
expect { config.sql.infer_relations = false }.to raise_error(NoMethodError)
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'handles unset keys when frozen' do
|
41
|
+
config.sql.infer_relations = false
|
42
|
+
config.freeze
|
43
|
+
|
44
|
+
expect(config.other).to be(nil)
|
45
|
+
expect(config.key?(:other)).to be(false)
|
46
|
+
expect(config.key?(:sql)).to be(true)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ROM::Configuration do
|
4
|
+
it 'is configurable via settings hash' do
|
5
|
+
configuration = ROM::Configuration.new(:memory, 'something', infer_schema: false)
|
6
|
+
|
7
|
+
expect(configuration.config.gateways.default.infer_schema).to be(false)
|
8
|
+
|
9
|
+
configuration = ROM::Configuration.new(:memory, infer_schema: false)
|
10
|
+
|
11
|
+
expect(configuration.config.gateways.default.infer_schema).to be(false)
|
12
|
+
|
13
|
+
configuration = ROM::Configuration.new(default: [:memory, infer_schema: false])
|
14
|
+
|
15
|
+
expect(configuration.config.gateways.default.infer_schema).to be(false)
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#method_missing' do
|
19
|
+
it 'returns a gateway if it is defined' do
|
20
|
+
repo = double('repo')
|
21
|
+
configuration = ROM::Configuration.new(repo: repo)
|
22
|
+
|
23
|
+
expect(configuration.repo).to be(repo)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'raises error if repo is not defined' do
|
27
|
+
configuration = ROM::Configuration.new
|
28
|
+
|
29
|
+
expect { configuration.not_here }.to raise_error(NoMethodError, /not_here/)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#[]' do
|
34
|
+
it 'returns a gateway if it is defined' do
|
35
|
+
repo = double('repo')
|
36
|
+
configuration = ROM::Configuration.new(repo: repo)
|
37
|
+
|
38
|
+
expect(configuration[:repo]).to be(repo)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'raises error if repo is not defined' do
|
42
|
+
configuration = ROM::Configuration.new({})
|
43
|
+
|
44
|
+
expect { configuration[:not_here] }.to raise_error(KeyError, /not_here/)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe 'defining components when adapter was not registered' do
|
49
|
+
it 'raises error when trying to define a relation' do
|
50
|
+
expect {
|
51
|
+
Class.new(ROM::Relation[:not_here])
|
52
|
+
}.to raise_error(ROM::AdapterNotPresentError, /not_here/)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'raises error when trying to define a command' do
|
56
|
+
expect {
|
57
|
+
Class.new(ROM::Commands::Create[:not_here])
|
58
|
+
}.to raise_error(ROM::AdapterNotPresentError, /not_here/)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -1,87 +1,93 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe ROM::Container do
|
4
|
+
include_context 'container'
|
4
5
|
include_context 'users and tasks'
|
5
6
|
|
6
7
|
before do
|
7
|
-
|
8
|
+
configuration
|
9
|
+
|
10
|
+
users = Class.new(ROM::Relation[:memory]) do
|
11
|
+
register_as :users
|
12
|
+
dataset :users
|
8
13
|
def by_name(name)
|
9
14
|
restrict(name: name).project(:name)
|
10
15
|
end
|
11
16
|
end
|
12
17
|
|
13
|
-
|
18
|
+
tasks = Class.new(ROM::Relation[:memory]) do
|
19
|
+
register_as :tasks
|
20
|
+
dataset :tasks
|
21
|
+
end
|
14
22
|
|
15
|
-
|
16
|
-
|
23
|
+
create_user = Class.new(ROM::Commands::Create[:memory]) do
|
24
|
+
relation :users
|
25
|
+
register_as :create
|
17
26
|
end
|
18
27
|
|
19
|
-
|
20
|
-
|
28
|
+
create_task = Class.new(ROM::Commands::Create[:memory]) do
|
29
|
+
relation :tasks
|
30
|
+
register_as :create
|
21
31
|
end
|
22
32
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
33
|
+
users_mapper = Class.new(ROM::Mapper) do
|
34
|
+
register_as :users
|
35
|
+
relation :users
|
36
|
+
attribute :name
|
37
|
+
attribute :email
|
38
|
+
end
|
28
39
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
40
|
+
name_list = Class.new(users_mapper) do
|
41
|
+
register_as :name_list
|
42
|
+
attribute :name
|
43
|
+
exclude :email
|
33
44
|
end
|
45
|
+
|
46
|
+
configuration.register_relation(users, tasks)
|
47
|
+
configuration.register_command(create_user, create_task)
|
48
|
+
configuration.register_mapper(users_mapper, name_list)
|
34
49
|
end
|
35
50
|
|
36
51
|
describe '#command' do
|
37
52
|
it 'returns registered command registry' do
|
38
|
-
expect(
|
53
|
+
expect(container.command(:users)).to be_instance_of(ROM::CommandRegistry)
|
39
54
|
end
|
40
55
|
|
41
56
|
it 'returns registered command' do
|
42
|
-
expect(
|
57
|
+
expect(container.command(:users).create).to be_kind_of(ROM::Commands::Create)
|
43
58
|
end
|
44
59
|
|
45
60
|
it 'accepts an array with graph options and input' do
|
46
|
-
expect(
|
61
|
+
expect(container.command([:users, [:create]])).to be_kind_of(ROM::Commands::Lazy)
|
47
62
|
end
|
48
63
|
|
49
64
|
it 'raises ArgumentError when unsupported arg was passed' do
|
50
|
-
expect {
|
65
|
+
expect { container.command(oops: 'sorry') }.to raise_error(ArgumentError)
|
51
66
|
end
|
52
67
|
end
|
53
68
|
|
54
69
|
describe '#relation' do
|
55
70
|
it 'yields selected relation to the block and returns a loaded relation' do
|
56
|
-
result =
|
71
|
+
result = container.relation(:users) { |r| r.by_name('Jane') }.as(:name_list)
|
57
72
|
|
58
73
|
expect(result.call).to match_array([{ name: 'Jane' }])
|
59
74
|
end
|
60
75
|
|
61
76
|
it 'returns lazy-mapped relation' do
|
62
|
-
by_name =
|
77
|
+
by_name = container.relation(:users).as(:name_list).by_name
|
63
78
|
|
64
79
|
expect(by_name['Jane']).to match_array([{ name: 'Jane' }])
|
65
80
|
end
|
66
81
|
|
67
82
|
it 'returns relation without mappers when mappers are not defined' do
|
68
|
-
expect(
|
69
|
-
expect(
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
describe '#read' do
|
74
|
-
it 'returns loaded relation and display a deprecation warning' do
|
75
|
-
expect {
|
76
|
-
result = rom.read(:users) { |r| r.by_name('Jane') }.as(:name_list)
|
77
|
-
expect(result.call).to match_array([{ name: 'Jane' }])
|
78
|
-
}.to output(/^ROM::Container#read is deprecated/).to_stderr
|
83
|
+
expect(container.relation(:tasks)).to be_kind_of(ROM::Relation)
|
84
|
+
expect(container.relation(:tasks).mappers.elements).to be_empty
|
79
85
|
end
|
80
86
|
end
|
81
87
|
|
82
88
|
describe '#mappers' do
|
83
89
|
it 'returns mappers for all relations' do
|
84
|
-
expect(
|
90
|
+
expect(container.mappers.users[:name_list]).to_not be(nil)
|
85
91
|
end
|
86
92
|
end
|
87
93
|
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ROM::CreateContainer do
|
4
|
+
describe '#finalize' do
|
5
|
+
include_context 'container'
|
6
|
+
|
7
|
+
context 'with gateway that supports schema inferring' do
|
8
|
+
it 'builds relation from inferred schema' do
|
9
|
+
repo = configuration.gateways[:default]
|
10
|
+
dataset = double('dataset')
|
11
|
+
|
12
|
+
allow(repo).to receive(:schema).and_return([:users])
|
13
|
+
allow(repo).to receive(:dataset).with(:users).and_return(dataset)
|
14
|
+
|
15
|
+
expect(container.relations.users.dataset).to be(dataset)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'skips inferring a relation when there is a defined one already' do
|
19
|
+
repo = configuration.gateways[:default]
|
20
|
+
dataset_double = double('dataset')
|
21
|
+
|
22
|
+
allow(repo).to receive(:schema).and_return([:users])
|
23
|
+
allow(repo).to receive(:dataset).with(:users).and_return(dataset_double)
|
24
|
+
|
25
|
+
users = Class.new(ROM::Relation[:memory]) do
|
26
|
+
register_as :users
|
27
|
+
dataset :users
|
28
|
+
end
|
29
|
+
|
30
|
+
configuration.register_relation(users)
|
31
|
+
|
32
|
+
expect { container }.not_to raise_error
|
33
|
+
|
34
|
+
expect(container.relations.users).to be_instance_of(users)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'skips inferring when it is turned off for the adapter' do
|
38
|
+
configuration.config.gateways.default.infer_relations = false
|
39
|
+
|
40
|
+
repo = configuration.default
|
41
|
+
|
42
|
+
expect(repo).not_to receive(:schema)
|
43
|
+
|
44
|
+
container
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'infers configured relations' do
|
48
|
+
configuration.config.gateways.default.inferrable_relations = [:test_tasks]
|
49
|
+
|
50
|
+
repo = configuration.default
|
51
|
+
dataset = double('dataset')
|
52
|
+
|
53
|
+
allow(repo).to receive(:schema).and_return([:test_tasks, :test_users])
|
54
|
+
|
55
|
+
expect(repo).to receive(:dataset).with(:test_tasks).and_return(dataset)
|
56
|
+
expect(repo).to_not receive(:dataset).with(:test_users)
|
57
|
+
|
58
|
+
expect(container.relations.elements.key?(:test_users)).to be(false)
|
59
|
+
expect(container.relations[:test_tasks]).to be_kind_of(ROM::Memory::Relation)
|
60
|
+
expect(container.relations[:test_tasks].dataset).to be(dataset)
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'skip inferring blacklisted relations' do
|
64
|
+
configuration.config.gateways.default.not_inferrable_relations = [:test_users]
|
65
|
+
|
66
|
+
repo = configuration.default
|
67
|
+
dataset = double('dataset')
|
68
|
+
|
69
|
+
allow(repo).to receive(:schema).and_return([:test_tasks, :test_users])
|
70
|
+
|
71
|
+
expect(repo).to receive(:dataset).with(:test_tasks).and_return(dataset)
|
72
|
+
expect(repo).to_not receive(:dataset).with(:test_users)
|
73
|
+
|
74
|
+
expect(container.relations.elements.key?(:test_users)).to be(false)
|
75
|
+
expect(container.relations[:test_tasks]).to be_kind_of(ROM::Memory::Relation)
|
76
|
+
expect(container.relations[:test_tasks].dataset).to be(dataset)
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'can register multiple relations with same dataset' do
|
80
|
+
configuration
|
81
|
+
|
82
|
+
apples = Class.new(ROM::Relation[:memory]) do
|
83
|
+
dataset :fruits
|
84
|
+
register_as :apples
|
85
|
+
|
86
|
+
def apple?
|
87
|
+
true
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
oranges = Class.new(ROM::Relation[:memory]) do
|
92
|
+
dataset :fruits
|
93
|
+
register_as :oranges
|
94
|
+
|
95
|
+
def orange?
|
96
|
+
true
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
configuration.register_relation(apples)
|
101
|
+
configuration.register_relation(oranges)
|
102
|
+
|
103
|
+
expect(container.relations.apples).to be_apple
|
104
|
+
expect(container.relations.oranges).to be_orange
|
105
|
+
expect(container.relations.apples).to_not eq(container.relations.oranges)
|
106
|
+
end
|
107
|
+
|
108
|
+
it "raises an error when registering relations with the same `register_as`" do
|
109
|
+
configuration
|
110
|
+
|
111
|
+
users = Class.new(ROM::Relation[:memory]) do
|
112
|
+
dataset :guests
|
113
|
+
register_as :users
|
114
|
+
end
|
115
|
+
|
116
|
+
users2 = Class.new(ROM::Relation[:memory]) do
|
117
|
+
dataset :admins
|
118
|
+
register_as :users
|
119
|
+
end
|
120
|
+
|
121
|
+
configuration.register_relation(users)
|
122
|
+
configuration.register_relation(users2)
|
123
|
+
|
124
|
+
expect { container }.to raise_error(
|
125
|
+
ROM::RelationAlreadyDefinedError, /register_as :users/
|
126
|
+
)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context 'empty setup' do
|
131
|
+
let(:configuration) { ROM::Configuration.new({}) }
|
132
|
+
let(:container) { ROM.container(configuration) }
|
133
|
+
|
134
|
+
it 'builds empty gateways' do
|
135
|
+
expect(container.gateways).to eql({})
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'builds empty relations' do
|
139
|
+
expect(container.relations).to eql(ROM::RelationRegistry.new)
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'builds empty mappers' do
|
143
|
+
expect(container.mappers).to eql(ROM::Registry.new)
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'builds empty commands' do
|
147
|
+
expect(container.commands).to eql(ROM::Registry.new)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|