objectify 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # objectify
1
+ # objectify [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/bitlove/objectify)
2
2
 
3
3
  Objectify is a framework that codifies good object oriented design practices for building maintainable rails applications. For more on the motivations that led to objectify, check out this blog post: http://jamesgolick.com/2012/5/22/objectify-a-better-way-to-build-rails-applications.html
4
4
 
@@ -27,7 +27,7 @@ Objectify has two primary components:
27
27
  ```ruby
28
28
  class RequiresLoginPolicy
29
29
  # more on how current user gets injected below
30
- def allowed?(current_user)
30
+ def allowed?(current_user)
31
31
  !current_user.nil?
32
32
  end
33
33
  end
@@ -207,7 +207,7 @@ objectify.resolvers :current_user => "objectify_auth/current_user"
207
207
  ```
208
208
 
209
209
  ### Why did you constructor-inject the User constant in to the CurrentUserResolver?
210
-
210
+
211
211
  Because that makes it possible to test in isolation.
212
212
 
213
213
  ```ruby
@@ -299,10 +299,8 @@ gem "objectify", "> 0"
299
299
  # config/application.rb
300
300
  module MyApp
301
301
  class Application < Rails::Application
302
- require "objectify/rails/application"
303
- require "objectify/rails/controller"
304
302
  # only have to require this if you want objectify logging
305
- require "objectify/rails/log_subscriber"
303
+ require "objectify/rails/log_subscriber"
306
304
  include Objectify::Rails::Application
307
305
  end
308
306
  end
data/Rakefile CHANGED
@@ -11,10 +11,7 @@ rescue Bundler::BundlerError => e
11
11
  end
12
12
  require 'rake'
13
13
 
14
- require 'rspec/core'
15
14
  require 'rspec/core/rake_task'
16
- RSpec::Core::RakeTask.new(:spec) do |spec|
17
- spec.pattern = FileList['spec/**/*_spec.rb']
18
- end
15
+ RSpec::Core::RakeTask.new(:spec)
19
16
 
20
17
  task :default => :spec
@@ -4,7 +4,8 @@ require "objectify/route"
4
4
  module Objectify
5
5
  module Config
6
6
  class Action
7
- attr_reader :resource_name, :name, :route, :policies, :service, :responder
7
+ attr_reader :resource_name, :name, :route, :policies,
8
+ :service, :responder, :namespace
8
9
 
9
10
  def initialize(routing_opts,
10
11
  resource_name, name, options, default_policies,
@@ -13,6 +14,7 @@ module Objectify
13
14
  @resource_name = resource_name
14
15
  @name = name
15
16
  @policies = default_policies.merge(options, options[name])
17
+ @namespace = options[:namespace] || resource_name
16
18
 
17
19
  if options[name]
18
20
  @service = options[name][:service]
@@ -21,11 +23,11 @@ module Objectify
21
23
  end
22
24
 
23
25
  def service
24
- @service ||= [resource_name, name].join("_").to_sym
26
+ @service ||= [namespace, name].join("/")
25
27
  end
26
28
 
27
29
  def responder
28
- @responder ||= [resource_name, name].join("_").to_sym
30
+ @responder ||= [namespace, name].join("/")
29
31
  end
30
32
  end
31
33
  end
@@ -14,20 +14,21 @@ module Objectify
14
14
  def call(object, method)
15
15
  payload = {:object => object, :method => method}
16
16
  instrument("inject.objectify", payload) do |payload|
17
+ namespace = object.respond_to?(:name) && object.name ? object.name.underscore.split("/")[0...-1].join("/") : nil
17
18
  method_obj = method_object(object, method)
18
19
  injectables = method_obj.parameters.map do |reqd, name|
19
- @decoration_context[name] || @config.get(name) if reqd == :req
20
+ @decoration_context[[namespace, name].join("/").to_sym] || @decoration_context[name] || @config.get(name) if reqd == :req
20
21
  end.compact
21
22
  arguments = injectables.map do |type, value|
22
23
  if type == :unknown
23
- type, value = unknown_value_to_injectable(value)
24
+ type, value = unknown_value_to_injectable(namespace, value)
24
25
  end
25
26
 
26
27
  if type == :resolver
27
- resolver_klass = [value, :resolver].join("_").classify.constantize
28
+ resolver_klass = [value, :resolver].join("_").camelize.constantize
28
29
  call(call(resolver_klass, :new), :call)
29
30
  elsif type == :implementation
30
- implementation_klass = value.to_s.classify.constantize
31
+ implementation_klass = value.to_s.camelize.constantize
31
32
  call(implementation_klass, :new)
32
33
  elsif type == :value
33
34
  value
@@ -45,7 +46,7 @@ module Objectify
45
46
  base_name = object.name.underscore.to_sym
46
47
  add_decoration_context(base_name, result)
47
48
  result = @config.decorators(base_name).inject(result) do |memo, decorator|
48
- call(decorator.to_s.classify.constantize, :new).tap do |decorated|
49
+ call(decorator.to_s.camelize.constantize, :new).tap do |decorated|
49
50
  add_decoration_context(base_name, decorated)
50
51
  end
51
52
  end
@@ -65,12 +66,14 @@ module Objectify
65
66
  end
66
67
  end
67
68
 
68
- def unknown_value_to_injectable(value)
69
- [nil, :resolver].each do |suffix|
70
- begin
71
- [value, suffix].compact.join("_").classify.constantize
72
- return [suffix.nil? ? :implementation : suffix, value]
73
- rescue NameError => e
69
+ def unknown_value_to_injectable(namespace, value)
70
+ [namespace, nil].uniq.each do |ns|
71
+ [nil, :resolver].each do |suffix|
72
+ begin
73
+ [ns, [value, suffix].compact.join("_")].compact.join("/").camelize.constantize
74
+ return [suffix.nil? ? :implementation : suffix, [ns, value].compact.join("/")]
75
+ rescue NameError => e
76
+ end
74
77
  end
75
78
  end
76
79
 
@@ -7,7 +7,8 @@ module Objectify
7
7
  end
8
8
 
9
9
  def call(name, type)
10
- klass = [name, type].join("_").classify.constantize
10
+ join_char = type == :policy ? "_" : "/"
11
+ klass = [name, type].join(join_char).classify.constantize
11
12
  @injector.call(klass, :new)
12
13
  end
13
14
  end
@@ -2,7 +2,6 @@ require "objectify/config/policies"
2
2
  require "objectify/executor"
3
3
  require "objectify/policy_chain_executor"
4
4
  require "objectify/instrumentation"
5
- require "objectify/rails/renderer"
6
5
  require "objectify/rails/routes"
7
6
 
8
7
  module Objectify
@@ -37,14 +36,13 @@ module Objectify
37
36
  injectables_context.add_value(:request, request)
38
37
  injectables_context.add_value(:response, response)
39
38
  injectables_context.add_value(:flash, flash)
40
- injectables_context.add_value(:renderer, Renderer.new(self))
41
39
  injectables_context.add_value(:format, objectify_response_collector)
42
40
  injectables_context.add_value(:routes, objectify_routes)
43
41
  end
44
42
  end
45
43
 
46
44
  def objectify_response_collector
47
- @objectify_response_collector ||= ActionController::MimeResponds::Collector.new { default_response }
45
+ @objectify_response_collector ||= ActionController::MimeResponds::Collector.new {}
48
46
  end
49
47
 
50
48
  def objectify_executor
@@ -1,3 +1,3 @@
1
1
  module Objectify
2
- VERSION = "0.2.1"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -19,12 +19,12 @@ Gem::Specification.new do |s|
19
19
  s.require_paths = ["lib"]
20
20
 
21
21
  # specify any dependencies here; for example:
22
- s.add_development_dependency "rspec", "~> 2.4.0"
22
+ s.add_development_dependency "rspec", "~> 2.10.0"
23
23
  s.add_development_dependency "bundler", ">= 1.0.0"
24
24
  s.add_development_dependency "jeweler", "~> 1.6.4"
25
25
  s.add_development_dependency "bourne", "1.0"
26
26
  s.add_development_dependency "mocha", "0.9.8"
27
27
 
28
- s.add_runtime_dependency "rails", ">=3.0.0"
28
+ s.add_runtime_dependency "rails", ">=3.2.5"
29
29
  s.add_runtime_dependency "i18n"
30
30
  end
@@ -20,6 +20,7 @@ describe "Objectify::Config::Action" do
20
20
  }
21
21
 
22
22
  @options = {
23
+ :namespace => :somewhere,
23
24
  :policies => :asdf,
24
25
  :skip_policies => :bsdf,
25
26
  :index => @index_options
@@ -72,12 +73,12 @@ describe "Objectify::Config::Action" do
72
73
  @route_factory)
73
74
  end
74
75
 
75
- it "has a default service of \#{resource_name}_\#{action_name}" do
76
- @action.service.should == :pictures_index
76
+ it "has a default service of \#{resource_name}/\#{action_name}" do
77
+ @action.service.should == "pictures/index"
77
78
  end
78
79
 
79
- it "has a default responder of \#{resource_name}_\#{action_name}" do
80
- @action.responder.should == :pictures_index
80
+ it "has a default responder of \#{resource_name}/\#{action_name}" do
81
+ @action.responder.should == "pictures/index"
81
82
  end
82
83
  end
83
84
  end
@@ -135,4 +135,55 @@ describe "Objectify::Injector" do
135
135
  @injector.call(ToBeDecorated, :new).should be_instance_of(ToBeDecorated)
136
136
  end
137
137
  end
138
+
139
+ module An
140
+ class Service
141
+ attr_reader :canada
142
+
143
+ def initialize(canada)
144
+ @canada = canada
145
+ end
146
+ end
147
+
148
+ class ServiceWithStuff
149
+ attr_reader :service
150
+
151
+ def initialize(service)
152
+ @service = service
153
+ end
154
+ end
155
+
156
+ class ServiceWithOtherStuff
157
+ def initialize(service, my_injected_class)
158
+ @service = service
159
+ @my_injected_class = my_injected_class
160
+ end
161
+ end
162
+
163
+ class Canada
164
+ end
165
+ end
166
+
167
+ context "within a namespace" do
168
+ before do
169
+ @config.stubs(:get).with(:canada).returns([:unknown, :canada])
170
+ @result = @injector.call(An::Service, :new)
171
+ end
172
+
173
+ it "first searches within the namespace to fulfill the dependency" do
174
+ @result.canada.should be_instance_of(An::Canada)
175
+ end
176
+
177
+ it "can decorate" do
178
+ @config.stubs(:decorators).with(:"an/service").returns([:"an/service_with_stuff"])
179
+ @injector.call(An::Service, :new).should be_instance_of(An::ServiceWithStuff)
180
+ end
181
+
182
+ it "can still look up the module chain for decorators" do
183
+ @config.stubs(:decorators).with(:"an/service").returns([:"an/service_with_other_stuff"])
184
+ @config.stubs(:get).with(:my_injected_class).returns([:unknown, :my_injected_class])
185
+ @config.stubs(:get).with(:some_dependency).returns([:value, :asdf])
186
+ @injector.call(An::Service, :new).should be_instance_of(An::ServiceWithOtherStuff)
187
+ end
188
+ end
138
189
  end
@@ -2,21 +2,48 @@ require "spec_helper"
2
2
  require "objectify/instantiator"
3
3
 
4
4
  describe "Objectify::Instantiator" do
5
- class MyService
5
+ module My
6
+ class Service
7
+ end
8
+ end
9
+
10
+ class MyPolicy
6
11
  end
7
12
 
8
13
  before do
9
- @service = MyService.new
10
- @injector = stub("Injector", :call => @service)
14
+ @injector = stub("Injector")
11
15
  @instantiator = Objectify::Instantiator.new(@injector)
12
- @result = @instantiator.call(:my, :service)
13
16
  end
14
17
 
15
- it "returns the result of injector#call" do
16
- @result.should == @service
18
+ context "with a service" do
19
+ before do
20
+ @service = My::Service.new
21
+ @injector.stubs(:call).returns(@service)
22
+ @result = @instantiator.call(:my, :service)
23
+ end
24
+
25
+ it "returns the result of injector#call" do
26
+ @result.should == @service
27
+ end
28
+
29
+ it "locates the service in the supplied namespace and instantiates" do
30
+ @injector.should have_received(:call).with(My::Service, :new)
31
+ end
17
32
  end
18
33
 
19
- it "calls the injector with the generated constant" do
20
- @injector.should have_received(:call).with(MyService, :new)
34
+ context "with a policy" do
35
+ before do
36
+ @policy = MyPolicy.new
37
+ @injector.stubs(:call).returns(@policy)
38
+ @result = @instantiator.call(:my, :policy)
39
+ end
40
+
41
+ it "returns the result of injector#call" do
42
+ @result.should == @policy
43
+ end
44
+
45
+ it "locates the policy namespace and instantiates" do
46
+ @injector.should have_received(:call).with(MyPolicy, :new)
47
+ end
21
48
  end
22
49
  end
@@ -1,15 +1,5 @@
1
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
- $LOAD_PATH.unshift(File.dirname(__FILE__))
3
- require 'rspec'
4
- require "rubygems"
5
- require "rspec"
6
- require "mocha"
7
1
  require "bourne"
8
2
 
9
- # Requires supporting files with custom matchers and macros, etc,
10
- # in ./support/ and its subdirectories.
11
- Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
12
-
13
3
  RSpec.configure do |config|
14
4
  config.mock_with :mocha
15
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: objectify
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,22 +9,22 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-05 00:00:00.000000000 Z
12
+ date: 2012-08-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &70230408805980 !ruby/object:Gem::Requirement
16
+ requirement: &70174896773480 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
20
20
  - !ruby/object:Gem::Version
21
- version: 2.4.0
21
+ version: 2.10.0
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70230408805980
24
+ version_requirements: *70174896773480
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: bundler
27
- requirement: &70230408805480 !ruby/object:Gem::Requirement
27
+ requirement: &70174896772980 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 1.0.0
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70230408805480
35
+ version_requirements: *70174896772980
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: jeweler
38
- requirement: &70230408805020 !ruby/object:Gem::Requirement
38
+ requirement: &70174896772520 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 1.6.4
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70230408805020
46
+ version_requirements: *70174896772520
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: bourne
49
- requirement: &70230408804560 !ruby/object:Gem::Requirement
49
+ requirement: &70174896772060 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - =
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '1.0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70230408804560
57
+ version_requirements: *70174896772060
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: mocha
60
- requirement: &70230408804100 !ruby/object:Gem::Requirement
60
+ requirement: &70174896771600 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - =
@@ -65,21 +65,21 @@ dependencies:
65
65
  version: 0.9.8
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70230408804100
68
+ version_requirements: *70174896771600
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rails
71
- requirement: &70230408803640 !ruby/object:Gem::Requirement
71
+ requirement: &70174896771140 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
75
75
  - !ruby/object:Gem::Version
76
- version: 3.0.0
76
+ version: 3.2.5
77
77
  type: :runtime
78
78
  prerelease: false
79
- version_requirements: *70230408803640
79
+ version_requirements: *70174896771140
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: i18n
82
- requirement: &70230408803260 !ruby/object:Gem::Requirement
82
+ requirement: &70174896770760 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,7 +87,7 @@ dependencies:
87
87
  version: '0'
88
88
  type: :runtime
89
89
  prerelease: false
90
- version_requirements: *70230408803260
90
+ version_requirements: *70174896770760
91
91
  description: Objects on rails.
92
92
  email:
93
93
  - jamesgolick@gmail.com
@@ -131,7 +131,6 @@ files:
131
131
  - spec/injector_spec.rb
132
132
  - spec/instantiator_spec.rb
133
133
  - spec/policy_chain_executor_spec.rb
134
- - spec/rails/renderer_spec.rb
135
134
  - spec/rails/routing_spec.rb
136
135
  - spec/route_spec.rb
137
136
  - spec/spec_helper.rb
@@ -170,7 +169,6 @@ test_files:
170
169
  - spec/injector_spec.rb
171
170
  - spec/instantiator_spec.rb
172
171
  - spec/policy_chain_executor_spec.rb
173
- - spec/rails/renderer_spec.rb
174
172
  - spec/rails/routing_spec.rb
175
173
  - spec/route_spec.rb
176
174
  - spec/spec_helper.rb
@@ -1,63 +0,0 @@
1
- require "spec_helper"
2
- require "objectify/rails/renderer"
3
-
4
- describe "Objectify::Rails::Renderer" do
5
- before do
6
- @controller = stub("Controller", :render => nil,
7
- :redirect_to => nil,
8
- :instance_variable_set => nil) # yeah, well.
9
- @renderer = Objectify::Rails::Renderer.new(@controller)
10
- end
11
-
12
- it "delegates template rendering" do
13
- @renderer.template("something.html.erb", :some => :option)
14
- @controller.should have_received(:render).with(:template => "something.html.erb",
15
- :some => :option)
16
- end
17
-
18
- it "delegates action rendering" do
19
- @renderer.action("something.html.erb", :some => :option)
20
- @controller.should have_received(:render).with(:action => "something.html.erb",
21
- :some => :option)
22
- end
23
-
24
- it "delegates partial rendering" do
25
- @renderer.partial("something.html.erb", :some => :option)
26
- @controller.should have_received(:render).with(:partial => "something.html.erb",
27
- :some => :option)
28
- end
29
-
30
- it "delegates rendering nothing" do
31
- @renderer.nothing(:some => :option)
32
- @controller.should have_received(:render).with(:nothing => true,
33
- :some => :option)
34
- end
35
-
36
- it "exposes the full render method" do
37
- @renderer.render(:json => "asdf")
38
- @controller.should have_received(:render).with(:json => "asdf")
39
- end
40
-
41
- it "delegates the respond_to method" do
42
- @responder = stub("Responder")
43
- @responder.stubs(:html).yields
44
- @controller.stubs(:respond_to).yields(@responder)
45
-
46
- @renderer.respond_to do |format|
47
- format.html { }
48
- end
49
-
50
- @responder.should have_received(:html)
51
- end
52
-
53
- it "delegates the redirect_to method" do
54
- @renderer.redirect_to :somewhere
55
- @controller.should have_received(:redirect_to).with(:somewhere)
56
- end
57
-
58
- it "can set the data on the controller" do
59
- @renderer.data("asdf")
60
- @controller.should have_received(:instance_variable_set).
61
- with(:@objectify_data, "asdf")
62
- end
63
- end