mindreframer-dim 1.2.5
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 +3 -0
- data/.rvmrc +1 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +29 -0
- data/LICENSE +22 -0
- data/README.markdown +81 -0
- data/Rakefile +11 -0
- data/dim.gemspec +21 -0
- data/lib/dim.rb +134 -0
- data/lib/version.rb +3 -0
- data/spec/dim_spec.rb +221 -0
- metadata +93 -0
data/.gitignore
ADDED
data/.rvmrc
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
rvm use 1.9.3-turbo@dim --create
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
dim (1.2.5)
|
|
5
|
+
|
|
6
|
+
GEM
|
|
7
|
+
remote: https://rubygems.org/
|
|
8
|
+
specs:
|
|
9
|
+
diff-lcs (1.2.1)
|
|
10
|
+
rspec (2.13.0)
|
|
11
|
+
rspec-core (~> 2.13.0)
|
|
12
|
+
rspec-expectations (~> 2.13.0)
|
|
13
|
+
rspec-mocks (~> 2.13.0)
|
|
14
|
+
rspec-core (2.13.0)
|
|
15
|
+
rspec-expectations (2.13.0)
|
|
16
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
|
17
|
+
rspec-given (2.4.0)
|
|
18
|
+
rspec (>= 2.11)
|
|
19
|
+
sorcerer (>= 0.3.7)
|
|
20
|
+
rspec-mocks (2.13.0)
|
|
21
|
+
sorcerer (0.3.10)
|
|
22
|
+
|
|
23
|
+
PLATFORMS
|
|
24
|
+
ruby
|
|
25
|
+
|
|
26
|
+
DEPENDENCIES
|
|
27
|
+
dim!
|
|
28
|
+
rspec
|
|
29
|
+
rspec-given
|
data/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) 2012 Mike Subelsky
|
|
2
|
+
|
|
3
|
+
MIT License
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# DIM: Dependency Injection - Minimal
|
|
2
|
+
|
|
3
|
+
DIM is [Jim Weirich's](http://onestepback.org) minimalistic dependency injection framework, maintained in
|
|
4
|
+
gem form by [Mike Subelsky](http://subelsky.com).
|
|
5
|
+
|
|
6
|
+
Dependency injection lets you organize all of your app's object setup code in one place by creating a
|
|
7
|
+
container. Whenver an object in your application needs access to another object or resource, it asks
|
|
8
|
+
the container to provide it (using lazily-evaluated code blocks).
|
|
9
|
+
|
|
10
|
+
When testing your code, you can either stub out services on the container, or you can provide a substitute container.
|
|
11
|
+
|
|
12
|
+
## Example
|
|
13
|
+
|
|
14
|
+
The following could be in a "lib.init.rb" file or in a Rails app, "config/initializers/container.rb":
|
|
15
|
+
|
|
16
|
+
require "dim"
|
|
17
|
+
require "logger"
|
|
18
|
+
require 'game'
|
|
19
|
+
require 'event_handler'
|
|
20
|
+
require 'transmitter'
|
|
21
|
+
|
|
22
|
+
ServerContainer = Dim::Container.new
|
|
23
|
+
|
|
24
|
+
ServerContainer.register(:transmitter) { |c| Transmitter.new(c.logger) }
|
|
25
|
+
|
|
26
|
+
ServerContainer.register(:event_handler) do |c|
|
|
27
|
+
eh = EventHandler.new
|
|
28
|
+
eh.transmitter = c.transmitter
|
|
29
|
+
eh.logger = c.logger
|
|
30
|
+
eh
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
ServerContainer.register(:listening_host) { "0.0.0.0" }
|
|
34
|
+
ServerContainer.register(:listening_port) { "8080" }
|
|
35
|
+
|
|
36
|
+
ServerContainer.register(:game) do |c|
|
|
37
|
+
game = Game.new
|
|
38
|
+
game.logger = c.logger
|
|
39
|
+
game.event_handler = c.event_handler
|
|
40
|
+
game.host = c.listening_host
|
|
41
|
+
game.port = c.listening_port
|
|
42
|
+
game
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
ServerContainer.register(:root_dir) do |c|
|
|
46
|
+
Pathname.new(File.expand_path(File.dirname(__FILE__) + "/.."))
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
ServerContainer.register(:log_file_path) do |c|
|
|
50
|
+
"#{c.root_dir}/log/#{c.environment}.log"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
ServerContainer.register(:logger) do |c|
|
|
54
|
+
Logger.new(c.log_file_path)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# attempts to read ENV["API_PASSWORD"], otherwise makes sure that the parent container has
|
|
58
|
+
# a service named api_password registered
|
|
59
|
+
ServerContainer.register_env(:api_password)
|
|
60
|
+
|
|
61
|
+
Using the above code elsewhere in the app, when you want a reference to the app's logger object:
|
|
62
|
+
|
|
63
|
+
ServerContainer.logger.info("I didn't have to setup my own logger")
|
|
64
|
+
|
|
65
|
+
Or if you wanted access to the game instance created during setup (which already is configured with everything it needs):
|
|
66
|
+
|
|
67
|
+
current_game = ServerContainer.game
|
|
68
|
+
|
|
69
|
+
If you don't like creating even the one dependency on the global constant ServerContainer, you could
|
|
70
|
+
inject ServerContainer itself into your objects like so:
|
|
71
|
+
|
|
72
|
+
World.new(GameContainer)
|
|
73
|
+
|
|
74
|
+
## More Background
|
|
75
|
+
|
|
76
|
+
Jim wrote a [nice article](http://onestepback.org/index.cgi/Tech/Ruby/DependencyInjectionInRuby.rdoc) explaining
|
|
77
|
+
the rationale for this code and how it works. Also check out [his slides](http://onestepback.org/articles/depinj/).
|
|
78
|
+
|
|
79
|
+
# License
|
|
80
|
+
|
|
81
|
+
Dim is available under the MIT license (see the file LICENSE for details).
|
data/Rakefile
ADDED
data/dim.gemspec
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
$:.unshift(File.dirname(__FILE__))
|
|
2
|
+
require 'lib/version'
|
|
3
|
+
|
|
4
|
+
Gem::Specification.new do |s|
|
|
5
|
+
s.name = %q{mindreframer-dim}
|
|
6
|
+
s.version = Dim::VERSION
|
|
7
|
+
s.authors = ["Jim Weirich", "Mike Subelsky"]
|
|
8
|
+
s.date = Time.now.utc.strftime("%Y-%m-%d")
|
|
9
|
+
s.email = %q{mike@subelsky.com}
|
|
10
|
+
s.extra_rdoc_files = %w(README.markdown)
|
|
11
|
+
s.files = `git ls-files`.split("\n")
|
|
12
|
+
s.homepage = %q{http://github.com/subelsky/dim}
|
|
13
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
|
14
|
+
s.require_paths = ["lib"]
|
|
15
|
+
s.summary = %q{Minimalistic dependency injection framework}
|
|
16
|
+
s.description = %q{Minimalistic dependency injection framework keeps all of your object setup code in one place.}
|
|
17
|
+
s.test_files = `git ls-files spec`.split("\n")
|
|
18
|
+
s.add_development_dependency 'rspec'
|
|
19
|
+
s.add_development_dependency 'rspec-given'
|
|
20
|
+
s.license = "MIT"
|
|
21
|
+
end
|
data/lib/dim.rb
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Copyright 2004, 2005, 2010, 2012 by Jim Weirich (jim.weirich@gmail.com)
|
|
3
|
+
# and Mike Subelsky (mike@subelsky.com)
|
|
4
|
+
#
|
|
5
|
+
# All rights reserved.
|
|
6
|
+
#
|
|
7
|
+
# This software is available under the MIT license. See the LICENSE file for details.
|
|
8
|
+
#++
|
|
9
|
+
#
|
|
10
|
+
# = Dependency Injection - Minimal (DIM)
|
|
11
|
+
#
|
|
12
|
+
# The DIM module provides a minimal dependency injection framework for
|
|
13
|
+
# Ruby programs.
|
|
14
|
+
#
|
|
15
|
+
# Example:
|
|
16
|
+
#
|
|
17
|
+
# require 'dim'
|
|
18
|
+
#
|
|
19
|
+
# container = Dim::Container.new
|
|
20
|
+
# container.register(:log_file) { "logfile.log" }
|
|
21
|
+
# container.register(:logger) { |c| FileLogger.new(c.log_file) }
|
|
22
|
+
# container.register(:application) { |c|
|
|
23
|
+
# app = Application.new
|
|
24
|
+
# app.logger = c.logger
|
|
25
|
+
# app
|
|
26
|
+
# }
|
|
27
|
+
#
|
|
28
|
+
# c.application.run
|
|
29
|
+
#
|
|
30
|
+
module Dim
|
|
31
|
+
# Thrown when a service cannot be located by name.
|
|
32
|
+
MissingServiceError = Class.new(StandardError)
|
|
33
|
+
|
|
34
|
+
# Thrown when a duplicate service is registered.
|
|
35
|
+
DuplicateServiceError = Class.new(StandardError)
|
|
36
|
+
|
|
37
|
+
# Thrown by register_env when a suitable ENV variable can't be found
|
|
38
|
+
EnvironmentVariableNotFound = Class.new(StandardError)
|
|
39
|
+
|
|
40
|
+
# Dim::Container is the central data store for registering services
|
|
41
|
+
# used for dependency injuction. Users register services by
|
|
42
|
+
# providing a name and a block used to create the service. Services
|
|
43
|
+
# may be retrieved by asking for them by name (via the [] operator)
|
|
44
|
+
# or by selector (via the method_missing technique).
|
|
45
|
+
#
|
|
46
|
+
class Container
|
|
47
|
+
attr_reader :parent
|
|
48
|
+
|
|
49
|
+
# Create a dependency injection container. Specify a parent
|
|
50
|
+
# container to use as a fallback for service lookup.
|
|
51
|
+
def initialize(parent=nil)
|
|
52
|
+
@services = {}
|
|
53
|
+
@cache = {}
|
|
54
|
+
@parent = parent || Container
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def to_s
|
|
58
|
+
info = " services: #{service_list}"
|
|
59
|
+
"<Dim::Container::#{self.__id__}:#{info}>"
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Register a service named +name+. The +block+ will be used to
|
|
63
|
+
# create the service on demand. It is recommended that symbols be
|
|
64
|
+
# used as the name of a service.
|
|
65
|
+
def register(name, &block)
|
|
66
|
+
if @services[name]
|
|
67
|
+
fail DuplicateServiceError, "Duplicate Service Name '#{name}'"
|
|
68
|
+
end
|
|
69
|
+
@services[name] = block
|
|
70
|
+
|
|
71
|
+
self.class.send(:define_method, name) do
|
|
72
|
+
self[name]
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Lookup a service from ENV variables; fall back to searching the container and its parents for a default value
|
|
77
|
+
def register_env(name)
|
|
78
|
+
if value = ENV[name.to_s.upcase]
|
|
79
|
+
register(name) { value }
|
|
80
|
+
else
|
|
81
|
+
begin
|
|
82
|
+
@parent.service_block(name)
|
|
83
|
+
rescue MissingServiceError
|
|
84
|
+
raise EnvironmentVariableNotFound, "Could not find an ENV variable named #{name.to_s.upcase} nor could we find a service named #{name} in the parent container"
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Lookup a service by name. Throw an exception if no service is
|
|
90
|
+
# found.
|
|
91
|
+
def [](name)
|
|
92
|
+
@cache[name] ||= service_block(name).call(self)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
##
|
|
96
|
+
# a list with services, that this container provides
|
|
97
|
+
# @return [Array]
|
|
98
|
+
def service_list
|
|
99
|
+
(@services.keys + @parent.service_list).flatten.uniq
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# initial implementation for a clean Container
|
|
103
|
+
def self.service_list
|
|
104
|
+
[]
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Lookup a service by message selector. A service with the same
|
|
108
|
+
# name as +sym+ will be returned, or an exception is thrown if no
|
|
109
|
+
# matching service is found.
|
|
110
|
+
def method_missing(sym, *args, &block)
|
|
111
|
+
self[sym]
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Return the block that creates the named service. Throw an
|
|
115
|
+
# exception if no service creation block of the given name can be
|
|
116
|
+
# found in the container or its parents.
|
|
117
|
+
def service_block(name)
|
|
118
|
+
@services[name] || @parent.service_block(name)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Resets the cached services
|
|
122
|
+
def clear_cache!
|
|
123
|
+
@cache = {}
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Searching for a service block only reaches the Container class
|
|
127
|
+
# when all the containers in the hierarchy search chain have no
|
|
128
|
+
# entry for the service. In this case, the only thing to do is
|
|
129
|
+
# signal a failure.
|
|
130
|
+
def self.service_block(name)
|
|
131
|
+
fail(MissingServiceError, "Unknown Service '#{name}'")
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
data/lib/version.rb
ADDED
data/spec/dim_spec.rb
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
require 'dim'
|
|
2
|
+
require 'rspec/given'
|
|
3
|
+
|
|
4
|
+
class ConsoleAppender
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
class Logger
|
|
8
|
+
attr_accessor :appender
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class MockDB
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class RealDB
|
|
15
|
+
attr_accessor :username, :password
|
|
16
|
+
def initialize(username, password)
|
|
17
|
+
@username, @password = username, password
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
class App
|
|
22
|
+
attr_accessor :logger, :db
|
|
23
|
+
def initialize(logger=nil)
|
|
24
|
+
@logger = logger
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
describe Dim::Container do
|
|
29
|
+
let(:container) { Dim::Container.new }
|
|
30
|
+
|
|
31
|
+
describe "creating objects" do
|
|
32
|
+
Given { container.register(:app) { App.new } }
|
|
33
|
+
Then { container.app.should be_a(App) }
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
describe "returning the same object every time" do
|
|
37
|
+
Given { container.register(:app) { App.new } }
|
|
38
|
+
Given(:app) { container.app }
|
|
39
|
+
Then { container.app.should be(app) }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "clears cache explicitly" do
|
|
43
|
+
container.register(:app) { App.new }
|
|
44
|
+
app_before = container.app
|
|
45
|
+
container.clear_cache!
|
|
46
|
+
app_after = container.app
|
|
47
|
+
app_before.should_not == app_after
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
describe "contructing dependent objects" do
|
|
51
|
+
Given { container.register(:app) { |c| App.new(c.logger) } }
|
|
52
|
+
Given { container.register(:logger) { Logger.new } }
|
|
53
|
+
Given(:app) { container.app }
|
|
54
|
+
Then { app.logger.should be(container.logger) }
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
describe "constructing dependent objects with setters" do
|
|
58
|
+
Given {
|
|
59
|
+
container.register(:app) { |c|
|
|
60
|
+
App.new.tap { |obj|
|
|
61
|
+
obj.db = c.database
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
Given { container.register(:database) { MockDB.new } }
|
|
66
|
+
Given(:app) { container.app }
|
|
67
|
+
|
|
68
|
+
Then { app.db.should be(container.database) }
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
describe "constructing multiple dependent objects" do
|
|
72
|
+
Given {
|
|
73
|
+
container.register(:app) { |c|
|
|
74
|
+
App.new(c.logger).tap { |obj|
|
|
75
|
+
obj.db = c.database
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
Given { container.register(:logger) { Logger.new } }
|
|
80
|
+
Given { container.register(:database) { MockDB.new } }
|
|
81
|
+
Given(:app) { container.app }
|
|
82
|
+
Then { app.logger.should be(container.logger) }
|
|
83
|
+
Then { app.db.should be(container.database) }
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
describe "constructing chains of dependencies" do
|
|
87
|
+
Given { container.register(:app) { |c| App.new(c.logger) } }
|
|
88
|
+
Given {
|
|
89
|
+
container.register(:logger) { |c|
|
|
90
|
+
Logger.new.tap { |obj|
|
|
91
|
+
obj.appender = c.logger_appender
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
Given { container.register(:logger_appender) { ConsoleAppender.new } }
|
|
96
|
+
Given { container.register(:database) { MockDB.new } }
|
|
97
|
+
Given(:logger) { container.app.logger }
|
|
98
|
+
|
|
99
|
+
Then { logger.appender.should be(container.logger_appender) }
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
describe "constructing literals" do
|
|
103
|
+
Given { container.register(:database) { |c| RealDB.new(c.username, c.userpassword) } }
|
|
104
|
+
Given { container.register(:username) { "user_name_value" } }
|
|
105
|
+
Given { container.register(:userpassword) { "password_value" } }
|
|
106
|
+
Given(:db) { container.database }
|
|
107
|
+
|
|
108
|
+
Then { db.username.should == "user_name_value" }
|
|
109
|
+
Then { db.password.should == "password_value" }
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
describe "Errors" do
|
|
113
|
+
describe "missing services" do
|
|
114
|
+
Then {
|
|
115
|
+
lambda {
|
|
116
|
+
container.undefined_service_name
|
|
117
|
+
}.should raise_error(Dim::MissingServiceError, /undefined_service_name/)
|
|
118
|
+
}
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
describe "duplicate service names" do
|
|
122
|
+
Given { container.register(:duplicate_name) { 0 } }
|
|
123
|
+
Then {
|
|
124
|
+
lambda {
|
|
125
|
+
container.register(:duplicate_name) { 0 }
|
|
126
|
+
}.should raise_error(Dim::DuplicateServiceError, /duplicate_name/)
|
|
127
|
+
}
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
describe "Parent/Child Container Interaction" do
|
|
132
|
+
Given(:parent) { container }
|
|
133
|
+
Given(:child) { Dim::Container.new(parent) }
|
|
134
|
+
|
|
135
|
+
Given { parent.register(:cell) { :parent_cell } }
|
|
136
|
+
Given { parent.register(:gene) { :parent_gene } }
|
|
137
|
+
Given { child.register(:gene) { :child_gene } }
|
|
138
|
+
|
|
139
|
+
describe "reusing a service from the parent" do
|
|
140
|
+
Then { child.cell.should == :parent_cell }
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
describe "overiding a service from the parent" do
|
|
144
|
+
Then { child.gene.should == :child_gene }
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
describe "wrapping a service from a parent" do
|
|
148
|
+
Given { child.register(:cell) { |c| [c.parent.cell] } }
|
|
149
|
+
Then { child.cell.should == [:parent_cell] }
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
describe "overriding an indirect dependency" do
|
|
153
|
+
Given { parent.register(:wrapped_cell) { |c| [c.cell] } }
|
|
154
|
+
Given { child.register(:cell) { :child_cell } }
|
|
155
|
+
Then { child.wrapped_cell.should == [:child_cell] }
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
describe "parent / child service conflicts from parents view" do
|
|
159
|
+
Then { parent.gene.should == :parent_gene }
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
describe "child / child service name conflicts" do
|
|
163
|
+
Given(:other_child) { Dim::Container.new(parent) }
|
|
164
|
+
Given { other_child.register(:gene) { :other_child_gene } }
|
|
165
|
+
|
|
166
|
+
Then { child.gene.should == :child_gene }
|
|
167
|
+
Then { other_child.gene.should == :other_child_gene }
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
describe "Registering env variables" do
|
|
172
|
+
describe "which exist in ENV" do
|
|
173
|
+
Given { ENV["SHAZ"] = "bot" }
|
|
174
|
+
Given { container.register_env(:shaz) }
|
|
175
|
+
Then { container.shaz.should == "bot" }
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
describe "which exist in optional hash" do
|
|
179
|
+
Given(:parent) { container }
|
|
180
|
+
Given { parent.register(:foo) { "bar" } }
|
|
181
|
+
Given(:child) { Dim::Container.new(parent) }
|
|
182
|
+
|
|
183
|
+
Given { ENV["FOO"] = nil }
|
|
184
|
+
Given { child.register_env(:foo) }
|
|
185
|
+
Then { container.foo.should == "bar" }
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
describe "which don't exist in optional hash" do
|
|
189
|
+
Then {
|
|
190
|
+
lambda {
|
|
191
|
+
container.register_env(:dont_exist_in_env_or_optional_hash)
|
|
192
|
+
}.should raise_error(Dim::EnvironmentVariableNotFound)
|
|
193
|
+
}
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
describe "output in terminal" do
|
|
199
|
+
describe "contains a short list of services" do
|
|
200
|
+
Given(:parent) { container }
|
|
201
|
+
Given { parent.register(:parent_foo) { "bar" } }
|
|
202
|
+
Then { parent.to_s.should include("services: [:parent_foo]") }
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
describe "also from parent" do
|
|
206
|
+
Given(:parent) { container }
|
|
207
|
+
Given { parent.register(:parent_foo) { "bar" } }
|
|
208
|
+
Given(:child) { Dim::Container.new(parent) }
|
|
209
|
+
Given { child.register(:child_foo) {"bar"} }
|
|
210
|
+
Then { child.to_s.should include("services: [:child_foo, :parent_foo]") }
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
describe "also when overridden from parent without duplicates" do
|
|
214
|
+
Given(:parent) { container }
|
|
215
|
+
Given { parent.register(:overriden_foo) { "parent" } }
|
|
216
|
+
Given(:child) { Dim::Container.new(parent) }
|
|
217
|
+
Given { child.register(:overriden_foo) {"child"} }
|
|
218
|
+
Then { child.to_s.should include("services: [:overriden_foo]") }
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: mindreframer-dim
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.2.5
|
|
5
|
+
prerelease:
|
|
6
|
+
platform: ruby
|
|
7
|
+
authors:
|
|
8
|
+
- Jim Weirich
|
|
9
|
+
- Mike Subelsky
|
|
10
|
+
autorequire:
|
|
11
|
+
bindir: bin
|
|
12
|
+
cert_chain: []
|
|
13
|
+
date: 2013-03-10 00:00:00.000000000 Z
|
|
14
|
+
dependencies:
|
|
15
|
+
- !ruby/object:Gem::Dependency
|
|
16
|
+
name: rspec
|
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
|
18
|
+
none: false
|
|
19
|
+
requirements:
|
|
20
|
+
- - ! '>='
|
|
21
|
+
- !ruby/object:Gem::Version
|
|
22
|
+
version: '0'
|
|
23
|
+
type: :development
|
|
24
|
+
prerelease: false
|
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
26
|
+
none: false
|
|
27
|
+
requirements:
|
|
28
|
+
- - ! '>='
|
|
29
|
+
- !ruby/object:Gem::Version
|
|
30
|
+
version: '0'
|
|
31
|
+
- !ruby/object:Gem::Dependency
|
|
32
|
+
name: rspec-given
|
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
|
34
|
+
none: false
|
|
35
|
+
requirements:
|
|
36
|
+
- - ! '>='
|
|
37
|
+
- !ruby/object:Gem::Version
|
|
38
|
+
version: '0'
|
|
39
|
+
type: :development
|
|
40
|
+
prerelease: false
|
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
42
|
+
none: false
|
|
43
|
+
requirements:
|
|
44
|
+
- - ! '>='
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '0'
|
|
47
|
+
description: Minimalistic dependency injection framework keeps all of your object
|
|
48
|
+
setup code in one place.
|
|
49
|
+
email: mike@subelsky.com
|
|
50
|
+
executables: []
|
|
51
|
+
extensions: []
|
|
52
|
+
extra_rdoc_files:
|
|
53
|
+
- README.markdown
|
|
54
|
+
files:
|
|
55
|
+
- .gitignore
|
|
56
|
+
- .rvmrc
|
|
57
|
+
- Gemfile
|
|
58
|
+
- Gemfile.lock
|
|
59
|
+
- LICENSE
|
|
60
|
+
- README.markdown
|
|
61
|
+
- Rakefile
|
|
62
|
+
- dim.gemspec
|
|
63
|
+
- lib/dim.rb
|
|
64
|
+
- lib/version.rb
|
|
65
|
+
- spec/dim_spec.rb
|
|
66
|
+
homepage: http://github.com/subelsky/dim
|
|
67
|
+
licenses:
|
|
68
|
+
- MIT
|
|
69
|
+
post_install_message:
|
|
70
|
+
rdoc_options:
|
|
71
|
+
- --charset=UTF-8
|
|
72
|
+
require_paths:
|
|
73
|
+
- lib
|
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
75
|
+
none: false
|
|
76
|
+
requirements:
|
|
77
|
+
- - ! '>='
|
|
78
|
+
- !ruby/object:Gem::Version
|
|
79
|
+
version: '0'
|
|
80
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
81
|
+
none: false
|
|
82
|
+
requirements:
|
|
83
|
+
- - ! '>='
|
|
84
|
+
- !ruby/object:Gem::Version
|
|
85
|
+
version: '0'
|
|
86
|
+
requirements: []
|
|
87
|
+
rubyforge_project:
|
|
88
|
+
rubygems_version: 1.8.25
|
|
89
|
+
signing_key:
|
|
90
|
+
specification_version: 3
|
|
91
|
+
summary: Minimalistic dependency injection framework
|
|
92
|
+
test_files:
|
|
93
|
+
- spec/dim_spec.rb
|