micon 0.1.16 → 0.1.17

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.
@@ -0,0 +1,171 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Micon Overview" do
4
+ before do
5
+ self.micon = Micon::Core.new
6
+ end
7
+ after do
8
+ remove_constants :Logger, :Router, :PagesController, :Request, :RackAdapter
9
+ end
10
+
11
+ it "example" do
12
+ require 'micon'
13
+
14
+ # Here's our Web Framework, let's call it Rad
15
+
16
+ # Let's define shortcut to access the IoC API (optional
17
+ # but handy step). I don't know how You would like to call it,
18
+ # so I leave this step to You.
19
+ class ::Object
20
+ def rad; MICON end
21
+ end
22
+
23
+ # let's define some components
24
+ # the :logger is one per application, it's a static component (like singleton)
25
+ class Logger
26
+ register_as :logger
27
+ attr_accessor :log_file_path
28
+ def info msg
29
+ puts "#{msg} (writen to #{log_file_path})" unless defined?(RSpec)
30
+ end
31
+ end
32
+
33
+ # To demostrate basics of working with compnents let's configure our :logger
34
+ # explicitly (in the next example, it will be configured automatically).
35
+ rad.logger.log_file_path = '/tmp/rad.log'
36
+
37
+ # The :router requires complex initialization, so we use
38
+ # another form of component registration.
39
+ class Router
40
+ def initialize routes; @routes = routes end
41
+ def decode request;
42
+ class_name, method = @routes[request.url]
43
+ return eval(class_name), method # returning actual class
44
+ end
45
+ end
46
+ rad.register :router do
47
+ Router.new '/index' => ['PagesController', :index]
48
+ end
49
+
50
+ # The :controller component should be created and destroyed dynamically,
51
+ # for each request, we specifying that component is dynamic
52
+ # by declaring it's :scope.
53
+ # And, we don't know beforehead what it actully will be, for different
54
+ # request there can be different controllers,
55
+ # so, here we just declaring it without any initialization block, it
56
+ # will be created at runtime later.
57
+ rad.register :controller, scope: :request
58
+
59
+ # Let's define some of our controllers, the PagesController, note - we
60
+ # don't register it as component.
61
+ class PagesController
62
+ # We need access to :logger and :request, let's inject them
63
+ inject logger: :logger, request: :request
64
+
65
+ def index
66
+ # Here we can use injected component
67
+ logger.info "Application: processing #{request}"
68
+ end
69
+ end
70
+
71
+ # Request is also dynamic, and it also can't be created beforehead.
72
+ # We also registering it without initialization, it will be
73
+ # created at runtime later.
74
+ class Request
75
+ attr_reader :url
76
+ def initialize url; @url = url end
77
+ def to_s; @url end
78
+ end
79
+ # Registering without initialization block.
80
+ rad.register :request, scope: :request
81
+
82
+ # We need to integrate our application with web server, for example with the Rack.
83
+ # When the server receive web request, it calls the :call method of our RackAdapter
84
+ class RackAdapter
85
+ # Injecting components
86
+ inject request: :request, controller: :controller
87
+
88
+ def call env
89
+ # We need to tell Micon that the :request scope is started, so it will know
90
+ # that some dynamic components should be created during this scope and
91
+ # destroyed at the end of it.
92
+ rad.activate :request, {} do
93
+ # Here we manually creating the Request component
94
+ self.request = Request.new '/index'
95
+
96
+ # The :router also can be injected via :inject,
97
+ # but we can also use another way to access components,
98
+ # every component also availiable as rad.<component_name>
99
+ controller_class, method = rad.router.decode request
100
+
101
+ # Let's create and call our controller
102
+ self.controller = controller_class.new
103
+ controller.send method
104
+ end
105
+ end
106
+ end
107
+
108
+ # Let's pretend that there's a Web Server and run our application,
109
+ # You should see something like this in the console:
110
+ # Application: processing /index
111
+ RackAdapter.new.call({})
112
+ end
113
+
114
+ describe 'real-life' do
115
+ class_loader_available = begin
116
+ require 'class_loader'
117
+ require 'class_loader/spec'
118
+ true
119
+ rescue LoadError
120
+ false
121
+ end
122
+
123
+ if class_loader_available
124
+ with_load_path "#{spec_dir}/lib"
125
+ with_autoload_path "#{spec_dir}/lib"
126
+
127
+ it "example" do
128
+ require 'micon'
129
+ require 'class_loader'
130
+
131
+ # Here's our Web Framework, let's call it Rad
132
+
133
+ # Let's define shortcut to access the IoC API (optional
134
+ # but handy step). I don't know how You would like to call it,
135
+ # so I leave this step to You.
136
+ class ::Object
137
+ def rad; MICON end
138
+ end
139
+
140
+ # Auto-discovering:
141
+ #
142
+ # All components (:logger, :router, :request, :controller) are
143
+ # defined in spec/example_spec/lib/components folder.
144
+ # All classes (PagesController, RackAdapter) are
145
+ # located in spec/example_spec/lib folder.
146
+ #
147
+ # Note that there's no any "require 'xxx'" clause, all components and
148
+ # classes are loaded and dependecies are resolved automatically.
149
+
150
+ # Auto-configuring
151
+ #
152
+ # Remember our manual configuration of "logger.log_file_path" from
153
+ # the previous example?
154
+ # This time it will be configured automatically, take a look at
155
+ # the spec/example_spec/lib/components/logger.yml file.
156
+ #
157
+ # Note, that there are also logger.production.yml, configs are smart
158
+ # and are merged in the following order:
159
+ # logger.yml <- logger.<env>.yml <- <runtime_path>/config/logger.yml
160
+ # (If you define :environment and :runtime_path variables).
161
+
162
+ # Let's pretend that there's a Web Server and run our application,
163
+ # You should see something like this in the console:
164
+ # Application: processing /index
165
+ RackAdapter.new.call({})
166
+ end
167
+ else
168
+ warn "The 'real-life example' requires 'class_loader' gem, please install it"
169
+ end
170
+ end
171
+ end
@@ -8,10 +8,10 @@ describe "Initialization" do
8
8
  it "clone" do
9
9
  m = Micon::Core.new
10
10
  m.initialize!
11
-
11
+
12
12
  m.register(:the_value){'the_value'}
13
13
  m[:the_value]
14
-
14
+
15
15
  another = m.clone
16
16
  another.metadata.should include(:the_value)
17
17
  another.instance_variable_get('@registry').should include(:the_value)
@@ -30,40 +30,40 @@ describe "Initialization" do
30
30
  it "should support isolation" do
31
31
  m1 = Micon::Core.new
32
32
  m1.initialize!
33
-
33
+
34
34
  m1.register(:first){'first'}
35
35
  m1.first.should == 'first'
36
-
36
+
37
37
  m1.deinitialize!
38
-
38
+
39
39
  # m2
40
40
  m2 = m1.clone
41
41
  m2.initialize!
42
-
42
+
43
43
  m2.first.should == 'first'
44
44
  m2.register(:second){'second'}
45
45
  m2.second.should == 'second'
46
46
  m2.deinitialize!
47
-
47
+
48
48
  # m1 shouldn't have any of m2 stuff
49
49
  m1.initialize!
50
50
  m1.first.should == 'first'
51
51
  m1.metadata.should_not include(:second)
52
52
  m1.include? :second
53
- m1.should_not include(:second)
53
+ m1.should_not include(:second)
54
54
  end
55
55
 
56
56
  # describe "constants" do
57
57
  # it "deinitialize! should delete all defined constants" do
58
58
  # m = Micon::Core.new
59
59
  # m.initialize!
60
- #
60
+ #
61
61
  # m.register(:TheRouter, constant: true){'TheRouter'}
62
62
  # ::TheRouter.should == 'TheRouter'
63
- #
63
+ #
64
64
  # m.deinitialize!
65
65
  # Object.const_defined?(:TheRouter).should be_false
66
- #
66
+ #
67
67
  # m.initialize!
68
68
  # ::TheRouter.should == 'TheRouter'
69
69
  # end
data/spec/managed_spec.rb CHANGED
@@ -3,12 +3,12 @@ require 'spec_helper'
3
3
  describe "Managed" do
4
4
  before :all do
5
5
  self.micon = Micon::Core.new
6
-
7
- class ManagedObject
6
+
7
+ class ManagedObject
8
8
  register_as :managed_object
9
9
  inject object: :object_key
10
10
 
11
- class << self
11
+ class << self
12
12
  inject object: :object_key
13
13
  end
14
14
  end
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe "Miscellaneous" do
4
- with_load_path "#{spec_dir}/autoload/lib"
4
+ with_load_path "#{spec_dir}/autoload/lib"
5
5
 
6
6
  before{self.micon = Micon::Core.new}
7
7
  after{remove_constants :TheRouter, :TheRad}
@@ -11,14 +11,14 @@ describe "Miscellaneous" do
11
11
  micon[:some_value].should == "some_value"
12
12
  end
13
13
 
14
- # it 'should autoload component - constants (and nested constants)' do
14
+ # it 'should autoload component - constants (and nested constants)' do
15
15
  # TheRouter.should == "TheRouter"
16
16
  # module ::TheRad; end
17
17
  # TheRad::TheView.should == "TheView"
18
18
  # end
19
19
  end
20
20
 
21
- describe "complex circullar dependencies" do
21
+ describe "complex circullar dependencies" do
22
22
  it "should not initialize twice (from error)" do
23
23
  micon.register :kit do
24
24
  micon[:kit]
@@ -26,7 +26,7 @@ describe "Miscellaneous" do
26
26
  end
27
27
  lambda{micon[:kit]}.should raise_error(/component :kit used before it's initialization is finished/)
28
28
  end
29
-
29
+
30
30
  it "should not initialize twice if called from dependency (from error)" do
31
31
  micon.register :environment do
32
32
  micon[:router]
@@ -39,7 +39,7 @@ describe "Miscellaneous" do
39
39
 
40
40
  -> {micon[:router]}.should raise_error(/component .* used before it's initialization is finished/)
41
41
  end
42
-
42
+
43
43
  it "should allow to use circullar dependency in :after callback" do
44
44
  check = mock
45
45
  check.should_receive(:initialized).once
@@ -52,27 +52,27 @@ describe "Miscellaneous" do
52
52
  end
53
53
  micon[:kit].should == 'kit'
54
54
  end
55
-
55
+
56
56
  it "should allow circullar dependencies in :after callback" do
57
57
  micon.register :environment do
58
58
  'environment'
59
59
  end
60
-
60
+
61
61
  micon.register :router, depends_on: :environment do
62
62
  'router'
63
63
  end
64
-
64
+
65
65
  micon.after :environment do
66
66
  micon[:router]
67
67
  end
68
-
69
- micon[:router]
68
+
69
+ micon[:router]
70
70
  end
71
71
  end
72
72
 
73
73
  it "helper method generation" do
74
74
  micon.register :router
75
-
75
+
76
76
  micon.router?.should be_false
77
77
  micon.router = 'router'
78
78
  micon.router?.should be_true
@@ -7,18 +7,18 @@ describe "Nested custom scope" do
7
7
 
8
8
  it "with block" do
9
9
  micon.register :value, scope: :custom
10
-
10
+
11
11
  custom_a = {}
12
12
  micon.activate :custom, custom_a do
13
13
  micon[:value] = 'value a'
14
-
14
+
15
15
  custom_b = {}
16
16
  micon.activate :custom, custom_b do
17
17
  micon.should_not include(:value)
18
18
  micon[:value] = 'value b'
19
19
  micon[:value].should == 'value b'
20
20
  end
21
-
21
+
22
22
  micon[:value].should == 'value a'
23
23
  end
24
24
  end
@@ -3,23 +3,23 @@ require 'spec_helper'
3
3
  describe "Application and Instance scopes" do
4
4
  before{self.micon = Micon::Core.new}
5
5
 
6
- it "dependencies" do
6
+ it "dependencies" do
7
7
  micon.register(:another_object, depends_on: :the_object){"another_object"}
8
8
  -> {micon[:another_object]}.should raise_error(/the_object.*not managed/)
9
9
  micon.register(:the_object){"the_object"}
10
10
  micon[:another_object]
11
11
  end
12
12
 
13
- it "instance scope" do
13
+ it "instance scope" do
14
14
  micon.register(:value, scope: :instance){"The Object"}
15
-
15
+
16
16
  micon[:value].should == "The Object"
17
17
  micon[:value].object_id.should_not == micon[:value].object_id
18
18
  end
19
19
 
20
20
  it "application scope" do
21
21
  micon.register(:value){"The Object"}
22
-
22
+
23
23
  micon[:value].should == "The Object"
24
24
  micon[:value].object_id.should == micon[:value].object_id
25
25
  end
@@ -53,26 +53,26 @@ describe "Application and Instance scopes" do
53
53
  it "cycle reference" do
54
54
  class CycleB; end
55
55
 
56
- class CycleA
56
+ class CycleA
57
57
  register_as :cycle_a
58
58
  inject b: :cycle_b
59
59
  end
60
60
 
61
- class CycleB
61
+ class CycleB
62
62
  register_as :cycle_b
63
63
  inject a: :cycle_a
64
64
  end
65
-
65
+
66
66
  a = micon[:cycle_a]
67
67
  b = micon[:cycle_b]
68
68
  a.b.equal?(b).should be_true
69
69
  b.a.equal?(a).should be_true
70
- end
71
-
72
- it "unregister" do
70
+ end
71
+
72
+ it "unregister" do
73
73
  micon.register(:value){"The Object"}
74
74
  micon[:value].should == "The Object"
75
-
75
+
76
76
  micon.unregister :value
77
77
  -> {micon[:value]}.should raise_error(/component not managed/)
78
78
  end
metadata CHANGED
@@ -1,28 +1,22 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: micon
3
- version: !ruby/object:Gem::Version
4
- version: 0.1.16
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.17
5
5
  prerelease:
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Alexey Petrushin
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2011-08-08 00:00:00 +04:00
14
- default_executable:
12
+ date: 2011-08-15 00:00:00.000000000Z
15
13
  dependencies: []
16
-
17
14
  description:
18
15
  email:
19
16
  executables: []
20
-
21
17
  extensions: []
22
-
23
18
  extra_rdoc_files: []
24
-
25
- files:
19
+ files:
26
20
  - Rakefile
27
21
  - readme.md
28
22
  - lib/micon/class.rb
@@ -45,6 +39,16 @@ files:
45
39
  - spec/constants_spec/get_constant_component/lib/components/TheController.rb
46
40
  - spec/constants_spec.rb
47
41
  - spec/custom_scope_spec.rb
42
+ - spec/example_spec/lib/components/controller.rb
43
+ - spec/example_spec/lib/components/logger.production.yml
44
+ - spec/example_spec/lib/components/logger.rb
45
+ - spec/example_spec/lib/components/logger.yml
46
+ - spec/example_spec/lib/components/request.rb
47
+ - spec/example_spec/lib/components/router.rb
48
+ - spec/example_spec/lib/pages_controller.rb
49
+ - spec/example_spec/lib/rack_adapter.rb
50
+ - spec/example_spec/lib/request.rb
51
+ - spec/example_spec.rb
48
52
  - spec/initialization_spec.rb
49
53
  - spec/managed_spec.rb
50
54
  - spec/miscellaneous_spec/autoload/lib/components/some_value.rb
@@ -52,36 +56,30 @@ files:
52
56
  - spec/miscellaneous_spec/autoload/lib/components/TheRouter.rb
53
57
  - spec/miscellaneous_spec.rb
54
58
  - spec/nested_custom_scope_spec.rb
55
- - spec/overview_spec.rb
56
59
  - spec/spec_helper.rb
57
60
  - spec/static_scope_spec.rb
58
- has_rdoc: true
59
61
  homepage: http://github.com/alexeypetrushin/micon
60
62
  licenses: []
61
-
62
63
  post_install_message:
63
64
  rdoc_options: []
64
-
65
- require_paths:
65
+ require_paths:
66
66
  - lib
67
- required_ruby_version: !ruby/object:Gem::Requirement
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
68
  none: false
69
- requirements:
70
- - - ">="
71
- - !ruby/object:Gem::Version
72
- version: "0"
73
- required_rubygems_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ! '>='
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
74
  none: false
75
- requirements:
76
- - - ">="
77
- - !ruby/object:Gem::Version
78
- version: "0"
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
79
  requirements: []
80
-
81
80
  rubyforge_project:
82
- rubygems_version: 1.5.1
81
+ rubygems_version: 1.8.6
83
82
  signing_key:
84
83
  specification_version: 3
85
- summary: Assembles and Manages Components of Your Application
84
+ summary: Micon IoC assembles and manages Your Application
86
85
  test_files: []
87
-
@@ -1,67 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe "Micon Overview" do
4
- before do
5
- self.micon = Micon::Core.new
6
- end
7
-
8
- it "sample" do
9
- class Object
10
- def app; MICON end
11
- end
12
-
13
- # static (singleton) components
14
- class Environment
15
- register_as :environment
16
- end
17
-
18
- class Logger
19
- register_as :logger
20
-
21
- def info msg; end
22
- end
23
-
24
- class Router
25
- register_as :router
26
-
27
- def parse rote_filename
28
- # do something
29
- end
30
- end
31
-
32
- # callbacks, we need to parse routes right after environment is initialized
33
- app.after :environment do
34
- app[:router].parse '/config/routes.rb'
35
- end
36
-
37
- # dynamic components, will be created and destroyed for every request
38
- class Request
39
- register_as :request, scope: :request
40
- end
41
-
42
- class Application
43
- # injecting components into attributes
44
- inject request: :request, logger: :logger
45
-
46
- def do_business
47
- # now we can use injected component
48
- do_something_with request
49
- logger.info 'done'
50
- end
51
-
52
- def do_something_with request; end
53
- end
54
-
55
- # Web Server / Rack Adapter
56
- class RackAdapter
57
- def call env
58
- # activating new request scope, the session component will be created and destroyed automatically
59
- app.activate :request, {} do
60
- Application.new.do_business
61
- end
62
- end
63
- end
64
-
65
- RackAdapter.new.call({})
66
- end
67
- end