dry-system 0.7.3 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +17 -0
  3. data/lib/dry/system.rb +24 -0
  4. data/lib/dry/system/booter.rb +75 -43
  5. data/lib/dry/system/booter/component_registry.rb +37 -0
  6. data/lib/dry/system/component.rb +9 -4
  7. data/lib/dry/system/components.rb +6 -0
  8. data/lib/dry/system/components/bootable.rb +307 -0
  9. data/lib/dry/system/components/config.rb +33 -0
  10. data/lib/dry/system/constants.rb +2 -0
  11. data/lib/dry/system/container.rb +69 -22
  12. data/lib/dry/system/errors.rb +2 -2
  13. data/lib/dry/system/lifecycle.rb +40 -7
  14. data/lib/dry/system/provider.rb +46 -0
  15. data/lib/dry/system/provider_registry.rb +25 -0
  16. data/lib/dry/system/settings.rb +59 -0
  17. data/lib/dry/system/settings/file_loader.rb +28 -0
  18. data/lib/dry/system/settings/file_parser.rb +49 -0
  19. data/lib/dry/system/system_components/settings.rb +9 -0
  20. data/lib/dry/system/version.rb +1 -1
  21. metadata +27 -144
  22. data/.gitignore +0 -39
  23. data/.rspec +0 -3
  24. data/.travis.yml +0 -22
  25. data/.yardopts +0 -5
  26. data/CONTRIBUTING.md +0 -29
  27. data/Gemfile +0 -9
  28. data/Rakefile +0 -12
  29. data/dry-system.gemspec +0 -31
  30. data/examples/custom_configuration_auto_register/Gemfile +0 -5
  31. data/examples/custom_configuration_auto_register/lib/entities/user.rb +0 -7
  32. data/examples/custom_configuration_auto_register/lib/user_repo.rb +0 -5
  33. data/examples/custom_configuration_auto_register/run.rb +0 -8
  34. data/examples/custom_configuration_auto_register/system/boot/persistence.rb +0 -13
  35. data/examples/custom_configuration_auto_register/system/container.rb +0 -16
  36. data/examples/custom_configuration_auto_register/system/import.rb +0 -3
  37. data/examples/standalone/Gemfile +0 -5
  38. data/examples/standalone/lib/user_repo.rb +0 -5
  39. data/examples/standalone/run.rb +0 -8
  40. data/examples/standalone/system/boot/persistence.rb +0 -13
  41. data/examples/standalone/system/container.rb +0 -9
  42. data/examples/standalone/system/import.rb +0 -3
  43. data/spec/fixtures/components/bar.rb +0 -5
  44. data/spec/fixtures/components/bar/baz.rb +0 -4
  45. data/spec/fixtures/components/foo.rb +0 -2
  46. data/spec/fixtures/components/no_register.rb +0 -4
  47. data/spec/fixtures/import_test/config/application.yml +0 -2
  48. data/spec/fixtures/import_test/lib/test/bar.rb +0 -4
  49. data/spec/fixtures/import_test/lib/test/foo.rb +0 -5
  50. data/spec/fixtures/import_test/system/boot/bar.rb +0 -11
  51. data/spec/fixtures/lazytest/config/application.yml +0 -2
  52. data/spec/fixtures/lazytest/lib/test/dep.rb +0 -4
  53. data/spec/fixtures/lazytest/lib/test/foo.rb +0 -5
  54. data/spec/fixtures/lazytest/lib/test/models.rb +0 -4
  55. data/spec/fixtures/lazytest/lib/test/models/book.rb +0 -6
  56. data/spec/fixtures/lazytest/lib/test/models/user.rb +0 -6
  57. data/spec/fixtures/lazytest/system/boot/bar.rb +0 -15
  58. data/spec/fixtures/magic_comments/comments.rb +0 -17
  59. data/spec/fixtures/manual_registration/container/foo.rb +0 -6
  60. data/spec/fixtures/manual_registration/lib/test/foo.rb +0 -9
  61. data/spec/fixtures/multiple_namespaced_components/multiple/level/baz.rb +0 -7
  62. data/spec/fixtures/multiple_namespaced_components/multiple/level/foz.rb +0 -6
  63. data/spec/fixtures/namespaced_components/namespaced/bar.rb +0 -5
  64. data/spec/fixtures/namespaced_components/namespaced/foo.rb +0 -4
  65. data/spec/fixtures/other/config/boot/bar.rb +0 -11
  66. data/spec/fixtures/other/config/boot/hell.rb +0 -3
  67. data/spec/fixtures/other/lib/test/dep.rb +0 -4
  68. data/spec/fixtures/other/lib/test/foo.rb +0 -5
  69. data/spec/fixtures/other/lib/test/models.rb +0 -4
  70. data/spec/fixtures/other/lib/test/models/book.rb +0 -6
  71. data/spec/fixtures/other/lib/test/models/user.rb +0 -6
  72. data/spec/fixtures/stubbing/lib/test/car.rb +0 -7
  73. data/spec/fixtures/stubbing/system/boot/db.rb +0 -8
  74. data/spec/fixtures/test/config/application.yml +0 -2
  75. data/spec/fixtures/test/config/subapp.yml +0 -2
  76. data/spec/fixtures/test/lib/test/dep.rb +0 -4
  77. data/spec/fixtures/test/lib/test/foo.rb +0 -5
  78. data/spec/fixtures/test/lib/test/models.rb +0 -4
  79. data/spec/fixtures/test/lib/test/models/book.rb +0 -6
  80. data/spec/fixtures/test/lib/test/models/user.rb +0 -6
  81. data/spec/fixtures/test/lib/test/singleton_dep.rb +0 -7
  82. data/spec/fixtures/test/log/.gitkeep +0 -0
  83. data/spec/fixtures/test/system/boot/bar.rb +0 -11
  84. data/spec/fixtures/test/system/boot/client.rb +0 -7
  85. data/spec/fixtures/test/system/boot/db.rb +0 -1
  86. data/spec/fixtures/test/system/boot/hell.rb +0 -3
  87. data/spec/fixtures/test/system/boot/logger.rb +0 -5
  88. data/spec/fixtures/umbrella/system/boot/db.rb +0 -10
  89. data/spec/integration/boot_spec.rb +0 -18
  90. data/spec/integration/container/lazy_loading/manual_registration_spec.rb +0 -18
  91. data/spec/integration/import_spec.rb +0 -81
  92. data/spec/spec_helper.rb +0 -48
  93. data/spec/unit/auto_registrar/configuration_spec.rb +0 -26
  94. data/spec/unit/component_spec.rb +0 -121
  95. data/spec/unit/container/auto_register_spec.rb +0 -113
  96. data/spec/unit/container/config_spec.rb +0 -38
  97. data/spec/unit/container/finalize_spec.rb +0 -97
  98. data/spec/unit/container/import_spec.rb +0 -53
  99. data/spec/unit/container/injector_spec.rb +0 -29
  100. data/spec/unit/container_spec.rb +0 -244
  101. data/spec/unit/loader_spec.rb +0 -64
  102. data/spec/unit/magic_comments_parser_spec.rb +0 -41
@@ -1,6 +0,0 @@
1
- module Test
2
- module Models
3
- class Book
4
- end
5
- end
6
- end
@@ -1,6 +0,0 @@
1
- module Test
2
- module Models
3
- class User
4
- end
5
- end
6
- end
@@ -1,7 +0,0 @@
1
- require 'singleton'
2
-
3
- module Test
4
- class SingletonDep
5
- include Singleton
6
- end
7
- end
File without changes
@@ -1,11 +0,0 @@
1
- Test::Container.namespace(:test) do |container|
2
- module Test
3
- module Bar
4
- # I shall be booted
5
- end
6
- end
7
-
8
- container.finalize(:bar) do
9
- container.register(:bar, 'I was finalized')
10
- end
11
- end
@@ -1,7 +0,0 @@
1
- Test::Container.finalize(:client) do |container|
2
- use :logger
3
-
4
- Client = Struct.new(:logger)
5
-
6
- container.register(:client, Client.new(logger))
7
- end
@@ -1 +0,0 @@
1
- # this is just for Container.finalize spec, actual finalization code is in the test
@@ -1,3 +0,0 @@
1
- Test::Container.finalize :heaven do |container|
2
- container.register('heaven', 'string')
3
- end
@@ -1,5 +0,0 @@
1
- Test::Container.finalize(:logger) do |container|
2
- require 'logger'
3
-
4
- container.register(:logger, Logger.new(container.root.join('log/test.log')))
5
- end
@@ -1,10 +0,0 @@
1
- Test::Umbrella.namespace(:db) do |container|
2
- module Db
3
- class Repo
4
- end
5
- end
6
-
7
- container.finalize(:db) do
8
- container.register(:repo, Db::Repo.new)
9
- end
10
- end
@@ -1,18 +0,0 @@
1
- RSpec.describe 'boot files' do
2
- subject(:system) { Test::Container }
3
-
4
- before do
5
- class Test::Container < Dry::System::Container
6
- configure do |config|
7
- config.root = SPEC_ROOT.join('fixtures/test').realpath
8
- end
9
- end
10
- end
11
-
12
- it 'auto-boots dependency of a bootable component' do
13
- system.start(:client)
14
-
15
- expect(system[:client]).to be_a(Client)
16
- expect(system[:client].logger).to be_a(Logger)
17
- end
18
- end
@@ -1,18 +0,0 @@
1
- RSpec.describe 'Lazy-loading manual registration files' do
2
- before do
3
- module Test
4
- class Container < Dry::System::Container
5
- configure do |config|
6
- config.root = SPEC_ROOT.join('fixtures/manual_registration').realpath
7
- end
8
-
9
- load_paths!('lib')
10
- end
11
- end
12
- end
13
-
14
- it 'loads a manual registration file if the component could not be found' do
15
- expect(Test::Container['foo.special']).to be_a(Test::Foo)
16
- expect(Test::Container['foo.special'].name).to eq "special"
17
- end
18
- end
@@ -1,81 +0,0 @@
1
- require 'dry/system/stubs'
2
-
3
- RSpec.describe 'Lazy-booting external deps' do
4
- before do
5
- module Test
6
- class Umbrella < Dry::System::Container
7
- configure do |config|
8
- config.name = :core
9
- config.root = SPEC_ROOT.join('fixtures/umbrella').realpath
10
- end
11
- end
12
-
13
- class App < Dry::System::Container
14
- configure do |config|
15
- config.name = :main
16
- end
17
- end
18
- end
19
- end
20
-
21
- shared_examples_for 'lazy booted dependency' do
22
- it 'lazy boots an external dep provided by top-level container' do
23
- expect(user_repo.repo).to be_instance_of(Db::Repo)
24
- end
25
-
26
- it 'loads an external dep during finalization' do
27
- system.finalize!
28
- expect(user_repo.repo).to be_instance_of(Db::Repo)
29
- end
30
- end
31
-
32
- context 'when top-level container provides the dependency' do
33
- let(:user_repo) do
34
- Class.new { include Test::Import['db.repo'] }.new
35
- end
36
-
37
- let(:system) { Test::Umbrella }
38
-
39
- before do
40
- module Test
41
- Umbrella.import(main: App)
42
- Import = Umbrella.injector
43
- end
44
- end
45
-
46
- it_behaves_like 'lazy booted dependency'
47
-
48
- context 'when stubs are enabled' do
49
- before do
50
- system.enable_stubs!
51
- end
52
-
53
- it_behaves_like 'lazy booted dependency'
54
- end
55
- end
56
-
57
- context 'when top-level container provides the dependency through import' do
58
- let(:user_repo) do
59
- Class.new { include Test::Import['core.db.repo'] }.new
60
- end
61
-
62
- let(:system) { Test::App }
63
-
64
- before do
65
- module Test
66
- App.import(core: Umbrella)
67
- Import = App.injector
68
- end
69
- end
70
-
71
- it_behaves_like 'lazy booted dependency'
72
-
73
- context 'when stubs are enabled' do
74
- before do
75
- system.enable_stubs!
76
- end
77
-
78
- it_behaves_like 'lazy booted dependency'
79
- end
80
- end
81
- end
data/spec/spec_helper.rb DELETED
@@ -1,48 +0,0 @@
1
- # encoding: utf-8
2
-
3
- if RUBY_ENGINE == 'ruby' && RUBY_VERSION >= '2.3'
4
- require 'simplecov'
5
- SimpleCov.start
6
- end
7
-
8
- begin
9
- require 'byebug'
10
- rescue LoadError; end
11
-
12
- SPEC_ROOT = Pathname(__FILE__).dirname
13
-
14
- Dir[SPEC_ROOT.join('support/*.rb').to_s].each { |f| require f }
15
- Dir[SPEC_ROOT.join('shared/*.rb').to_s].each { |f| require f }
16
-
17
- require 'dry/system/container'
18
- require 'dry/system/stubs'
19
-
20
- module TestNamespace
21
- def remove_constants
22
- constants.each do |name|
23
- remove_const(name)
24
- end
25
- end
26
- end
27
-
28
- RSpec.configure do |config|
29
- config.disable_monkey_patching!
30
-
31
- config.before do
32
- @load_paths = $LOAD_PATH.dup
33
- @loaded_features = $LOADED_FEATURES.dup
34
- Object.const_set(:Test, Module.new { |m| m.extend(TestNamespace) })
35
- end
36
-
37
- config.after do
38
- ($LOAD_PATH - @load_paths).each do |path|
39
- $LOAD_PATH.delete(path)
40
- end
41
- ($LOADED_FEATURES - @loaded_features).each do |file|
42
- $LOADED_FEATURES.delete(file)
43
- end
44
-
45
- Test.remove_constants
46
- Object.send(:remove_const, :Test)
47
- end
48
- end
@@ -1,26 +0,0 @@
1
- require 'dry/system/auto_registrar/configuration'
2
-
3
- RSpec.describe Dry::System::AutoRegistrar::Configuration do
4
- subject(:auto_registration_conf) { Dry::System::AutoRegistrar::Configuration.new }
5
-
6
- describe "deafult values" do
7
- it "will setup exclude default proc" do
8
- expect(subject.exclude.(8)).to eq false
9
- end
10
-
11
- it "will setup instance default proc" do
12
- component = double("component")
13
- expect(component).to receive(:instance)
14
- subject.instance.(component)
15
- end
16
- end
17
-
18
- describe "add custom proc object to configuration" do
19
- it "execute proc that was previously save" do
20
- proc = Proc.new { |value| value + 1 }
21
- subject.instance(&proc)
22
- result = subject.instance.(5)
23
- expect(result).to eq 6
24
- end
25
- end
26
- end
@@ -1,121 +0,0 @@
1
- require 'dry/system/component'
2
-
3
- RSpec.describe Dry::System::Component do
4
- subject(:component) { Dry::System::Component.new(name) }
5
-
6
- describe '.new' do
7
- it 'caches components' do
8
- create = -> {
9
- Dry::System::Component.new('foo.bar', namespace: 'foo')
10
- }
11
-
12
- expect(create.()).to be(create.())
13
- end
14
-
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/)
28
- end
29
- end
30
-
31
- context 'when name is a symbol' do
32
- let(:name) { :foo }
33
-
34
- describe '#identifier' do
35
- it 'returns qualified identifier' do
36
- expect(component.identifier).to eql('foo')
37
- end
38
- end
39
-
40
- describe '#namespace' do
41
- it 'returns configured namespace' do
42
- expect(component.namespace).to be(nil)
43
- end
44
- end
45
-
46
- describe '#root_key' do
47
- it 'returns component key' do
48
- expect(component.root_key).to be(:foo)
49
- end
50
- end
51
-
52
- describe '#instance' do
53
- it 'builds an instance' do
54
- class Foo; end
55
- expect(component.instance).to be_instance_of(Foo)
56
- Object.send(:remove_const, :Foo)
57
- end
58
- end
59
- end
60
-
61
- shared_examples_for 'a valid component' do
62
- describe '#identifier' do
63
- it 'returns qualified identifier' do
64
- expect(component.identifier).to eql('test.foo')
65
- end
66
- end
67
-
68
- describe '#file' do
69
- it 'returns relative path to the component file' do
70
- expect(component.file).to eql('test/foo.rb')
71
- end
72
- end
73
-
74
- describe '#namespace' do
75
- it 'returns configured namespace' do
76
- expect(component.namespace).to be(nil)
77
- end
78
- end
79
-
80
- describe '#namespaced' do
81
- it 'returns a namespaced component' do
82
- namespaced = component.namespaced(:test)
83
-
84
- expect(namespaced.identifier).to eql('foo')
85
- expect(namespaced.path).to eql('test/foo')
86
- expect(namespaced.file).to eql('test/foo.rb')
87
- end
88
- end
89
-
90
- describe '#root_key' do
91
- it 'returns component key' do
92
- expect(component.root_key).to be(:test)
93
- end
94
- end
95
-
96
- describe '#instance' do
97
- it 'builds an instance' do
98
- module Test; class Foo; end; end
99
- expect(component.instance).to be_instance_of(Test::Foo)
100
- end
101
- end
102
- end
103
-
104
- context 'when name is a path' do
105
- let(:name) { 'test/foo' }
106
-
107
- it_behaves_like 'a valid component'
108
- end
109
-
110
- context 'when name is a qualified string identifier' do
111
- let(:name) { 'test.foo' }
112
-
113
- it_behaves_like 'a valid component'
114
- end
115
-
116
- context 'when name is a qualified symbol identifier' do
117
- let(:name) { :'test.foo' }
118
-
119
- it_behaves_like 'a valid component'
120
- end
121
- end
@@ -1,113 +0,0 @@
1
- require 'dry/system/container'
2
-
3
- RSpec.describe Dry::System::Container, '.auto_register!' do
4
- context 'standard loader' do
5
- before do
6
- class Test::Container < Dry::System::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
-
20
- it "doesn't register files with inline option 'auto_register: false'" do
21
- expect(Test::Container.key?('no_register')).to eql false
22
- end
23
- end
24
-
25
- context 'with custom configuration block' do
26
- before do
27
- class Test::Container < Dry::System::Container
28
- configure do |config|
29
- config.root = SPEC_ROOT.join('fixtures').realpath
30
- end
31
-
32
- load_paths!('components')
33
- end
34
- end
35
-
36
- it 'exclude specific components' do
37
- Test::Container.auto_register!('components') do |config|
38
- config.instance do |component|
39
- component.identifier
40
- end
41
-
42
- config.exclude do |component|
43
- component.path =~ /bar/
44
- end
45
- end
46
-
47
- expect(Test::Container['foo']).to eql('foo')
48
-
49
- expect(Test::Container.key?('bar')).to eql false
50
- expect(Test::Container.key?('bar.baz')).to eql false
51
- end
52
- end
53
-
54
- context 'standard loader with a default namespace configured' do
55
- before do
56
- class Test::Container < Dry::System::Container
57
- configure do |config|
58
- config.root = SPEC_ROOT.join('fixtures').realpath
59
- config.default_namespace = 'namespaced'
60
- end
61
-
62
- load_paths!('namespaced_components')
63
- auto_register!('namespaced_components')
64
- end
65
- end
66
-
67
- specify { expect(Test::Container['bar']).to be_a(Namespaced::Bar) }
68
- specify { expect(Test::Container['bar'].foo).to be_a(Namespaced::Foo) }
69
- specify { expect(Test::Container['foo']).to be_a(Namespaced::Foo) }
70
- end
71
-
72
- context 'standard loader with a default namespace with multiple level' do
73
- before do
74
- class Test::Container < Dry::System::Container
75
- configure do |config|
76
- config.root = SPEC_ROOT.join('fixtures').realpath
77
- config.default_namespace = 'multiple.level'
78
- end
79
-
80
- load_paths!('multiple_namespaced_components')
81
- auto_register!('multiple_namespaced_components')
82
- end
83
- end
84
-
85
- specify { expect(Test::Container['baz']).to be_a(Multiple::Level::Baz) }
86
- specify { expect(Test::Container['foz']).to be_a(Multiple::Level::Foz) }
87
- end
88
-
89
- context 'with a custom loader' do
90
- before do
91
- class Test::Loader < Dry::System::Loader
92
- def call(*args)
93
- constant.respond_to?(:call) ? constant : constant.new(*args)
94
- end
95
- end
96
-
97
- class Test::Container < Dry::System::Container
98
- configure do |config|
99
- config.root = SPEC_ROOT.join('fixtures').realpath
100
- config.loader = ::Test::Loader
101
- end
102
-
103
- load_paths!('components')
104
- auto_register!('components')
105
- end
106
- end
107
-
108
- it { expect(Test::Container['foo']).to be_an_instance_of(Foo) }
109
- it { expect(Test::Container['bar']).to eq(Bar) }
110
- it { expect(Test::Container['bar'].call).to eq("Welcome to my Moe's Tavern!") }
111
- it { expect(Test::Container['bar.baz']).to be_an_instance_of(Bar::Baz) }
112
- end
113
- end