rom 3.2.2 → 3.2.3
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/CHANGELOG.md +21 -1
- data/Gemfile +1 -1
- data/README.md +72 -4
- data/lib/rom/auto_curry.rb +2 -2
- data/lib/rom/relation.rb +4 -1
- data/lib/rom/relation/graph.rb +6 -1
- data/lib/rom/setup/auto_registration.rb +3 -2
- data/lib/rom/setup/auto_registration_strategies/base.rb +1 -1
- data/lib/rom/setup/auto_registration_strategies/custom_namespace.rb +41 -1
- data/lib/rom/version.rb +1 -1
- data/spec/fixtures/custom_namespace/commands/create_customer.rb +8 -0
- data/spec/fixtures/custom_namespace/mappers/customer_list.rb +8 -0
- data/spec/fixtures/custom_namespace/relations/customers.rb +8 -0
- data/spec/fixtures/wrong/commands/create_customer.rb +8 -0
- data/spec/fixtures/wrong/mappers/customer_list.rb +8 -0
- data/spec/fixtures/wrong/relations/customers.rb +8 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/unit/rom/auto_curry_spec.rb +9 -1
- data/spec/unit/rom/relation/lazy/combine_spec.rb +4 -4
- data/spec/unit/rom/relation/lazy/graph_spec.rb +165 -0
- data/spec/unit/rom/setup/auto_registration_spec.rb +83 -21
- metadata +9 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0f727af1309d22c607fa43b3c26345749233dbef
|
|
4
|
+
data.tar.gz: 7a1d5142394e77da212457c8d656ca2d9d632759
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2b915a97368fd38abcaab1160d28bbc4aa5b218415fc58605fc8517d6149ca21f7ae749b383a5733e00d937b362dde5a0e61e3acfe65d98e0c847a6632982682
|
|
7
|
+
data.tar.gz: ca3d98f9a4446d108bc029aa6ee8da32a0185b52a6a2dd4ed007abf702fb7cf1a8d742b300db5d796ba2e141b3f90bc0608182198f7d64c3e4cfb90265d5c4a4
|
data/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,28 @@
|
|
|
1
|
+
# v3.2.3 2017-05-31
|
|
2
|
+
|
|
3
|
+
## Added
|
|
4
|
+
|
|
5
|
+
* auto-registration was improved with better handling of custom namespaces (Krule)
|
|
6
|
+
|
|
7
|
+
## Changed
|
|
8
|
+
|
|
9
|
+
* `Relation#combine` was deprecated in favor of `Relation#graph` (solnic)
|
|
10
|
+
|
|
11
|
+
[Compare v3.2.2...v3.2.3](https://github.com/rom-rb/rom/compare/v3.2.2...v3.2.3)
|
|
12
|
+
|
|
13
|
+
# v3.2.2 2017-05-05
|
|
14
|
+
|
|
15
|
+
## Changed
|
|
16
|
+
|
|
17
|
+
* [internal] Compatibility with `dry-core` v0.3.0 (flash-gordon)
|
|
18
|
+
|
|
19
|
+
[Compare v3.2.1...v3.2.2](https://github.com/rom-rb/rom/compare/v3.2.1...v3.2.2)
|
|
20
|
+
|
|
1
21
|
# v3.2.1 2017-05-02
|
|
2
22
|
|
|
3
23
|
## Changed
|
|
4
24
|
|
|
5
|
-
* `ROM::Schema::Attribute` uses `Initializer` now (flash-gordon)
|
|
25
|
+
* [internal] `ROM::Schema::Attribute` uses `Initializer` now (flash-gordon)
|
|
6
26
|
|
|
7
27
|
[Compare v3.2.0...v3.2.1](https://github.com/rom-rb/rom/compare/v3.2.0...v3.2.1)
|
|
8
28
|
|
data/Gemfile
CHANGED
|
@@ -24,7 +24,7 @@ group :test do
|
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
group :sql do
|
|
27
|
-
gem 'rom-sql', git: 'https://github.com/rom-rb/rom-sql.git', branch: '
|
|
27
|
+
gem 'rom-sql', git: 'https://github.com/rom-rb/rom-sql.git', branch: 'release-1.0'
|
|
28
28
|
gem 'sequel'
|
|
29
29
|
gem 'jdbc-sqlite3', platforms: :jruby
|
|
30
30
|
gem 'jdbc-postgres', platforms: :jruby
|
data/README.md
CHANGED
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
[][codeclimate]
|
|
14
14
|
[][codeclimate]
|
|
15
15
|
[][inchpages]
|
|
16
|
+
[](#backers)
|
|
17
|
+
[](#sponsors)
|
|
16
18
|
|
|
17
19
|
Ruby Object Mapper (ROM) is a data mapping and persistence toolkit for Ruby
|
|
18
20
|
with the goal to provide powerful object mapping capabilities without limiting
|
|
@@ -22,10 +24,76 @@ Learn more:
|
|
|
22
24
|
|
|
23
25
|
* [Introduction](http://rom-rb.org/learn/introduction)
|
|
24
26
|
* [Quick Start](http://rom-rb.org/learn/repositories/quick-start)
|
|
25
|
-
|
|
26
|
-
##
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
|
|
28
|
+
## Backers
|
|
29
|
+
|
|
30
|
+
Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/rom#backer)]
|
|
31
|
+
|
|
32
|
+
<a href="https://opencollective.com/rom/backer/0/website" target="_blank"><img src="https://opencollective.com/rom/backer/0/avatar.svg"></a>
|
|
33
|
+
<a href="https://opencollective.com/rom/backer/1/website" target="_blank"><img src="https://opencollective.com/rom/backer/1/avatar.svg"></a>
|
|
34
|
+
<a href="https://opencollective.com/rom/backer/2/website" target="_blank"><img src="https://opencollective.com/rom/backer/2/avatar.svg"></a>
|
|
35
|
+
<a href="https://opencollective.com/rom/backer/3/website" target="_blank"><img src="https://opencollective.com/rom/backer/3/avatar.svg"></a>
|
|
36
|
+
<a href="https://opencollective.com/rom/backer/4/website" target="_blank"><img src="https://opencollective.com/rom/backer/4/avatar.svg"></a>
|
|
37
|
+
<a href="https://opencollective.com/rom/backer/5/website" target="_blank"><img src="https://opencollective.com/rom/backer/5/avatar.svg"></a>
|
|
38
|
+
<a href="https://opencollective.com/rom/backer/6/website" target="_blank"><img src="https://opencollective.com/rom/backer/6/avatar.svg"></a>
|
|
39
|
+
<a href="https://opencollective.com/rom/backer/7/website" target="_blank"><img src="https://opencollective.com/rom/backer/7/avatar.svg"></a>
|
|
40
|
+
<a href="https://opencollective.com/rom/backer/8/website" target="_blank"><img src="https://opencollective.com/rom/backer/8/avatar.svg"></a>
|
|
41
|
+
<a href="https://opencollective.com/rom/backer/9/website" target="_blank"><img src="https://opencollective.com/rom/backer/9/avatar.svg"></a>
|
|
42
|
+
<a href="https://opencollective.com/rom/backer/10/website" target="_blank"><img src="https://opencollective.com/rom/backer/10/avatar.svg"></a>
|
|
43
|
+
<a href="https://opencollective.com/rom/backer/11/website" target="_blank"><img src="https://opencollective.com/rom/backer/11/avatar.svg"></a>
|
|
44
|
+
<a href="https://opencollective.com/rom/backer/12/website" target="_blank"><img src="https://opencollective.com/rom/backer/12/avatar.svg"></a>
|
|
45
|
+
<a href="https://opencollective.com/rom/backer/13/website" target="_blank"><img src="https://opencollective.com/rom/backer/13/avatar.svg"></a>
|
|
46
|
+
<a href="https://opencollective.com/rom/backer/14/website" target="_blank"><img src="https://opencollective.com/rom/backer/14/avatar.svg"></a>
|
|
47
|
+
<a href="https://opencollective.com/rom/backer/15/website" target="_blank"><img src="https://opencollective.com/rom/backer/15/avatar.svg"></a>
|
|
48
|
+
<a href="https://opencollective.com/rom/backer/16/website" target="_blank"><img src="https://opencollective.com/rom/backer/16/avatar.svg"></a>
|
|
49
|
+
<a href="https://opencollective.com/rom/backer/17/website" target="_blank"><img src="https://opencollective.com/rom/backer/17/avatar.svg"></a>
|
|
50
|
+
<a href="https://opencollective.com/rom/backer/18/website" target="_blank"><img src="https://opencollective.com/rom/backer/18/avatar.svg"></a>
|
|
51
|
+
<a href="https://opencollective.com/rom/backer/19/website" target="_blank"><img src="https://opencollective.com/rom/backer/19/avatar.svg"></a>
|
|
52
|
+
<a href="https://opencollective.com/rom/backer/20/website" target="_blank"><img src="https://opencollective.com/rom/backer/20/avatar.svg"></a>
|
|
53
|
+
<a href="https://opencollective.com/rom/backer/21/website" target="_blank"><img src="https://opencollective.com/rom/backer/21/avatar.svg"></a>
|
|
54
|
+
<a href="https://opencollective.com/rom/backer/22/website" target="_blank"><img src="https://opencollective.com/rom/backer/22/avatar.svg"></a>
|
|
55
|
+
<a href="https://opencollective.com/rom/backer/23/website" target="_blank"><img src="https://opencollective.com/rom/backer/23/avatar.svg"></a>
|
|
56
|
+
<a href="https://opencollective.com/rom/backer/24/website" target="_blank"><img src="https://opencollective.com/rom/backer/24/avatar.svg"></a>
|
|
57
|
+
<a href="https://opencollective.com/rom/backer/25/website" target="_blank"><img src="https://opencollective.com/rom/backer/25/avatar.svg"></a>
|
|
58
|
+
<a href="https://opencollective.com/rom/backer/26/website" target="_blank"><img src="https://opencollective.com/rom/backer/26/avatar.svg"></a>
|
|
59
|
+
<a href="https://opencollective.com/rom/backer/27/website" target="_blank"><img src="https://opencollective.com/rom/backer/27/avatar.svg"></a>
|
|
60
|
+
<a href="https://opencollective.com/rom/backer/28/website" target="_blank"><img src="https://opencollective.com/rom/backer/28/avatar.svg"></a>
|
|
61
|
+
<a href="https://opencollective.com/rom/backer/29/website" target="_blank"><img src="https://opencollective.com/rom/backer/29/avatar.svg"></a>
|
|
62
|
+
|
|
63
|
+
## Sponsors
|
|
64
|
+
|
|
65
|
+
Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/rom#sponsor)]
|
|
66
|
+
|
|
67
|
+
<a href="https://opencollective.com/rom/sponsor/0/website" target="_blank"><img src="https://opencollective.com/rom/sponsor/0/avatar.svg"></a>
|
|
68
|
+
<a href="https://opencollective.com/rom/sponsor/1/website" target="_blank"><img src="https://opencollective.com/rom/sponsor/1/avatar.svg"></a>
|
|
69
|
+
<a href="https://opencollective.com/rom/sponsor/2/website" target="_blank"><img src="https://opencollective.com/rom/sponsor/2/avatar.svg"></a>
|
|
70
|
+
<a href="https://opencollective.com/rom/sponsor/3/website" target="_blank"><img src="https://opencollective.com/rom/sponsor/3/avatar.svg"></a>
|
|
71
|
+
<a href="https://opencollective.com/rom/sponsor/4/website" target="_blank"><img src="https://opencollective.com/rom/sponsor/4/avatar.svg"></a>
|
|
72
|
+
<a href="https://opencollective.com/rom/sponsor/5/website" target="_blank"><img src="https://opencollective.com/rom/sponsor/5/avatar.svg"></a>
|
|
73
|
+
<a href="https://opencollective.com/rom/sponsor/6/website" target="_blank"><img src="https://opencollective.com/rom/sponsor/6/avatar.svg"></a>
|
|
74
|
+
<a href="https://opencollective.com/rom/sponsor/7/website" target="_blank"><img src="https://opencollective.com/rom/sponsor/7/avatar.svg"></a>
|
|
75
|
+
<a href="https://opencollective.com/rom/sponsor/8/website" target="_blank"><img src="https://opencollective.com/rom/sponsor/8/avatar.svg"></a>
|
|
76
|
+
<a href="https://opencollective.com/rom/sponsor/9/website" target="_blank"><img src="https://opencollective.com/rom/sponsor/9/avatar.svg"></a>
|
|
77
|
+
<a href="https://opencollective.com/rom/sponsor/10/website" target="_blank"><img src="https://opencollective.com/rom/sponsor/10/avatar.svg"></a>
|
|
78
|
+
<a href="https://opencollective.com/rom/sponsor/11/website" target="_blank"><img src="https://opencollective.com/rom/sponsor/11/avatar.svg"></a>
|
|
79
|
+
<a href="https://opencollective.com/rom/sponsor/12/website" target="_blank"><img src="https://opencollective.com/rom/sponsor/12/avatar.svg"></a>
|
|
80
|
+
<a href="https://opencollective.com/rom/sponsor/13/website" target="_blank"><img src="https://opencollective.com/rom/sponsor/13/avatar.svg"></a>
|
|
81
|
+
<a href="https://opencollective.com/rom/sponsor/14/website" target="_blank"><img src="https://opencollective.com/rom/sponsor/14/avatar.svg"></a>
|
|
82
|
+
<a href="https://opencollective.com/rom/sponsor/15/website" target="_blank"><img src="https://opencollective.com/rom/sponsor/15/avatar.svg"></a>
|
|
83
|
+
<a href="https://opencollective.com/rom/sponsor/16/website" target="_blank"><img src="https://opencollective.com/rom/sponsor/16/avatar.svg"></a>
|
|
84
|
+
<a href="https://opencollective.com/rom/sponsor/17/website" target="_blank"><img src="https://opencollective.com/rom/sponsor/17/avatar.svg"></a>
|
|
85
|
+
<a href="https://opencollective.com/rom/sponsor/18/website" target="_blank"><img src="https://opencollective.com/rom/sponsor/18/avatar.svg"></a>
|
|
86
|
+
<a href="https://opencollective.com/rom/sponsor/19/website" target="_blank"><img src="https://opencollective.com/rom/sponsor/19/avatar.svg"></a>
|
|
87
|
+
<a href="https://opencollective.com/rom/sponsor/20/website" target="_blank"><img src="https://opencollective.com/rom/sponsor/20/avatar.svg"></a>
|
|
88
|
+
<a href="https://opencollective.com/rom/sponsor/21/website" target="_blank"><img src="https://opencollective.com/rom/sponsor/21/avatar.svg"></a>
|
|
89
|
+
<a href="https://opencollective.com/rom/sponsor/22/website" target="_blank"><img src="https://opencollective.com/rom/sponsor/22/avatar.svg"></a>
|
|
90
|
+
<a href="https://opencollective.com/rom/sponsor/23/website" target="_blank"><img src="https://opencollective.com/rom/sponsor/23/avatar.svg"></a>
|
|
91
|
+
<a href="https://opencollective.com/rom/sponsor/24/website" target="_blank"><img src="https://opencollective.com/rom/sponsor/24/avatar.svg"></a>
|
|
92
|
+
<a href="https://opencollective.com/rom/sponsor/25/website" target="_blank"><img src="https://opencollective.com/rom/sponsor/25/avatar.svg"></a>
|
|
93
|
+
<a href="https://opencollective.com/rom/sponsor/26/website" target="_blank"><img src="https://opencollective.com/rom/sponsor/26/avatar.svg"></a>
|
|
94
|
+
<a href="https://opencollective.com/rom/sponsor/27/website" target="_blank"><img src="https://opencollective.com/rom/sponsor/27/avatar.svg"></a>
|
|
95
|
+
<a href="https://opencollective.com/rom/sponsor/28/website" target="_blank"><img src="https://opencollective.com/rom/sponsor/28/avatar.svg"></a>
|
|
96
|
+
<a href="https://opencollective.com/rom/sponsor/29/website" target="_blank"><img src="https://opencollective.com/rom/sponsor/29/avatar.svg"></a>
|
|
29
97
|
|
|
30
98
|
## Ecosystem
|
|
31
99
|
|
data/lib/rom/auto_curry.rb
CHANGED
|
@@ -31,10 +31,10 @@ module ROM
|
|
|
31
31
|
mod = Module.new
|
|
32
32
|
|
|
33
33
|
mod.module_eval do
|
|
34
|
-
define_method(name) do |*args|
|
|
34
|
+
define_method(name) do |*args, &mblock|
|
|
35
35
|
response =
|
|
36
36
|
if arity < 0 || arity == args.size
|
|
37
|
-
super(*args)
|
|
37
|
+
super(*args, &mblock)
|
|
38
38
|
else
|
|
39
39
|
self.class.curried.new(self, name: name, curry_args: args, arity: arity)
|
|
40
40
|
end
|
data/lib/rom/relation.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require 'dry/core/class_attributes'
|
|
2
|
+
require 'dry/core/deprecations'
|
|
2
3
|
|
|
3
4
|
require 'rom/initializer'
|
|
4
5
|
require 'rom/relation/class_interface'
|
|
@@ -41,6 +42,7 @@ module ROM
|
|
|
41
42
|
|
|
42
43
|
extend Initializer
|
|
43
44
|
extend ClassInterface
|
|
45
|
+
extend Dry::Core::Deprecations[:rom]
|
|
44
46
|
|
|
45
47
|
extend Dry::Core::ClassAttributes
|
|
46
48
|
defines :schema_class, :schema_inferrer, :schema_dsl
|
|
@@ -120,9 +122,10 @@ module ROM
|
|
|
120
122
|
# @return [Relation::Graph]
|
|
121
123
|
#
|
|
122
124
|
# @api public
|
|
123
|
-
def
|
|
125
|
+
def graph(*others)
|
|
124
126
|
Graph.build(self, others)
|
|
125
127
|
end
|
|
128
|
+
deprecate :combine, :graph
|
|
126
129
|
|
|
127
130
|
# Loads relation
|
|
128
131
|
#
|
data/lib/rom/relation/graph.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require 'dry/core/deprecations'
|
|
2
|
+
|
|
1
3
|
require 'rom/relation/loaded'
|
|
2
4
|
require 'rom/relation/composite'
|
|
3
5
|
require 'rom/relation/materializable'
|
|
@@ -24,6 +26,8 @@ module ROM
|
|
|
24
26
|
#
|
|
25
27
|
# @api public
|
|
26
28
|
class Graph
|
|
29
|
+
extend Dry::Core::Deprecations[:rom]
|
|
30
|
+
|
|
27
31
|
include Materializable
|
|
28
32
|
include Pipeline
|
|
29
33
|
include Pipeline::Proxy
|
|
@@ -82,9 +86,10 @@ module ROM
|
|
|
82
86
|
# @return [Graph]
|
|
83
87
|
#
|
|
84
88
|
# @api public
|
|
85
|
-
def
|
|
89
|
+
def graph(*others)
|
|
86
90
|
self.class.new(root, nodes + others)
|
|
87
91
|
end
|
|
92
|
+
deprecate :combine, :graph
|
|
88
93
|
|
|
89
94
|
# Materialize this relation graph
|
|
90
95
|
#
|
|
@@ -29,7 +29,7 @@ module ROM
|
|
|
29
29
|
option :globs, default: -> {
|
|
30
30
|
Hash[
|
|
31
31
|
component_dirs.map { |component, path|
|
|
32
|
-
[component, directory.join("#{
|
|
32
|
+
[component, directory.join("#{path}/**/*.rb")]
|
|
33
33
|
}
|
|
34
34
|
]
|
|
35
35
|
}
|
|
@@ -55,7 +55,7 @@ module ROM
|
|
|
55
55
|
case namespace
|
|
56
56
|
when String
|
|
57
57
|
AutoRegistrationStrategies::CustomNamespace.new(
|
|
58
|
-
namespace: namespace, file: file
|
|
58
|
+
namespace: namespace, file: file, directory: directory
|
|
59
59
|
).call
|
|
60
60
|
when TrueClass
|
|
61
61
|
AutoRegistrationStrategies::WithNamespace.new(
|
|
@@ -66,6 +66,7 @@ module ROM
|
|
|
66
66
|
file: file, directory: directory, entity: component_dirs.fetch(entity)
|
|
67
67
|
).call
|
|
68
68
|
end
|
|
69
|
+
|
|
69
70
|
Dry::Core::Inflector.constantize(klass_name)
|
|
70
71
|
end
|
|
71
72
|
end
|
|
@@ -7,17 +7,57 @@ require 'rom/setup/auto_registration_strategies/base'
|
|
|
7
7
|
module ROM
|
|
8
8
|
module AutoRegistrationStrategies
|
|
9
9
|
class CustomNamespace < Base
|
|
10
|
+
option :directory, type: PathnameType
|
|
10
11
|
option :namespace, type: Types::Strict::String
|
|
11
12
|
|
|
12
13
|
def call
|
|
13
|
-
|
|
14
|
+
potential = []
|
|
15
|
+
attempted = []
|
|
16
|
+
|
|
17
|
+
path_arr.reverse.each do |dir|
|
|
18
|
+
const_fragment = potential.unshift(
|
|
19
|
+
Dry::Core::Inflector.camelize(dir)
|
|
20
|
+
).join("::")
|
|
21
|
+
|
|
22
|
+
constant = "#{namespace}::#{const_fragment}"
|
|
23
|
+
|
|
24
|
+
return constant if ns_const.const_defined?(const_fragment)
|
|
25
|
+
|
|
26
|
+
attempted << constant
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# If we have reached this point, its means constant is not defined and
|
|
30
|
+
# NameError will be thrown if we attempt to camelize something like:
|
|
31
|
+
# `"#{namespace}::#{Dry::Core::Inflector.camelize(filename)}"`
|
|
32
|
+
# so we can assume naming convention was not respected in required
|
|
33
|
+
# file.
|
|
34
|
+
|
|
35
|
+
raise NameError, name_error_message(attempted)
|
|
14
36
|
end
|
|
15
37
|
|
|
16
38
|
private
|
|
17
39
|
|
|
40
|
+
def name_error_message(attempted)
|
|
41
|
+
"required file does not define expected constant name; either " \
|
|
42
|
+
"register your constant explicitly of try following the path" \
|
|
43
|
+
"naming convention like:\n\n\t- #{attempted.join("\n\t- ")}\n"
|
|
44
|
+
end
|
|
45
|
+
|
|
18
46
|
def filename
|
|
19
47
|
Pathname(file).basename('.rb')
|
|
20
48
|
end
|
|
49
|
+
|
|
50
|
+
def ns_const
|
|
51
|
+
@namespace_constant ||= Dry::Core::Inflector.constantize(namespace)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def path_arr
|
|
55
|
+
file_path << filename
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def file_path
|
|
59
|
+
File.dirname(file).split("/") - directory.to_s.split("/")
|
|
60
|
+
end
|
|
21
61
|
end
|
|
22
62
|
end
|
|
23
63
|
end
|
data/lib/rom/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
|
@@ -30,6 +30,10 @@ RSpec.describe ROM::AutoCurry do
|
|
|
30
30
|
args
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
+
def yielding_block(arg)
|
|
34
|
+
yield(arg)
|
|
35
|
+
end
|
|
36
|
+
|
|
33
37
|
protected
|
|
34
38
|
|
|
35
39
|
def leave_me_alone(foo)
|
|
@@ -39,7 +43,7 @@ RSpec.describe ROM::AutoCurry do
|
|
|
39
43
|
end
|
|
40
44
|
|
|
41
45
|
it 'registers auto-curried methods' do
|
|
42
|
-
expect(object.class.auto_curried_methods).to eql(%i[arity_1 arity_2 arity_many])
|
|
46
|
+
expect(object.class.auto_curried_methods).to eql(%i[arity_1 arity_2 arity_many yielding_block])
|
|
43
47
|
end
|
|
44
48
|
|
|
45
49
|
it 'auto-curries method with arity == 0' do
|
|
@@ -60,4 +64,8 @@ RSpec.describe ROM::AutoCurry do
|
|
|
60
64
|
expect(object.arity_many).to eql([])
|
|
61
65
|
expect(object.arity_many(1, 2)).to eql([1, 2])
|
|
62
66
|
end
|
|
67
|
+
|
|
68
|
+
it 'yields block' do
|
|
69
|
+
expect(object.yielding_block(1) { |arg| [arg, 2] }).to eql([1, 2])
|
|
70
|
+
end
|
|
63
71
|
end
|
|
@@ -106,8 +106,8 @@ RSpec.describe ROM::Relation, '#combine' do
|
|
|
106
106
|
{ name: 'Jane', title: 'be cool', priority: 2 }
|
|
107
107
|
],
|
|
108
108
|
tags: [
|
|
109
|
-
{ task: 'be cool', name: 'red' },
|
|
110
|
-
{ task: 'be cool', name: 'green' }
|
|
109
|
+
{ task: 'be cool', name: 'red', user: 'Jane' },
|
|
110
|
+
{ task: 'be cool', name: 'green', user: 'Jane' }
|
|
111
111
|
]
|
|
112
112
|
}
|
|
113
113
|
]
|
|
@@ -129,8 +129,8 @@ RSpec.describe ROM::Relation, '#combine' do
|
|
|
129
129
|
{ name: 'Jane', title: 'be cool', priority: 2 }
|
|
130
130
|
],
|
|
131
131
|
tags: [
|
|
132
|
-
{ task: 'be cool', name: 'red' },
|
|
133
|
-
{ task: 'be cool', name: 'green' }
|
|
132
|
+
{ task: 'be cool', name: 'red', user: 'Jane' },
|
|
133
|
+
{ task: 'be cool', name: 'green', user: 'Jane' }
|
|
134
134
|
]
|
|
135
135
|
}
|
|
136
136
|
]
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe ROM::Relation, '#graph' do
|
|
4
|
+
include_context 'gateway only'
|
|
5
|
+
include_context 'users and tasks'
|
|
6
|
+
|
|
7
|
+
let(:tags_dataset) { gateway.dataset(:tags) }
|
|
8
|
+
|
|
9
|
+
let(:users_relation) do
|
|
10
|
+
Class.new(ROM::Memory::Relation) do
|
|
11
|
+
def by_name(name)
|
|
12
|
+
restrict(name: name)
|
|
13
|
+
end
|
|
14
|
+
end.new(users_dataset)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
let(:tasks_relation) do
|
|
18
|
+
Class.new(ROM::Memory::Relation) do
|
|
19
|
+
def for_users(users)
|
|
20
|
+
names = users.map { |user| user[:name] }
|
|
21
|
+
restrict { |task| names.include?(task[:name]) }
|
|
22
|
+
end
|
|
23
|
+
end.new(tasks_dataset)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
let(:tags_relation) do
|
|
27
|
+
Class.new(ROM::Memory::Relation) do
|
|
28
|
+
attr_accessor :tasks
|
|
29
|
+
forward :map
|
|
30
|
+
|
|
31
|
+
def for_tasks(tasks)
|
|
32
|
+
titles = tasks.map { |task| task[:title] }
|
|
33
|
+
restrict { |tag| titles.include?(tag[:task]) }
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def for_users(users)
|
|
37
|
+
user_tasks = tasks.for_users(users)
|
|
38
|
+
|
|
39
|
+
for_tasks(user_tasks).map { |tag|
|
|
40
|
+
tag.merge(user: user_tasks.detect { |task|
|
|
41
|
+
task[:title] == tag[:task]
|
|
42
|
+
} [:name])
|
|
43
|
+
}
|
|
44
|
+
end
|
|
45
|
+
end.new(tags_dataset).tap { |r| r.tasks = tasks_relation }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
before do
|
|
49
|
+
tags_dataset.insert(task: 'be cool', name: 'red')
|
|
50
|
+
tags_dataset.insert(task: 'be cool', name: 'green')
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
let(:map_users) {
|
|
54
|
+
proc { |users, tasks|
|
|
55
|
+
users.map { |user|
|
|
56
|
+
user.merge(tasks: tasks.select { |task| task[:name] == user[:name] })
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
let(:map_tasks) {
|
|
62
|
+
proc { |(tasks, children)|
|
|
63
|
+
tags = children.first
|
|
64
|
+
|
|
65
|
+
tasks.map { |task|
|
|
66
|
+
task.merge(tags: tags.select { |tag| tag[:task] == task[:title] })
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
let(:map_user_with_tasks_and_tags) {
|
|
72
|
+
proc { |users, (tasks, tags)|
|
|
73
|
+
users.map { |user|
|
|
74
|
+
user_tasks = tasks.select { |task| task[:name] == user[:name] }
|
|
75
|
+
|
|
76
|
+
user_tags = tasks.flat_map { |task|
|
|
77
|
+
tags.select { |tag| tag[:task] == task[:title] }
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
user.merge(
|
|
81
|
+
tasks: user_tasks,
|
|
82
|
+
tags: user_tags
|
|
83
|
+
)
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
let(:map_user_with_tasks) {
|
|
89
|
+
proc { |users, children|
|
|
90
|
+
map_users[users, map_tasks[children.first]]
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
it 'raises error when composite relation is passed as a node' do
|
|
95
|
+
expect {
|
|
96
|
+
users_relation.graph(tasks_relation >> proc {})
|
|
97
|
+
}.to raise_error(ROM::UnsupportedRelationError)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
it 'supports more than one eagerly-loaded relation' do
|
|
101
|
+
expected = [
|
|
102
|
+
{
|
|
103
|
+
name: 'Jane',
|
|
104
|
+
email: 'jane@doe.org',
|
|
105
|
+
tasks: [
|
|
106
|
+
{ name: 'Jane', title: 'be cool', priority: 2 }
|
|
107
|
+
],
|
|
108
|
+
tags: [
|
|
109
|
+
{ task: 'be cool', name: 'red', user: 'Jane' },
|
|
110
|
+
{ task: 'be cool', name: 'green', user: 'Jane' }
|
|
111
|
+
]
|
|
112
|
+
}
|
|
113
|
+
]
|
|
114
|
+
|
|
115
|
+
user_with_tasks_and_tags = users_relation.by_name('Jane')
|
|
116
|
+
.graph(tasks_relation.for_users, tags_relation.for_users)
|
|
117
|
+
|
|
118
|
+
result = user_with_tasks_and_tags >> map_user_with_tasks_and_tags
|
|
119
|
+
|
|
120
|
+
expect(result.to_a).to eql(expected)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it 'supports more than one eagerly-loaded relation via chaining' do
|
|
124
|
+
expected = [
|
|
125
|
+
{
|
|
126
|
+
name: 'Jane',
|
|
127
|
+
email: 'jane@doe.org',
|
|
128
|
+
tasks: [
|
|
129
|
+
{ name: 'Jane', title: 'be cool', priority: 2 }
|
|
130
|
+
],
|
|
131
|
+
tags: [
|
|
132
|
+
{ task: 'be cool', name: 'red', user: 'Jane' },
|
|
133
|
+
{ task: 'be cool', name: 'green', user: 'Jane' }
|
|
134
|
+
]
|
|
135
|
+
}
|
|
136
|
+
]
|
|
137
|
+
|
|
138
|
+
user_with_tasks_and_tags = users_relation.by_name('Jane')
|
|
139
|
+
.graph(tasks_relation.for_users).graph(tags_relation.for_users)
|
|
140
|
+
|
|
141
|
+
result = user_with_tasks_and_tags >> map_user_with_tasks_and_tags
|
|
142
|
+
|
|
143
|
+
expect(result).to match_array(expected)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
it 'supports nested eager-loading' do
|
|
147
|
+
expected = [
|
|
148
|
+
{
|
|
149
|
+
name: 'Jane', email: 'jane@doe.org', tasks: [
|
|
150
|
+
{ name: 'Jane', title: 'be cool', priority: 2, tags: [
|
|
151
|
+
{ task: 'be cool', name: 'red' },
|
|
152
|
+
{ task: 'be cool', name: 'green' }
|
|
153
|
+
] }
|
|
154
|
+
]
|
|
155
|
+
}
|
|
156
|
+
]
|
|
157
|
+
|
|
158
|
+
user_with_tasks = users_relation.by_name('Jane')
|
|
159
|
+
.graph(tasks_relation.for_users.graph(tags_relation.for_tasks))
|
|
160
|
+
|
|
161
|
+
result = user_with_tasks >> map_user_with_tasks
|
|
162
|
+
|
|
163
|
+
expect(result).to match_array(expected)
|
|
164
|
+
end
|
|
165
|
+
end
|
|
@@ -117,34 +117,96 @@ RSpec.describe ROM::Setup, '#auto_registration' do
|
|
|
117
117
|
end
|
|
118
118
|
end
|
|
119
119
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
120
|
+
describe 'custom namespace' do
|
|
121
|
+
context 'when namespace has subnamespace' do
|
|
122
|
+
before do
|
|
123
|
+
setup.auto_registration(
|
|
124
|
+
SPEC_ROOT.join('fixtures/custom_namespace'),
|
|
125
|
+
component_dirs: {
|
|
126
|
+
relations: :relations,
|
|
127
|
+
mappers: :mappers,
|
|
128
|
+
commands: :commands
|
|
129
|
+
},
|
|
130
|
+
namespace: 'My::Namespace'
|
|
131
|
+
)
|
|
132
|
+
end
|
|
132
133
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
134
|
+
describe '#relations' do
|
|
135
|
+
it 'loads files and returns constants' do
|
|
136
|
+
expect(setup.relation_classes).to eql([My::Namespace::Relations::Customers])
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
describe '#commands' do
|
|
141
|
+
it 'loads files and returns constants' do
|
|
142
|
+
expect(setup.command_classes).to eql([My::Namespace::Commands::CreateCustomer])
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
describe '#mappers' do
|
|
147
|
+
it 'loads files and returns constants' do
|
|
148
|
+
expect(setup.mapper_classes).to eql([My::Namespace::Mappers::CustomerList])
|
|
149
|
+
end
|
|
136
150
|
end
|
|
137
151
|
end
|
|
138
152
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
153
|
+
context 'when namespace has wrong subnamespace' do
|
|
154
|
+
subject do
|
|
155
|
+
-> do
|
|
156
|
+
setup.auto_registration(
|
|
157
|
+
SPEC_ROOT.join('fixtures/wrong'),
|
|
158
|
+
component_dirs: {
|
|
159
|
+
relations: :relations,
|
|
160
|
+
mappers: :mappers,
|
|
161
|
+
commands: :commands
|
|
162
|
+
},
|
|
163
|
+
namespace: 'My::NewNamespace'
|
|
164
|
+
)
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
describe '#relations' do
|
|
169
|
+
it { is_expected.to raise_exception NameError }
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
describe '#commands' do
|
|
173
|
+
it { is_expected.to raise_exception NameError }
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
describe '#mappers' do
|
|
177
|
+
it { is_expected.to raise_exception NameError }
|
|
142
178
|
end
|
|
143
179
|
end
|
|
144
180
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
181
|
+
context 'when namespace does not implement subnamespace' do
|
|
182
|
+
before do
|
|
183
|
+
setup.auto_registration(
|
|
184
|
+
SPEC_ROOT.join('fixtures/custom'),
|
|
185
|
+
component_dirs: {
|
|
186
|
+
relations: :relations,
|
|
187
|
+
mappers: :mappers,
|
|
188
|
+
commands: :commands
|
|
189
|
+
},
|
|
190
|
+
namespace: 'My::Namespace'
|
|
191
|
+
)
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
describe '#relations' do
|
|
195
|
+
it 'loads files and returns constants' do
|
|
196
|
+
expect(setup.relation_classes).to eql([My::Namespace::Users])
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
describe '#commands' do
|
|
201
|
+
it 'loads files and returns constants' do
|
|
202
|
+
expect(setup.command_classes).to eql([My::Namespace::CreateUser])
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
describe '#mappers' do
|
|
207
|
+
it 'loads files and returns constants' do
|
|
208
|
+
expect(setup.mapper_classes).to eql([My::Namespace::UserList])
|
|
209
|
+
end
|
|
148
210
|
end
|
|
149
211
|
end
|
|
150
212
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rom
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.2.
|
|
4
|
+
version: 3.2.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Piotr Solnica
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2017-05-
|
|
11
|
+
date: 2017-05-31 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: concurrent-ruby
|
|
@@ -258,12 +258,18 @@ files:
|
|
|
258
258
|
- spec/fixtures/custom/commands/create_user.rb
|
|
259
259
|
- spec/fixtures/custom/mappers/user_list.rb
|
|
260
260
|
- spec/fixtures/custom/relations/users.rb
|
|
261
|
+
- spec/fixtures/custom_namespace/commands/create_customer.rb
|
|
262
|
+
- spec/fixtures/custom_namespace/mappers/customer_list.rb
|
|
263
|
+
- spec/fixtures/custom_namespace/relations/customers.rb
|
|
261
264
|
- spec/fixtures/lib/persistence/commands/create_user.rb
|
|
262
265
|
- spec/fixtures/lib/persistence/mappers/user_list.rb
|
|
263
266
|
- spec/fixtures/lib/persistence/my_commands/create_user.rb
|
|
264
267
|
- spec/fixtures/lib/persistence/my_mappers/user_list.rb
|
|
265
268
|
- spec/fixtures/lib/persistence/my_relations/users.rb
|
|
266
269
|
- spec/fixtures/lib/persistence/relations/users.rb
|
|
270
|
+
- spec/fixtures/wrong/commands/create_customer.rb
|
|
271
|
+
- spec/fixtures/wrong/mappers/customer_list.rb
|
|
272
|
+
- spec/fixtures/wrong/relations/customers.rb
|
|
267
273
|
- spec/integration/command_registry_spec.rb
|
|
268
274
|
- spec/integration/commands/create_spec.rb
|
|
269
275
|
- spec/integration/commands/delete_spec.rb
|
|
@@ -353,6 +359,7 @@ files:
|
|
|
353
359
|
- spec/unit/rom/relation/curried_spec.rb
|
|
354
360
|
- spec/unit/rom/relation/graph_spec.rb
|
|
355
361
|
- spec/unit/rom/relation/lazy/combine_spec.rb
|
|
362
|
+
- spec/unit/rom/relation/lazy/graph_spec.rb
|
|
356
363
|
- spec/unit/rom/relation/lazy_spec.rb
|
|
357
364
|
- spec/unit/rom/relation/loaded_spec.rb
|
|
358
365
|
- spec/unit/rom/relation/name_spec.rb
|