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 +4 -4
- data/.rspec +1 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +7 -6
- data/lib/smart_ioc/args.rb +19 -0
- data/lib/smart_ioc/bean_definition.rb +5 -19
- data/lib/smart_ioc/bean_definitions_storage.rb +20 -2
- data/lib/smart_ioc/bean_factory.rb +62 -36
- data/lib/smart_ioc/bean_locations.rb +4 -2
- data/lib/smart_ioc/bean_locator.rb +3 -5
- data/lib/smart_ioc/container.rb +10 -25
- data/lib/smart_ioc/errors.rb +17 -0
- data/lib/smart_ioc/extra_package_contexts.rb +4 -7
- data/lib/smart_ioc/iocify.rb +3 -3
- data/lib/smart_ioc/scopes/prototype.rb +1 -1
- data/lib/smart_ioc/version.rb +1 -1
- data/lib/smart_ioc.rb +17 -3
- data/spec/smart_ioc/bean_factory_spec.rb +70 -6
- data/spec/smart_ioc/bean_file_loader_spec.rb +1 -1
- data/spec/smart_ioc/container_spec.rb +9 -0
- data/spec/smart_ioc/factory_method_spec.rb +49 -0
- data/spec/smart_ioc/iocify_spec.rb +13 -0
- data/spec/smart_ioc/object_spec.rb +10 -12
- data/spec/smart_ioc/smart_ioc_spec.rb +7 -3
- data/spec/spec_helper.rb +3 -0
- metadata +11 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 352b07a40889da6bddbe42aac89e88b75f6d2d4a
|
4
|
+
data.tar.gz: b07c856f9db346aadffdb96ad3387abe3316213c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b762d682eedb6b5750ac3ded2b560f36589dc0438d243362e251cf587c622083f8b40e6722021121bdab5555dd1712c55f97271beb8cce55a9275cdb1c59762e
|
7
|
+
data.tar.gz: e58089f9a8548784fcd34746ad9e18ee78d29a2d6bd17c6207b843513a8acf8be69214314a06add0b3c9da90722a0810e3fe18b5a06aa49b5c7ea29539a09894
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,19 +1,19 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
smart_ioc (0.1.
|
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.
|
10
|
+
codecov (0.1.10)
|
11
11
|
json
|
12
12
|
simplecov
|
13
13
|
url
|
14
|
-
diff-lcs (1.
|
14
|
+
diff-lcs (1.3)
|
15
15
|
docile (1.1.5)
|
16
|
-
json (2.0.
|
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.
|
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.
|
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
|
-
|
28
|
-
|
29
|
-
|
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 [
|
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
|
-
|
29
|
-
|
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
|
-
|
32
|
-
|
33
|
-
bean_definition.context
|
34
|
-
end
|
46
|
+
dependency_cache = {}
|
47
|
+
beans_cache = {}
|
35
48
|
|
36
|
-
|
37
|
-
|
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
|
-
|
55
|
+
private
|
41
56
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
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
|
-
|
50
|
-
|
51
|
-
|
66
|
+
if !dep_bean
|
67
|
+
dep_bean = get_bean(
|
68
|
+
bd.name, package: bd.package, context: bd.context
|
69
|
+
)
|
52
70
|
|
53
|
-
|
54
|
-
|
55
|
-
|
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
|
-
|
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
|
-
|
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
|
@@ -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
|
-
|
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)
|
data/lib/smart_ioc/container.rb
CHANGED
@@ -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
|
-
|
55
|
-
|
56
|
-
|
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
|
-
|
10
|
-
|
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
|
data/lib/smart_ioc/iocify.rb
CHANGED
@@ -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
|
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
|
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, "
|
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(
|
data/lib/smart_ioc/version.rb
CHANGED
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
|
-
|
40
|
+
BeanLocations.load_all
|
36
41
|
end
|
37
42
|
|
38
43
|
# Full clear of data (mostly for tests)
|
39
44
|
def clear
|
40
|
-
|
41
|
-
|
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
|
25
|
-
expect(SmartIoC
|
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
|
30
|
-
expect(SmartIoC
|
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
|
35
|
-
expect(SmartIoC
|
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
|
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
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
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
|
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
|
32
|
-
SmartIoC
|
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.
|
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-
|
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
|