micon 0.1.6 → 0.1.7
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.
- data/Rakefile +5 -5
- data/lib/micon.rb +5 -1
- data/lib/micon/class.rb +2 -2
- data/lib/micon/core.rb +408 -0
- data/lib/micon/helper.rb +26 -0
- data/lib/micon/metadata.rb +120 -124
- data/lib/micon/module.rb +39 -8
- data/lib/micon/rad.rb +8 -0
- data/lib/micon/spec.rb +20 -0
- data/lib/micon/support.rb +23 -9
- data/readme.md +18 -4
- data/spec/callbacks_spec.rb +65 -22
- data/spec/constants_spec.rb +75 -0
- data/spec/constants_spec/get_constant_component/lib/components/TheController.rb +3 -0
- data/spec/custom_scope_spec.rb +33 -34
- data/spec/initialization_spec.rb +71 -0
- data/spec/managed_spec.rb +14 -14
- data/spec/micelaneous_spec.rb +33 -29
- data/spec/micelaneous_spec/autoload/lib/components/TheRad/TheView.rb +3 -0
- data/spec/micelaneous_spec/autoload/lib/components/TheRouter.rb +3 -0
- data/spec/micelaneous_spec/autoload/lib/components/some_value.rb +3 -0
- data/spec/nested_custom_scope_spec.rb +13 -14
- data/spec/overview_spec.rb +7 -3
- data/spec/spec_helper.rb +10 -3
- data/spec/static_scope_spec.rb +47 -22
- metadata +30 -41
- data/lib/micon/micon.rb +0 -250
data/spec/overview_spec.rb
CHANGED
@@ -1,9 +1,13 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe "Micon Overview" do
|
4
|
+
before do
|
5
|
+
self.micon = Micon::Core.new
|
6
|
+
end
|
7
|
+
|
4
8
|
it "sample" do
|
5
9
|
class Object
|
6
|
-
def app;
|
10
|
+
def app; MICON end
|
7
11
|
end
|
8
12
|
|
9
13
|
# static (singleton) components
|
@@ -32,12 +36,12 @@ describe "Micon Overview" do
|
|
32
36
|
|
33
37
|
# dynamic components, will be created and destroyed for every request
|
34
38
|
class Request
|
35
|
-
register_as :request, :
|
39
|
+
register_as :request, scope: :request
|
36
40
|
end
|
37
41
|
|
38
42
|
class Application
|
39
43
|
# injecting components into attributes
|
40
|
-
inject :
|
44
|
+
inject request: :request, logger: :logger
|
41
45
|
|
42
46
|
def do_business
|
43
47
|
# now we can use injected component
|
data/spec/spec_helper.rb
CHANGED
@@ -1,6 +1,13 @@
|
|
1
1
|
require 'rspec_ext'
|
2
2
|
|
3
|
-
|
4
|
-
$LOAD_PATH << lib_dir unless $LOAD_PATH.include? lib_dir
|
3
|
+
require "micon"
|
5
4
|
|
6
|
-
|
5
|
+
Micon::Core.send :include, Micon::Helper
|
6
|
+
|
7
|
+
def micon; $micon end
|
8
|
+
def micon= value
|
9
|
+
$micon = value
|
10
|
+
$micon.initialize!
|
11
|
+
|
12
|
+
$micon
|
13
|
+
end
|
data/spec/static_scope_spec.rb
CHANGED
@@ -1,32 +1,55 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe "Application and Instance scopes" do
|
4
|
-
before
|
5
|
-
Micon.
|
6
|
-
|
4
|
+
before do
|
5
|
+
self.micon = Micon::Core.new
|
6
|
+
end
|
7
|
+
|
8
|
+
it "dependencies" do
|
9
|
+
micon.register(:another_object, depends_on: :the_object){"another_object"}
|
10
|
+
-> {micon[:another_object]}.should raise_error(/the_object/)
|
11
|
+
micon.register(:the_object){"the_object"}
|
12
|
+
micon[:another_object]
|
7
13
|
end
|
8
14
|
|
9
15
|
it "instance scope" do
|
10
|
-
|
16
|
+
micon.register(:value, scope: :instance){"The Object"}
|
11
17
|
|
12
|
-
|
13
|
-
|
18
|
+
micon[:value].should == "The Object"
|
19
|
+
micon[:value].object_id.should_not == micon[:value].object_id
|
14
20
|
end
|
15
21
|
|
16
22
|
it "application scope" do
|
17
|
-
|
23
|
+
micon.register(:value){"The Object"}
|
18
24
|
|
19
|
-
|
20
|
-
|
25
|
+
micon[:value].should == "The Object"
|
26
|
+
micon[:value].object_id.should == micon[:value].object_id
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should not allow to return nill in initializer" do
|
30
|
+
micon.register(:value){nil}
|
31
|
+
-> {micon[:value]}.should raise_error(/returns nill/)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should not allow to register component without initializer but shouldn't allow to instantiate it" do
|
35
|
+
micon.register :value
|
36
|
+
-> {micon[:value]}.should raise_error(/no initializer/)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should not allow to assign nill as component" do
|
40
|
+
micon.register :value
|
41
|
+
-> {micon[:value] = nil}.should raise_error(/can't assign nill/)
|
21
42
|
end
|
22
43
|
|
23
44
|
it "application scope, outjection" do
|
24
45
|
the_object = "The Object"
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
46
|
+
micon.register :value do
|
47
|
+
"some_value"
|
48
|
+
end
|
49
|
+
|
50
|
+
micon[:value].should == "some_value"
|
51
|
+
micon[:value] = the_object
|
52
|
+
micon[:value].object_id.should == the_object.object_id
|
30
53
|
end
|
31
54
|
|
32
55
|
it "cycle reference" do
|
@@ -34,25 +57,27 @@ describe "Application and Instance scopes" do
|
|
34
57
|
|
35
58
|
class CycleA
|
36
59
|
register_as :cycle_a
|
37
|
-
inject :
|
60
|
+
inject b: :cycle_b
|
38
61
|
end
|
39
62
|
|
40
63
|
class CycleB
|
41
64
|
register_as :cycle_b
|
42
|
-
inject :
|
65
|
+
inject a: :cycle_a
|
43
66
|
end
|
44
67
|
|
45
|
-
a =
|
46
|
-
b =
|
68
|
+
a = micon[:cycle_a]
|
69
|
+
b = micon[:cycle_b]
|
47
70
|
a.b.equal?(b).should be_true
|
48
71
|
b.a.equal?(a).should be_true
|
49
72
|
end
|
50
73
|
|
51
74
|
it "unregister" do
|
52
|
-
|
53
|
-
|
75
|
+
micon.register(:value){"The Object"}
|
76
|
+
micon[:value].should == "The Object"
|
54
77
|
|
55
|
-
|
56
|
-
|
78
|
+
micon.unregister :value
|
79
|
+
-> {micon[:value]}.should raise_error(/component not managed/)
|
57
80
|
end
|
81
|
+
|
82
|
+
it 'delete'
|
58
83
|
end
|
metadata
CHANGED
@@ -1,44 +1,43 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: micon
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 1
|
9
|
-
- 6
|
10
|
-
version: 0.1.6
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.7
|
5
|
+
prerelease:
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Alexey Petrushin
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
date: 2010-10-22 00:00:00 +04:00
|
12
|
+
date: 2011-06-17 00:00:00.000000000 +04:00
|
19
13
|
default_executable:
|
20
14
|
dependencies: []
|
21
|
-
|
22
15
|
description:
|
23
16
|
email:
|
24
17
|
executables: []
|
25
|
-
|
26
18
|
extensions: []
|
27
|
-
|
28
19
|
extra_rdoc_files: []
|
29
|
-
|
30
|
-
files:
|
20
|
+
files:
|
31
21
|
- Rakefile
|
32
22
|
- readme.md
|
33
23
|
- lib/micon/class.rb
|
24
|
+
- lib/micon/core.rb
|
25
|
+
- lib/micon/helper.rb
|
34
26
|
- lib/micon/metadata.rb
|
35
|
-
- lib/micon/micon.rb
|
36
27
|
- lib/micon/module.rb
|
28
|
+
- lib/micon/rad.rb
|
29
|
+
- lib/micon/spec.rb
|
37
30
|
- lib/micon/support.rb
|
38
31
|
- lib/micon.rb
|
39
32
|
- spec/callbacks_spec.rb
|
33
|
+
- spec/constants_spec/get_constant_component/lib/components/TheController.rb
|
34
|
+
- spec/constants_spec.rb
|
40
35
|
- spec/custom_scope_spec.rb
|
36
|
+
- spec/initialization_spec.rb
|
41
37
|
- spec/managed_spec.rb
|
38
|
+
- spec/micelaneous_spec/autoload/lib/components/some_value.rb
|
39
|
+
- spec/micelaneous_spec/autoload/lib/components/TheRad/TheView.rb
|
40
|
+
- spec/micelaneous_spec/autoload/lib/components/TheRouter.rb
|
42
41
|
- spec/micelaneous_spec.rb
|
43
42
|
- spec/nested_custom_scope_spec.rb
|
44
43
|
- spec/overview_spec.rb
|
@@ -47,36 +46,26 @@ files:
|
|
47
46
|
has_rdoc: true
|
48
47
|
homepage: http://github.com/alexeypetrushin/micon
|
49
48
|
licenses: []
|
50
|
-
|
51
49
|
post_install_message:
|
52
50
|
rdoc_options: []
|
53
|
-
|
54
|
-
require_paths:
|
51
|
+
require_paths:
|
55
52
|
- lib
|
56
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
57
54
|
none: false
|
58
|
-
requirements:
|
59
|
-
- -
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
|
62
|
-
|
63
|
-
- 0
|
64
|
-
version: "0"
|
65
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ! '>='
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
66
60
|
none: false
|
67
|
-
requirements:
|
68
|
-
- -
|
69
|
-
- !ruby/object:Gem::Version
|
70
|
-
|
71
|
-
segments:
|
72
|
-
- 0
|
73
|
-
version: "0"
|
61
|
+
requirements:
|
62
|
+
- - ! '>='
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '0'
|
74
65
|
requirements: []
|
75
|
-
|
76
66
|
rubyforge_project:
|
77
|
-
rubygems_version: 1.
|
67
|
+
rubygems_version: 1.5.1
|
78
68
|
signing_key:
|
79
69
|
specification_version: 3
|
80
|
-
summary: Assembles and
|
70
|
+
summary: Assembles and Manages Components of Your Application
|
81
71
|
test_files: []
|
82
|
-
|
data/lib/micon/micon.rb
DELETED
@@ -1,250 +0,0 @@
|
|
1
|
-
# Predefined scopes are: :application | :session | :thread | :instance | :"custom_name"
|
2
|
-
#
|
3
|
-
# Micons :"custom_name" are managed by 'scope_begin' / 'scope_end' methods
|
4
|
-
#
|
5
|
-
# :"custom_name" can't be nested (it will destroy old and start new one) and always should be explicitly started!.
|
6
|
-
|
7
|
-
module Micon
|
8
|
-
SYNC, MSYNC = Monitor.new, Monitor.new
|
9
|
-
|
10
|
-
# quick access to Metadata inner variable.
|
11
|
-
# I intentially broke the Metadata incapsulation to provide better performance, don't refactor it.
|
12
|
-
@_r = {}
|
13
|
-
|
14
|
-
@application, @metadata = {}, Metadata.new(@_r, MSYNC)
|
15
|
-
|
16
|
-
class << self
|
17
|
-
attr_accessor :metadata
|
18
|
-
|
19
|
-
#
|
20
|
-
# Scope Management
|
21
|
-
#
|
22
|
-
def activate scope, container, &block
|
23
|
-
raise_without_self "Only custom scopes can be activated!" if scope == :application or scope == :instance
|
24
|
-
raise "container should have type of Hash but has #{container.class.name}" unless container.is_a? Hash
|
25
|
-
|
26
|
-
scope_with_prefix = add_prefix(scope)
|
27
|
-
raise_without_self "Scope '#{remove_prefix(scope)}' already active!" if !block and Thread.current[scope_with_prefix]
|
28
|
-
|
29
|
-
if block
|
30
|
-
begin
|
31
|
-
outer_container_or_nil = Thread.current[scope_with_prefix]
|
32
|
-
Thread.current[scope_with_prefix] = container
|
33
|
-
@metadata.with_scope_callbacks scope, container, &block
|
34
|
-
ensure
|
35
|
-
Thread.current[scope_with_prefix] = outer_container_or_nil
|
36
|
-
end
|
37
|
-
else
|
38
|
-
# not support nested scopes without block
|
39
|
-
Thread.current[scope_with_prefix] = container
|
40
|
-
@metadata.call_before_scope scope, container
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def deactivate scope
|
45
|
-
raise_without_self "Only custom scopes can be deactivated!" if scope == :application or scope == :instance
|
46
|
-
|
47
|
-
scope_with_prefix = add_prefix(scope)
|
48
|
-
raise_without_self "Scope '#{scope}' not active!" unless container = Thread.current[scope_with_prefix]
|
49
|
-
|
50
|
-
@metadata.call_after_scope scope, container
|
51
|
-
Thread.current[scope_with_prefix] = nil
|
52
|
-
container
|
53
|
-
end
|
54
|
-
|
55
|
-
def active? scope
|
56
|
-
if scope == :application or scope == :instance
|
57
|
-
true
|
58
|
-
else
|
59
|
-
Thread.current.key?(add_prefix(scope))
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def clear
|
64
|
-
SYNC.synchronize{@application.clear}
|
65
|
-
Thread.current.keys.each do |key|
|
66
|
-
Thread.current[key] = nil if key.to_s =~ /^mc_/
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def empty?
|
71
|
-
return false unless SYNC.synchronize{@application.empty?}
|
72
|
-
Thread.current.keys.each do |key|
|
73
|
-
return false if key.to_s =~ /^mc_/
|
74
|
-
end
|
75
|
-
return true
|
76
|
-
end
|
77
|
-
|
78
|
-
|
79
|
-
#
|
80
|
-
# Object Management
|
81
|
-
#
|
82
|
-
def include? key
|
83
|
-
scope = MSYNC.synchronize{@_r[key]}
|
84
|
-
|
85
|
-
case scope
|
86
|
-
when nil
|
87
|
-
raise_without_self "'#{key}' component not managed!"
|
88
|
-
when :instance
|
89
|
-
true
|
90
|
-
when :application
|
91
|
-
SYNC.synchronize do
|
92
|
-
@application.include? key
|
93
|
-
end
|
94
|
-
else # custom
|
95
|
-
container = Thread.current[scope]
|
96
|
-
return false unless container
|
97
|
-
container.include? key
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
def [] key
|
102
|
-
scope = MSYNC.synchronize{@_r[key]}
|
103
|
-
|
104
|
-
case scope
|
105
|
-
when nil
|
106
|
-
raise_without_self "'#{key}' component not managed!"
|
107
|
-
when :instance
|
108
|
-
return create_object(key)
|
109
|
-
when :application
|
110
|
-
SYNC.synchronize do
|
111
|
-
o = @application[key]
|
112
|
-
unless o
|
113
|
-
return create_object(key, @application)
|
114
|
-
else
|
115
|
-
return o
|
116
|
-
end
|
117
|
-
end
|
118
|
-
else # custom
|
119
|
-
container = Thread.current[scope]
|
120
|
-
raise_without_self "Scope '#{remove_prefix(scope)}' not started!" unless container
|
121
|
-
o = container[key]
|
122
|
-
unless o
|
123
|
-
return create_object(key, container)
|
124
|
-
else
|
125
|
-
return o
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
def []= key, value
|
131
|
-
scope = MSYNC.synchronize{@_r[key]}
|
132
|
-
|
133
|
-
case scope
|
134
|
-
when nil
|
135
|
-
raise_without_self "'#{key}' component not managed!"
|
136
|
-
when :instance
|
137
|
-
raise_without_self "You can't outject variable with the 'instance' scope!"
|
138
|
-
when :application
|
139
|
-
SYNC.synchronize{@application[key] = value}
|
140
|
-
else # Custom
|
141
|
-
container = Thread.current[scope]
|
142
|
-
raise_without_self "Scope '#{remove_prefix(scope)}' not started!" unless container
|
143
|
-
container[key] = value
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
|
148
|
-
#
|
149
|
-
# Metadata
|
150
|
-
#
|
151
|
-
def register key, options = {}, &initializer
|
152
|
-
raise "key should not be nil or false value!" unless key
|
153
|
-
options = options.symbolize_keys
|
154
|
-
|
155
|
-
scope = options.delete(:scope) || :application
|
156
|
-
scope = Micon.add_prefix(scope) unless scope == :application or scope == :instance
|
157
|
-
dependencies = Array(options.delete(:require) || options.delete(:depends_on))
|
158
|
-
|
159
|
-
options.each{|key| raise "Unknown option :#{key}!"}
|
160
|
-
|
161
|
-
MSYNC.synchronize do
|
162
|
-
unless @_r.object_id == @metadata.registry.object_id
|
163
|
-
raise "internal error, reference to registry aren't equal to actual registry!"
|
164
|
-
end
|
165
|
-
@metadata.registry[key] = scope
|
166
|
-
@metadata.initializers[key] = [(initializer || lambda{nil}), dependencies]
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
def unregister key
|
171
|
-
@metadata.delete key
|
172
|
-
end
|
173
|
-
|
174
|
-
def before component, &block
|
175
|
-
@metadata.register_before component, &block
|
176
|
-
end
|
177
|
-
|
178
|
-
def after component, &block
|
179
|
-
@metadata.register_after component, &block
|
180
|
-
end
|
181
|
-
|
182
|
-
def before_scope scope, &block
|
183
|
-
@metadata.register_before_scope scope, &block
|
184
|
-
end
|
185
|
-
|
186
|
-
def after_scope scope, &block
|
187
|
-
@metadata.register_after_scope scope, &block
|
188
|
-
end
|
189
|
-
|
190
|
-
# handy method, usually for test purposes
|
191
|
-
def swap_metadata metadata = nil
|
192
|
-
metadata ||= Metadata.new({}, MSYNC)
|
193
|
-
old = self.metadata
|
194
|
-
|
195
|
-
self.metadata = metadata
|
196
|
-
@_r = metadata.registry
|
197
|
-
|
198
|
-
old
|
199
|
-
end
|
200
|
-
|
201
|
-
protected
|
202
|
-
def create_object key, container = nil
|
203
|
-
initializer, dependencies = MSYNC.synchronize{@metadata.initializers[key]}
|
204
|
-
dependencies.each{|d| Micon[d]}
|
205
|
-
@metadata.call_before key
|
206
|
-
|
207
|
-
if container
|
208
|
-
unless o = container[key]
|
209
|
-
o = initializer.call
|
210
|
-
container[key] = o
|
211
|
-
else
|
212
|
-
# complex case, there's an circular dependency, and the 'o' already has been
|
213
|
-
# initialized in dependecies or callbacks
|
214
|
-
# here's the sample case:
|
215
|
-
#
|
216
|
-
# Micon.register :environment, :application do
|
217
|
-
# p :environment
|
218
|
-
# 'environment'
|
219
|
-
# end
|
220
|
-
#
|
221
|
-
# Micon.register :conveyors, :application, :depends_on => :environment do
|
222
|
-
# p :conveyors
|
223
|
-
# 'conveyors'
|
224
|
-
# end
|
225
|
-
#
|
226
|
-
# Micon.after :environment do
|
227
|
-
# Micon[:conveyors]
|
228
|
-
# end
|
229
|
-
#
|
230
|
-
# Micon[:conveyors]
|
231
|
-
|
232
|
-
o = container[key]
|
233
|
-
end
|
234
|
-
else
|
235
|
-
o = initializer.call
|
236
|
-
end
|
237
|
-
|
238
|
-
@metadata.call_after key, o
|
239
|
-
o
|
240
|
-
end
|
241
|
-
|
242
|
-
def add_prefix scope
|
243
|
-
:"mc_#{scope}"
|
244
|
-
end
|
245
|
-
|
246
|
-
def remove_prefix scope
|
247
|
-
scope.to_s.gsub(/^mc_/, '')
|
248
|
-
end
|
249
|
-
end
|
250
|
-
end
|