smart_ioc 0.1.19 → 0.1.20

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: 5397abe56282d5f41ac3b7cef502fa15e7fd457e
4
- data.tar.gz: 6eb3ea3abaaa91cf5fd1a93689d6109ba81862ac
3
+ metadata.gz: 352b07a40889da6bddbe42aac89e88b75f6d2d4a
4
+ data.tar.gz: b07c856f9db346aadffdb96ad3387abe3316213c
5
5
  SHA512:
6
- metadata.gz: 90d799e2feb6a443305967f86e9201ee41ca3a10a68514d8b0817dc646fe333dc03ed062c55ee58221e8f67400d99c17df7cb61d1ad027874eda137272cf34ad
7
- data.tar.gz: f447b52709d6f414fc596c9f6f55b9f93f5a1ee2671c4b658a094fad0bd5b2a66e4582dfe26df19d2f4f4b9c9dd559630ad21b6c51ae6ec69e90c1f424e58db3
6
+ metadata.gz: b762d682eedb6b5750ac3ded2b560f36589dc0438d243362e251cf587c622083f8b40e6722021121bdab5555dd1712c55f97271beb8cce55a9275cdb1c59762e
7
+ data.tar.gz: e58089f9a8548784fcd34746ad9e18ee78d29a2d6bd17c6207b843513a8acf8be69214314a06add0b3c9da90722a0810e3fe18b5a06aa49b5c7ea29539a09894
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile CHANGED
@@ -6,4 +6,5 @@ gemspec
6
6
  group :test do
7
7
  gem 'rspec'
8
8
  gem 'byebug'
9
+ gem 'simplecov'
9
10
  end
data/Gemfile.lock CHANGED
@@ -1,19 +1,19 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- smart_ioc (0.1.19)
4
+ smart_ioc (0.1.20)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
9
  byebug (9.0.6)
10
- codecov (0.1.9)
10
+ codecov (0.1.10)
11
11
  json
12
12
  simplecov
13
13
  url
14
- diff-lcs (1.2.5)
14
+ diff-lcs (1.3)
15
15
  docile (1.1.5)
16
- json (2.0.2)
16
+ json (2.0.3)
17
17
  rake (12.0.0)
18
18
  rspec (3.5.0)
19
19
  rspec-core (~> 3.5.0)
@@ -28,7 +28,7 @@ GEM
28
28
  diff-lcs (>= 1.2.0, < 2.0)
29
29
  rspec-support (~> 3.5.0)
30
30
  rspec-support (3.5.0)
31
- simplecov (0.12.0)
31
+ simplecov (0.14.1)
32
32
  docile (~> 1.1.0)
33
33
  json (>= 1.8, < 3)
34
34
  simplecov-html (~> 0.10.0)
@@ -44,7 +44,8 @@ DEPENDENCIES
44
44
  codecov
45
45
  rake
46
46
  rspec
47
+ simplecov
47
48
  smart_ioc!
48
49
 
49
50
  BUNDLED WITH
50
- 1.13.6
51
+ 1.14.5
@@ -0,0 +1,19 @@
1
+ module SmartIoC::Args
2
+ def check_arg(value, name, klass)
3
+ if !value.is_a?(klass)
4
+ raise ArgumentError, ":#{name} should be a #{klass}"
5
+ end
6
+ end
7
+
8
+ def check_arg_any(value, name, klasses)
9
+ if !klasses.detect {|klass| value.is_a?(klass)}
10
+ raise ArgumentError, ":#{name} should be any of #{klasses.inspect}"
11
+ end
12
+ end
13
+
14
+ def not_nil(value, name)
15
+ if value.nil?
16
+ raise ArgumentError, ":#{name} should not be blank"
17
+ end
18
+ end
19
+ end
@@ -1,4 +1,6 @@
1
1
  class SmartIoC::BeanDefinition
2
+ include SmartIoC::Args
3
+
2
4
  attr_reader :name, :package, :path, :klass, :scope, :instance, :factory_method,
3
5
  :context, :dependencies
4
6
 
@@ -24,17 +26,9 @@ class SmartIoC::BeanDefinition
24
26
  end
25
27
 
26
28
  def add_dependency(bean_name:, ref: nil, package: nil)
27
- if !bean_name.is_a?(Symbol)
28
- raise ArgumentError, 'bean name should be a Symbol'
29
- end
30
-
31
- if ref && !ref.is_a?(Symbol)
32
- raise ArgumentError, 'ref name should be a Symbol'
33
- end
34
-
35
- if package && !package.is_a?(Symbol)
36
- raise ArgumentError, 'package/from should be a Symbol'
37
- end
29
+ check_arg(bean_name, :bean_name, Symbol)
30
+ check_arg(ref, :ref, Symbol) if ref
31
+ check_arg(package, :package, Symbol) if package
38
32
 
39
33
  @dependencies << SmartIoC::BeanDependency.new(
40
34
  bean: bean_name,
@@ -66,12 +60,4 @@ class SmartIoC::BeanDefinition
66
60
  str << "factory_method: #{@factory_method}"
67
61
  str.join("\n")
68
62
  end
69
-
70
- private
71
-
72
- def not_nil(value, name)
73
- if value.nil?
74
- raise ArgumentError, ":#{name} should not be blank"
75
- end
76
- end
77
63
  end
@@ -1,4 +1,6 @@
1
1
  class SmartIoC::BeanDefinitionsStorage
2
+ include SmartIoC::Errors
3
+
2
4
  def initialize
3
5
  @collection = []
4
6
  end
@@ -51,8 +53,24 @@ Existing bean details:
51
53
  end
52
54
 
53
55
  # @bean_name [Symbol] bean name
54
- # @package [Symbol] package name
55
- # @context [Array[Symbol]] context
56
+ # @package [Symbol, nil] package name
57
+ # @context [Symbol, nil] context
58
+ # @raises Errors::AmbiguousBeanDefinition if multiple bean definitions are found
59
+ def find(bean_name, package = nil, context = nil)
60
+ bds = filter_by_with_drop_to_default_context(bean_name, package, context)
61
+
62
+ if bds.size > 1
63
+ raise Errors::AmbiguousBeanDefinition.new(bean_name, bds)
64
+ elsif bds.size == 0
65
+ raise Errors::BeanNotFound.new(bean_name)
66
+ end
67
+
68
+ bds.first
69
+ end
70
+
71
+ # @bean_name [Symbol] bean name
72
+ # @package [Symbol, nil] package name
73
+ # @context [Symbol, nil] context
56
74
  def filter_by_with_drop_to_default_context(bean_name, package = nil, context = nil)
57
75
  bean_definitions = @collection.select do |bd|
58
76
  bd.name == bean_name
@@ -1,5 +1,8 @@
1
1
  # Instantiates beans according to their scopes
2
2
  class SmartIoC::BeanFactory
3
+ include SmartIoC::Errors
4
+ include SmartIoC::Args
5
+
3
6
  def initialize(bean_definitions_storage, extra_package_contexts)
4
7
  @bean_definitions_storage = bean_definitions_storage
5
8
  @extra_package_contexts = extra_package_contexts
@@ -25,37 +28,64 @@ class SmartIoC::BeanFactory
25
28
  # @raise [ArgumentError] if bean is not found
26
29
  # @raise [ArgumentError] if ambiguous bean definition was found
27
30
  def get_bean(bean_name, package: nil, context: nil)
28
- context ||= if package
29
- @extra_package_contexts.get_context(package)
31
+ check_arg(bean_name, :bean_name, Symbol)
32
+ check_arg(package, :package, Symbol) if package
33
+ check_arg(context, :context, Symbol) if context
34
+
35
+ @bean_file_loader.require_bean(bean_name)
36
+
37
+ context = autodetect_context(bean_name, package, context)
38
+ bean_definition = @bean_definitions_storage.find(bean_name, package, context)
39
+ scope = get_scope(bean_definition)
40
+ bean = scope.get_bean(bean_definition.klass)
41
+
42
+ if bean
43
+ update_dependencies(bean, bean_definition)
44
+ bean
30
45
  else
31
- @bean_file_loader.require_bean(bean_name)
32
- bean_definition = autodetect_bean_definition(bean_name, package, nil)
33
- bean_definition.context
34
- end
46
+ dependency_cache = {}
47
+ beans_cache = {}
35
48
 
36
- if !context.is_a?(Symbol)
37
- raise ArgumentError, 'context should be a Symbol'
49
+ autodetect_bean_definitions_for_dependencies(bean_definition, dependency_cache)
50
+ preload_beans(bean_definition, dependency_cache, beans_cache)
51
+ load_bean(bean_definition, dependency_cache, beans_cache)
38
52
  end
53
+ end
39
54
 
40
- @bean_file_loader.require_bean(bean_name)
55
+ private
41
56
 
42
- bds = @bean_definitions_storage.filter_by_with_drop_to_default_context(bean_name, package, context)
43
- if bds.size > 1
44
- raise ArgumentError, "Unable to create bean :#{bean_name}.\nSeveral definitions were found.\n#{bds.map(&:inspect).join("\n\n")}"
45
- elsif bds.size == 0
46
- raise ArgumentError, "Unable to find bean :#{bean_name} in any packages"
47
- end
57
+ def update_dependencies(bean, bean_definition, updated_beans = {})
58
+ bean_definition.dependencies.each do |dependency|
59
+ bd = autodetect_bean_definition(
60
+ dependency.ref, dependency.package, bean_definition.package
61
+ )
62
+
63
+ scope = get_scope(bean_definition)
64
+ dep_bean = updated_beans[bd] || scope.get_bean(bd.class)
48
65
 
49
- bean_definition = bds.first
50
- dependency_cache = {}
51
- beans_cache = {}
66
+ if !dep_bean
67
+ dep_bean = get_bean(
68
+ bd.name, package: bd.package, context: bd.context
69
+ )
52
70
 
53
- autodetect_bean_definitions_for_dependencies(bean_definition, dependency_cache)
54
- preload_beans(bean_definition, dependency_cache, beans_cache)
55
- load_bean(bean_definition, dependency_cache, beans_cache)
71
+ bean.instance_variable_set(:"@#{dependency.bean}", dep_bean)
72
+ updated_beans[bd] = dep_bean
73
+ else
74
+ update_dependencies(dep_bean, bd, updated_beans)
75
+ end
76
+ end
56
77
  end
57
78
 
58
- private
79
+ def autodetect_context(bean_name, package, context)
80
+ return context if context
81
+
82
+ if package
83
+ @extra_package_contexts.get_context(package)
84
+ else
85
+ bean_definition = autodetect_bean_definition(bean_name, package, nil)
86
+ bean_definition.context
87
+ end
88
+ end
59
89
 
60
90
  def autodetect_bean_definitions_for_dependencies(bean_definition, dependency_cache)
61
91
  bean_definition.dependencies.each do |dependency|
@@ -117,7 +147,13 @@ class SmartIoC::BeanFactory
117
147
  end
118
148
 
119
149
  def preload_beans(bean_definition, dependency_cache, beans_cache)
120
- preload_bean_instance(bean_definition, beans_cache)
150
+ scope = get_scope(bean_definition)
151
+
152
+ if bean = scope.get_bean(bean_definition.klass)
153
+ beans_cache[bean_definition] = bean
154
+ else
155
+ preload_bean_instance(bean_definition, beans_cache)
156
+ end
121
157
 
122
158
  bean_definition.dependencies.each do |dependency|
123
159
  bd = dependency_cache[dependency]
@@ -174,8 +210,10 @@ class SmartIoC::BeanFactory
174
210
  (zero_dep_bd_with_factory_methods + bd_with_factory_methods).each do |bean_definition|
175
211
  inject_beans(bean_definition, dependency_cache, beans_cache)
176
212
  bean = beans_cache[bean_definition]
177
- bean = bean.send(bean_definition.factory_method)
213
+ bean = bean.send(bean_definition.factory_method) if bean.is_a?(bean_definition.klass)
178
214
  beans_cache[bean_definition] = bean
215
+ scope = get_scope(bean_definition)
216
+ scope.save_bean(bean_definition.klass, bean)
179
217
  end
180
218
 
181
219
  inject_beans(bean_definition, dependency_cache, beans_cache)
@@ -211,18 +249,6 @@ class SmartIoC::BeanFactory
211
249
  nil
212
250
  end
213
251
 
214
- def set_bean_dependencies(bean, bean_definition, parent_bean_package)
215
- bean_definition.dependencies.each do |dependency|
216
- context = if dependency.package
217
- @extra_package_contexts.get_context(dependency.package)
218
- end
219
-
220
- dependent_bean = get_or_load_bean(dependency.ref, dependency.package, context, bean_definition.package)
221
-
222
- bean.instance_variable_set(:"@#{dependency.bean}", dependent_bean)
223
- end
224
- end
225
-
226
252
  def all_scopes
227
253
  [@singleton_scope, @prototype_scope, @thread_scope]
228
254
  end
@@ -46,8 +46,10 @@ class SmartIoC::BeanLocations
46
46
 
47
47
  def load_all
48
48
  @data.each do |package, bean_locations|
49
- bean_locations.each do |bean, path|
50
- load(path)
49
+ bean_locations.each do |bean, paths|
50
+ paths.each do |path|
51
+ load(path)
52
+ end
51
53
  end
52
54
  end
53
55
  end
@@ -1,15 +1,13 @@
1
1
  class SmartIoC::BeanLocator
2
+ include SmartIoC::Args
3
+
2
4
  BEAN_PATTERN = /bean\s+(:[a-zA-z0-9\-\_]+)/
3
5
 
4
6
  # @param package_name [Symbol] package name for bean (ex: :repository)
5
7
  # @param dir [String] absolute path for directory with bean definitions
6
8
  # @return nil
7
9
  def locate_beans(package_name, dir)
8
- if !package_name.is_a?(Symbol)
9
- raise ArgumentError, 'package name should be a symbol'
10
- end
11
-
12
- package_name = package_name
10
+ check_arg(package_name, :package_name, Symbol)
13
11
 
14
12
  Dir.glob(File.join(dir, '**/*.rb')).each do |file_path|
15
13
  source_str = File.read(file_path)
@@ -1,6 +1,8 @@
1
1
  module SmartIoC
2
2
  # SmartIoC::Container is a beans store used for dependency injection
3
3
  class Container
4
+ include SmartIoC::Args
5
+
4
6
  DEFAULT_CONTEXT = :default
5
7
 
6
8
  class << self
@@ -29,32 +31,15 @@ module SmartIoC
29
31
  # @return [SmartIoC::BeanDefinition] bean definition
30
32
  def register_bean(bean_name:, klass:, context:, scope:, path:,
31
33
  factory_method: nil, package_name: nil, instance: true)
32
- if !bean_name.is_a?(Symbol)
33
- raise ArgumentError, 'bean name should be a Symbol'
34
- end
35
-
36
- if !klass.is_a?(Class)
37
- raise ArgumentError, 'bean class should be a Class'
38
- end
39
-
40
- if !path.is_a?(String)
41
- raise ArgumentError, 'path should be a String'
42
- end
43
-
44
- if !(instance.is_a?(TrueClass) || instance.is_a?(FalseClass))
45
- raise ArgumentError, 'instance should be true or false'
46
- end
47
-
48
- if (factory_method && !factory_method.is_a?(Symbol))
49
- raise ArgumentError, 'factory method should be a Symbol'
50
- end
51
-
52
34
  context ||= DEFAULT_CONTEXT
53
-
54
- if !context.is_a?(Symbol)
55
- raise ArgumentError, 'context should be a Symbol'
56
- end
57
-
35
+
36
+ check_arg(bean_name, :bean_name, Symbol)
37
+ check_arg(context, :context, Symbol)
38
+ check_arg(klass, :klass, Class)
39
+ check_arg(path, :path, String)
40
+ check_arg(factory_method, :factory_method, Symbol) if factory_method
41
+ check_arg_any(instance, :instance, [TrueClass, FalseClass])
42
+
58
43
  scope ||= SmartIoC::Scopes::Singleton::VALUE
59
44
 
60
45
  allowed_scopes = [
@@ -0,0 +1,17 @@
1
+ module SmartIoC::Errors
2
+ class BeanNotFound < StandardError
3
+ def initialize(bean_name)
4
+ super("Unable to find bean :#{bean_name} in any packages")
5
+ end
6
+ end
7
+
8
+ class AmbiguousBeanDefinition < StandardError
9
+ def initialize(bean_name, bean_definitions)
10
+ super(%Q(
11
+ Unable to create bean :#{bean_name}.
12
+ Several definitions were found.
13
+ #{bean_definitions.map(&:inspect).join("\n\n")}
14
+ ))
15
+ end
16
+ end
17
+ end
@@ -1,4 +1,6 @@
1
1
  class SmartIoC::ExtraPackageContexts
2
+ include SmartIoC::Args
3
+
2
4
  def initialize
3
5
  @data = {}
4
6
  end
@@ -6,13 +8,8 @@ class SmartIoC::ExtraPackageContexts
6
8
  # @param package_name [Symbol]
7
9
  # @param context [Symbol]
8
10
  def set_context(package_name, context)
9
- if !package_name.is_a?(Symbol)
10
- raise ArgumentError, "package name should be a Symbol"
11
- end
12
-
13
- if !context.is_a?(Symbol)
14
- raise ArgumentError, "context should be a Symbol"
15
- end
11
+ check_arg(package_name, :package_name, Symbol)
12
+ check_arg(context, :context, Symbol)
16
13
 
17
14
  @data[package_name] = context
18
15
  end
@@ -33,12 +33,12 @@ module SmartIoC::Iocify
33
33
  def bean(bean_name, scope: nil, package: nil, instance: true, factory_method: nil, context: nil)
34
34
  file_path = caller[0].split(':').first
35
35
 
36
- bean_definition = SmartIoC::Container.get_instance.get_bean_definition_by_class(self)
36
+ bean_definition = SmartIoC.get_bean_definition_by_class(self)
37
37
 
38
38
  # skip if bean was registered
39
39
  return if bean_definition
40
40
 
41
- bean_definition = SmartIoC::Container.get_instance.register_bean(
41
+ bean_definition = SmartIoC.register_bean(
42
42
  bean_name: bean_name,
43
43
  klass: self,
44
44
  scope: scope,
@@ -72,7 +72,7 @@ module SmartIoC::Iocify
72
72
  bean_definition = SmartIoC::Container.get_instance.get_bean_definition_by_class(self)
73
73
 
74
74
  if bean_definition.nil?
75
- raise ArgumentError, "current class is not registered as bean. Add bean :bean_name declaration"
75
+ raise ArgumentError, "#{self.to_s} is not registered as bean. Add `bean :bean_name` declaration"
76
76
  end
77
77
 
78
78
  bean_definition.add_dependency(
@@ -1,4 +1,4 @@
1
- # Prototype scope instantiates new bean instance on each call
1
+ # Prototype scope instantiates new bean instance on each SmartIoC.get_bean call
2
2
  class SmartIoC::Scopes::Prototype
3
3
  VALUE = :prototype
4
4
 
@@ -1,3 +1,3 @@
1
1
  module SmartIoC
2
- VERSION = "0.1.19"
2
+ VERSION = "0.1.20"
3
3
  end
data/lib/smart_ioc.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'smart_ioc/version'
2
2
 
3
3
  module SmartIoC
4
+ autoload :Args, 'smart_ioc/args'
4
5
  autoload :BeanDefinition, 'smart_ioc/bean_definition'
5
6
  autoload :BeanDefinitionsStorage, 'smart_ioc/bean_definitions_storage'
6
7
  autoload :BeanDependency, 'smart_ioc/bean_dependency'
@@ -20,6 +21,10 @@ module SmartIoC
20
21
  autoload :Request, 'smart_ioc/scopes/request'
21
22
  end
22
23
 
24
+ module Errors
25
+ require 'smart_ioc/errors'
26
+ end
27
+
23
28
  class << self
24
29
  # @param package_name [String or Symbol] package name for bean definitions
25
30
  # @param dir [String] absolute path with bean definitions
@@ -32,13 +37,22 @@ module SmartIoC
32
37
 
33
38
  # Load all beans (usually required for production env)
34
39
  def load_all_beans
35
- SmartIoC::BeanLocations.load_all
40
+ BeanLocations.load_all
36
41
  end
37
42
 
38
43
  # Full clear of data (mostly for tests)
39
44
  def clear
40
- SmartIoC::BeanLocations.clear
41
- SmartIoC::Container.clear
45
+ BeanLocations.clear
46
+ Container.clear
47
+ end
48
+
49
+ def container
50
+ Container.get_instance
42
51
  end
52
+
53
+ extend Forwardable
54
+
55
+ def_delegators :container, :register_bean, :get_bean_definition_by_class,
56
+ :set_extra_context_for_package, :get_bean, :clear_scopes, :force_clear_scopes
43
57
  end
44
58
  end
@@ -18,20 +18,84 @@ describe SmartIoC::BeanFactory do
18
18
  include SmartIoC::Iocify
19
19
  bean :dao, context: :default, package: :bean_factory
20
20
  end
21
+
22
+ class TestObject
23
+ end
24
+
25
+ class Factory
26
+ include SmartIoC::Iocify
27
+ bean :factory, factory_method: :build_bean, package: :bean_factory
28
+
29
+ def build_bean
30
+ TestObject.new
31
+ end
32
+ end
33
+ end
34
+
35
+ it 'returns same instance for singleton scope' do
36
+ SmartIoC.set_extra_context_for_package(:bean_factory, :test)
37
+ instance1 = SmartIoC.get_bean(:repo)
38
+ instance2 = SmartIoC.get_bean(:repo)
39
+ expect(instance1.object_id).to eq(instance2.object_id)
40
+ end
41
+
42
+ it 'returns same instance for factory method and singleton scope' do
43
+ instance1_object_id = SmartIoC.get_bean(:factory).object_id
44
+ instance2_object_id = SmartIoC.get_bean(:factory).object_id
45
+ expect(instance1_object_id).to eq(instance2_object_id)
21
46
  end
22
47
 
23
48
  it 'returns proper bean for test context' do
24
- SmartIoC::Container.get_instance.set_extra_context_for_package(:bean_factory, :test)
25
- expect(SmartIoC::Container.get_bean(:repo)).to be_a(TestRepo)
49
+ SmartIoC.set_extra_context_for_package(:bean_factory, :test)
50
+ expect(SmartIoC.get_bean(:repo)).to be_a(TestRepo)
26
51
  end
27
52
 
28
53
  it 'returns proper bean for default context' do
29
- SmartIoC::Container.get_instance.set_extra_context_for_package(:bean_factory, :default)
30
- expect(SmartIoC::Container.get_bean(:repo)).to be_a(Repo)
54
+ SmartIoC.set_extra_context_for_package(:bean_factory, :default)
55
+ expect(SmartIoC.get_bean(:repo)).to be_a(Repo)
31
56
  end
32
57
 
33
58
  it 'returns proper bean for test context with fallback to default context' do
34
- SmartIoC::Container.get_instance.set_extra_context_for_package(:bean_factory, :test)
35
- expect(SmartIoC::Container.get_bean(:dao)).to be_a(DAO)
59
+ SmartIoC.set_extra_context_for_package(:bean_factory, :test)
60
+ expect(SmartIoC.get_bean(:dao)).to be_a(DAO)
61
+ end
62
+
63
+ it 'updates dependencies' do
64
+ class SingletonBean
65
+ include SmartIoC::Iocify
66
+ bean :singleton_bean, scope: :singleton, package: :test
67
+
68
+ inject :prototype_bean
69
+
70
+ attr_reader :prototype_bean
71
+ end
72
+
73
+ class SecondSingletonBean
74
+ include SmartIoC::Iocify
75
+ bean :second_singleton_bean, scope: :singleton, package: :test
76
+ end
77
+
78
+ class PrototypeBean
79
+ include SmartIoC::Iocify
80
+ bean :prototype_bean, scope: :prototype, package: :test
81
+
82
+ inject :second_singleton_bean
83
+
84
+ attr_reader :second_singleton_bean
85
+ end
86
+
87
+ bean1 = SmartIoC.get_bean(:singleton_bean, package: :test)
88
+ bean1_object_id = bean1.object_id
89
+ prototype_bean1_object_id = bean1.prototype_bean.object_id
90
+ second_singleton_bean1_object_id = bean1.prototype_bean.second_singleton_bean.object_id
91
+
92
+ bean2 = SmartIoC.get_bean(:singleton_bean, package: :test)
93
+ bean2_object_id = bean2.object_id
94
+ prototype_bean2_object_id = bean2.prototype_bean.object_id
95
+ second_singleton_bean2_object_id = bean2.prototype_bean.second_singleton_bean.object_id
96
+
97
+ expect(bean1_object_id).to eq(bean2_object_id)
98
+ expect(prototype_bean1_object_id).not_to eq(prototype_bean2_object_id)
99
+ expect(second_singleton_bean1_object_id).to eq(second_singleton_bean2_object_id)
36
100
  end
37
101
  end
@@ -10,7 +10,7 @@ describe SmartIoC::BeanFileLoader do
10
10
  dir_path = File.join(File.expand_path(File.dirname(__FILE__)), 'example/utils')
11
11
  SmartIoC.find_package_beans(:utils, dir_path)
12
12
 
13
- @container = SmartIoC::Container.get_instance
13
+ @container = SmartIoC.container
14
14
  end
15
15
 
16
16
  it 'requires beans only once' do
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe SmartIoC::Container do
4
+ it 'does not have initializer' do
5
+ expect {
6
+ SmartIoC::Container.new
7
+ }.to raise_error(ArgumentError, "SmartIoC::Container should not be allocated. Use SmartIoC::Container.get_instance instead")
8
+ end
9
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Factory Method' do
4
+ before :all do
5
+ class TestService
6
+ include SmartIoC::Iocify
7
+
8
+ bean :test_service, package: :test
9
+
10
+ inject :test_config
11
+
12
+ attr_reader :test_config
13
+ end
14
+
15
+ class OtherService
16
+ include SmartIoC::Iocify
17
+
18
+ bean :other_service, package: :test
19
+
20
+ inject :test_config
21
+
22
+ attr_reader :test_config
23
+ end
24
+
25
+ class TestConfig
26
+ include SmartIoC::Iocify
27
+
28
+ bean :test_config, package: :test, factory_method: :build_config
29
+
30
+ class Config
31
+ end
32
+
33
+ def build_config
34
+ Config.new
35
+ end
36
+ end
37
+
38
+ @test_service = SmartIoC.get_bean(:test_service)
39
+ @other_service = SmartIoC.get_bean(:other_service)
40
+ end
41
+
42
+ it 'assigns bean with factory method' do
43
+ expect(@test_service.test_config).to be_a(TestConfig::Config)
44
+ end
45
+
46
+ it 'assigns bean with factory method' do
47
+ expect(@other_service.test_config).to be_a(TestConfig::Config)
48
+ end
49
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe SmartIoC::Iocify do
4
+ it 'raises if inject method was used without bean declaration' do
5
+ expect {
6
+ class MyTestClass
7
+ include SmartIoC::Iocify
8
+
9
+ inject :some_bean
10
+ end
11
+ }.to raise_error(ArgumentError, "MyTestClass is not registered as bean. Add `bean :bean_name` declaration")
12
+ end
13
+ end
@@ -31,19 +31,17 @@ describe Object do
31
31
  bean :my_bean, scope: :request, package: :my_package, instance: false,
32
32
  factory_method: :my_method, context: :test
33
33
  end
34
+
35
+ @bean_definition = SmartIoC.get_bean_definition_by_class(BeanClass)
34
36
  end
35
37
 
36
- it {
37
- bean_definition = SmartIoC::Container.get_instance.get_bean_definition_by_class(BeanClass)
38
-
39
- expect(bean_definition.name).to eq(:my_bean)
40
- expect(bean_definition.package).to eq(:my_package)
41
- expect(bean_definition.path).to match(/object_spec.rb/)
42
- expect(bean_definition.klass).to eq(BeanClass)
43
- expect(bean_definition.scope).to eq(:request)
44
- expect(bean_definition.instance).to eq(false)
45
- expect(bean_definition.factory_method).to eq(:my_method)
46
- expect(bean_definition.context).to eq(:test)
47
- }
38
+ it { expect(@bean_definition.name).to eq(:my_bean) }
39
+ it { expect(@bean_definition.package).to eq(:my_package) }
40
+ it { expect(@bean_definition.path).to match(/object_spec.rb/) }
41
+ it { expect(@bean_definition.klass).to eq(BeanClass) }
42
+ it { expect(@bean_definition.scope).to eq(:request) }
43
+ it { expect(@bean_definition.instance).to eq(false) }
44
+ it { expect(@bean_definition.factory_method).to eq(:my_method) }
45
+ it { expect(@bean_definition.context).to eq(:test) }
48
46
  end
49
47
  end
@@ -13,7 +13,11 @@ describe SmartIoC do
13
13
  dir_path = File.join(File.expand_path(File.dirname(__FILE__)), 'example/utils')
14
14
  SmartIoC.find_package_beans(:utils, dir_path)
15
15
 
16
- @container = SmartIoC::Container.get_instance
16
+ @container = SmartIoC.container
17
+ end
18
+
19
+ it 'loads all beans' do
20
+ SmartIoC.load_all_beans
17
21
  end
18
22
 
19
23
  it 'sets beans' do
@@ -28,8 +32,8 @@ describe SmartIoC do
28
32
  end
29
33
 
30
34
  it 'sets beans with extra package context' do
31
- SmartIoC::Container.get_instance.set_extra_context_for_package(:admins, :test)
32
- SmartIoC::Container.get_instance.force_clear_scopes
35
+ SmartIoC.set_extra_context_for_package(:admins, :test)
36
+ SmartIoC.force_clear_scopes
33
37
 
34
38
  users_creator = @container.get_bean(:users_creator)
35
39
  users_creator.create(1, 'test@test.com')
data/spec/spec_helper.rb CHANGED
@@ -1,12 +1,15 @@
1
1
  require 'rubygems'
2
2
  require 'bundler/setup'
3
3
  require 'simplecov'
4
+
4
5
  SimpleCov.start do
5
6
  add_filter "/spec/"
6
7
  add_filter "/.direnv/"
7
8
  end
9
+
8
10
  if ENV['CI']=='true'
9
11
  require 'codecov'
12
+
10
13
  SimpleCov.formatter = SimpleCov::Formatter::Codecov
11
14
  end
12
15
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smart_ioc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.19
4
+ version: 0.1.20
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ruslan Gatiyatov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-11 00:00:00.000000000 Z
11
+ date: 2017-03-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -60,6 +60,7 @@ extensions: []
60
60
  extra_rdoc_files: []
61
61
  files:
62
62
  - ".gitignore"
63
+ - ".rspec"
63
64
  - ".travis.yml"
64
65
  - ".yardops"
65
66
  - Gemfile
@@ -70,6 +71,7 @@ files:
70
71
  - docs/_config.yml
71
72
  - docs/index.md
72
73
  - lib/smart_ioc.rb
74
+ - lib/smart_ioc/args.rb
73
75
  - lib/smart_ioc/bean_definition.rb
74
76
  - lib/smart_ioc/bean_definitions_storage.rb
75
77
  - lib/smart_ioc/bean_dependency.rb
@@ -78,6 +80,7 @@ files:
78
80
  - lib/smart_ioc/bean_locations.rb
79
81
  - lib/smart_ioc/bean_locator.rb
80
82
  - lib/smart_ioc/container.rb
83
+ - lib/smart_ioc/errors.rb
81
84
  - lib/smart_ioc/extra_package_contexts.rb
82
85
  - lib/smart_ioc/inject_metadata.rb
83
86
  - lib/smart_ioc/iocify.rb
@@ -91,6 +94,7 @@ files:
91
94
  - spec/smart_ioc/bean_factory_spec.rb
92
95
  - spec/smart_ioc/bean_file_loader_spec.rb
93
96
  - spec/smart_ioc/bean_locator_spec.rb
97
+ - spec/smart_ioc/container_spec.rb
94
98
  - spec/smart_ioc/example/admins/repository/admins_dao.rb
95
99
  - spec/smart_ioc/example/admins/repository/admins_repository.rb
96
100
  - spec/smart_ioc/example/admins/repository/test/admins_repository.rb
@@ -100,6 +104,8 @@ files:
100
104
  - spec/smart_ioc/example/users/user.rb
101
105
  - spec/smart_ioc/example/utils/config.rb
102
106
  - spec/smart_ioc/example/utils/logger.rb
107
+ - spec/smart_ioc/factory_method_spec.rb
108
+ - spec/smart_ioc/iocify_spec.rb
103
109
  - spec/smart_ioc/object_spec.rb
104
110
  - spec/smart_ioc/smart_ioc_spec.rb
105
111
  - spec/spec_helper.rb
@@ -132,6 +138,7 @@ test_files:
132
138
  - spec/smart_ioc/bean_factory_spec.rb
133
139
  - spec/smart_ioc/bean_file_loader_spec.rb
134
140
  - spec/smart_ioc/bean_locator_spec.rb
141
+ - spec/smart_ioc/container_spec.rb
135
142
  - spec/smart_ioc/example/admins/repository/admins_dao.rb
136
143
  - spec/smart_ioc/example/admins/repository/admins_repository.rb
137
144
  - spec/smart_ioc/example/admins/repository/test/admins_repository.rb
@@ -141,6 +148,8 @@ test_files:
141
148
  - spec/smart_ioc/example/users/user.rb
142
149
  - spec/smart_ioc/example/utils/config.rb
143
150
  - spec/smart_ioc/example/utils/logger.rb
151
+ - spec/smart_ioc/factory_method_spec.rb
152
+ - spec/smart_ioc/iocify_spec.rb
144
153
  - spec/smart_ioc/object_spec.rb
145
154
  - spec/smart_ioc/smart_ioc_spec.rb
146
155
  - spec/spec_helper.rb