injection 2.0.0
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/.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
|