dry-system 0.7.1 → 0.7.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: a21788fc7c60708d5a764c16be462eb0efba44d1
4
- data.tar.gz: f147f16d6283e31fa9382392259b3313c481c92a
3
+ metadata.gz: 6f148327cdac0f870ac0ac39a244d59cc2edfb15
4
+ data.tar.gz: d712c57e08f1968fb7092a99e3c84fe706bb4097
5
5
  SHA512:
6
- metadata.gz: 4f6252dd95293e42e307dbbf38991c07153b08f532ca222659625a166a29447e328c6a1acbe74070447ea8f143673fa86c4b3f7bbb13efa0aab50eb23015d21b
7
- data.tar.gz: 8357c9d5e79c649d7d6794db762debf0056db52e213616a04e1660a2974b2d6c5ea75def5f43031385b794cd9d329063c81cec816e19ff8121ec3c35caf0b3d5
6
+ metadata.gz: 9fa712dbe64d87958faa6eaac6fc7dfbbf0d5b30e20b1cc52c196c2159db05380fdb45da00c39b52f02488db0aebaebbc65602fab66cbc091406ac73fe44c354
7
+ data.tar.gz: d5214fded99b89eed583d9fbb6397432d73407eba966bfab7026a8007d9670e7b214e3a50b07ffa964a84a0a6d1b349abae7b818e3d71b57e57851edc1ea5dde
data/.travis.yml CHANGED
@@ -10,11 +10,8 @@ rvm:
10
10
  - 2.1
11
11
  - 2.2
12
12
  - 2.3.1
13
- - rbx
13
+ - 2.4.1
14
14
  - jruby-9.1.5.0
15
- matrix:
16
- allow_failures:
17
- - rvm: rbx
18
15
  notifications:
19
16
  email: false
20
17
  webhooks:
data/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ # 0.7.2 - 2017-08-02
2
+
3
+ ### Added
4
+
5
+ * `Container.enable_stubs!` for test environments which enables stubbing components (GustavoCaso)
6
+
7
+ ### Changed
8
+
9
+ * Component identifiers can now include same name more than once ie `foo.stuff.foo` (GustavoCaso)
10
+ * `Container#boot!` was renamed to `Container#start` (davydovanton)
11
+ * `Container#boot` was renamed to `Container#init` (davydovanton)
12
+
13
+ [Compare v0.7.1...v0.7.2](https://github.com/dry-rb/dry-system/compare/v0.7.1...v0.7.2)
14
+
1
15
  # 0.7.1 - 2017-06-16
2
16
 
3
17
  ### Changed
data/dry-system.gemspec CHANGED
@@ -19,6 +19,7 @@ Gem::Specification.new do |spec|
19
19
 
20
20
  spec.add_runtime_dependency 'inflecto', '>= 0.0.2'
21
21
  spec.add_runtime_dependency 'concurrent-ruby', '~> 1.0'
22
+ spec.add_runtime_dependency 'dry-core', '>= 0.3.1'
22
23
  spec.add_runtime_dependency 'dry-equalizer', '~> 0.2'
23
24
  spec.add_runtime_dependency 'dry-container', '~> 0.6'
24
25
  spec.add_runtime_dependency 'dry-auto_inject', '>= 0.4.0'
@@ -33,13 +33,13 @@ module Dry
33
33
  # @api private
34
34
  def finalize!
35
35
  Dir[boot_files].each do |path|
36
- boot!(File.basename(path, '.rb').to_sym)
36
+ start(File.basename(path, '.rb').to_sym)
37
37
  end
38
38
  freeze
39
39
  end
40
40
 
41
41
  # @api private
42
- def boot(name)
42
+ def init(name)
43
43
  Kernel.require(path.join(name.to_s))
44
44
 
45
45
  call(name) do |lifecycle|
@@ -51,12 +51,12 @@ module Dry
51
51
  end
52
52
 
53
53
  # @api private
54
- def boot!(name)
54
+ def start(name)
55
55
  check_component_identifier(name)
56
56
 
57
57
  return self if booted.key?(name)
58
58
 
59
- boot(name) { |lifecycle| lifecycle.(:start) }
59
+ init(name) { |lifecycle| lifecycle.(:start) }
60
60
  booted[name] = true
61
61
 
62
62
  self
@@ -76,7 +76,7 @@ module Dry
76
76
  # @api private
77
77
  def boot_dependency(component)
78
78
  boot_file = component.boot_file(path)
79
- boot!(boot_file.basename('.*').to_s.to_sym) if boot_file.exist?
79
+ start(boot_file.basename('.*').to_s.to_sym) if boot_file.exist?
80
80
  end
81
81
 
82
82
  private
@@ -47,7 +47,7 @@ module Dry
47
47
  options = DEFAULT_OPTIONS.merge(options || {})
48
48
 
49
49
  ns, sep = options.values_at(:namespace, :separator)
50
- identifier = ensure_valid_identifier(name, ns, sep)
50
+ identifier = extract_identifier(name, ns, sep)
51
51
 
52
52
  path = name.to_s.gsub(sep, PATH_SEPARATOR)
53
53
  loader = options.fetch(:loader, Loader).new(path)
@@ -57,14 +57,18 @@ module Dry
57
57
  end
58
58
 
59
59
  # @api private
60
- def self.ensure_valid_identifier(name, ns, sep)
61
- keys = name.to_s.scan(WORD_REGEX)
60
+ def self.extract_identifier(name, ns, sep)
61
+ name_s = name.to_s
62
+ identifier = ns ? remove_namespace_from_path(name_s, ns) : name_s
62
63
 
63
- if keys.uniq.size != keys.size
64
- raise InvalidComponentError, name, 'duplicated keys in the name'
65
- end
64
+ identifier.scan(WORD_REGEX).join(sep)
65
+ end
66
66
 
67
- keys.reject { |s| ns.to_s.include?(s) }.join(sep)
67
+ # @api private
68
+ def self.remove_namespace_from_path(name, ns)
69
+ match_value = name.match(/^(?<remove_namespace>#{ns}).(?<identifier>.*)/)
70
+ raise InvalidComponentError.new(name, "namespace +#{ns}+ not found in path") unless match_value
71
+ match_value[:identifier]
68
72
  end
69
73
 
70
74
  # @api private
@@ -4,6 +4,8 @@ require 'dry-auto_inject'
4
4
  require 'dry-configurable'
5
5
  require 'dry-container'
6
6
 
7
+ require 'dry/core/deprecations'
8
+
7
9
  require 'dry/system/errors'
8
10
  require 'dry/system/loader'
9
11
  require 'dry/system/booter'
@@ -77,6 +79,7 @@ module Dry
77
79
  setting :importer, Dry::System::Importer
78
80
 
79
81
  class << self
82
+ extend Dry::Core::Deprecations['Dry::System::Container']
80
83
  # Configures the container
81
84
  #
82
85
  # @example
@@ -239,7 +242,7 @@ module Dry
239
242
  # @return [self] frozen container
240
243
  #
241
244
  # @api public
242
- def finalize!(&block)
245
+ def finalize!(freeze: true, &block)
243
246
  return self if frozen?
244
247
 
245
248
  yield(self) if block
@@ -249,7 +252,7 @@ module Dry
249
252
  manual_registrar.finalize!
250
253
  auto_registrar.finalize!
251
254
 
252
- freeze
255
+ self.freeze if freeze
253
256
  end
254
257
 
255
258
  # Boots a specific component
@@ -257,17 +260,18 @@ module Dry
257
260
  # As a result, `init` and `start` lifecycle triggers are called
258
261
  #
259
262
  # @example
260
- # MyApp.boot!(:persistence)
263
+ # MyApp.start(:persistence)
261
264
  #
262
265
  # @param name [Symbol] the name of a registered bootable component
263
266
  #
264
267
  # @return [self]
265
268
  #
266
269
  # @api public
267
- def boot!(name)
268
- booter.boot!(name)
270
+ def start(name)
271
+ booter.start(name)
269
272
  self
270
273
  end
274
+ deprecate :boot!, :start
271
275
 
272
276
  # Boots a specific component but calls only `init` lifecycle trigger
273
277
  #
@@ -275,17 +279,18 @@ module Dry
275
279
  # needed but its started environment is not required
276
280
  #
277
281
  # @example
278
- # MyApp.boot(:persistence)
282
+ # MyApp.init(:persistence)
279
283
  #
280
284
  # @param [Symbol] name The name of a registered bootable component
281
285
  #
282
286
  # @return [self]
283
287
  #
284
288
  # @api public
285
- def boot(name)
286
- booter.boot(name)
289
+ def init(name)
290
+ booter.init(name)
287
291
  self
288
292
  end
293
+ deprecate :boot, :init
289
294
 
290
295
  # Sets load paths relative to the container's root dir
291
296
  #
@@ -71,7 +71,7 @@ module Dry
71
71
  # @api private
72
72
  def use(*names)
73
73
  names.each do |name|
74
- container.boot!(name)
74
+ container.start(name)
75
75
  end
76
76
  end
77
77
 
@@ -0,0 +1,20 @@
1
+ module Dry
2
+ module System
3
+ class Container
4
+ # Incuded only in the Test environment
5
+ # Sending the message enable_stubs! allow you to stub components after
6
+ # finalize your container in your tests.
7
+ #
8
+ # @api private
9
+ module Stubs
10
+ def finalize!(&block)
11
+ super(freeze: false, &block)
12
+ end
13
+ end
14
+
15
+ def self.enable_stubs!
16
+ extend ::Dry::System::Container::Stubs
17
+ end
18
+ end
19
+ end
20
+ end
@@ -1,5 +1,5 @@
1
1
  module Dry
2
2
  module System
3
- VERSION = '0.7.1'.freeze
3
+ VERSION = '0.7.2'.freeze
4
4
  end
5
5
  end
@@ -0,0 +1,7 @@
1
+ module Stubbing
2
+ class Car
3
+ def wheels_count
4
+ 4
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ Test::Container.finalize(:mock) do |container|
2
+ container.register(:mock, false)
3
+ end
@@ -10,7 +10,7 @@ RSpec.describe 'boot files' do
10
10
  end
11
11
 
12
12
  it 'auto-boots dependency of a bootable component' do
13
- system.boot!(:client)
13
+ system.start(:client)
14
14
 
15
15
  expect(system[:client]).to be_a(Client)
16
16
  expect(system[:client].logger).to be_a(Logger)
data/spec/spec_helper.rb CHANGED
@@ -15,6 +15,7 @@ Dir[SPEC_ROOT.join('support/*.rb').to_s].each { |f| require f }
15
15
  Dir[SPEC_ROOT.join('shared/*.rb').to_s].each { |f| require f }
16
16
 
17
17
  require 'dry/system/container'
18
+ require 'dry/system/stubs'
18
19
 
19
20
  module TestNamespace
20
21
  def remove_constants
@@ -12,9 +12,19 @@ RSpec.describe Dry::System::Component do
12
12
  expect(create.()).to be(create.())
13
13
  end
14
14
 
15
- it 'raises when identifier/path has duplicated keys' do
16
- expect { Dry::System::Component.new('foo.bar.foo', namespace: 'foo') }
17
- .to raise_error(Dry::System::InvalidComponentError, /foo\.bar\.foo/)
15
+ it 'allows to have the same key multiple times in the identifier/path' do
16
+ component = Dry::System::Component.new('foo.bar.foo', namespace: 'foo')
17
+ expect(component.identifier).to eql('bar.foo')
18
+ end
19
+
20
+ it 'removes only the initial part from the identifier/path' do
21
+ component = Dry::System::Component.new('foo.bar.foo.user.foo.bar', namespace: 'foo.bar.foo')
22
+ expect(component.identifier).to eql('user.foo.bar')
23
+ end
24
+
25
+ it 'raises when namepsace is not present in path' do
26
+ expect { Dry::System::Component.new('foo.bar.foo', namespace: 'baz') }
27
+ .to raise_error(Dry::System::InvalidComponentError, /baz/)
18
28
  end
19
29
  end
20
30
 
@@ -53,28 +53,28 @@ RSpec.describe Dry::System::Container, '.finalize' do
53
53
  end
54
54
 
55
55
  specify 'boot triggers init' do
56
- system.booter.boot(:db)
56
+ system.booter.init(:db)
57
57
 
58
58
  expect(db).to have_received(:establish_connection)
59
59
  expect(db).to_not have_received(:load)
60
60
  end
61
61
 
62
- specify 'boot! triggers init + start' do
63
- system.booter.boot!(:db)
62
+ specify 'start triggers init + start' do
63
+ system.booter.start(:db)
64
64
 
65
65
  expect(db).to have_received(:establish_connection)
66
66
  expect(db).to have_received(:load)
67
67
  end
68
68
 
69
- specify 'boot! raises error on undefined method or variable' do
69
+ specify 'start raises error on undefined method or variable' do
70
70
  expect {
71
71
  system.finalize(:db) { oops('arg') }
72
- system.booter.boot!(:db)
72
+ system.booter.start(:db)
73
73
  }.to raise_error(NoMethodError, /oops/)
74
74
 
75
75
  expect {
76
76
  system.finalize(:db) { oops }
77
- system.booter.boot!(:db)
77
+ system.booter.start(:db)
78
78
  }.to raise_error(NameError, /oops/)
79
79
  end
80
80
 
@@ -83,11 +83,11 @@ RSpec.describe Dry::System::Container, '.finalize' do
83
83
  end
84
84
 
85
85
  specify 'lifecycle triggers are called only once' do
86
- system.booter.boot!(:db)
87
- system.booter.boot!(:db)
86
+ system.booter.start(:db)
87
+ system.booter.start(:db)
88
88
 
89
- system.booter.boot(:db)
90
- system.booter.boot(:db)
89
+ system.booter.init(:db)
90
+ system.booter.init(:db)
91
91
 
92
92
  expect(db).to have_received(:establish_connection).exactly(1)
93
93
  expect(db).to have_received(:load).exactly(1)
@@ -100,7 +100,7 @@ RSpec.describe Dry::System::Container do
100
100
  end
101
101
  end
102
102
 
103
- describe '.boot' do
103
+ describe '.init' do
104
104
  before do
105
105
  class Test::Container < Dry::System::Container
106
106
  configure do |config|
@@ -112,17 +112,17 @@ RSpec.describe Dry::System::Container do
112
112
  end
113
113
 
114
114
  it 'lazy-boot a given system' do
115
- container.boot(:bar)
115
+ container.init(:bar)
116
116
 
117
117
  expect(Test.const_defined?(:Bar)).to be(true)
118
118
  expect(container.key?('test.bar')).to be(false)
119
119
  end
120
120
  end
121
121
 
122
- describe '.boot!' do
122
+ describe '.start' do
123
123
  shared_examples_for 'a booted system' do
124
124
  it 'boots a given system and finalizes it' do
125
- container.boot!(:bar)
125
+ container.start(:bar)
126
126
 
127
127
  expect(Test.const_defined?(:Bar)).to be(true)
128
128
  expect(container['test.bar']).to eql('I was finalized')
@@ -130,13 +130,13 @@ RSpec.describe Dry::System::Container do
130
130
 
131
131
  it 'expects a symbol identifier matching file name' do
132
132
  expect {
133
- container.boot!('bar')
133
+ container.start('bar')
134
134
  }.to raise_error(ArgumentError, 'component identifier "bar" must be a symbol')
135
135
  end
136
136
 
137
137
  it 'expects identifier to point to an existing boot file' do
138
138
  expect {
139
- container.boot!(:foo)
139
+ container.start(:foo)
140
140
  }.to raise_error(
141
141
  ArgumentError,
142
142
  'component identifier +foo+ is invalid or boot file is missing'
@@ -146,7 +146,7 @@ RSpec.describe Dry::System::Container do
146
146
  describe "missmatch betwenn finalize name and registered component" do
147
147
  it "raises a meaningful error" do
148
148
  expect{
149
- container.boot!(:hell)
149
+ container.start(:hell)
150
150
  }.to raise_error(Dry::System::ComponentFileMismatchError)
151
151
  end
152
152
  end
@@ -195,4 +195,48 @@ RSpec.describe Dry::System::Container do
195
195
  expect(Test::Container[:w00t]).to be(:awesome)
196
196
  end
197
197
  end
198
+
199
+ context 'Allow to stub container' do
200
+ before do
201
+ class Test::Container < Dry::System::Container
202
+ configure do |config|
203
+ config.root = SPEC_ROOT.join('fixtures/stubbing').realpath
204
+ end
205
+ load_paths!('lib')
206
+ auto_register!('lib')
207
+ end
208
+ end
209
+
210
+ describe 'without enable_stubs!' do
211
+ before do
212
+ container.finalize!
213
+ end
214
+
215
+ it 'raises error when trying to stub freeze container' do
216
+ expect {
217
+ allow(container).to receive(:[]).with('mock').and_return(true)
218
+ }.to raise_error(RuntimeError, /frozen/)
219
+ end
220
+ end
221
+
222
+ describe 'with enable_stubs!' do
223
+ before do
224
+ container.enable_stubs!
225
+ container.finalize!
226
+ end
227
+
228
+ it 'allows to stub the container it self' do
229
+ expect(container['mock']).to eq false
230
+ allow(container).to receive(:[]).with('mock').and_return(true)
231
+ expect(container['mock']).to eq true
232
+ end
233
+
234
+ it 'allows to stub components' do
235
+ car = container['stubbing.car']
236
+ expect(car.wheels_count).to eq 4
237
+ allow(car).to receive(:wheels_count).and_return(5)
238
+ expect(car.wheels_count).to eq 5
239
+ end
240
+ end
241
+ end
198
242
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dry-system
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 0.7.2
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-06-16 00:00:00.000000000 Z
11
+ date: 2017-08-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: inflecto
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: dry-core
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 0.3.1
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 0.3.1
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: dry-equalizer
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -187,6 +201,7 @@ files:
187
201
  - lib/dry/system/loader.rb
188
202
  - lib/dry/system/magic_comments_parser.rb
189
203
  - lib/dry/system/manual_registrar.rb
204
+ - lib/dry/system/stubs.rb
190
205
  - lib/dry/system/version.rb
191
206
  - spec/fixtures/components/bar.rb
192
207
  - spec/fixtures/components/bar/baz.rb
@@ -217,6 +232,8 @@ files:
217
232
  - spec/fixtures/other/lib/test/models.rb
218
233
  - spec/fixtures/other/lib/test/models/book.rb
219
234
  - spec/fixtures/other/lib/test/models/user.rb
235
+ - spec/fixtures/stubbing/lib/stubbing/car.rb
236
+ - spec/fixtures/stubbing/system/boot/mock.rb
220
237
  - spec/fixtures/test/config/application.yml
221
238
  - spec/fixtures/test/config/subapp.yml
222
239
  - spec/fixtures/test/lib/test/dep.rb
@@ -300,6 +317,8 @@ test_files:
300
317
  - spec/fixtures/other/lib/test/models.rb
301
318
  - spec/fixtures/other/lib/test/models/book.rb
302
319
  - spec/fixtures/other/lib/test/models/user.rb
320
+ - spec/fixtures/stubbing/lib/stubbing/car.rb
321
+ - spec/fixtures/stubbing/system/boot/mock.rb
303
322
  - spec/fixtures/test/config/application.yml
304
323
  - spec/fixtures/test/config/subapp.yml
305
324
  - spec/fixtures/test/lib/test/dep.rb