dry-container 0.2.1 → 0.2.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 80070803509a4e967b6874018aa178ab1fff0c12
4
- data.tar.gz: 3a46e86e6ada0346d0da825d93c04bb225f6d31d
3
+ metadata.gz: 00fac333cd99a672b9cb5d60dac62f5ebcb197c1
4
+ data.tar.gz: 3e040234421d7e23618d0a8fc6e5273ccdb73fb0
5
5
  SHA512:
6
- metadata.gz: e32f26c42d3d6c268866b72eba0b4a6bac760c278da01c8d3b46d0ac12b9c5ebcfa31a6150bd38ae88998d7561d77fe0f95d8ea33dc8d0ce0be7be657f1d676f
7
- data.tar.gz: 8dc9547baf6a1b3ba22767c9008d4cd467e444269a0341e4cf0a1da01ebc90b6cc91cf673ea695cb237b5775389213dbec52eef05e6b0c6ab0364acfb482f3eb
6
+ metadata.gz: f161b567597ebd6f7a102ca2815687dbd1d50b4bf6d95187e4252f4793e28ef9318cf38ffd71ffdd136721ad7b65aeadde21f392e8016c538b016236c2485618
7
+ data.tar.gz: 1d6644026909c74463aa84963876d6af086ed7c6c2e8246769159298e76a8bcec1381955d2031b99fdc129e9edcc1cc05eb2784d8f5f2b0d5d4161bbc028d510
data/.rubocop.yml CHANGED
@@ -18,3 +18,7 @@ Lint/NestedMethodDefinition:
18
18
  Metrics/MethodLength:
19
19
  Exclude:
20
20
  - lib/dry/container/mixin.rb
21
+
22
+ Style/FileName:
23
+ Exclude:
24
+ - lib/dry-container.rb
data/README.md CHANGED
@@ -49,6 +49,25 @@ container.register(:block, call: false) do
49
49
  end
50
50
  container.resolve(:block)
51
51
  # => #<Proc:0x007fa75e6830f0@(irb):36>
52
+
53
+ # You can also register items under namespaces using the #namespace method
54
+ container.namespace('repositories') do
55
+ namespace('checkout') do
56
+ register('orders') { ThreadSafe::Array.new }
57
+ end
58
+ end
59
+ container.resolve('repositories.checkout.orders')
60
+ # => []
61
+
62
+ # Or import a namespace
63
+ ns = Dry::Container::Namespace.new('repositories') do
64
+ namespace('authentication') do
65
+ register('users') { ThreadSafe::Array.new }
66
+ end
67
+ end
68
+ container.import(ns)
69
+ container.resolve('repositories.authentication.users')
70
+ # => []
52
71
  ```
53
72
 
54
73
  You can also get container behaviour at both the class and instance level via the mixin:
@@ -76,7 +95,7 @@ You can configure how items are registered and resolved from the container:
76
95
  ```ruby
77
96
  Dry::Container.configure do |config|
78
97
  config.registry = ->(container, key, item, options) { container[key] = item }
79
- config.resolver = ->(key) { container[key] }
98
+ config.resolver = ->(container, key) { container[key] }
80
99
  end
81
100
 
82
101
  class Container
@@ -84,7 +103,7 @@ class Container
84
103
 
85
104
  configure do |config|
86
105
  config.registry = ->(container, key, item, options) { container[key] = item }
87
- config.resolver = ->(key) { container[key] }
106
+ config.resolver = ->(container, key) { container[key] }
88
107
  end
89
108
  end
90
109
 
@@ -93,7 +112,7 @@ class ContainerObject
93
112
 
94
113
  configure do |config|
95
114
  config.registry = ->(container, key, item, options) { container[key] = item }
96
- config.resolver = ->(key) { container[key] }
115
+ config.resolver = ->(container, key) { container[key] }
97
116
  end
98
117
  end
99
118
  ```
data/lib/dry/container.rb CHANGED
@@ -2,11 +2,15 @@ require 'thread_safe'
2
2
  require 'dry-configurable'
3
3
  require 'dry/container/error'
4
4
  require 'dry/container/item'
5
+ require 'dry/container/namespace'
5
6
  require 'dry/container/registry'
6
7
  require 'dry/container/resolver'
8
+ require 'dry/container/namespace_dsl'
7
9
  require 'dry/container/mixin'
8
10
  require 'dry/container/version'
9
11
 
12
+ # A collection of micro-libraries, each intended to encapsulate
13
+ # a common task in Ruby
10
14
  module Dry
11
15
  # Inversion of Control (IoC) container
12
16
  #
@@ -31,10 +31,11 @@ module Dry
31
31
  base.class_eval do
32
32
  extend ::Dry::Configurable
33
33
 
34
- setting :registry, Registry.new
35
- setting :resolver, Resolver.new
34
+ setting :registry, ::Dry::Container::Registry.new
35
+ setting :resolver, ::Dry::Container::Resolver.new
36
+ setting :namespace_separator, '.'
36
37
 
37
- @_container = ThreadSafe::Cache.new
38
+ @_container = ::ThreadSafe::Cache.new
38
39
  end
39
40
  end
40
41
  # @private
@@ -42,13 +43,14 @@ module Dry
42
43
  base.class_eval do
43
44
  extend ::Dry::Configurable
44
45
 
45
- setting :registry, Registry.new
46
- setting :resolver, Resolver.new
46
+ setting :registry, ::Dry::Container::Registry.new
47
+ setting :resolver, ::Dry::Container::Resolver.new
48
+ setting :namespace_separator, '.'
47
49
 
48
50
  attr_reader :_container
49
51
 
50
52
  def initialize(*args, &block)
51
- @_container = ThreadSafe::Cache.new
53
+ @_container = ::ThreadSafe::Cache.new
52
54
  super(*args, &block)
53
55
  end
54
56
 
@@ -69,7 +71,7 @@ module Dry
69
71
  # If a block is given, contents will be ignored and the block
70
72
  # will be registered instead
71
73
  #
72
- # @return [Dry::Container] self
74
+ # @return [Dry::Container::Mixin] self
73
75
  #
74
76
  # @api public
75
77
  def register(key, contents = nil, options = {}, &block)
@@ -96,6 +98,37 @@ module Dry
96
98
  config.resolver.call(_container, key)
97
99
  end
98
100
  alias_method :[], :resolve
101
+ # Evaluate block and register items in namespace
102
+ #
103
+ # @param [Mixed] namespace
104
+ # The namespace to register items in
105
+ #
106
+ # @return [Dry::Container::Mixin] self
107
+ #
108
+ # @api public
109
+ def namespace(namespace, &block)
110
+ ::Dry::Container::NamespaceDSL.new(
111
+ self,
112
+ namespace,
113
+ config.namespace_separator,
114
+ &block
115
+ )
116
+
117
+ self
118
+ end
119
+ # Import a namespace
120
+ #
121
+ # @param [Dry::Container::Namespace] namespace
122
+ # The namespace to import
123
+ #
124
+ # @return [Dry::Container::Mixin] self
125
+ #
126
+ # @api public
127
+ def import(namespace)
128
+ namespace(namespace.name, &namespace.block)
129
+
130
+ self
131
+ end
99
132
  end
100
133
  end
101
134
  end
@@ -0,0 +1,38 @@
1
+ module Dry
2
+ class Container
3
+ # Create a namespace to be imported
4
+ #
5
+ # @example
6
+ #
7
+ # ns = Dry::Container::Namespace.new('name') do
8
+ # register('item', 'item')
9
+ # end
10
+ #
11
+ # container = Dry::Container.new
12
+ #
13
+ # container.import(ns)
14
+ #
15
+ # container.resolve('name.item')
16
+ # => 'item'
17
+ #
18
+ #
19
+ # @api public
20
+ class Namespace
21
+ attr_reader :name, :block
22
+ # Create a new namespace
23
+ #
24
+ # @param [Mixed] name
25
+ # The name of the namespace
26
+ # @yield
27
+ # The block to evaluate when the namespace is imported
28
+ #
29
+ # @return [Dry::Container::Namespace]
30
+ #
31
+ # @api public
32
+ def initialize(name, &block)
33
+ @name = name
34
+ @block = block
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,39 @@
1
+ module Dry
2
+ class Container
3
+ # @api private
4
+ class NamespaceDSL < ::SimpleDelegator
5
+ def initialize(container, namespace, namespace_separator, &block)
6
+ @namespace = namespace
7
+ @namespace_separator = namespace_separator
8
+
9
+ super(container)
10
+
11
+ if block.arity.zero?
12
+ instance_eval(&block)
13
+ else
14
+ block.call(self)
15
+ end
16
+ end
17
+
18
+ def register(key, *args, &block)
19
+ super(namespaced(key), *args, &block)
20
+ end
21
+
22
+ def namespace(namespace, &block)
23
+ super(namespaced(namespace), &block)
24
+ end
25
+
26
+ def import(namespace)
27
+ namespace(namespace.name, &namespace.block)
28
+
29
+ self
30
+ end
31
+
32
+ private
33
+
34
+ def namespaced(key)
35
+ [@namespace, key].join(@namespace_separator)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -6,7 +6,7 @@ module Dry
6
6
  class Registry
7
7
  # @private
8
8
  def initialize
9
- @_mutex = Mutex.new
9
+ @_mutex = ::Mutex.new
10
10
  end
11
11
  # Register an item with the container to be resolved later
12
12
  #
@@ -31,7 +31,7 @@ module Dry
31
31
  if container.key?(key)
32
32
  fail Error, "There is already an item registered with the key #{key.inspect}"
33
33
  else
34
- container[key] = Item.new(item, options)
34
+ container[key] = ::Dry::Container::Item.new(item, options)
35
35
  end
36
36
  end
37
37
  end
@@ -1,6 +1,6 @@
1
1
  module Dry
2
2
  class Container
3
3
  # @api public
4
- VERSION = '0.2.1'.freeze
4
+ VERSION = '0.2.2'.freeze
5
5
  end
6
6
  end
@@ -72,6 +72,41 @@ shared_examples 'a container' do
72
72
  it { is_expected.to eq(item) }
73
73
  end
74
74
  end
75
+
76
+ describe 'namespace_separator' do
77
+ describe 'default' do
78
+ it { expect(klass.config.namespace_separator).to eq('.') }
79
+ end
80
+
81
+ describe 'custom' do
82
+ let(:custom_registry) { double('Registry') }
83
+ let(:key) { 'key' }
84
+ let(:namespace_separator) { '-' }
85
+ let(:namespace) { 'one' }
86
+
87
+ before do
88
+ klass.configure do |config|
89
+ config.namespace_separator = namespace_separator
90
+ end
91
+
92
+ container.namespace(namespace) do
93
+ register('key', 'item')
94
+ end
95
+ end
96
+
97
+ after do
98
+ # HACK: Have to reset the configuration so that it doesn't
99
+ # interfere with other specs
100
+ klass.configure do |config|
101
+ config.namespace_separator = '.'
102
+ end
103
+ end
104
+
105
+ subject! { container.resolve([namespace, key].join(namespace_separator)) }
106
+
107
+ it { is_expected.to eq('item') }
108
+ end
109
+ end
75
110
  end
76
111
 
77
112
  context 'with default configuration' do
@@ -149,5 +184,75 @@ shared_examples 'a container' do
149
184
  expect { container.resolve(:item) }.to raise_error(Dry::Container::Error)
150
185
  end
151
186
  end
187
+
188
+ describe 'namespace' do
189
+ context 'when block does not take arguments' do
190
+ before do
191
+ container.namespace('one') do
192
+ register('two', 2)
193
+ end
194
+ end
195
+
196
+ subject! { container.resolve('one.two') }
197
+
198
+ it 'registers items under the given namespace' do
199
+ is_expected.to eq(2)
200
+ end
201
+ end
202
+
203
+ context 'when block takes arguments' do
204
+ before do
205
+ container.namespace('one') do |c|
206
+ c.register('two', 2)
207
+ end
208
+ end
209
+
210
+ subject! { container.resolve('one.two') }
211
+
212
+ it 'registers items under the given namespace' do
213
+ is_expected.to eq(2)
214
+ end
215
+ end
216
+
217
+ context 'with nesting' do
218
+ before do
219
+ container.namespace('one') do
220
+ namespace('two') do
221
+ register('three', 3)
222
+ end
223
+ end
224
+ end
225
+
226
+ subject! { container.resolve('one.two.three') }
227
+
228
+ it 'registers items under the given namespaces' do
229
+ is_expected.to eq(3)
230
+ end
231
+ end
232
+ end
233
+
234
+ describe 'import' do
235
+ it 'allows importing of namespaces' do
236
+ ns = Dry::Container::Namespace.new('one') do
237
+ register('two', 2)
238
+ end
239
+
240
+ container.import(ns)
241
+
242
+ expect(container.resolve('one.two')).to eq(2)
243
+ end
244
+
245
+ it 'allows importing of nested namespaces' do
246
+ ns = Dry::Container::Namespace.new('two') do
247
+ register('three', 3)
248
+ end
249
+
250
+ container.namespace('one') do
251
+ import(ns)
252
+ end
253
+
254
+ expect(container.resolve('one.two.three')).to eq(3)
255
+ end
256
+ end
152
257
  end
153
258
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dry-container
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Holland
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-20 00:00:00.000000000 Z
11
+ date: 2015-08-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thread_safe
@@ -102,6 +102,8 @@ files:
102
102
  - lib/dry/container/error.rb
103
103
  - lib/dry/container/item.rb
104
104
  - lib/dry/container/mixin.rb
105
+ - lib/dry/container/namespace.rb
106
+ - lib/dry/container/namespace_dsl.rb
105
107
  - lib/dry/container/registry.rb
106
108
  - lib/dry/container/resolver.rb
107
109
  - lib/dry/container/version.rb