injection 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +6 -0
- data/Gemfile +4 -0
- data/README.rdoc +116 -0
- data/Rakefile +21 -0
- data/injection.gemspec +28 -0
- data/lib/injection.rb +45 -0
- data/lib/injection/class_inject.rb +38 -0
- data/lib/injection/observer_inject.rb +44 -0
- data/lib/injection/railtie.rb +41 -0
- data/lib/injection/version.rb +3 -0
- data/spec/class_inject_spec.rb +197 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +45 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +22 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +26 -0
- data/spec/dummy/config/environments/production.rb +49 -0
- data/spec/dummy/config/environments/test.rb +35 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/objects.yml +20 -0
- data/spec/dummy/config/routes.rb +58 -0
- data/spec/dummy/db/migrate/20101227205147_create_bananas.rb +13 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/lib/class_inject_classes.rb +12 -0
- data/spec/dummy/lib/observer_inject_classes.rb +2 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/public/javascripts/application.js +2 -0
- data/spec/dummy/public/javascripts/controls.js +965 -0
- data/spec/dummy/public/javascripts/dragdrop.js +974 -0
- data/spec/dummy/public/javascripts/effects.js +1123 -0
- data/spec/dummy/public/javascripts/prototype.js +6001 -0
- data/spec/dummy/public/javascripts/rails.js +175 -0
- data/spec/dummy/public/stylesheets/.gitkeep +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/observer_inject_spec.rb +228 -0
- data/spec/spec_helper.rb +40 -0
- metadata +223 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
== DESCRIPTION:
|
2
|
+
|
3
|
+
Injection is a simple dependency injection plugin for rails3. It allows you to inject objects into your controllers and observers which have been described in a yaml file (config/objects.yml).
|
4
|
+
|
5
|
+
* https://github.com/atomicobject/injection
|
6
|
+
|
7
|
+
(for the rails2 plugin install from the rails_2_plugin tag of this repository)
|
8
|
+
|
9
|
+
== FEATURES/PROBLEMS:
|
10
|
+
|
11
|
+
* Declarative dependency injection that automatically instantiates ivars via the objects.yml file
|
12
|
+
|
13
|
+
== SYNOPSIS:
|
14
|
+
To specify objects to be injected from the DIY context into your controller or observer
|
15
|
+
use the inject class method:
|
16
|
+
|
17
|
+
inject :one_component, :another
|
18
|
+
|
19
|
+
=== Example
|
20
|
+
|
21
|
+
This example defines a context with two objects, _foo_ and _bar_, which
|
22
|
+
are injected into every instance of the WidgetController or WidgetObserver. The objects
|
23
|
+
are available as instance variables within the controller and observer.
|
24
|
+
|
25
|
+
config/objects.yml:
|
26
|
+
---
|
27
|
+
foo:
|
28
|
+
bar:
|
29
|
+
|
30
|
+
lib/foo.rb:
|
31
|
+
class Foo
|
32
|
+
...
|
33
|
+
end
|
34
|
+
|
35
|
+
lib/bar.rb:
|
36
|
+
class Bar
|
37
|
+
...
|
38
|
+
end
|
39
|
+
|
40
|
+
app/controllers/widget_controller.rb:
|
41
|
+
class WidgetController < ApplicationController
|
42
|
+
inject :foo, :bar
|
43
|
+
|
44
|
+
def index
|
45
|
+
render :text => "{@foo.inspect} {@bar.inspect}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
app/models/widget_observer.rb:
|
50
|
+
class WidgetObserver < ActiveRecord::Observer
|
51
|
+
inject :foo, :bar
|
52
|
+
|
53
|
+
before :save do |widget|
|
54
|
+
@foo.bar(widget)
|
55
|
+
@bar.foo(widget)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
=== Declarative Observations
|
60
|
+
|
61
|
+
Observations on an active record object can be specified in a declarative way using
|
62
|
+
the before and after class methods. The methods are invoked with a
|
63
|
+
symbol which specifies what kind of event the observer is interested in, and a block
|
64
|
+
that defines what actions it will perform.
|
65
|
+
|
66
|
+
class WidgetObserver < ActiveRecord::Observer
|
67
|
+
before :update do |record|
|
68
|
+
...
|
69
|
+
end
|
70
|
+
|
71
|
+
after :create do |record|
|
72
|
+
...
|
73
|
+
end
|
74
|
+
|
75
|
+
after :validation do |record|
|
76
|
+
...
|
77
|
+
end
|
78
|
+
|
79
|
+
before :validation do |record|
|
80
|
+
...
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
== REQUIREMENTS:
|
85
|
+
|
86
|
+
* constructor
|
87
|
+
* diy
|
88
|
+
|
89
|
+
== INSTALL:
|
90
|
+
|
91
|
+
* gem install injection
|
92
|
+
|
93
|
+
== LICENSE:
|
94
|
+
|
95
|
+
(The MIT License)
|
96
|
+
|
97
|
+
Copyright (c) 2007-2010 Atomic Object
|
98
|
+
|
99
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
100
|
+
a copy of this software and associated documentation files (the
|
101
|
+
'Software'), to deal in the Software without restriction, including
|
102
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
103
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
104
|
+
permit persons to whom the Software is furnished to do so, subject to
|
105
|
+
the following conditions:
|
106
|
+
|
107
|
+
The above copyright notice and this permission notice shall be
|
108
|
+
included in all copies or substantial portions of the Software.
|
109
|
+
|
110
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
111
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
112
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
113
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
114
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
115
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
116
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
require 'rake'
|
5
|
+
require 'rake/rdoctask'
|
6
|
+
|
7
|
+
desc 'Default: run unit specs'
|
8
|
+
task :default => :spec
|
9
|
+
|
10
|
+
desc 'Generate documentation for the injection plugin.'
|
11
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
12
|
+
rdoc.rdoc_dir = 'doc'
|
13
|
+
rdoc.title = 'injection'
|
14
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
15
|
+
rdoc.rdoc_files.include('README')
|
16
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
17
|
+
end
|
18
|
+
|
19
|
+
require 'rspec/core'
|
20
|
+
require 'rspec/core/rake_task'
|
21
|
+
RSpec::Core::RakeTask.new(:spec)
|
data/injection.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "injection/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "injection"
|
7
|
+
s.version = Injection::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Atomic Object"]
|
10
|
+
s.email = ["github@atomicobject.com"]
|
11
|
+
s.homepage = "https://github.com/atomicobject/injection"
|
12
|
+
s.summary = %q{Dependency injection for Rails controllers and observers}
|
13
|
+
s.description = %q{Injection is a simple dependency injection gem for rails3. It allows you to inject objects into your controllers and observers which have been described in a yaml file (config/objects.yml).}
|
14
|
+
|
15
|
+
s.rubyforge_project = "injection"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n").reject {|f| f =~ /homepage/}
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_dependency "rails", ["~> 3"]
|
23
|
+
s.add_dependency "diy", ["~> 1"]
|
24
|
+
s.add_dependency "constructor", ["~> 2"]
|
25
|
+
|
26
|
+
s.add_development_dependency "rspec-rails", "~> 2"
|
27
|
+
s.add_development_dependency "sqlite3-ruby"
|
28
|
+
end
|
data/lib/injection.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'diy'
|
2
|
+
require 'constructor'
|
3
|
+
require 'injection/railtie'
|
4
|
+
require 'injection/class_inject'
|
5
|
+
require 'injection/observer_inject'
|
6
|
+
|
7
|
+
# === Accessing Objects in the Context
|
8
|
+
#
|
9
|
+
# Provides access to the context loaded from <tt>config/objects.yml</tt> which
|
10
|
+
# can be used to look up individual components.
|
11
|
+
#
|
12
|
+
# config/objects.yml:
|
13
|
+
# ---
|
14
|
+
# foo:
|
15
|
+
# bar:
|
16
|
+
#
|
17
|
+
# lib/foo.rb:
|
18
|
+
# class Foo
|
19
|
+
# ...
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# Inject.context[:foo] #=> #<Foo:0x81eb0>
|
23
|
+
#
|
24
|
+
module Injection
|
25
|
+
@@context = {}
|
26
|
+
@@extra_inputs = {}
|
27
|
+
|
28
|
+
# Accessor for the context loaded from <tt>config/objects.yml</tt>
|
29
|
+
def self.context
|
30
|
+
@@context
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.context_file=(path)
|
34
|
+
@@context_file = path
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.extra_inputs=(hash)
|
38
|
+
@@extra_inputs = hash
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.reset_context
|
42
|
+
@@context = DIY::Context.from_file(@@context_file, @@extra_inputs) if File.exists?(@@context_file)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Injection
|
2
|
+
module ClassInject
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
module Initialize #:nodoc:
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
def initialize(*args)
|
9
|
+
if args.empty?
|
10
|
+
raise 'No context file loaded' if Injection.context.is_a?(Hash)
|
11
|
+
constructor_args = self.class.constructor_keys.inject({}) do |memo, key|
|
12
|
+
memo[key] = Injection.context[key]
|
13
|
+
memo
|
14
|
+
end
|
15
|
+
super(constructor_args)
|
16
|
+
else
|
17
|
+
super
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
module ClassMethods
|
23
|
+
#
|
24
|
+
# Specify which components should be injected into this observer as the
|
25
|
+
# list of <tt>keys</tt> to look them up from the DI context.
|
26
|
+
#
|
27
|
+
def inject(*keys)
|
28
|
+
constructor_args = if keys.last.is_a?(Hash)
|
29
|
+
keys[0..-2] + [{:super => []}.merge(keys.last)]
|
30
|
+
else
|
31
|
+
keys + [:super => []]
|
32
|
+
end
|
33
|
+
constructor *constructor_args
|
34
|
+
include Initialize
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Injection
|
2
|
+
module ObserverExtension
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
#
|
7
|
+
# Specify what events the observer is interested in after an activerecord object has
|
8
|
+
# performed an operation by passing in a <tt>symbol</tt> and a <tt>block</tt>.
|
9
|
+
def after(observation, &block)
|
10
|
+
build_methods(:after, observation, &block)
|
11
|
+
end
|
12
|
+
|
13
|
+
#
|
14
|
+
# Specify what events the observer is interested in before an activerecord object has
|
15
|
+
# performed an operation by passing in a <tt>symbol</tt> and a <tt>block</tt>.
|
16
|
+
def before(observation, &block)
|
17
|
+
build_methods(:before, observation, &block)
|
18
|
+
end
|
19
|
+
|
20
|
+
#
|
21
|
+
# Specify what events the observer is interested in before and after an activerecord object has
|
22
|
+
# performed an operation by passing in a <tt>symbol</tt> and a <tt>block</tt> that yields.
|
23
|
+
def around(observation, &block)
|
24
|
+
build_methods(:around, observation, &block)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def build_methods(before_after, observation, &block)
|
30
|
+
mname = build_method_name(before_after, observation)
|
31
|
+
validate_observation! mname
|
32
|
+
define_method(mname, &block)
|
33
|
+
end
|
34
|
+
|
35
|
+
def build_method_name(before_after, observation)
|
36
|
+
"#{before_after}_#{observation}"
|
37
|
+
end
|
38
|
+
|
39
|
+
def validate_observation!(observation)
|
40
|
+
raise "#{observation} is not an observable action" unless ActiveRecord::Callbacks::CALLBACKS.include? observation.to_sym
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'rails'
|
2
|
+
|
3
|
+
module Injection
|
4
|
+
class Railtie < ::Rails::Railtie
|
5
|
+
config.before_configuration do
|
6
|
+
Injection.context_file = ::Rails.root.to_s + '/config/objects.yml'
|
7
|
+
end
|
8
|
+
|
9
|
+
config.after_initialize do
|
10
|
+
# Let Rails do the auto loading
|
11
|
+
DIY::Context.auto_require = false
|
12
|
+
|
13
|
+
# Reload the context from the file
|
14
|
+
Injection.reset_context
|
15
|
+
end
|
16
|
+
|
17
|
+
# Reload the context after each request in development
|
18
|
+
initializer "injection.clear_context", :before => :set_clear_dependencies_hook do |app|
|
19
|
+
unless app.config.cache_classes
|
20
|
+
::ActionDispatch::Callbacks.after do
|
21
|
+
Injection.reset_context
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
initializer "injection.initialize_action_controller" do |app|
|
27
|
+
::ActiveSupport.on_load(:action_controller) do
|
28
|
+
include ClassInject
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
initializer "injection.initialize_observers" do |app|
|
33
|
+
::ActiveSupport.on_load(:active_record) do
|
34
|
+
::ActiveRecord::Observer.class_eval do
|
35
|
+
include ClassInject
|
36
|
+
include ObserverExtension
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,197 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class NormalController < ActionController::Base
|
4
|
+
end
|
5
|
+
|
6
|
+
class InjectedController < ActionController::Base
|
7
|
+
inject :foo, :bar
|
8
|
+
attr_reader :foo, :bar
|
9
|
+
end
|
10
|
+
|
11
|
+
class PoorlyInjectedController < ActionController::Base
|
12
|
+
inject :foo, :bar, :qux
|
13
|
+
attr_reader :foo, :bar, :qux
|
14
|
+
end
|
15
|
+
|
16
|
+
class GalaxyController < ActionController::Base
|
17
|
+
inject :foo
|
18
|
+
attr_accessor :foo
|
19
|
+
end
|
20
|
+
|
21
|
+
class SpiralGalaxyController < GalaxyController
|
22
|
+
inject :bar
|
23
|
+
attr_accessor :bar
|
24
|
+
end
|
25
|
+
|
26
|
+
class MilkyWayGalaxyController < SpiralGalaxyController
|
27
|
+
inject :foo_piece_two
|
28
|
+
attr_accessor :foo_piece_two
|
29
|
+
end
|
30
|
+
|
31
|
+
class FutureMilkyWayGalaxyController < MilkyWayGalaxyController;
|
32
|
+
constructor
|
33
|
+
end
|
34
|
+
|
35
|
+
class CommercialController < ActionController::Base
|
36
|
+
inject :old, :readers => true
|
37
|
+
end
|
38
|
+
|
39
|
+
describe 'class inject' do
|
40
|
+
before do
|
41
|
+
# Instantiate a controller to kick start Rails into loading Injection
|
42
|
+
InjectedController.new
|
43
|
+
end
|
44
|
+
|
45
|
+
it "does not mess up construction of a normal controller" do
|
46
|
+
controller = NormalController.new
|
47
|
+
controller.should_not be_nil
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'injects objects from context' do
|
51
|
+
controller = InjectedController.new
|
52
|
+
controller.should_not be_nil
|
53
|
+
controller.foo.should equal(injection_context[:foo])
|
54
|
+
controller.bar.should equal(injection_context[:bar])
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'uses the params in injected object' do
|
58
|
+
foo, bar = 'foo', 'bar'
|
59
|
+
controller = InjectedController.new :foo => foo, :bar => bar
|
60
|
+
controller.should_not be_nil
|
61
|
+
controller.foo.should equal(foo)
|
62
|
+
controller.bar.should equal(bar)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "raises an error for a poorly injected object when a component is not found" do
|
66
|
+
lambda { PoorlyInjectedController.new }.should raise_error(DIY::ConstructionError, /qux/i)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "constructs poorly injected object given params" do
|
70
|
+
foo, bar, qux = 'foo', 'bar', 'qux'
|
71
|
+
controller = PoorlyInjectedController.new :foo => foo, :bar => bar, :qux => qux
|
72
|
+
controller.foo.should equal(foo)
|
73
|
+
controller.bar.should equal(bar)
|
74
|
+
controller.qux.should equal(qux)
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
it "raises for an injected object given only partial params" do
|
79
|
+
lambda { InjectedController.new(:foo => 'foo') }.should raise_error(Constructor::ArgumentError, /bar/i)
|
80
|
+
err = assert_raise Constructor::ArgumentError do
|
81
|
+
InjectedController.new :foo => 'foo'
|
82
|
+
end
|
83
|
+
assert_match(/bar/i, err.message)
|
84
|
+
end
|
85
|
+
|
86
|
+
context 'with an invalid context file' do
|
87
|
+
before do
|
88
|
+
set_context 'not a file path'
|
89
|
+
end
|
90
|
+
|
91
|
+
after do
|
92
|
+
set_context "#{::Rails.root}/config/objects.yml"
|
93
|
+
end
|
94
|
+
|
95
|
+
it "allows an injected object that is given params to have a non-existent context file" do
|
96
|
+
foo, bar = 'foo', 'bar'
|
97
|
+
controller = InjectedController.new :foo => foo, :bar => bar
|
98
|
+
controller.should_not be_nil
|
99
|
+
controller.foo.should equal(foo)
|
100
|
+
controller.bar.should equal(bar)
|
101
|
+
end
|
102
|
+
|
103
|
+
it "does not affect a normal object when set to a non-existent context file" do
|
104
|
+
foo, bar = 'foo', 'bar'
|
105
|
+
NormalController.new.should_not be_nil
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
it "supports object inheritance" do
|
110
|
+
GalaxyController.new.foo.should be_a_kind_of(TheFooClass)
|
111
|
+
|
112
|
+
controller = SpiralGalaxyController.new
|
113
|
+
injected_controller = SpiralGalaxyController.new(:foo => "foo", :bar => "bar")
|
114
|
+
SpiralGalaxyController.superclass.should == GalaxyController
|
115
|
+
|
116
|
+
controller.foo.should be_a_kind_of(TheFooClass)
|
117
|
+
controller.bar.should be_a_kind_of(Bar)
|
118
|
+
injected_controller.foo.should == "foo"
|
119
|
+
injected_controller.bar.should == "bar"
|
120
|
+
|
121
|
+
controller = MilkyWayGalaxyController.new
|
122
|
+
injected_controller = MilkyWayGalaxyController.new(:foo => "foo", :bar => "bar", :foo_piece_two => "foo2")
|
123
|
+
MilkyWayGalaxyController.superclass.should == SpiralGalaxyController
|
124
|
+
controller.foo.should be_a_kind_of(TheFooClass)
|
125
|
+
assert_kind_of(TheFooClass, controller.foo)
|
126
|
+
controller.bar.should be_a_kind_of(Bar)
|
127
|
+
controller.foo_piece_two.should be_a_kind_of(FooPieceTwo)
|
128
|
+
injected_controller.foo.should == "foo"
|
129
|
+
injected_controller.bar.should == "bar"
|
130
|
+
injected_controller.foo_piece_two.should == "foo2"
|
131
|
+
|
132
|
+
controller = FutureMilkyWayGalaxyController.new
|
133
|
+
injected_controller = FutureMilkyWayGalaxyController.new(:foo => "foo", :bar => "bar", :foo_piece_two => "foo2")
|
134
|
+
FutureMilkyWayGalaxyController.superclass.should == MilkyWayGalaxyController
|
135
|
+
controller.foo.should be_a_kind_of(TheFooClass)
|
136
|
+
assert_kind_of(TheFooClass, controller.foo)
|
137
|
+
controller.bar.should be_a_kind_of(Bar)
|
138
|
+
controller.foo_piece_two.should be_a_kind_of(FooPieceTwo)
|
139
|
+
injected_controller.foo.should == "foo"
|
140
|
+
injected_controller.bar.should == "bar"
|
141
|
+
injected_controller.foo_piece_two.should == "foo2"
|
142
|
+
end
|
143
|
+
|
144
|
+
it "resets the context to having no built components" do
|
145
|
+
ic = InjectedController.new
|
146
|
+
ic.foo.should eql(Injection.context['foo'])
|
147
|
+
ic.bar.should eql(Injection.context['bar'])
|
148
|
+
|
149
|
+
# See that the inject context is being reused, as well as its previously built components:
|
150
|
+
ic2 = InjectedController.new
|
151
|
+
ic.foo.should eql(Injection.context['foo'])
|
152
|
+
ic.bar.should eql(Injection.context['bar'])
|
153
|
+
ic2.foo.should eql(Injection.context['foo'])
|
154
|
+
ic2.bar.should eql(Injection.context['bar'])
|
155
|
+
ic.foo.foo_piece_one.should eql(Injection.context['foo_piece_one'])
|
156
|
+
ic2.foo.foo_piece_one.should eql(Injection.context['foo_piece_one'])
|
157
|
+
|
158
|
+
Injection.reset_context
|
159
|
+
Injection.context['foo_piece_one'] = "Mock Foo Piece One"
|
160
|
+
|
161
|
+
ic3 = InjectedController.new
|
162
|
+
ic3.foo.should eql(Injection.context['foo'])
|
163
|
+
ic2.foo.should_not eql(Injection.context['foo'])
|
164
|
+
ic.foo.should_not eql(Injection.context['foo'])
|
165
|
+
ic3.foo.foo_piece_one.should == "Mock Foo Piece One"
|
166
|
+
end
|
167
|
+
|
168
|
+
it 'allows extra inputs to be provided when context is reset' do
|
169
|
+
lambda { injection_context[:old] }.should raise_error(/failed/i)
|
170
|
+
Injection.extra_inputs = {:old => 'spice'}
|
171
|
+
Injection.reset_context
|
172
|
+
injection_context[:old].should == 'spice'
|
173
|
+
|
174
|
+
CommercialController.new.old.should == 'spice'
|
175
|
+
end
|
176
|
+
|
177
|
+
it "does not reset context after ActionDispatch::Callbacks" do
|
178
|
+
ic = InjectedController.new
|
179
|
+
ic.foo.should eql(Injection.context['foo'])
|
180
|
+
ic.bar.should eql(Injection.context['bar'])
|
181
|
+
|
182
|
+
# See that the inject context is being reused, as well as its previously built components:
|
183
|
+
ic2 = InjectedController.new
|
184
|
+
ic.foo.should eql(Injection.context['foo'])
|
185
|
+
ic.bar.should eql(Injection.context['bar'])
|
186
|
+
ic2.foo.should eql(Injection.context['foo'])
|
187
|
+
ic2.bar.should eql(Injection.context['bar'])
|
188
|
+
ic.foo.foo_piece_one.should eql(Injection.context['foo_piece_one'])
|
189
|
+
ic2.foo.foo_piece_one.should eql(Injection.context['foo_piece_one'])
|
190
|
+
|
191
|
+
# This will trigger the class reloading
|
192
|
+
ActionDispatch::Callbacks.new(Proc.new {}, false).call({})
|
193
|
+
|
194
|
+
lambda { Injection.context['foo_piece_one'] = "Mock Foo Piece One" }.should raise_error(/already exists/i)
|
195
|
+
end
|
196
|
+
|
197
|
+
end
|