smart_core 0.6.0 → 0.7.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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +1 -1
  3. data/.rubocop.yml +1 -1
  4. data/.travis.yml +5 -8
  5. data/CHANGELOG.md +5 -0
  6. data/README.md +14 -4
  7. data/lib/smart_core.rb +2 -2
  8. data/lib/smart_core/container.rb +49 -56
  9. data/lib/smart_core/container/arbitary_lock.rb +22 -0
  10. data/lib/smart_core/container/definition_dsl.rb +105 -55
  11. data/lib/smart_core/container/{command_set.rb → definition_dsl/command_set.rb} +20 -26
  12. data/lib/smart_core/container/definition_dsl/commands.rb +12 -0
  13. data/lib/smart_core/container/{commands → definition_dsl/commands}/base.rb +3 -3
  14. data/lib/smart_core/container/definition_dsl/commands/definition/compose.rb +46 -0
  15. data/lib/smart_core/container/definition_dsl/commands/definition/namespace.rb +51 -0
  16. data/lib/smart_core/container/{commands → definition_dsl/commands/definition}/register.rb +13 -25
  17. data/lib/smart_core/container/definition_dsl/commands/instantiation/compose.rb +50 -0
  18. data/lib/smart_core/container/definition_dsl/commands/instantiation/freeze_state.rb +24 -0
  19. data/lib/smart_core/container/dependency_compatability.rb +3 -3
  20. data/lib/smart_core/container/dependency_compatability/definition.rb +42 -0
  21. data/lib/smart_core/container/dependency_compatability/general.rb +61 -0
  22. data/lib/smart_core/container/dependency_compatability/registry.rb +28 -29
  23. data/lib/smart_core/container/dependency_resolver.rb +9 -4
  24. data/lib/smart_core/container/entities.rb +11 -0
  25. data/lib/smart_core/container/{entity.rb → entities/base.rb} +7 -7
  26. data/lib/smart_core/container/entities/dependency.rb +38 -0
  27. data/lib/smart_core/container/entities/dependency_builder.rb +50 -0
  28. data/lib/smart_core/container/entities/namespace.rb +73 -0
  29. data/lib/smart_core/container/entities/namespace_builder.rb +41 -0
  30. data/lib/smart_core/container/errors.rb +43 -0
  31. data/lib/smart_core/container/key_guard.rb +5 -5
  32. data/lib/smart_core/container/mixin.rb +20 -16
  33. data/lib/smart_core/container/registry.rb +224 -201
  34. data/lib/smart_core/container/registry_builder.rb +38 -5
  35. data/lib/smart_core/{exceptions.rb → errors.rb} +0 -0
  36. data/lib/smart_core/operation.rb +3 -1
  37. data/lib/smart_core/operation/{custom.rb → callback.rb} +7 -7
  38. data/lib/smart_core/operation/result.rb +1 -1
  39. data/lib/smart_core/operation/result_interface.rb +3 -3
  40. data/lib/smart_core/version.rb +1 -1
  41. data/smart_core.gemspec +6 -5
  42. metadata +28 -38
  43. data/lib/smart_core/container/command_definer.rb +0 -117
  44. data/lib/smart_core/container/commands.rb +0 -9
  45. data/lib/smart_core/container/commands/namespace.rb +0 -53
  46. data/lib/smart_core/container/dependency.rb +0 -44
  47. data/lib/smart_core/container/dependency_builder.rb +0 -48
  48. data/lib/smart_core/container/dependency_compatability/abstract.rb +0 -59
  49. data/lib/smart_core/container/dependency_compatability/command_set.rb +0 -35
  50. data/lib/smart_core/container/exceptions.rb +0 -31
  51. data/lib/smart_core/container/memoized_dependency.rb +0 -28
  52. data/lib/smart_core/container/namespace.rb +0 -51
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b7867022eeaee9e4538e85a8daa448b0906cae19bf54bdeb1d527699de3934d3
4
- data.tar.gz: ba755bf600dfd06a1cf82f318dc48a5e6ed1955e703073757ca35ecba711d803
3
+ metadata.gz: 19dd6183688e0576100f7178ad66764ca76d1461c459eaeb239815c1b75a2d30
4
+ data.tar.gz: 34419b8bac8cc0e409c823282320fadf14f562225a5c4dd62545c4270b298919
5
5
  SHA512:
6
- metadata.gz: 745b23e80f8eaa5799cc538ee470f6fcd8bea122fe421b1baf719655f33c0fba4b838f5a985f5a3180247aa5e1b0f07e7e16266c1b0ac0ac22ce975fc336db06
7
- data.tar.gz: 70de948e0cc48516091af87cf194ed2564544c3d2586aaee5d7c97daaee96eee593a1426102461c36d76bd1add72ceb4bd1557b2746084ede695beccefdaef71
6
+ metadata.gz: '06718cef684bec320e3fa67d83e9486df6c991571fcabe6fad48a2a7063f554499e46a7c231bc37edb8dcb2325daf9004ae293f3e736e85f73a6eb6c791d7a74'
7
+ data.tar.gz: d13ec368c4bed72a132f1de1963c322383e8ad7d5168c3da188a13b649f7ec1cc27da080cc917b0c5c30c344436847229dd7bf92b429d6cd499dc77557274070
data/.rspec CHANGED
@@ -1,3 +1,3 @@
1
+ --format documentation
1
2
  --color
2
- --format progress
3
3
  --require spec_helper
@@ -5,7 +5,7 @@ inherit_gem:
5
5
 
6
6
  AllCops:
7
7
  UseCache: true
8
- TargetRubyVersion: 2.6.3
8
+ TargetRubyVersion: 2.6.5
9
9
  Include:
10
10
  - bin/console
11
11
  - lib/**/*.rb
@@ -1,20 +1,17 @@
1
1
  language: ruby
2
2
  sudo: false
3
- before_install: gem install bundler
4
3
  cache: bundler
4
+ before_install: gem install bundler
5
+ script: bundle exec rspec
5
6
  matrix:
6
7
  fast_finish: true
7
8
  include:
8
9
  - rvm: 2.3.8
9
- - rvm: 2.4.7
10
- - rvm: 2.5.6
11
- - rvm: 2.6.4
10
+ - rvm: 2.4.9
11
+ - rvm: 2.5.7
12
+ - rvm: 2.6.5
12
13
  - rvm: ruby-head
13
14
  - rvm: jruby-head
14
15
  allow_failures:
15
16
  - rvm: ruby-head
16
17
  - rvm: jruby-head
17
- script: bundle exec rspec
18
- notifications:
19
- slack:
20
- secure: CUM3xnSJvn/y6Z+epQrO5uSk1EUuP4S+ugcS+48nlWD6eEzhYZwcBAK9tvD6kYGOPzoWyKSbW6Is1kzSunNr6f8ICc8HtrVHzoHE8UCzwZ7FpjgD0JgMgC4+xLLBO6lV0Hc7dNh4KLAhy4Zvbr09DPjcG8UW9/QgUdn+wBf9LHMgA+2SpBPEzMwz6pMbWW/+kkoCz2KU877kEfuFFGfvoOEFWTxUUhuCYi5a1SmTjm9A7CFTEWNkX8yHJwdgVgONjvm9lnhTeV0DvMeEOhk8Kx/hzQ2OGIicXZXWyZFkzNzpQm5xE12Hs4rY7mGPbo3bsYRDH9Ys6yf4fpNf0oZ/1agzl/gnDzacA2wL2b+eq1uZblE/fdwrNp+GIH0R+Ec2rsVKM7kh71sA6Xp1pzFb2DnHj5O4QFaPMsLyIZqD0BkVt4pNfwi4ZUB56sWkYeRQGm8x2Beh02IyFfxI65lY5kZrW6GjXx5eFeOHcmzQzeADWLSBf4iw01G/A/QqwZzlZ3fm0fRJi8BKDh3Jj0IrGndE9Bl+E7uOClKKngTPxOVLOLo/vY5mfI8M94f99kr0J45XkoAdc0SQfi3hDa/tHaakI5GJsmByjgOQwV7OU/2wzJoXAg/RPYjsYcwnTgzm9bLXPhQzfM8rUS5vLTOWIW+N0QKmWml7eWVtiedcwXA=
@@ -1,6 +1,11 @@
1
1
  # Changelog
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
+ ## [0.7.0] - 2019-11-10
5
+ ### Changed
6
+ - `SmartCore::Operation::Custom` result type is renamed to `SmartCore::Operation::Callback`;
7
+ - Full reimplementation of `SmartCore::Container`;
8
+
4
9
  ## [0.6.0] - 2019-09-18
5
10
  ### Added
6
11
  - New result type: `SmartCore::Operation::Custom` with custom logic provided as a proc;
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # SmartCore · [![Gem Version](https://badge.fury.io/rb/smart_core.svg)](https://badge.fury.io/rb/smart_core) [![Build Status](https://travis-ci.org/0exp/smart_core.svg?branch=master)](https://travis-ci.org/0exp/smart_core) [![Coverage Status](https://coveralls.io/repos/github/0exp/smart_core/badge.svg?branch=master)](https://coveralls.io/github/0exp/smart_core?branch=master)
1
+ # SmartCore · [![Gem Version](https://badge.fury.io/rb/smart_core.svg)](https://badge.fury.io/rb/smart_core) [![Build Status](https://travis-ci.org/0exp/smart_core.svg?branch=master)](https://travis-ci.org/0exp/smart_core)
2
2
 
3
3
  In active development (**Coming Soon**: Powerful documentaion :))
4
4
  > Meetup Slides: [link](docs/SmartCore.pdf)
@@ -26,10 +26,20 @@ require 'smart_core'
26
26
  #### Completed abstractions:
27
27
 
28
28
  - Service Object (Operation, Functional Object);
29
+ - IoC Container (Dependency Container);
29
30
  - Initializer (DSL);
30
31
  - Validator (Validation Layer);
31
- - Dependency Container;
32
- - (Soon) Schema;
32
+
33
+ ---
34
+
35
+ #### Roadmap
36
+
37
+ - Value Object (`SmartCore::ValueObject` (`DTO`) (truely immutable and comparable objects 😈));
38
+ - Schema Structure Validator (`SmartCore::Schema`);
39
+ - Saga (`SmartCore::Saga`);
40
+ - External Type System (`SmartCore::Types`);
41
+ - Step-like execution behavior for `SmartCore::Operation` (`.step`);
42
+ - Automatic result instantiation and handling for `SmartCore::Operation`;
33
43
 
34
44
  ---
35
45
 
@@ -37,7 +47,7 @@ require 'smart_core'
37
47
 
38
48
  - Fork it ( https://github.com/0exp/smart_core/fork )
39
49
  - Create your feature branch (`git checkout -b feature/my-new-feature`)
40
- - Commit your changes (`git commit -am 'Add some feature'`)
50
+ - Commit your changes (`git commit -am '[feature_context] Add some feature'`)
41
51
  - Push to the branch (`git push origin feature/my-new-feature`)
42
52
  - Create new Pull Request
43
53
 
@@ -4,9 +4,9 @@
4
4
  # @since 0.1.0
5
5
  module SmartCore
6
6
  require_relative 'smart_core/version'
7
- require_relative 'smart_core/exceptions'
8
- require_relative 'smart_core/initializer'
7
+ require_relative 'smart_core/errors'
9
8
  require_relative 'smart_core/container'
9
+ require_relative 'smart_core/initializer'
10
10
  require_relative 'smart_core/injector'
11
11
  require_relative 'smart_core/validator'
12
12
  require_relative 'smart_core/operation'
@@ -1,123 +1,116 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # @api public
4
- # @since 0.5.0
4
+ # @since 0.1.0
5
5
  class SmartCore::Container
6
- require_relative 'container/exceptions'
7
- require_relative 'container/commands'
8
- require_relative 'container/command_set'
6
+ require_relative 'container/errors'
7
+ require_relative 'container/arbitary_lock'
9
8
  require_relative 'container/key_guard'
10
- require_relative 'container/entity'
11
- require_relative 'container/dependency'
12
- require_relative 'container/memoized_dependency'
13
- require_relative 'container/namespace'
14
- require_relative 'container/dependency_builder'
9
+ require_relative 'container/entities'
10
+ require_relative 'container/definition_dsl'
11
+ require_relative 'container/dependency_compatability'
15
12
  require_relative 'container/registry'
16
13
  require_relative 'container/registry_builder'
17
- require_relative 'container/dependency_compatability'
18
14
  require_relative 'container/dependency_resolver'
19
- require_relative 'container/definition_dsl'
20
15
  require_relative 'container/mixin'
21
16
 
22
- # TODO: container composition
23
- # TODO: #merge / #merge!
24
-
25
- # @since 0.5.0
17
+ # @since 0.1.0
26
18
  include DefinitionDSL
27
19
 
28
20
  # @return [void]
29
21
  #
30
22
  # @api public
31
- # @since 0.5.0
23
+ # @since 0.1.0
32
24
  def initialize
33
- build_registry
34
- @access_lock = Mutex.new
25
+ build_registry!
26
+ @access_lock = ArbitaryLock.new
35
27
  end
36
28
 
37
29
  # @param dependency_name [String, Symbol]
38
- # @param options [Hash<Symbol,Any>]
39
30
  # @param dependency_definition [Block]
40
31
  # @return [void]
41
32
  #
42
- # @todo option list
43
- #
44
33
  # @api public
45
- # @since 0.5.0
46
- def register(dependency_name, **options, &dependency_definition)
47
- thread_safe do
48
- registry.register(dependency_name, **options, &dependency_definition)
49
- end
34
+ # @sicne 0.1.0
35
+ def register(dependency_name, &dependency_definition)
36
+ thread_safe { registry.register_dependency(dependency_name, &dependency_definition) }
50
37
  end
51
38
 
39
+ # @param namespace_name [String, Symbol]
40
+ # @param dependencies_definition [Block]
52
41
  # @return [void]
53
42
  #
54
43
  # @api public
55
- # @since 0.5.0
56
- def freeze
57
- thread_safe { registry.freeze }
44
+ # @since 0.1.0
45
+ def namespace(namespace_name, &dependencies_definition)
46
+ thread_safe { registry.register_namespace(namespace_name, &dependencies_definition) }
58
47
  end
59
48
 
60
- # @return [Boolean]
49
+ # @param dependency_path [String, Symbol]
50
+ # @return [Any]
61
51
  #
62
52
  # @api public
63
- # @since 0.5.0
64
- def frozen?
65
- thread_safe { registry.frozen? }
53
+ # @since 0.1.0
54
+ def resolve(dependency_path)
55
+ thread_safe { DependencyResolver.resolve(registry, dependency_path) }
66
56
  end
67
57
 
68
- # @param namespace_name [String, Symbol]
69
- # @param dependency_definitions [Block]
70
58
  # @return [void]
71
59
  #
72
60
  # @api public
73
- # @since 0.5.0
74
- def namespace(namespace_name, &dependency_definitions)
75
- thread_safe do
76
- registry.namespace(namespace_name, &dependency_definitions)
77
- end
61
+ # @since 0.1.0
62
+ def freeze!
63
+ thread_safe { registry.freeze! }
78
64
  end
79
65
 
80
- # @param dependency_path [String, Symbol]
81
- # @return [Any]
66
+ # @return [Boolean]
82
67
  #
83
68
  # @api public
84
- # @since 0.5.0
85
- def resolve(dependency_path)
86
- thread_safe do
87
- DependencyResolver.resolve(registry, dependency_path)
88
- end
69
+ # @since 0.1.0
70
+ def frozen?
71
+ thread_safe { registry.frozen? }
89
72
  end
90
73
 
91
74
  # @return [void]
92
75
  #
93
76
  # @api public
94
- # @since 0.5.0
77
+ # @since 0.1.0
95
78
  def reload!
96
- thread_safe { build_registry }
79
+ thread_safe { build_registry! }
80
+ end
81
+
82
+ # @return [Hash<String|Symbol,SmartCore::Container::Entities::Base|Any>]
83
+ #
84
+ # @api public
85
+ # @since 0.1.0
86
+ def hash_tree(resolve_dependencies: false)
87
+ thread_safe { registry.hash_tree(resolve_dependencies: resolve_dependencies) }
97
88
  end
89
+ alias_method :to_h, :hash_tree
90
+ alias_method :to_hash, :hash_tree
98
91
 
99
92
  private
100
93
 
101
94
  # @return [SmartCore::Container::Registry]
102
95
  #
103
96
  # @api private
104
- # @since 0.5.0
97
+ # @since 0.1.0
105
98
  attr_reader :registry
106
99
 
107
100
  # @return [void]
108
101
  #
109
102
  # @api private
110
- # @since 0.5.0
111
- def build_registry
112
- @registry = RegistryBuilder.build(self.class.__commands__)
103
+ # @since 0.1.0
104
+ def build_registry!
105
+ @registry = RegistryBuilder.build(self)
113
106
  end
114
107
 
115
- # @param block [Proc]
108
+ # @param block [Block]
116
109
  # @return [Any]
117
110
  #
118
111
  # @api private
119
- # @since 0.5.0
112
+ # @since 0.1.0
120
113
  def thread_safe(&block)
121
- @access_lock.synchronize(&block)
114
+ @access_lock.thread_safe(&block)
122
115
  end
123
116
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api private
4
+ # @since 0.7.0
5
+ class SmartCore::Container::ArbitaryLock
6
+ # @return [void]
7
+ #
8
+ # @api private
9
+ # @since 0.7.0
10
+ def initialize
11
+ @lock = Mutex.new
12
+ end
13
+
14
+ # @param block [Proc]
15
+ # @return [Any]
16
+ #
17
+ # @api private
18
+ # @since 0.7.0
19
+ def thread_safe(&block)
20
+ @lock.owned? ? yield : @lock.synchronize(&block)
21
+ end
22
+ end
@@ -1,66 +1,116 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # @api private
4
- # @since 0.5.0
5
- module SmartCore::Container::DefinitionDSL
6
- class << self
7
- # @param base_klass [Class<SmartCore::Container>]
8
- # @return [void]
9
- #
10
- # @api private
11
- # @since 0.5.0
12
- def included(base_klass)
13
- base_klass.instance_variable_set(:@__commands__, SmartCore::Container::CommandSet.new)
14
- base_klass.singleton_class.send(:attr_reader, :__commands__)
15
- base_klass.extend(ClassMethods)
16
- base_klass.singleton_class.prepend(ClassInheritance)
3
+ class SmartCore::Container
4
+ # @api private
5
+ # @since 0.7.0
6
+ module DefinitionDSL
7
+ require_relative 'definition_dsl/commands'
8
+ require_relative 'definition_dsl/command_set'
9
+
10
+ class << self
11
+ # @param base_klass [Class<SmartCore::Container>]
12
+ # @return [void]
13
+ #
14
+ # @api private
15
+ # @since 0.7.0
16
+ def included(base_klass)
17
+ base_klass.instance_variable_set(:@__container_definition_commands__, CommandSet.new)
18
+ base_klass.instance_variable_set(:@__container_instantiation_commands__, CommandSet.new)
19
+ base_klass.instance_variable_set(:@__container_definition_lock__, ArbitaryLock.new)
20
+ base_klass.singleton_class.send(:attr_reader, :__container_definition_commands__)
21
+ base_klass.singleton_class.send(:attr_reader, :__container_instantiation_commands__)
22
+ base_klass.extend(ClassMethods)
23
+ base_klass.singleton_class.prepend(ClassInheritance)
24
+ end
17
25
  end
18
- end
19
26
 
20
- # @api private
21
- # @since 0.5.0
22
- module ClassInheritance
23
- # @param child_klass [Class<SmartCore::Container>]
24
- # @return [void]
25
- #
26
27
  # @api private
27
- # @since 0.5.0
28
- def inherited(child_klass)
29
- child_klass.instance_variable_set(:@__commands__, SmartCore::Container::CommandSet.new)
30
- child_klass.__commands__.concat(__commands__)
31
- child_klass.singleton_class.prepend(ClassInheritance)
32
- super
33
- end
34
- end
28
+ # @since 0.7.0
29
+ module ClassInheritance
30
+ # @param child_klass [Class<SmartCore::Container>]
31
+ # @return [void]
32
+ #
33
+ # @api private
34
+ # @since 0.7.0
35
+ def inherited(child_klass)
36
+ child_klass.instance_variable_set(:@__container_definition_commands__, CommandSet.new)
37
+ child_klass.instance_variable_set(:@__container_instantiation_commands__, CommandSet.new)
38
+ child_klass.instance_variable_set(:@__container_definition_lock__, ArbitaryLock.new)
35
39
 
36
- # @api private
37
- # @since 0.5.0
38
- module ClassMethods
39
- # @param namespace_name [String, Symbol]
40
- # @param dependency_definitions [Block]
41
- # @return [void]
42
- #
43
- # @api public
44
- # @since 0.5.0
45
- def namespace(namespace_name, &dependency_definitions)
46
- __commands__ << SmartCore::Container::Commands::Namespace.new(
47
- namespace_name, dependency_definitions
48
- )
40
+ child_klass.__container_definition_commands__.concat(
41
+ __container_definition_commands__
42
+ )
43
+
44
+ child_klass.__container_instantiation_commands__.concat(
45
+ __container_instantiation_commands__
46
+ )
47
+
48
+ child_klass.singleton_class.prepend(ClassInheritance)
49
+ super
50
+ end
49
51
  end
50
52
 
51
- # @param dependency_name [String, Symbol]
52
- # @param options [Hash<Symbol,Any>]
53
- # @param dependency_definition [Proc]
54
- # @return [void]
55
- #
56
- # @todo option list
57
- #
58
- # @api public
59
- # @since 0.5.0
60
- def register(dependency_name, **options, &dependency_definition)
61
- __commands__ << SmartCore::Container::Commands::Register.new(
62
- dependency_name, dependency_definition, **options
63
- )
53
+ # @api private
54
+ # @since 0.7.0
55
+ module ClassMethods
56
+ # @param namespace_name [String, Symbol]
57
+ # @param dependencies_definition [Block]
58
+ # @return [void]
59
+ #
60
+ # @api public
61
+ # @since 0.7.0
62
+ def namespace(namespace_name, &dependencies_definition)
63
+ @__container_definition_lock__.thread_safe do
64
+ DependencyCompatability::Definition.prevent_dependency_overlap!(self, namespace_name)
65
+
66
+ __container_definition_commands__ << Commands::Definition::Namespace.new(
67
+ namespace_name, dependencies_definition
68
+ )
69
+ end
70
+ end
71
+
72
+ # @param dependency_name [String, Symbol]
73
+ # @param dependency_definition [Block]
74
+ # @return [void]
75
+ #
76
+ # @api public
77
+ # @since 0.7.0
78
+ def register(dependency_name, &dependency_definition)
79
+ @__container_definition_lock__.thread_safe do
80
+ DependencyCompatability::Definition.prevent_namespace_overlap!(self, dependency_name)
81
+
82
+ __container_definition_commands__ << Commands::Definition::Register.new(
83
+ dependency_name, dependency_definition
84
+ )
85
+ end
86
+ end
87
+
88
+ # @param container_klass [Class<SmartCore::Container>]
89
+ # @return [void]
90
+ #
91
+ # @api public
92
+ # @since 0.7.0
93
+ def compose(container_klass)
94
+ @__container_definition_lock__.thread_safe do
95
+ __container_definition_commands__ << Commands::Definition::Compose.new(
96
+ container_klass
97
+ )
98
+
99
+ __container_instantiation_commands__ << Commands::Instantiation::Compose.new(
100
+ container_klass
101
+ )
102
+ end
103
+ end
104
+
105
+ # @return [void]
106
+ #
107
+ # @api public
108
+ # @since 0.7.0
109
+ def freeze_state!
110
+ @__container_definition_lock__.thread_safe do
111
+ __container_instantiation_commands__ << Commands::Instantiation::FreezeState.new
112
+ end
113
+ end
64
114
  end
65
115
  end
66
116
  end