micon 0.1.16 → 0.1.17

Sign up to get free protection for your applications and to get access to all the features.
@@ -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