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.
@@ -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; Micon end
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, :scope => :request
39
+ register_as :request, scope: :request
36
40
  end
37
41
 
38
42
  class Application
39
43
  # injecting components into attributes
40
- inject :request => :request, :logger => :logger
44
+ inject request: :request, logger: :logger
41
45
 
42
46
  def do_business
43
47
  # now we can use injected component
@@ -1,6 +1,13 @@
1
1
  require 'rspec_ext'
2
2
 
3
- lib_dir = "#{__FILE__.parent_dirname}/lib"
4
- $LOAD_PATH << lib_dir unless $LOAD_PATH.include? lib_dir
3
+ require "micon"
5
4
 
6
- require "micon"
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
@@ -1,32 +1,55 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe "Application and Instance scopes" do
4
- before :each do
5
- Micon.clear
6
- Micon.metadata.clear
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
- Micon.register(:value, :scope => :instance){"The Object"}
16
+ micon.register(:value, scope: :instance){"The Object"}
11
17
 
12
- Micon[:value].should == "The Object"
13
- Micon[:value].object_id.should_not == Micon[:value].object_id
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
- Micon.register(:value){"The Object"}
23
+ micon.register(:value){"The Object"}
18
24
 
19
- Micon[:value].should == "The Object"
20
- Micon[:value].object_id.should == Micon[:value].object_id
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
- Micon.register :value
26
-
27
- Micon[:value].should be_nil
28
- Micon[:value] = the_object
29
- Micon[:value].object_id.should == the_object.object_id
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 :b => :cycle_b
60
+ inject b: :cycle_b
38
61
  end
39
62
 
40
63
  class CycleB
41
64
  register_as :cycle_b
42
- inject :a => :cycle_a
65
+ inject a: :cycle_a
43
66
  end
44
67
 
45
- a = Micon[:cycle_a]
46
- b = Micon[:cycle_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
- Micon.register(:value){"The Object"}
53
- Micon[:value].should == "The Object"
75
+ micon.register(:value){"The Object"}
76
+ micon[:value].should == "The Object"
54
77
 
55
- Micon.unregister :value
56
- lambda{Micon[:value]}.should raise_error(/component not managed/)
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
- hash: 23
5
- prerelease: false
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
- hash: 3
62
- segments:
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
- hash: 3
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.3.7
67
+ rubygems_version: 1.5.1
78
68
  signing_key:
79
69
  specification_version: 3
80
- summary: Assembles and manages pieces of your application
70
+ summary: Assembles and Manages Components of Your Application
81
71
  test_files: []
82
-
@@ -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