dry-component 0.0.1 → 0.1.0
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/.travis.yml +2 -1
- data/CHANGELOG.md +37 -1
- data/README.md +7 -210
- data/dry-component.gemspec +2 -3
- data/lib/dry/component/config.rb +8 -8
- data/lib/dry/component/container.rb +67 -21
- data/lib/dry/component/injector.rb +63 -0
- data/lib/dry/component/loader.rb +11 -22
- data/lib/dry/component/version.rb +1 -1
- data/spec/fixtures/components/bar.rb +5 -0
- data/spec/fixtures/components/bar/baz.rb +4 -0
- data/spec/fixtures/components/foo.rb +2 -0
- data/spec/fixtures/import_test/config/application.yml +2 -0
- data/spec/fixtures/import_test/core/boot/bar.rb +11 -0
- data/spec/fixtures/import_test/lib/test/bar.rb +4 -0
- data/spec/fixtures/import_test/lib/test/foo.rb +5 -0
- data/spec/fixtures/lazytest/config/application.yml +2 -0
- data/spec/fixtures/lazytest/core/boot/bar.rb +11 -0
- data/spec/fixtures/lazytest/lib/test/dep.rb +4 -0
- data/spec/fixtures/lazytest/lib/test/foo.rb +5 -0
- data/spec/fixtures/lazytest/lib/test/models.rb +4 -0
- data/spec/fixtures/lazytest/lib/test/models/book.rb +6 -0
- data/spec/fixtures/lazytest/lib/test/models/user.rb +6 -0
- data/spec/fixtures/test/config/subapp.yml +2 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/unit/config_spec.rb +12 -0
- data/spec/unit/container/auto_register_spec.rb +50 -0
- data/spec/unit/container/import_spec.rb +70 -0
- data/spec/unit/container_spec.rb +39 -6
- data/spec/unit/injector_spec.rb +59 -0
- data/spec/unit/loader_spec.rb +3 -9
- metadata +46 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6fd0b3400c225e2c1f856aff61cf4e554b8f9fc5
|
4
|
+
data.tar.gz: b9ead2e64ad32dee264b29973c932a1394dc6775
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6b38cbe04c32bd241421fe438551c8fc3d51ca9e23332f222f93f14c1afe33a4574848418298db8eeec621a679000d5eea01e42e2f389e5cfe43b1dcba339460
|
7
|
+
data.tar.gz: 06af0944d5af7614a50e381b2ceb5efd850ae10519f1deb8487e9ed7f19b3a6ec413446f2ec32f52983b11a3e718b3f22c9b3189c4ce95a70f6aac97a9ed42a7
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,39 @@
|
|
1
|
-
#
|
1
|
+
# 0.1.0 - 2016-06-07
|
2
|
+
|
3
|
+
## Added
|
4
|
+
|
5
|
+
* Provide a dependency injector as an `Inject` constant inside any subclass of `Dry::Component::Container`. This injector supports all of `dry-auto_inject`'s default injection strategies, and will lazily load any dependencies as they are injected. It also supports arbitrarily switching strategies, so they can be used in different classes as required (e.g. `include MyComponent::Inject.args["dep"]`) (timriley)
|
6
|
+
* Support aliased dependency names when calling the injector object (e.g. `MyComponent::Inject[foo: "my_app.foo", bar: "another.thing"]`) (timriley)
|
7
|
+
* Allow a custom dependency loader to be set on a container via its config (AMHOL)
|
8
|
+
```ruby
|
9
|
+
class MyContainer < Dry::Component::Container
|
10
|
+
configure do |config|
|
11
|
+
# other config
|
12
|
+
config.loader = MyLoader
|
13
|
+
end
|
14
|
+
end
|
15
|
+
```
|
16
|
+
|
17
|
+
## Changed
|
18
|
+
|
19
|
+
* `Container.boot` now only makes a simple `require` for the boot file (solnic)
|
20
|
+
* Container object is passed to `Container.finalize` blocks (solnic)
|
21
|
+
* Allow `Pathname` objects passed to `Container.require` (solnic)
|
22
|
+
* Support lazily loading missing dependencies from imported containers (solnic)
|
23
|
+
* `Container.import_module` renamed to `.injector` (timriley)
|
24
|
+
* Default injection strategy is now `kwargs`, courtesy of the new dry-auto_inject default (timriley)
|
25
|
+
|
26
|
+
# 0.0.2 - 2015-12-24
|
27
|
+
|
28
|
+
## Added
|
29
|
+
|
30
|
+
* Containers have a `name` setting (solnic)
|
31
|
+
* Containers can be imported into one another (solnic)
|
32
|
+
|
33
|
+
## Changed
|
34
|
+
|
35
|
+
* Container name is used to determine the name of its config file (solnic)
|
36
|
+
|
37
|
+
# 0.0.1 - 2015-12-24
|
2
38
|
|
3
39
|
First public release, extracted from rodakase project
|
data/README.md
CHANGED
@@ -1,217 +1,14 @@
|
|
1
|
-
# dry-component <a href="https://gitter.im/
|
1
|
+
# dry-component <a href="https://gitter.im/dry-rb/chat" target="_blank"></a>
|
2
2
|
|
3
3
|
<a href="https://rubygems.org/gems/dry-component" target="_blank"></a>
|
4
|
-
<a href="https://travis-ci.org/
|
5
|
-
<a href="https://gemnasium.com/
|
6
|
-
<a href="https://codeclimate.com/github/
|
7
|
-
<a href="http://inch-ci.org/github/
|
4
|
+
<a href="https://travis-ci.org/dry-rb/dry-component" target="_blank"></a>
|
5
|
+
<a href="https://gemnasium.com/dry-rb/dry-component" target="_blank"></a>
|
6
|
+
<a href="https://codeclimate.com/github/dry-rb/dry-component" target="_blank"></a>
|
7
|
+
<a href="http://inch-ci.org/github/dry-rb/dry-component" target="_blank"></a>
|
8
8
|
|
9
|
-
|
10
|
-
in any environment, set up their load-paths, require needed files and instantiate
|
11
|
-
objects automatically with the ability to have them injected as dependencies.
|
9
|
+
## Links
|
12
10
|
|
13
|
-
|
14
|
-
a standalone, small library.
|
15
|
-
|
16
|
-
This is a simple system that relies on very basic mechanisms provided by Ruby,
|
17
|
-
specifically `require` and managing `$LOAD_PATH`. It does not rely on any magic
|
18
|
-
like automatic const resolution, it's pretty much the opposite and forces you to
|
19
|
-
be explicit about dependencies in your applications.
|
20
|
-
|
21
|
-
It does a couple of things for you that are really not something you want to do
|
22
|
-
yourself:
|
23
|
-
|
24
|
-
* Provides an abstract dependency container implementation
|
25
|
-
* Handles `$LOAD_PATH` configuration
|
26
|
-
* Loads needed files using `require`
|
27
|
-
* Resolves dependencies automatically
|
28
|
-
* Supports auto-registration of dependencies via file/dir naming conventions
|
29
|
-
* Provides support for custom configuration loaded from external sources (ie YAML)
|
30
|
-
|
31
|
-
To put it all together, this allows you to configure your system in a way where
|
32
|
-
you have full control over dependencies and it's very easy to draw the boundaries
|
33
|
-
between individual components.
|
34
|
-
|
35
|
-
This comes with a bunch of nice benefits:
|
36
|
-
|
37
|
-
* Your system relies on abstractions rather than concrete classes and modules
|
38
|
-
* It helps in decoupling your code from 3rd party code
|
39
|
-
* It makes it possible to load components in complete isolation. In example you
|
40
|
-
can run a single test for a single component and only required files will be
|
41
|
-
loaded, or you can run a rake task and it will only load the things it needs.
|
42
|
-
* It opens up doors for better instrumentation and debugging tools
|
43
|
-
|
44
|
-
## Container
|
45
|
-
|
46
|
-
Main API is the abstract container that you inherit from. It allows you to configure
|
47
|
-
basic settings and exposes APIs for requiring files easily.
|
48
|
-
|
49
|
-
Let's say you want to define an application container that will provide a logger:
|
50
|
-
|
51
|
-
``` ruby
|
52
|
-
require 'dry/component/container'
|
53
|
-
|
54
|
-
class Application < Dry::Component::Container
|
55
|
-
configure do |config|
|
56
|
-
config.root = '/my/app'
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
# now you can register a logger
|
61
|
-
require 'logger'
|
62
|
-
Application.register('utils.logger', Logger.new($stdout))
|
63
|
-
|
64
|
-
# and access it
|
65
|
-
Application['utils.logger']
|
66
|
-
```
|
67
|
-
|
68
|
-
## Auto-Registration
|
69
|
-
|
70
|
-
By using simple naming conventions we can automatically register objects within
|
71
|
-
our container.
|
72
|
-
|
73
|
-
Let's provide a custom logger object and put it under a custom load-path that we
|
74
|
-
will configure:
|
75
|
-
|
76
|
-
``` ruby
|
77
|
-
require 'dry/component/container'
|
78
|
-
|
79
|
-
class Application < Dry::Component::Container
|
80
|
-
configure do |config|
|
81
|
-
config.root = '/my/app'
|
82
|
-
|
83
|
-
# we set 'lib' relative to `root` as a path which contains class definitions
|
84
|
-
# that can be auto-registered
|
85
|
-
config.auto_register = 'lib'
|
86
|
-
end
|
87
|
-
|
88
|
-
# this alters $LOAD_PATH hence the `!`
|
89
|
-
load_paths!('lib')
|
90
|
-
end
|
91
|
-
|
92
|
-
# under /my/app/lib/logger.rb we put
|
93
|
-
class Logger
|
94
|
-
# some neat logger implementation
|
95
|
-
end
|
96
|
-
|
97
|
-
# we can finalize the container which triggers auto-registration
|
98
|
-
Application.finalize!
|
99
|
-
|
100
|
-
# the logger becomes available
|
101
|
-
Application['logger']
|
102
|
-
```
|
103
|
-
|
104
|
-
## Auto-Import Mechanism
|
105
|
-
|
106
|
-
After defining a container, we can use its import module that will inject object
|
107
|
-
dependencies automatically.
|
108
|
-
|
109
|
-
Let's say we have an object that will need a logger:
|
110
|
-
|
111
|
-
``` ruby
|
112
|
-
# let's define an import module
|
113
|
-
Import = Application.import_module
|
114
|
-
|
115
|
-
# in a class definition you simply specify what it needs
|
116
|
-
class PostPublisher
|
117
|
-
include Import['utils.logger']
|
118
|
-
|
119
|
-
def call(post)
|
120
|
-
# some stuff
|
121
|
-
logger.debug("post published: #{post}")
|
122
|
-
end
|
123
|
-
end
|
124
|
-
```
|
125
|
-
|
126
|
-
## Directory Structure
|
127
|
-
|
128
|
-
You need to provide a specific directory/file structure but names of directories
|
129
|
-
are configurable. The default is as follows:
|
130
|
-
|
131
|
-
```
|
132
|
-
#{root}
|
133
|
-
|- core
|
134
|
-
|- boot
|
135
|
-
# arbitrary files that are automatically loaded on finalization
|
136
|
-
```
|
137
|
-
|
138
|
-
## Booting a Dependency
|
139
|
-
|
140
|
-
In some cases a dependency can be huge, so huge it needs to load some additional
|
141
|
-
files (often 3rd party code) and it may rely on custom configuration.
|
142
|
-
|
143
|
-
Because of this reason `dry-component` has the concept of booting a dependency.
|
144
|
-
|
145
|
-
The convention is pretty simple. You put files under `boot` directory and use
|
146
|
-
your container to register dependencies with the ability to postpone finalization.
|
147
|
-
This gives us a way to define what's needed but load it and boot it on demand.
|
148
|
-
|
149
|
-
Here's a simple example:
|
150
|
-
|
151
|
-
``` ruby
|
152
|
-
# under /my/app/boot/heavy_dep.rb
|
153
|
-
|
154
|
-
Application.finalize(:persistence) do
|
155
|
-
# some 3rd-party dependency
|
156
|
-
require '3rd-party/database'
|
157
|
-
|
158
|
-
container.register('database') do
|
159
|
-
# some code which initializes this thing
|
160
|
-
end
|
161
|
-
end
|
162
|
-
```
|
163
|
-
|
164
|
-
After defining the finalization block our container will not call it until its
|
165
|
-
own finalization. This means we can require file that defines our container
|
166
|
-
and ask it to boot *just that one :persistence dependency*:
|
167
|
-
|
168
|
-
``` ruby
|
169
|
-
# under /my/app/boot/container.rb
|
170
|
-
class Application < Dry::Component::Container
|
171
|
-
configure do |config|
|
172
|
-
config.root = '/my/app'
|
173
|
-
end
|
174
|
-
end
|
175
|
-
|
176
|
-
Application.boot!(:persistence)
|
177
|
-
|
178
|
-
# and now `database` becomes available
|
179
|
-
Application['database']
|
180
|
-
```
|
181
|
-
|
182
|
-
## Environment & Providing Arbitrary Options
|
183
|
-
|
184
|
-
In most of the systems you need some kind of options for your runtime. Typically
|
185
|
-
it's provided via ENV vars or a yaml file in development mode. `dry-component`
|
186
|
-
has a built-in support for this.
|
187
|
-
|
188
|
-
You can simply put a file under `#{root}/config/application.yml` and it will be
|
189
|
-
loaded:
|
190
|
-
|
191
|
-
``` yaml
|
192
|
-
# /my/app/config/application.yml
|
193
|
-
development:
|
194
|
-
foo: 'bar'
|
195
|
-
```
|
196
|
-
|
197
|
-
Now let's configure our container for a specific env:
|
198
|
-
|
199
|
-
``` ruby
|
200
|
-
class Application < Dry::Component::Container
|
201
|
-
configure('development') do |config|
|
202
|
-
config.root = '/my/app'
|
203
|
-
end
|
204
|
-
end
|
205
|
-
|
206
|
-
# now our application options are available
|
207
|
-
Application.options.foo # => "bar"
|
208
|
-
```
|
209
|
-
|
210
|
-
## Underlying Tools
|
211
|
-
|
212
|
-
`dry-component` uses [dry-container](https://github.com/dryrb/dry-container) and
|
213
|
-
[dry-auto_inject](https://github.com/dryrb/dry-auto_inject) under the hood. These
|
214
|
-
gems are very small and simple with a total 254LOC. Just saying.
|
11
|
+
* [Documentation](http://dry-rb.org/gems/dry-component)
|
215
12
|
|
216
13
|
## LICENSE
|
217
14
|
|
data/dry-component.gemspec
CHANGED
@@ -15,10 +15,9 @@ Gem::Specification.new do |spec|
|
|
15
15
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
16
16
|
spec.require_paths = ['lib']
|
17
17
|
|
18
|
-
spec.add_runtime_dependency 'memoizable', '~> 0.4'
|
19
18
|
spec.add_runtime_dependency 'inflecto', '>= 0.0.2'
|
20
|
-
spec.add_runtime_dependency 'dry-container', '~> 0.
|
21
|
-
spec.add_runtime_dependency 'dry-auto_inject', '~> 0.
|
19
|
+
spec.add_runtime_dependency 'dry-container', '~> 0.3', '>= 0.3.4'
|
20
|
+
spec.add_runtime_dependency 'dry-auto_inject', '~> 0.3'
|
22
21
|
spec.add_runtime_dependency 'dry-configurable', '~> 0.1'
|
23
22
|
|
24
23
|
spec.add_development_dependency 'bundler'
|
data/lib/dry/component/config.rb
CHANGED
@@ -3,20 +3,20 @@ require 'yaml'
|
|
3
3
|
module Dry
|
4
4
|
module Component
|
5
5
|
class Config
|
6
|
-
|
7
|
-
|
8
|
-
def self.load(root, env)
|
9
|
-
path = root.join('config').join('application.yml')
|
6
|
+
def self.load(root, name, env)
|
7
|
+
path = root.join('config').join("#{name}.yml")
|
10
8
|
|
11
9
|
return {} unless File.exist?(path)
|
12
10
|
|
13
11
|
yaml = YAML.load_file(path)
|
14
12
|
|
15
|
-
|
16
|
-
|
17
|
-
end
|
13
|
+
Class.new do
|
14
|
+
extend Dry::Configurable
|
18
15
|
|
19
|
-
|
16
|
+
yaml.fetch(env.to_s).each do |key, value|
|
17
|
+
setting key.downcase.to_sym, ENV.fetch(key, value)
|
18
|
+
end
|
19
|
+
end.config
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
@@ -1,7 +1,9 @@
|
|
1
|
+
require 'pathname'
|
1
2
|
require 'inflecto'
|
3
|
+
|
2
4
|
require 'dry-container'
|
3
|
-
require 'dry-auto_inject'
|
4
5
|
|
6
|
+
require 'dry/component/injector'
|
5
7
|
require 'dry/component/loader'
|
6
8
|
require 'dry/component/config'
|
7
9
|
|
@@ -11,17 +13,24 @@ module Dry
|
|
11
13
|
extend Dry::Container::Mixin
|
12
14
|
|
13
15
|
setting :env
|
16
|
+
setting :name
|
14
17
|
setting :root, Pathname.pwd.freeze
|
15
18
|
setting :core_dir, 'core'.freeze
|
16
19
|
setting :auto_register
|
17
20
|
setting :options
|
21
|
+
setting :loader, Dry::Component::Loader
|
22
|
+
|
23
|
+
def self.inherited(subclass)
|
24
|
+
super
|
25
|
+
subclass.const_set :Inject, subclass.injector
|
26
|
+
end
|
18
27
|
|
19
28
|
def self.configure(env = config.env, &block)
|
20
29
|
return self if configured?
|
21
30
|
|
22
31
|
super() do |config|
|
23
32
|
yield(config) if block
|
24
|
-
config.options = Config.load(root, env)
|
33
|
+
config.options = Config.load(root, config.name, env)
|
25
34
|
end
|
26
35
|
|
27
36
|
load_paths!(config.core_dir)
|
@@ -31,12 +40,23 @@ module Dry
|
|
31
40
|
self
|
32
41
|
end
|
33
42
|
|
43
|
+
def self.import(other)
|
44
|
+
case other
|
45
|
+
when Dry::Container::Namespace then super
|
46
|
+
when Hash then imports.update(other)
|
47
|
+
else
|
48
|
+
if other < Component::Container
|
49
|
+
imports.update(other.config.name => other)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
34
54
|
def self.options
|
35
55
|
config.options
|
36
56
|
end
|
37
57
|
|
38
58
|
def self.finalize(name, &block)
|
39
|
-
finalizers[name] = block
|
59
|
+
finalizers[name] = proc { block.(self) }
|
40
60
|
end
|
41
61
|
|
42
62
|
def self.configured?
|
@@ -46,6 +66,10 @@ module Dry
|
|
46
66
|
def self.finalize!(&_block)
|
47
67
|
yield(self) if block_given?
|
48
68
|
|
69
|
+
imports.each do |ns, container|
|
70
|
+
import_container(ns, container.finalize!)
|
71
|
+
end
|
72
|
+
|
49
73
|
Dir[root.join("#{config.core_dir}/boot/**/*.rb")].each do |path|
|
50
74
|
boot!(File.basename(path, '.rb').to_sym)
|
51
75
|
end
|
@@ -55,13 +79,8 @@ module Dry
|
|
55
79
|
freeze
|
56
80
|
end
|
57
81
|
|
58
|
-
def self.
|
59
|
-
|
60
|
-
|
61
|
-
-> *keys {
|
62
|
-
keys.each { |key| load_component(key) unless key?(key) }
|
63
|
-
auto_inject[*keys]
|
64
|
-
}
|
82
|
+
def self.injector
|
83
|
+
Injector.new(self)
|
65
84
|
end
|
66
85
|
|
67
86
|
def self.auto_register!(dir, &_block)
|
@@ -69,7 +88,7 @@ module Dry
|
|
69
88
|
|
70
89
|
Dir["#{root}/#{dir}/**/*.rb"].each do |path|
|
71
90
|
component_path = path.to_s.gsub("#{dir_root}/", '').gsub('.rb', '')
|
72
|
-
|
91
|
+
config.loader.new(component_path).tap do |component|
|
73
92
|
next if key?(component.identifier)
|
74
93
|
|
75
94
|
Kernel.require component.path
|
@@ -87,19 +106,22 @@ module Dry
|
|
87
106
|
|
88
107
|
def self.boot!(name)
|
89
108
|
check_component_identifier!(name)
|
109
|
+
|
90
110
|
return self unless booted?(name)
|
91
|
-
boot(name)
|
92
|
-
self
|
93
|
-
end
|
94
111
|
|
95
|
-
|
96
|
-
require "#{config.core_dir}/boot/#{name}.rb"
|
112
|
+
boot(name)
|
97
113
|
|
98
114
|
finalizers[name].tap do |finalizer|
|
99
115
|
finalizer.() if finalizer
|
100
116
|
end
|
101
117
|
|
102
118
|
booted[name] = true
|
119
|
+
|
120
|
+
self
|
121
|
+
end
|
122
|
+
|
123
|
+
def self.boot(name)
|
124
|
+
require "#{config.core_dir}/boot/#{name}"
|
103
125
|
end
|
104
126
|
|
105
127
|
def self.booted?(name)
|
@@ -108,25 +130,37 @@ module Dry
|
|
108
130
|
|
109
131
|
def self.require(*paths)
|
110
132
|
paths.flat_map { |path|
|
111
|
-
path.include?('*') ? Dir[root.join(path)] : root.join(path)
|
133
|
+
path.to_s.include?('*') ? Dir[root.join(path)] : root.join(path)
|
112
134
|
}.each { |path|
|
113
135
|
Kernel.require path.to_s
|
114
136
|
}
|
115
137
|
end
|
116
138
|
|
117
139
|
def self.load_component(key)
|
118
|
-
|
140
|
+
component = config.loader.new(key)
|
141
|
+
src_key = component.namespaces[0]
|
142
|
+
|
143
|
+
if imports.key?(src_key)
|
144
|
+
src_container = imports[src_key]
|
145
|
+
|
146
|
+
src_container.load_component(
|
147
|
+
(component.namespaces - [src_key]).map(&:to_s).join('.')
|
148
|
+
)
|
149
|
+
|
150
|
+
import_container(src_key, src_container)
|
151
|
+
else
|
152
|
+
require_component(component) { |klass| register(key) { klass.new } }
|
153
|
+
end
|
119
154
|
end
|
120
155
|
|
121
|
-
def self.require_component(
|
122
|
-
component = Component.Loader(key)
|
156
|
+
def self.require_component(component, &block)
|
123
157
|
path = load_paths.detect { |p| p.join(component.file).exist? }
|
124
158
|
|
125
159
|
if path
|
126
160
|
Kernel.require component.path
|
127
161
|
yield(component.constant) if block
|
128
162
|
else
|
129
|
-
fail ArgumentError, "could not resolve require file for #{
|
163
|
+
fail ArgumentError, "could not resolve require file for #{component.identifier}"
|
130
164
|
end
|
131
165
|
end
|
132
166
|
|
@@ -155,8 +189,20 @@ module Dry
|
|
155
189
|
@finalizers ||= {}
|
156
190
|
end
|
157
191
|
|
192
|
+
def self.imports
|
193
|
+
@imports ||= {}
|
194
|
+
end
|
195
|
+
|
158
196
|
private
|
159
197
|
|
198
|
+
def self.import_container(ns, container)
|
199
|
+
items = container._container.each_with_object({}) { |(key, item), res|
|
200
|
+
res[[ns, key].join(config.namespace_separator)] = item
|
201
|
+
}
|
202
|
+
|
203
|
+
_container.update(items)
|
204
|
+
end
|
205
|
+
|
160
206
|
def self.auto_register
|
161
207
|
Array(config.auto_register)
|
162
208
|
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require "dry-auto_inject"
|
2
|
+
|
3
|
+
module Dry
|
4
|
+
module Component
|
5
|
+
class Injector
|
6
|
+
# @api private
|
7
|
+
attr_reader :container
|
8
|
+
|
9
|
+
# @api private
|
10
|
+
attr_reader :injector
|
11
|
+
|
12
|
+
# @api private
|
13
|
+
def initialize(container, strategy: :args, strategies_cache: nil)
|
14
|
+
@container = container
|
15
|
+
@strategies = strategies_cache
|
16
|
+
|
17
|
+
@injector = if strategy == :args
|
18
|
+
Dry::AutoInject(container)
|
19
|
+
else
|
20
|
+
Dry::AutoInject(container).send(strategy)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# @api public
|
25
|
+
def [](*deps)
|
26
|
+
load_components(*deps)
|
27
|
+
injector[*deps]
|
28
|
+
end
|
29
|
+
|
30
|
+
# @api public
|
31
|
+
def args
|
32
|
+
strategies[:args]
|
33
|
+
end
|
34
|
+
|
35
|
+
# @api public
|
36
|
+
def hash
|
37
|
+
strategies[:hash]
|
38
|
+
end
|
39
|
+
|
40
|
+
# @api public
|
41
|
+
def kwargs
|
42
|
+
strategies[:kwargs]
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def load_components(*components)
|
48
|
+
components = components.dup
|
49
|
+
aliases = components.last.is_a?(Hash) ? components.pop : {}
|
50
|
+
|
51
|
+
(components + aliases.values).each do |key|
|
52
|
+
container.load_component(key) unless container.key?(key)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def strategies
|
57
|
+
@strategies ||= Hash.new do |cache, strategy|
|
58
|
+
cache[strategy] = self.class.new(container, strategy: strategy, strategies_cache: cache)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/lib/dry/component/loader.rb
CHANGED
@@ -1,47 +1,36 @@
|
|
1
|
-
require 'memoizable'
|
2
1
|
require 'inflecto'
|
3
2
|
|
4
3
|
module Dry
|
5
4
|
module Component
|
6
|
-
def self.Loader(input)
|
7
|
-
Loader.new(Loader.identifier(input), Loader.path(input))
|
8
|
-
end
|
9
|
-
|
10
5
|
class Loader
|
11
|
-
include Memoizable
|
12
|
-
|
13
6
|
IDENTIFIER_SEPARATOR = '.'.freeze
|
14
7
|
PATH_SEPARATOR = '/'.freeze
|
15
8
|
|
16
9
|
attr_reader :identifier, :path, :file
|
17
10
|
|
18
|
-
def
|
19
|
-
input.to_s.gsub(PATH_SEPARATOR, IDENTIFIER_SEPARATOR)
|
20
|
-
|
21
|
-
|
22
|
-
def self.path(input)
|
23
|
-
input.to_s.gsub(IDENTIFIER_SEPARATOR, PATH_SEPARATOR)
|
24
|
-
end
|
25
|
-
|
26
|
-
def initialize(identifier, path)
|
27
|
-
@identifier = identifier
|
28
|
-
@path = path
|
11
|
+
def initialize(input)
|
12
|
+
@identifier = input.to_s.gsub(PATH_SEPARATOR, IDENTIFIER_SEPARATOR)
|
13
|
+
@path = input.to_s.gsub(IDENTIFIER_SEPARATOR, PATH_SEPARATOR)
|
29
14
|
@file = "#{path}.rb"
|
30
15
|
end
|
31
16
|
|
32
|
-
def
|
33
|
-
|
17
|
+
def namespaces
|
18
|
+
identifier.split(IDENTIFIER_SEPARATOR).map(&:to_sym)
|
34
19
|
end
|
35
|
-
memoize :name
|
36
20
|
|
37
21
|
def constant
|
38
22
|
Inflecto.constantize(name)
|
39
23
|
end
|
40
|
-
memoize :constant
|
41
24
|
|
42
25
|
def instance(*args)
|
43
26
|
constant.new(*args)
|
44
27
|
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def name
|
32
|
+
Inflecto.camelize(path)
|
33
|
+
end
|
45
34
|
end
|
46
35
|
end
|
47
36
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -33,6 +33,7 @@ RSpec.configure do |config|
|
|
33
33
|
|
34
34
|
config.before do
|
35
35
|
@load_paths = $LOAD_PATH.dup
|
36
|
+
@loaded_features = $LOADED_FEATURES.dup
|
36
37
|
Object.const_set(:Test, Module.new { |m| m.extend(TestNamespace) })
|
37
38
|
end
|
38
39
|
|
@@ -40,6 +41,10 @@ RSpec.configure do |config|
|
|
40
41
|
($LOAD_PATH - @load_paths).each do |path|
|
41
42
|
$LOAD_PATH.delete(path)
|
42
43
|
end
|
44
|
+
($LOADED_FEATURES - @loaded_features).each do |file|
|
45
|
+
$LOADED_FEATURES.delete(file)
|
46
|
+
end
|
47
|
+
|
43
48
|
Test.remove_constants
|
44
49
|
Object.send(:remove_const, :Test)
|
45
50
|
end
|
data/spec/unit/config_spec.rb
CHANGED
@@ -4,6 +4,14 @@ RSpec.describe Dry::Component::Config do
|
|
4
4
|
before do
|
5
5
|
class Test::App < Dry::Component::Container
|
6
6
|
configure do |config|
|
7
|
+
config.name = :application
|
8
|
+
config.root = SPEC_ROOT.join('fixtures/test').realpath
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class Test::SubApp < Dry::Component::Container
|
13
|
+
configure do |config|
|
14
|
+
config.name = :subapp
|
7
15
|
config.root = SPEC_ROOT.join('fixtures/test').realpath
|
8
16
|
end
|
9
17
|
end
|
@@ -12,4 +20,8 @@ RSpec.describe Dry::Component::Config do
|
|
12
20
|
it 'loads config under component name' do
|
13
21
|
expect(Test::App.options.foo).to eql('bar')
|
14
22
|
end
|
23
|
+
|
24
|
+
it 'allows different components to have different configurations' do
|
25
|
+
expect(Test::SubApp.options.bar).to eql('baz')
|
26
|
+
end
|
15
27
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'dry/component/container'
|
2
|
+
|
3
|
+
RSpec.describe Dry::Component::Container, '.auto_register!' do
|
4
|
+
context 'with the standard loader' do
|
5
|
+
before do
|
6
|
+
class Test::Container < Dry::Component::Container
|
7
|
+
configure do |config|
|
8
|
+
config.root = SPEC_ROOT.join('fixtures').realpath
|
9
|
+
end
|
10
|
+
|
11
|
+
load_paths!('components')
|
12
|
+
auto_register!('components')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it { expect(Test::Container['foo']).to be_an_instance_of(Foo) }
|
17
|
+
it { expect(Test::Container['bar']).to be_an_instance_of(Bar) }
|
18
|
+
it { expect(Test::Container['bar.baz']).to be_an_instance_of(Bar::Baz) }
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'with a custom loader' do
|
22
|
+
before do
|
23
|
+
class Test::Loader < Dry::Component::Loader
|
24
|
+
def identifier
|
25
|
+
super.gsub('.', '-')
|
26
|
+
end
|
27
|
+
|
28
|
+
def instance(*args)
|
29
|
+
constant.respond_to?(:call) ? constant : constant.new(*args)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class Test::Container < Dry::Component::Container
|
34
|
+
configure do |config|
|
35
|
+
config.root = SPEC_ROOT.join('fixtures').realpath
|
36
|
+
config.loader = ::Test::Loader
|
37
|
+
end
|
38
|
+
|
39
|
+
load_paths!('components')
|
40
|
+
auto_register!('components')
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
it { expect(Test::Container['foo']).to be_an_instance_of(Foo) }
|
45
|
+
it { expect(Test::Container['bar']).to eq(Bar) }
|
46
|
+
it { expect(Test::Container['bar'].call).to eq("Welcome to my Moe's Tavern!") }
|
47
|
+
it { expect(Test::Container['bar-baz']).to be_an_instance_of(Bar::Baz) }
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'dry/component/container'
|
2
|
+
|
3
|
+
RSpec.describe Dry::Component::Container, '.import' do
|
4
|
+
subject(:app) { Class.new(Dry::Component::Container) }
|
5
|
+
|
6
|
+
let(:db) do
|
7
|
+
Class.new(Dry::Component::Container) do
|
8
|
+
register(:users, %w(jane joe))
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
shared_examples_for 'an extended container' do
|
13
|
+
it 'imports one container into another' do
|
14
|
+
expect(app.key?('persistence.users')).to be(false)
|
15
|
+
|
16
|
+
app.finalize!
|
17
|
+
|
18
|
+
expect(app['persistence.users']).to eql(%w(jane joe))
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'when a container has a name' do
|
23
|
+
before do
|
24
|
+
db.configure { |c| c.name = :persistence }
|
25
|
+
app.import(db)
|
26
|
+
end
|
27
|
+
|
28
|
+
it_behaves_like 'an extended container'
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'when container does not have a name' do
|
32
|
+
before do
|
33
|
+
app.import(persistence: db)
|
34
|
+
end
|
35
|
+
|
36
|
+
it_behaves_like 'an extended container'
|
37
|
+
end
|
38
|
+
|
39
|
+
describe 'import module' do
|
40
|
+
it 'loads component when it was not loaded in the imported container yet' do
|
41
|
+
class Test::Other < Dry::Component::Container
|
42
|
+
configure do |config|
|
43
|
+
config.root = SPEC_ROOT.join('fixtures/import_test').realpath
|
44
|
+
end
|
45
|
+
|
46
|
+
load_paths!('lib')
|
47
|
+
end
|
48
|
+
|
49
|
+
class Test::Container < Dry::Component::Container
|
50
|
+
configure do |config|
|
51
|
+
config.root = SPEC_ROOT.join('fixtures/test').realpath
|
52
|
+
end
|
53
|
+
|
54
|
+
load_paths!('lib')
|
55
|
+
|
56
|
+
import other: Test::Other
|
57
|
+
end
|
58
|
+
|
59
|
+
module Test
|
60
|
+
Import = Container::Inject
|
61
|
+
end
|
62
|
+
|
63
|
+
class Test::Foo
|
64
|
+
include Test::Import['other.test.bar']
|
65
|
+
end
|
66
|
+
|
67
|
+
expect(Test::Foo.new.bar).to be_instance_of(Test::Bar)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/spec/unit/container_spec.rb
CHANGED
@@ -14,28 +14,28 @@ RSpec.describe Dry::Component::Container do
|
|
14
14
|
end
|
15
15
|
|
16
16
|
module Test
|
17
|
-
Import = Container
|
17
|
+
Import = Container::Inject
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
21
|
describe '.require' do
|
22
22
|
it 'requires a single file' do
|
23
|
-
container.require('lib/test/models')
|
23
|
+
container.require(Pathname('lib/test/models'))
|
24
24
|
|
25
25
|
expect(Test.const_defined?(:Models)).to be(true)
|
26
26
|
end
|
27
27
|
|
28
28
|
it 'requires many files when glob pattern is passed' do
|
29
|
-
container.require('lib/test/models/*.rb')
|
29
|
+
container.require(Pathname('lib/test/models/*.rb'))
|
30
30
|
|
31
31
|
expect(Test::Models.const_defined?(:User)).to be(true)
|
32
32
|
expect(Test::Models.const_defined?(:Book)).to be(true)
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
describe '.
|
37
|
-
it '
|
38
|
-
container.
|
36
|
+
describe '.load_component' do
|
37
|
+
it 'loads and registers components from configured load paths' do
|
38
|
+
container.load_component('test.foo')
|
39
39
|
|
40
40
|
expect(Test.const_defined?(:Foo)).to be(true)
|
41
41
|
expect(Test.const_defined?(:Dep)).to be(true)
|
@@ -45,6 +45,25 @@ RSpec.describe Dry::Component::Container do
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
+
describe '.boot' do
|
49
|
+
before do
|
50
|
+
class Test::Container < Dry::Component::Container
|
51
|
+
configure do |config|
|
52
|
+
config.root = SPEC_ROOT.join('fixtures/lazytest').realpath
|
53
|
+
end
|
54
|
+
|
55
|
+
load_paths!('lib')
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'lazy-boot a given component' do
|
60
|
+
container.boot(:bar)
|
61
|
+
|
62
|
+
expect(Test.const_defined?(:Bar)).to be(true)
|
63
|
+
expect(container.key?('test.bar')).to be(false)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
48
67
|
describe '.boot!' do
|
49
68
|
shared_examples_for 'a booted component' do
|
50
69
|
it 'boots a given component and finalizes it' do
|
@@ -98,5 +117,19 @@ RSpec.describe Dry::Component::Container do
|
|
98
117
|
end
|
99
118
|
end
|
100
119
|
end
|
120
|
+
|
121
|
+
it 'passes container to the finalizer block' do
|
122
|
+
class Test::Container < Dry::Component::Container
|
123
|
+
configure { |c| c.env = :awesome }
|
124
|
+
|
125
|
+
finalize(:foo) do |container|
|
126
|
+
register(:w00t, container.config.env)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
Test::Container.finalizers[:foo].()
|
131
|
+
|
132
|
+
expect(Test::Container[:w00t]).to be(:awesome)
|
133
|
+
end
|
101
134
|
end
|
102
135
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
RSpec.describe Dry::Component::Injector do
|
2
|
+
before do
|
3
|
+
class Test::Container < Dry::Component::Container
|
4
|
+
configure do |config|
|
5
|
+
config.root = SPEC_ROOT.join("fixtures/test").realpath
|
6
|
+
end
|
7
|
+
|
8
|
+
load_paths! "lib"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
it "supports args injection by default" do
|
13
|
+
obj = Class.new do
|
14
|
+
include Test::Container::Inject["test.dep"]
|
15
|
+
end.new
|
16
|
+
|
17
|
+
expect(obj.dep).to be_a Test::Dep
|
18
|
+
end
|
19
|
+
|
20
|
+
it "supports args injection with explicit method" do
|
21
|
+
obj = Class.new do
|
22
|
+
include Test::Container::Inject.args["test.dep"]
|
23
|
+
end.new
|
24
|
+
|
25
|
+
expect(obj.dep).to be_a Test::Dep
|
26
|
+
end
|
27
|
+
|
28
|
+
it "supports hash injection" do
|
29
|
+
obj = Class.new do
|
30
|
+
include Test::Container::Inject.hash["test.dep"]
|
31
|
+
end.new
|
32
|
+
|
33
|
+
expect(obj.dep).to be_a Test::Dep
|
34
|
+
end
|
35
|
+
|
36
|
+
it "support kwargs injection" do
|
37
|
+
obj = Class.new do
|
38
|
+
include Test::Container::Inject.kwargs["test.dep"]
|
39
|
+
end.new
|
40
|
+
|
41
|
+
expect(obj.dep).to be_a Test::Dep
|
42
|
+
end
|
43
|
+
|
44
|
+
it "allows injection strategies to be swapped" do
|
45
|
+
obj = Class.new do
|
46
|
+
include Test::Container::Inject.kwargs.hash["test.dep"]
|
47
|
+
end.new
|
48
|
+
|
49
|
+
expect(obj.dep).to be_a Test::Dep
|
50
|
+
end
|
51
|
+
|
52
|
+
it "supports aliases" do
|
53
|
+
obj = Class.new do
|
54
|
+
include Test::Container::Inject[foo: "test.dep"]
|
55
|
+
end.new
|
56
|
+
|
57
|
+
expect(obj.foo).to be_a Test::Dep
|
58
|
+
end
|
59
|
+
end
|
data/spec/unit/loader_spec.rb
CHANGED
@@ -9,12 +9,6 @@ RSpec.describe Dry::Component::Loader do
|
|
9
9
|
end
|
10
10
|
|
11
11
|
shared_examples_for 'a valid component' do
|
12
|
-
describe '#name' do
|
13
|
-
it 'returns name of the constant' do
|
14
|
-
expect(component.name).to eql('Test::Bar')
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
12
|
describe '#constant' do
|
19
13
|
it 'returns the constant' do
|
20
14
|
expect(component.constant).to be(Test::Bar)
|
@@ -47,19 +41,19 @@ RSpec.describe Dry::Component::Loader do
|
|
47
41
|
end
|
48
42
|
|
49
43
|
context 'from identifier as a symbol' do
|
50
|
-
subject(:component) { Dry::Component::Loader(:'test.bar') }
|
44
|
+
subject(:component) { Dry::Component::Loader.new(:'test.bar') }
|
51
45
|
|
52
46
|
it_behaves_like 'a valid component'
|
53
47
|
end
|
54
48
|
|
55
49
|
context 'from identifier as a string' do
|
56
|
-
subject(:component) { Dry::Component::Loader('test.bar') }
|
50
|
+
subject(:component) { Dry::Component::Loader.new('test.bar') }
|
57
51
|
|
58
52
|
it_behaves_like 'a valid component'
|
59
53
|
end
|
60
54
|
|
61
55
|
context 'from path' do
|
62
|
-
subject(:component) { Dry::Component::Loader('test/bar') }
|
56
|
+
subject(:component) { Dry::Component::Loader.new('test/bar') }
|
63
57
|
|
64
58
|
it_behaves_like 'a valid component'
|
65
59
|
end
|
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dry-component
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Solnica
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-06-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: memoizable
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0.4'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0.4'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: inflecto
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -44,34 +30,34 @@ dependencies:
|
|
44
30
|
requirements:
|
45
31
|
- - "~>"
|
46
32
|
- !ruby/object:Gem::Version
|
47
|
-
version: '0.
|
33
|
+
version: '0.3'
|
48
34
|
- - ">="
|
49
35
|
- !ruby/object:Gem::Version
|
50
|
-
version: 0.
|
36
|
+
version: 0.3.4
|
51
37
|
type: :runtime
|
52
38
|
prerelease: false
|
53
39
|
version_requirements: !ruby/object:Gem::Requirement
|
54
40
|
requirements:
|
55
41
|
- - "~>"
|
56
42
|
- !ruby/object:Gem::Version
|
57
|
-
version: '0.
|
43
|
+
version: '0.3'
|
58
44
|
- - ">="
|
59
45
|
- !ruby/object:Gem::Version
|
60
|
-
version: 0.
|
46
|
+
version: 0.3.4
|
61
47
|
- !ruby/object:Gem::Dependency
|
62
48
|
name: dry-auto_inject
|
63
49
|
requirement: !ruby/object:Gem::Requirement
|
64
50
|
requirements:
|
65
51
|
- - "~>"
|
66
52
|
- !ruby/object:Gem::Version
|
67
|
-
version: '0.
|
53
|
+
version: '0.3'
|
68
54
|
type: :runtime
|
69
55
|
prerelease: false
|
70
56
|
version_requirements: !ruby/object:Gem::Requirement
|
71
57
|
requirements:
|
72
58
|
- - "~>"
|
73
59
|
- !ruby/object:Gem::Version
|
74
|
-
version: '0.
|
60
|
+
version: '0.3'
|
75
61
|
- !ruby/object:Gem::Dependency
|
76
62
|
name: dry-configurable
|
77
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -150,8 +136,23 @@ files:
|
|
150
136
|
- lib/dry/component.rb
|
151
137
|
- lib/dry/component/config.rb
|
152
138
|
- lib/dry/component/container.rb
|
139
|
+
- lib/dry/component/injector.rb
|
153
140
|
- lib/dry/component/loader.rb
|
154
141
|
- lib/dry/component/version.rb
|
142
|
+
- spec/fixtures/components/bar.rb
|
143
|
+
- spec/fixtures/components/bar/baz.rb
|
144
|
+
- spec/fixtures/components/foo.rb
|
145
|
+
- spec/fixtures/import_test/config/application.yml
|
146
|
+
- spec/fixtures/import_test/core/boot/bar.rb
|
147
|
+
- spec/fixtures/import_test/lib/test/bar.rb
|
148
|
+
- spec/fixtures/import_test/lib/test/foo.rb
|
149
|
+
- spec/fixtures/lazytest/config/application.yml
|
150
|
+
- spec/fixtures/lazytest/core/boot/bar.rb
|
151
|
+
- spec/fixtures/lazytest/lib/test/dep.rb
|
152
|
+
- spec/fixtures/lazytest/lib/test/foo.rb
|
153
|
+
- spec/fixtures/lazytest/lib/test/models.rb
|
154
|
+
- spec/fixtures/lazytest/lib/test/models/book.rb
|
155
|
+
- spec/fixtures/lazytest/lib/test/models/user.rb
|
155
156
|
- spec/fixtures/other/config/boot/bar.rb
|
156
157
|
- spec/fixtures/other/lib/test/dep.rb
|
157
158
|
- spec/fixtures/other/lib/test/foo.rb
|
@@ -159,6 +160,7 @@ files:
|
|
159
160
|
- spec/fixtures/other/lib/test/models/book.rb
|
160
161
|
- spec/fixtures/other/lib/test/models/user.rb
|
161
162
|
- spec/fixtures/test/config/application.yml
|
163
|
+
- spec/fixtures/test/config/subapp.yml
|
162
164
|
- spec/fixtures/test/core/boot/bar.rb
|
163
165
|
- spec/fixtures/test/lib/test/dep.rb
|
164
166
|
- spec/fixtures/test/lib/test/foo.rb
|
@@ -167,7 +169,10 @@ files:
|
|
167
169
|
- spec/fixtures/test/lib/test/models/user.rb
|
168
170
|
- spec/spec_helper.rb
|
169
171
|
- spec/unit/config_spec.rb
|
172
|
+
- spec/unit/container/auto_register_spec.rb
|
173
|
+
- spec/unit/container/import_spec.rb
|
170
174
|
- spec/unit/container_spec.rb
|
175
|
+
- spec/unit/injector_spec.rb
|
171
176
|
- spec/unit/loader_spec.rb
|
172
177
|
homepage: https://github.com/dryrb/dry-component
|
173
178
|
licenses:
|
@@ -189,11 +194,25 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
189
194
|
version: '0'
|
190
195
|
requirements: []
|
191
196
|
rubyforge_project:
|
192
|
-
rubygems_version: 2.
|
197
|
+
rubygems_version: 2.5.1
|
193
198
|
signing_key:
|
194
199
|
specification_version: 4
|
195
200
|
summary: Organize your code into reusable components
|
196
201
|
test_files:
|
202
|
+
- spec/fixtures/components/bar.rb
|
203
|
+
- spec/fixtures/components/bar/baz.rb
|
204
|
+
- spec/fixtures/components/foo.rb
|
205
|
+
- spec/fixtures/import_test/config/application.yml
|
206
|
+
- spec/fixtures/import_test/core/boot/bar.rb
|
207
|
+
- spec/fixtures/import_test/lib/test/bar.rb
|
208
|
+
- spec/fixtures/import_test/lib/test/foo.rb
|
209
|
+
- spec/fixtures/lazytest/config/application.yml
|
210
|
+
- spec/fixtures/lazytest/core/boot/bar.rb
|
211
|
+
- spec/fixtures/lazytest/lib/test/dep.rb
|
212
|
+
- spec/fixtures/lazytest/lib/test/foo.rb
|
213
|
+
- spec/fixtures/lazytest/lib/test/models.rb
|
214
|
+
- spec/fixtures/lazytest/lib/test/models/book.rb
|
215
|
+
- spec/fixtures/lazytest/lib/test/models/user.rb
|
197
216
|
- spec/fixtures/other/config/boot/bar.rb
|
198
217
|
- spec/fixtures/other/lib/test/dep.rb
|
199
218
|
- spec/fixtures/other/lib/test/foo.rb
|
@@ -201,6 +220,7 @@ test_files:
|
|
201
220
|
- spec/fixtures/other/lib/test/models/book.rb
|
202
221
|
- spec/fixtures/other/lib/test/models/user.rb
|
203
222
|
- spec/fixtures/test/config/application.yml
|
223
|
+
- spec/fixtures/test/config/subapp.yml
|
204
224
|
- spec/fixtures/test/core/boot/bar.rb
|
205
225
|
- spec/fixtures/test/lib/test/dep.rb
|
206
226
|
- spec/fixtures/test/lib/test/foo.rb
|
@@ -209,5 +229,8 @@ test_files:
|
|
209
229
|
- spec/fixtures/test/lib/test/models/user.rb
|
210
230
|
- spec/spec_helper.rb
|
211
231
|
- spec/unit/config_spec.rb
|
232
|
+
- spec/unit/container/auto_register_spec.rb
|
233
|
+
- spec/unit/container/import_spec.rb
|
212
234
|
- spec/unit/container_spec.rb
|
235
|
+
- spec/unit/injector_spec.rb
|
213
236
|
- spec/unit/loader_spec.rb
|