Add support for custom default controller configuration (#788)
* Add configure functionality to allow customizing the default. * Add configuration module and tests. * Add documentation to the README.md * Skip tests that only fail when whole suite is ran. * Fix the double leaking by re-writing the test that caused the issue. * Clean up railtie - Exract out method, Remove unnecessary compatibility. * Add new functionality to the dummy app to increase test coverage.
This commit is contained in:
parent
2e6f741a63
commit
ff36bd81ad
12
README.md
12
README.md
|
@ -368,6 +368,18 @@ you'll have access to an ArticleDecorator object instead. In your controller you
|
||||||
can continue to use the `@article` instance variable to manipulate the model -
|
can continue to use the `@article` instance variable to manipulate the model -
|
||||||
for example, `@article.comments.build` to add a new blank comment for a form.
|
for example, `@article.comments.build` to add a new blank comment for a form.
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
Draper works out the box well, but also provides a hook for you to configure its
|
||||||
|
default functionality. For example, Draper assumes you have a base `ApplicationController`.
|
||||||
|
If your base controller is named something different (e.g. `BaseController`),
|
||||||
|
you can tell Draper to use it by adding the following to an initializer:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
Draper.configure do |config|
|
||||||
|
config.default_controller = BaseController
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
Draper supports RSpec, MiniTest::Rails, and Test::Unit, and will add the
|
Draper supports RSpec, MiniTest::Rails, and Test::Unit, and will add the
|
||||||
|
|
|
@ -9,6 +9,7 @@ require 'active_support/core_ext/hash/reverse_merge'
|
||||||
require 'active_support/core_ext/name_error'
|
require 'active_support/core_ext/name_error'
|
||||||
|
|
||||||
require 'draper/version'
|
require 'draper/version'
|
||||||
|
require 'draper/configuration'
|
||||||
require 'draper/view_helpers'
|
require 'draper/view_helpers'
|
||||||
require 'draper/delegation'
|
require 'draper/delegation'
|
||||||
require 'draper/automatic_delegation'
|
require 'draper/automatic_delegation'
|
||||||
|
@ -27,6 +28,8 @@ require 'draper/decorates_assigned'
|
||||||
require 'draper/railtie' if defined?(Rails)
|
require 'draper/railtie' if defined?(Rails)
|
||||||
|
|
||||||
module Draper
|
module Draper
|
||||||
|
extend Draper::Configuration
|
||||||
|
|
||||||
def self.setup_action_controller(base)
|
def self.setup_action_controller(base)
|
||||||
base.class_eval do
|
base.class_eval do
|
||||||
include Draper::ViewContext
|
include Draper::ViewContext
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
module Draper
|
||||||
|
module Configuration
|
||||||
|
def configure
|
||||||
|
yield self
|
||||||
|
end
|
||||||
|
|
||||||
|
def default_controller
|
||||||
|
@@default_controller ||= ApplicationController
|
||||||
|
end
|
||||||
|
|
||||||
|
def default_controller=(controller)
|
||||||
|
@@default_controller = controller
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -3,8 +3,6 @@ require 'rails/railtie'
|
||||||
module ActiveModel
|
module ActiveModel
|
||||||
class Railtie < Rails::Railtie
|
class Railtie < Rails::Railtie
|
||||||
generators do |app|
|
generators do |app|
|
||||||
app ||= Rails.application # Rails 3.0.x does not yield `app`
|
|
||||||
|
|
||||||
Rails::Generators.configure! app.config.generators
|
Rails::Generators.configure! app.config.generators
|
||||||
require_relative '../generators/controller_override'
|
require_relative '../generators/controller_override'
|
||||||
end
|
end
|
||||||
|
@ -13,7 +11,6 @@ end
|
||||||
|
|
||||||
module Draper
|
module Draper
|
||||||
class Railtie < Rails::Railtie
|
class Railtie < Rails::Railtie
|
||||||
|
|
||||||
config.after_initialize do |app|
|
config.after_initialize do |app|
|
||||||
app.config.paths.add 'app/decorators', eager_load: true
|
app.config.paths.add 'app/decorators', eager_load: true
|
||||||
|
|
||||||
|
@ -23,19 +20,19 @@ module Draper
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
initializer "draper.setup_action_controller" do |app|
|
initializer 'draper.setup_action_controller' do
|
||||||
ActiveSupport.on_load :action_controller do
|
ActiveSupport.on_load :action_controller do
|
||||||
Draper.setup_action_controller self
|
Draper.setup_action_controller self
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
initializer "draper.setup_action_mailer" do |app|
|
initializer 'draper.setup_action_mailer' do
|
||||||
ActiveSupport.on_load :action_mailer do
|
ActiveSupport.on_load :action_mailer do
|
||||||
Draper.setup_action_mailer self
|
Draper.setup_action_mailer self
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
initializer "draper.setup_orm" do |app|
|
initializer 'draper.setup_orm' do
|
||||||
[:active_record, :mongoid].each do |orm|
|
[:active_record, :mongoid].each do |orm|
|
||||||
ActiveSupport.on_load orm do
|
ActiveSupport.on_load orm do
|
||||||
Draper.setup_orm self
|
Draper.setup_orm self
|
||||||
|
@ -43,26 +40,22 @@ module Draper
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
initializer "draper.minitest-rails_integration" do |app|
|
initializer 'draper.minitest-rails_integration' do
|
||||||
ActiveSupport.on_load :minitest do
|
ActiveSupport.on_load :minitest do
|
||||||
require "draper/test/minitest_integration"
|
require 'draper/test/minitest_integration'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
console do
|
def initialize_view_context
|
||||||
require 'action_controller/test_case'
|
require 'action_controller/test_case'
|
||||||
ApplicationController.new.view_context
|
Draper.default_controller.new.view_context
|
||||||
Draper::ViewContext.build
|
Draper::ViewContext.build
|
||||||
end
|
end
|
||||||
|
|
||||||
runner do
|
console { initialize_view_context }
|
||||||
require 'action_controller/test_case'
|
|
||||||
ApplicationController.new.view_context
|
|
||||||
Draper::ViewContext.build
|
|
||||||
end
|
|
||||||
|
|
||||||
rake_tasks do
|
runner { initialize_view_context }
|
||||||
Dir[File.join(File.dirname(__FILE__),'tasks/*.rake')].each { |f| load f }
|
|
||||||
end
|
rake_tasks { Dir[File.join(File.dirname(__FILE__), 'tasks/*.rake')].each { |f| load f } }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -37,7 +37,8 @@ module Draper
|
||||||
attr_reader :block
|
attr_reader :block
|
||||||
|
|
||||||
def controller
|
def controller
|
||||||
(Draper::ViewContext.controller || ApplicationController.new).tap do |controller|
|
Draper::ViewContext.controller ||= Draper.default_controller.new
|
||||||
|
Draper::ViewContext.controller.tap do |controller|
|
||||||
controller.request ||= new_test_request controller if defined?(ActionController::TestRequest)
|
controller.request ||= new_test_request controller if defined?(ActionController::TestRequest)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
module Draper
|
||||||
|
RSpec.describe Configuration do
|
||||||
|
it 'yields Draper on configure' do
|
||||||
|
Draper.configure { |config| expect(config).to be Draper }
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'defaults default_controller to ApplicationController' do
|
||||||
|
expect(Draper.default_controller).to be ApplicationController
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'allows customizing default_controller through configure' do
|
||||||
|
default = Draper.default_controller
|
||||||
|
|
||||||
|
Draper.configure do |config|
|
||||||
|
config.default_controller = CustomController
|
||||||
|
end
|
||||||
|
|
||||||
|
expect(Draper.default_controller).to be CustomController
|
||||||
|
|
||||||
|
Draper.default_controller = default
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -23,11 +23,10 @@ module Draper
|
||||||
|
|
||||||
context "when a current controller is not set" do
|
context "when a current controller is not set" do
|
||||||
it "uses ApplicationController" do
|
it "uses ApplicationController" do
|
||||||
view_context = fake_view_context
|
expect(Draper::ViewContext.controller).to be_nil
|
||||||
stub_const "ApplicationController", double(new: fake_controller(view_context))
|
view_context = ViewContext::BuildStrategy::Full.new.call
|
||||||
strategy = ViewContext::BuildStrategy::Full.new
|
expect(view_context.controller).to eq Draper::ViewContext.controller
|
||||||
|
expect(view_context.controller).to be_an ApplicationController
|
||||||
expect(strategy.call).to be view_context
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
class ApplicationController < ActionController::Base
|
|
||||||
include LocalizedUrls
|
|
||||||
protect_from_forgery
|
|
||||||
end
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
class BaseController < ActionController::Base
|
||||||
|
include LocalizedUrls
|
||||||
|
protect_from_forgery
|
||||||
|
end
|
|
@ -1,4 +1,4 @@
|
||||||
class PostsController < ApplicationController
|
class PostsController < BaseController
|
||||||
decorates_assigned :post
|
decorates_assigned :post
|
||||||
|
|
||||||
def show
|
def show
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
Draper.configure do |config|
|
||||||
|
config.default_controller = BaseController
|
||||||
|
end
|
|
@ -58,7 +58,7 @@ describe PostDecorator do
|
||||||
expect(xml).to have_css "post > updated-at", text: "overridden"
|
expect(xml).to have_css "post > updated-at", text: "overridden"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "uses a test view context from ApplicationController" do
|
it "uses a test view context from BaseController" do
|
||||||
expect(Draper::ViewContext.current.controller).to be_an ApplicationController
|
expect(Draper::ViewContext.current.controller).to be_an BaseController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -30,6 +30,9 @@ module Namespaced
|
||||||
class OtherDecorator < Draper::Decorator; end
|
class OtherDecorator < Draper::Decorator; end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
ApplicationController = Class.new(ActionController::Base)
|
||||||
|
CustomController = Class.new(ActionController::Base)
|
||||||
|
|
||||||
# After each example, revert changes made to the class
|
# After each example, revert changes made to the class
|
||||||
def protect_class(klass)
|
def protect_class(klass)
|
||||||
before { stub_const klass.name, Class.new(klass) }
|
before { stub_const klass.name, Class.new(klass) }
|
||||||
|
|
Loading…
Reference in New Issue