dry-system 0.7.1 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
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