dependor 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
4
+ .rvmrc
5
+ tags
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.2
4
+ - 1.9.3
5
+ - jruby-19mode
6
+ - rbx-19mode
7
+ script: bundle exec rspec spec
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in dependor.gemspec
4
+ gemspec
@@ -0,0 +1,37 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ dependor (0.0.1)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.1.2)
10
+ ffi (1.0.11)
11
+ growl (1.0.3)
12
+ guard (1.0.1)
13
+ ffi (>= 0.5.0)
14
+ thor (~> 0.14.6)
15
+ guard-rspec (0.6.0)
16
+ guard (>= 0.10.0)
17
+ libnotify (0.7.2)
18
+ rspec (2.5.0)
19
+ rspec-core (~> 2.5.0)
20
+ rspec-expectations (~> 2.5.0)
21
+ rspec-mocks (~> 2.5.0)
22
+ rspec-core (2.5.1)
23
+ rspec-expectations (2.5.0)
24
+ diff-lcs (~> 1.1.2)
25
+ rspec-mocks (2.5.0)
26
+ thor (0.14.6)
27
+
28
+ PLATFORMS
29
+ ruby
30
+
31
+ DEPENDENCIES
32
+ dependor!
33
+ growl
34
+ guard
35
+ guard-rspec
36
+ libnotify
37
+ rspec
@@ -0,0 +1,18 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec', :version => 2 do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+
9
+ # Rails example
10
+ watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
11
+ watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
12
+ watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
13
+ watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
14
+ watch('config/routes.rb') { "spec/routing" }
15
+ watch('app/controllers/application_controller.rb') { "spec/controllers" }
16
+ # Capybara request specs
17
+ watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" }
18
+ end
@@ -0,0 +1,7 @@
1
+ Copyright (C) 2012 Adam Pohorecki
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,286 @@
1
+ # Dependor
2
+
3
+ [![build status](https://secure.travis-ci.org/psyho/dependor.png)](http://travis-ci.org/psyho/dependor)
4
+
5
+ ## What is Dependor
6
+
7
+ Dependor is a set of helpers that make writing Ruby apps that use the dependency injection pattern easier.
8
+ It comes as a set of modules, which you can selectively add to your project.
9
+ It is designed do play nice with Rails and similar frameworks.
10
+
11
+ ## Manual Dependency Injection
12
+
13
+ ```ruby
14
+ class Foo
15
+ def do_foo
16
+ "foo"
17
+ end
18
+ end
19
+
20
+ class Bar
21
+ def initialize(foo)
22
+ @foo = foo
23
+ end
24
+
25
+ def do_bar
26
+ @foo.do_foo + "bar"
27
+ end
28
+ end
29
+
30
+ class Injector
31
+ def foo
32
+ Foo.new
33
+ end
34
+
35
+ def bar
36
+ Bar.new(foo)
37
+ end
38
+ end
39
+
40
+ class EntryPoint
41
+ def inject
42
+ @injector ||= Injector.new
43
+ end
44
+
45
+ def bar
46
+ inject.bar
47
+ end
48
+
49
+ def run
50
+ bar.do_bar
51
+ end
52
+ end
53
+
54
+ EntryPoint.new.run
55
+ ```
56
+
57
+ ## The same thing with Dependor
58
+
59
+ ```ruby
60
+ require 'dependor'
61
+ require 'dependor/shorty'
62
+
63
+ class Foo
64
+ def do_foo
65
+ "foo"
66
+ end
67
+ end
68
+
69
+ class Bar
70
+ takes :foo
71
+
72
+ def do_bar
73
+ @foo.do_foo + "bar"
74
+ end
75
+ end
76
+
77
+ class Injector
78
+ include Dependor::AutoInject
79
+ end
80
+
81
+ class EntryPoint
82
+ include Dependor::Injectable
83
+ inject_from Injector
84
+
85
+ inject :bar
86
+
87
+ def run
88
+ bar.do_bar
89
+ end
90
+ end
91
+
92
+ EntryPoint.new.run
93
+ ```
94
+
95
+ ## Dependor::AutoInject
96
+
97
+ This is the core part of the library.
98
+ It looks at the constructor of a class to find out it's dependencies and instantiates it's instances with proper objects injected.
99
+ It looks up classes by name.
100
+
101
+ AutoInject can also use the methods declared on injector as injection sources, which is quite useful for things like configuration.
102
+
103
+ ```ruby
104
+ class Injector
105
+ include Dependor::AutoInject
106
+
107
+ attr_reader :session
108
+
109
+ def initialize(session)
110
+ @session = session
111
+ end
112
+
113
+ let(:current_user) { current_user_service.get }
114
+ let(:users_repository) { User }
115
+ let(:comments_repository) { Comment }
116
+ end
117
+
118
+ class CurrentUserService
119
+ takes :session, :users_repository
120
+
121
+ def get
122
+ @current_user ||= users_repository.find(session[:current_user_id])
123
+ end
124
+ end
125
+
126
+ class CreatesComments
127
+ takes :current_user, :comments_repository
128
+
129
+ def create
130
+ # ...
131
+ end
132
+ end
133
+
134
+ class User < ActiveRecord::Base
135
+ end
136
+
137
+ class Comment < ActiveRecord::Base
138
+ end
139
+ ```
140
+
141
+ ## Dependor::Shorty
142
+
143
+ This makes the constructor definition less verbose and includes Dependor::Let for shorter method definition syntax.
144
+
145
+ ```ruby
146
+ class Foo
147
+ takes :foo, :bar, :baz
148
+ let(:hello) { "world" }
149
+ end
150
+ ```
151
+
152
+ is equivalent to:
153
+
154
+ ```ruby
155
+ class Foo
156
+ attr_reader :foo, :bar, :baz
157
+
158
+ def initialize(foo, bar, baz)
159
+ @foo = foo
160
+ @bar = bar
161
+ @baz = baz
162
+ end
163
+
164
+ def hello
165
+ "world"
166
+ end
167
+ end
168
+ ```
169
+
170
+ ## Dependor::Constructor
171
+
172
+ Sometimes you don't want to pollute every class with a `takes` method.
173
+ You can then shorten the class declaration with Dependor::Constructor.
174
+
175
+ ```ruby
176
+ class Foo
177
+ include Dependor::Constructor(:foo, :bar, :baz)
178
+ end
179
+ ```
180
+
181
+ is equivalent to:
182
+
183
+ ```ruby
184
+ class Foo
185
+ def initialize(foo, bar, baz)
186
+ @foo = foo
187
+ @bar = bar
188
+ @baz = baz
189
+ end
190
+ end
191
+ ```
192
+
193
+ ## Dependor::Let
194
+
195
+ It allows a simpler syntax to define getter methods.
196
+
197
+ ```ruby
198
+ class Foo
199
+ def foo
200
+ do_something_or_other
201
+ end
202
+ end
203
+ ```
204
+
205
+ becomes:
206
+
207
+ ```ruby
208
+ class Foo
209
+ extend Dependor::Let
210
+ let(:foo) { do_something_or_other }
211
+ end
212
+ ```
213
+
214
+ ## Dependor::Injectable
215
+
216
+ You can include this to make usage of the injector more convenient.
217
+ This is used in the entry point of your application, typically a Rails controller.
218
+
219
+ ```ruby
220
+ class MyInjector
221
+ def foo
222
+ "foo"
223
+ end
224
+ end
225
+
226
+ class ApplicationController
227
+ extend Dependor::Injectable
228
+ inject_from MyInjector
229
+ end
230
+
231
+ class PostsController < ApplicationController
232
+ inject :foo
233
+
234
+ def get
235
+ render text: foo
236
+ end
237
+ end
238
+ ```
239
+
240
+ Sometimes you might want to pass request, params or session to your injector.
241
+ Here is an example, how to do it:
242
+
243
+ ```ruby
244
+ require 'dependor/shorty'
245
+
246
+ class MyInjector
247
+ include Dependor::AutoInject
248
+
249
+ takes :params, :session, :request
250
+
251
+ def foo
252
+ session[:foo]
253
+ end
254
+ end
255
+
256
+ class ApplicationController
257
+ extend Dependor::Injectable
258
+
259
+ def injector
260
+ @injector ||= MyInjector.new(params, session, request)
261
+ end
262
+ end
263
+
264
+ class PostsController < ApplicationController
265
+ inject :foo
266
+
267
+ def get
268
+ render text: foo
269
+ end
270
+ end
271
+ ```
272
+
273
+ ## License
274
+
275
+ MIT. See the MIT-LICENSE file.
276
+
277
+ ## Author
278
+
279
+ Adam Pohorecki
280
+
281
+ ## Acknowledgements
282
+
283
+ Dependor::Shorty is inspired (or rather blatantly copied) from Gary Bernhardt's [Destroy All Software Screencast][das] ["Shorter Class Syntax"][shorter-syntax].
284
+
285
+ [das]: http://www.destroyallsoftware.com
286
+ [shorter-syntax]: https://www.destroyallsoftware.com/screencasts/catalog/shorter-class-syntax
@@ -0,0 +1,13 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core'
5
+ require 'rspec/core/rake_task'
6
+
7
+ desc "Run all specs"
8
+ RSpec::Core::RakeTask.new(:spec) do |t|
9
+ t.pattern = "./spec/**/*_spec.rb"
10
+ t.rspec_opts = ["--profile --color --format=documentation"]
11
+ end
12
+
13
+ task :default => :spec
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "dependor/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "dependor"
7
+ s.version = Dependor::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Adam Pohorecki"]
10
+ s.email = ["adam@pohorecki.pl"]
11
+ s.homepage = "http://github.com/psyho/dependor"
12
+ s.summary = %q{A couple of classes and modules that simplify dependency injection in Ruby.}
13
+ s.description = %q{Dependor is not a framework for Dependency Injection, but something thatt reduces duplication a little bit when doing manual dependency injection in settings like Rails apps.}
14
+
15
+ s.rubyforge_project = "dependor"
16
+
17
+ s.add_development_dependency 'rspec'
18
+
19
+ s.add_development_dependency 'guard'
20
+ s.add_development_dependency 'guard-rspec'
21
+ s.add_development_dependency 'growl'
22
+ s.add_development_dependency 'libnotify'
23
+
24
+ s.files = `git ls-files`.split("\n")
25
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
26
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
27
+ s.require_paths = ["lib"]
28
+ end
@@ -0,0 +1,13 @@
1
+ require 'dependor/constructor'
2
+
3
+ module Dependor
4
+ autoload :AutoInject, 'dependor/auto_inject'
5
+ autoload :AutoInjector, 'dependor/auto_injector'
6
+ autoload :ClassNameResolver, 'dependor/class_name_resolver'
7
+ autoload :Injectable, 'dependor/injectable'
8
+ autoload :Instantiator, 'dependor/instantiator'
9
+ autoload :Let, 'dependor/let'
10
+ autoload :Shorty, 'dependor/shorty'
11
+ autoload :UnknownObject, 'dependor/exceptions'
12
+ autoload :VERSION, 'dependor/version'
13
+ end
@@ -0,0 +1,35 @@
1
+ module Dependor
2
+ module AutoInject
3
+
4
+ module ClassMethods
5
+ def look_in_modules(*modules)
6
+ search_modules.concat(modules)
7
+ end
8
+
9
+ def search_modules
10
+ @search_modules ||= []
11
+ end
12
+ end
13
+
14
+ def self.included(klass)
15
+ klass.extend ClassMethods
16
+ end
17
+
18
+ def method_missing(name, *args, &block)
19
+ auto_injector.get(name)
20
+ end
21
+
22
+ def respond_to?(name)
23
+ auto_injector.resolvable?(name)
24
+ end
25
+
26
+ private
27
+
28
+ def auto_injector
29
+ @auto_injector ||= Dependor::AutoInjector.new(self, self.class.search_modules)
30
+ end
31
+
32
+ end
33
+
34
+ end
35
+
@@ -0,0 +1,37 @@
1
+ module Dependor
2
+ class AutoInjector
3
+
4
+ def initialize(injector, search_modules)
5
+ @injector = injector
6
+ @instantiator = Instantiator.new(self)
7
+ @class_name_resolver = ClassNameResolver.new(search_modules)
8
+ end
9
+
10
+ def get(name)
11
+ ensure_resolvable!(name)
12
+
13
+ return @injector.send(name) if method_exists?(name)
14
+
15
+ klass = @class_name_resolver.for_name(name)
16
+ @instantiator.instantiate(klass)
17
+ end
18
+
19
+ def resolvable?(name)
20
+ method_exists?(name) || !!@class_name_resolver.for_name(name)
21
+ end
22
+
23
+ private
24
+
25
+ def ensure_resolvable!(name)
26
+ unless resolvable?(name)
27
+ raise UnknownObject.new("Injector does not know how to create object: #{name}")
28
+ end
29
+ end
30
+
31
+ def method_exists?(name)
32
+ @injector.methods.include?(name)
33
+ end
34
+
35
+ end
36
+
37
+ end
@@ -0,0 +1,30 @@
1
+ module Dependor
2
+ class ClassNameResolver
3
+ attr_reader :search_modules
4
+
5
+ def initialize(search_modules)
6
+ @search_modules = search_modules
7
+ end
8
+
9
+ def for_name(name)
10
+ class_name = camelize(name)
11
+ modules = search_modules.concat([Object])
12
+ klass = nil
13
+
14
+ modules.each do |mod|
15
+ klass = mod.const_get(class_name) rescue nil
16
+ break if klass
17
+ end
18
+
19
+ klass
20
+ end
21
+
22
+ private
23
+
24
+ def camelize(symbol)
25
+ string = symbol.to_s
26
+ string = string.gsub(/_\w/) { |match| match[1].upcase }
27
+ return string.gsub(/^\w/) { |match| match.upcase }
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,13 @@
1
+ module Dependor
2
+ def self.Constructor(*names)
3
+ eval <<-RUBY
4
+
5
+ Module.new do
6
+ def initialize(#{names.join(', ')})
7
+ #{names.map{ |name| "@#{name} = #{name}" }.join("\n") }
8
+ end
9
+ end
10
+
11
+ RUBY
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ module Dependor
2
+ class UnknownObject < RuntimeError; end
3
+ end
@@ -0,0 +1,17 @@
1
+ module Dependor
2
+ module Injectable
3
+ def inject_from(klass)
4
+ define_method :injector do
5
+ @injector ||= klass.new
6
+ end
7
+ end
8
+
9
+ def inject(*names)
10
+ names.each do |name|
11
+ define_method name do
12
+ injector.send(name)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,14 @@
1
+ module Dependor
2
+ class Instantiator
3
+ def initialize(injector)
4
+ @injector = injector
5
+ end
6
+
7
+ def instantiate(klass)
8
+ params = klass.instance_method(:initialize).parameters
9
+ dependency_names = params.select{|type, name| type == :req}.map{|type, name| name}
10
+ dependencies = dependency_names.map{|name| @injector.get(name)}
11
+ return klass.new(*dependencies)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,7 @@
1
+ module Dependor
2
+ module Let
3
+ def let(name, &block)
4
+ define_method(name, &block)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,13 @@
1
+ module Dependor
2
+ module Shorty
3
+ def takes(*names)
4
+ attr_reader *names
5
+ include Dependor::Constructor(*names)
6
+ extend Dependor::Let
7
+ end
8
+ end
9
+ end
10
+
11
+ class Object
12
+ extend Dependor::Shorty
13
+ end
@@ -0,0 +1,3 @@
1
+ module Dependor
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,79 @@
1
+ require_relative '../spec_helper'
2
+
3
+ require 'dependor/shorty'
4
+
5
+ describe Dependor::AutoInject do
6
+ class SampleClassWithNoDependencies
7
+ end
8
+
9
+ class SampleClassWithDependency
10
+ takes :sample_class_with_no_dependencies
11
+ end
12
+
13
+ class SampleClassWithManualDependency
14
+ takes :manual_dep
15
+ end
16
+
17
+ module SomeModule
18
+ class SampleClassWithinSomeModule
19
+ end
20
+ end
21
+
22
+ class SampleInjector
23
+ include Dependor::AutoInject
24
+ look_in_modules SomeModule
25
+
26
+ def manual_dep
27
+ "manual dep"
28
+ end
29
+ end
30
+
31
+ let(:injector) { SampleInjector.new }
32
+
33
+ shared_examples_for 'dependency injector' do
34
+ it 'responds to the object name' do
35
+ injector.should respond_to(object_name)
36
+ end
37
+
38
+ it 'creates the object' do
39
+ injector.send(object_name).should be_an_instance_of(object_class)
40
+ end
41
+ end
42
+
43
+ context 'no dependencies' do
44
+ let(:object_name) { :sample_class_with_no_dependencies }
45
+ let(:object_class) { SampleClassWithNoDependencies }
46
+
47
+ it_behaves_like 'dependency injector'
48
+ end
49
+
50
+ context 'dependencies on other objects' do
51
+ let(:object_name) { :sample_class_with_dependency }
52
+ let(:object_class) { SampleClassWithDependency }
53
+
54
+ it_behaves_like 'dependency injector'
55
+ end
56
+
57
+ context 'dependencies on objects returned by methods on the injector' do
58
+ let(:object_name) { :sample_class_with_manual_dependency }
59
+ let(:object_class) { SampleClassWithManualDependency }
60
+
61
+ it_behaves_like 'dependency injector'
62
+ end
63
+
64
+ context 'dependencies from another module' do
65
+ let(:object_name) { :sample_class_within_some_module }
66
+ let(:object_class) { SomeModule::SampleClassWithinSomeModule }
67
+
68
+ it_behaves_like 'dependency injector'
69
+ end
70
+
71
+ it "raises an error if the object is not found" do
72
+ proc{ injector.unknown_object }.should raise_exception(Dependor::UnknownObject)
73
+ end
74
+
75
+ it 'responds to regular methods on injector' do
76
+ injector.should respond_to(:manual_dep)
77
+ end
78
+
79
+ end
@@ -0,0 +1,43 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe Dependor::ClassNameResolver do
4
+ class FooBarBaz
5
+ end
6
+
7
+ class FooBarBaz2
8
+ end
9
+
10
+ module Foo
11
+ class FooBarBaz
12
+ end
13
+ end
14
+
15
+ module Bar
16
+ class FooBarBaz
17
+ end
18
+ end
19
+
20
+ it "returns nil when the class could not be found" do
21
+ resolver = Dependor::ClassNameResolver.new([])
22
+
23
+ resolver.for_name(:something).should be_nil
24
+ end
25
+
26
+ it "uses global scope with no search_modules" do
27
+ resolver = Dependor::ClassNameResolver.new([])
28
+
29
+ resolver.for_name(:foo_bar_baz).should == FooBarBaz
30
+ end
31
+
32
+ it "searches modules in order specified" do
33
+ resolver = Dependor::ClassNameResolver.new([Foo, Bar])
34
+
35
+ resolver.for_name(:foo_bar_baz).should == Foo::FooBarBaz
36
+ end
37
+
38
+ it "searches in order specified, with the global scope last" do
39
+ resolver = Dependor::ClassNameResolver.new([Foo, Bar])
40
+
41
+ resolver.for_name(:foo_bar_baz_2).should == FooBarBaz2
42
+ end
43
+ end
@@ -0,0 +1,16 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe 'Dependor::Constructor' do
4
+ class SampleClassUsingConstructor
5
+ include Dependor::Constructor(:foo, :bar, :baz)
6
+
7
+ def as_instance_variables
8
+ {foo: @foo, bar: @bar, baz: @baz}
9
+ end
10
+ end
11
+
12
+ it 'defines a constructor with given parameters' do
13
+ sample = SampleClassUsingConstructor.new('aaa', 'bbb', 'ccc')
14
+ sample.as_instance_variables.should == {foo: 'aaa', bar: 'bbb', baz: 'ccc'}
15
+ end
16
+ end
@@ -0,0 +1,63 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe Dependor::Injectable do
4
+ class SampleInjector
5
+ def foo
6
+ "foo"
7
+ end
8
+ end
9
+
10
+ class SampleInjectable
11
+ extend Dependor::Injectable
12
+ inject_from(SampleInjector)
13
+
14
+ inject :foo
15
+
16
+ def hello_foo
17
+ "hello #{foo}"
18
+ end
19
+ end
20
+
21
+ class SampleInjectableWithoutAnInjector
22
+ extend Dependor::Injectable
23
+
24
+ inject :foo
25
+
26
+ def hello_foo
27
+ "hello #{foo}"
28
+ end
29
+ end
30
+
31
+ it "requires the class to provide injector method" do
32
+ injectable = SampleInjectableWithoutAnInjector.new
33
+
34
+ expect do
35
+ injectable.hello_foo
36
+ end.to raise_exception
37
+ end
38
+
39
+ it "uses the provided injector" do
40
+ injectable = SampleInjectable.new
41
+
42
+ injectable.hello_foo.should == 'hello foo'
43
+ end
44
+
45
+ describe "typical Rails usage" do
46
+ class ApplicationController
47
+ extend Dependor::Injectable
48
+ inject_from SampleInjector
49
+ end
50
+
51
+ class PostsController < ApplicationController
52
+ inject :foo
53
+
54
+ def get
55
+ "render #{foo}"
56
+ end
57
+ end
58
+
59
+ it "should return foo value in child controller" do
60
+ PostsController.new.get.should == "render foo"
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,37 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe Dependor::Instantiator do
4
+ let(:injector) { stub(:injector) }
5
+ let(:instantiator) { Dependor::Instantiator.new(injector) }
6
+
7
+ it "instantiates objects with no-arg constructors" do
8
+ klass = Class.new do
9
+ def foo
10
+ "foo"
11
+ end
12
+ end
13
+
14
+ instance = instantiator.instantiate(klass)
15
+ instance.foo.should == "foo"
16
+ end
17
+
18
+ it "instantiates objects with constructors" do
19
+ klass = Class.new do
20
+ def initialize(foo, bar, baz)
21
+ @foo = [foo, bar, baz].join('-')
22
+ end
23
+
24
+ def foo
25
+ @foo
26
+ end
27
+ end
28
+
29
+ injector.should_receive(:get).with(:foo).and_return("foo")
30
+ injector.should_receive(:get).with(:bar).and_return("bar")
31
+ injector.should_receive(:get).with(:baz).and_return("baz")
32
+
33
+ instance = instantiator.instantiate(klass)
34
+
35
+ instance.foo.should == 'foo-bar-baz'
36
+ end
37
+ end
@@ -0,0 +1,13 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe Dependor::Let do
4
+ class SampleClassUsingLet
5
+ extend Dependor::Let
6
+
7
+ let(:foo) { "foo foo" }
8
+ end
9
+
10
+ it 'shortens method declaration' do
11
+ SampleClassUsingLet.new.foo.should == "foo foo"
12
+ end
13
+ end
@@ -0,0 +1,33 @@
1
+ require_relative '../spec_helper'
2
+
3
+ require 'dependor/shorty'
4
+
5
+ describe Dependor::Shorty do
6
+ class SampleClassThatUsesTakes
7
+ takes :foo, :bar, :baz
8
+
9
+ def as_instance_variables
10
+ {foo: @foo, bar: @bar, baz: @baz}
11
+ end
12
+
13
+ def as_attributes
14
+ {foo: foo, bar: bar, baz: baz}
15
+ end
16
+ end
17
+
18
+ subject{ SampleClassThatUsesTakes.new('foo value', 'bar value', 'baz value') }
19
+
20
+ it 'defines a constructor with given names' do
21
+ subject.as_instance_variables.should == { foo: 'foo value',
22
+ bar: 'bar value',
23
+ baz: 'baz value'
24
+ }
25
+ end
26
+
27
+ it 'defines attr_reader for the given names' do
28
+ subject.as_attributes.should == { foo: 'foo value',
29
+ bar: 'bar value',
30
+ baz: 'baz value'
31
+ }
32
+ end
33
+ end
@@ -0,0 +1,10 @@
1
+ $:.push File.expand_path("../../lib", __FILE__)
2
+
3
+ require 'rubygems'
4
+ require 'rspec'
5
+
6
+ require 'dependor'
7
+
8
+ RSpec.configure do |c|
9
+ c.color_enabled = true
10
+ end
metadata ADDED
@@ -0,0 +1,136 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dependor
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Adam Pohorecki
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-03-15 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &71879150 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *71879150
25
+ - !ruby/object:Gem::Dependency
26
+ name: guard
27
+ requirement: &71878830 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *71878830
36
+ - !ruby/object:Gem::Dependency
37
+ name: guard-rspec
38
+ requirement: &71878470 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *71878470
47
+ - !ruby/object:Gem::Dependency
48
+ name: growl
49
+ requirement: &71878150 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *71878150
58
+ - !ruby/object:Gem::Dependency
59
+ name: libnotify
60
+ requirement: &71877780 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *71877780
69
+ description: Dependor is not a framework for Dependency Injection, but something thatt
70
+ reduces duplication a little bit when doing manual dependency injection in settings
71
+ like Rails apps.
72
+ email:
73
+ - adam@pohorecki.pl
74
+ executables: []
75
+ extensions: []
76
+ extra_rdoc_files: []
77
+ files:
78
+ - .gitignore
79
+ - .travis.yml
80
+ - Gemfile
81
+ - Gemfile.lock
82
+ - Guardfile
83
+ - MIT-LICENSE
84
+ - README.md
85
+ - Rakefile
86
+ - dependor.gemspec
87
+ - lib/dependor.rb
88
+ - lib/dependor/auto_inject.rb
89
+ - lib/dependor/auto_injector.rb
90
+ - lib/dependor/class_name_resolver.rb
91
+ - lib/dependor/constructor.rb
92
+ - lib/dependor/exceptions.rb
93
+ - lib/dependor/injectable.rb
94
+ - lib/dependor/instantiator.rb
95
+ - lib/dependor/let.rb
96
+ - lib/dependor/shorty.rb
97
+ - lib/dependor/version.rb
98
+ - spec/dependor/auto_inject_spec.rb
99
+ - spec/dependor/class_name_resolver_spec.rb
100
+ - spec/dependor/constructor_spec.rb
101
+ - spec/dependor/injectable_spec.rb
102
+ - spec/dependor/instantiator_spec.rb
103
+ - spec/dependor/let_spec.rb
104
+ - spec/dependor/shorty_spec.rb
105
+ - spec/spec_helper.rb
106
+ homepage: http://github.com/psyho/dependor
107
+ licenses: []
108
+ post_install_message:
109
+ rdoc_options: []
110
+ require_paths:
111
+ - lib
112
+ required_ruby_version: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ segments:
119
+ - 0
120
+ hash: 637782349
121
+ required_rubygems_version: !ruby/object:Gem::Requirement
122
+ none: false
123
+ requirements:
124
+ - - ! '>='
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ segments:
128
+ - 0
129
+ hash: 637782349
130
+ requirements: []
131
+ rubyforge_project: dependor
132
+ rubygems_version: 1.8.10
133
+ signing_key:
134
+ specification_version: 3
135
+ summary: A couple of classes and modules that simplify dependency injection in Ruby.
136
+ test_files: []