drape 1.0.0.beta1
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.
- checksums.yaml +7 -0
- data/.codeclimate.yml +27 -0
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/.rubocop.yml +1159 -0
- data/.travis.yml +14 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +230 -0
- data/CONTRIBUTING.md +20 -0
- data/Gemfile +16 -0
- data/Guardfile +26 -0
- data/LICENSE +7 -0
- data/README.md +592 -0
- data/Rakefile +76 -0
- data/drape.gemspec +31 -0
- data/gemfiles/5.0.gemfile +8 -0
- data/lib/drape.rb +63 -0
- data/lib/drape/automatic_delegation.rb +55 -0
- data/lib/drape/collection_decorator.rb +102 -0
- data/lib/drape/decoratable.rb +93 -0
- data/lib/drape/decoratable/equality.rb +26 -0
- data/lib/drape/decorated_association.rb +33 -0
- data/lib/drape/decorates_assigned.rb +44 -0
- data/lib/drape/decorator.rb +282 -0
- data/lib/drape/delegation.rb +13 -0
- data/lib/drape/factory.rb +91 -0
- data/lib/drape/finders.rb +36 -0
- data/lib/drape/helper_proxy.rb +43 -0
- data/lib/drape/helper_support.rb +5 -0
- data/lib/drape/lazy_helpers.rb +13 -0
- data/lib/drape/railtie.rb +69 -0
- data/lib/drape/tasks/test.rake +9 -0
- data/lib/drape/test/devise_helper.rb +30 -0
- data/lib/drape/test/minitest_integration.rb +6 -0
- data/lib/drape/test/rspec_integration.rb +20 -0
- data/lib/drape/test_case.rb +42 -0
- data/lib/drape/undecorate.rb +9 -0
- data/lib/drape/version.rb +3 -0
- data/lib/drape/view_context.rb +104 -0
- data/lib/drape/view_context/build_strategy.rb +46 -0
- data/lib/drape/view_helpers.rb +34 -0
- data/lib/generators/controller_override.rb +17 -0
- data/lib/generators/mini_test/decorator_generator.rb +20 -0
- data/lib/generators/mini_test/templates/decorator_spec.rb +4 -0
- data/lib/generators/mini_test/templates/decorator_test.rb +4 -0
- data/lib/generators/rails/decorator_generator.rb +36 -0
- data/lib/generators/rails/templates/decorator.rb +19 -0
- data/lib/generators/rspec/decorator_generator.rb +9 -0
- data/lib/generators/rspec/templates/decorator_spec.rb +4 -0
- data/lib/generators/test_unit/decorator_generator.rb +9 -0
- data/lib/generators/test_unit/templates/decorator_test.rb +4 -0
- data/spec/draper/collection_decorator_spec.rb +305 -0
- data/spec/draper/decoratable/equality_spec.rb +10 -0
- data/spec/draper/decoratable_spec.rb +203 -0
- data/spec/draper/decorated_association_spec.rb +85 -0
- data/spec/draper/decorates_assigned_spec.rb +70 -0
- data/spec/draper/decorator_spec.rb +828 -0
- data/spec/draper/factory_spec.rb +250 -0
- data/spec/draper/finders_spec.rb +165 -0
- data/spec/draper/helper_proxy_spec.rb +61 -0
- data/spec/draper/lazy_helpers_spec.rb +21 -0
- data/spec/draper/undecorate_spec.rb +19 -0
- data/spec/draper/view_context/build_strategy_spec.rb +116 -0
- data/spec/draper/view_context_spec.rb +160 -0
- data/spec/draper/view_helpers_spec.rb +8 -0
- data/spec/dummy/.gitignore +21 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/config/manifest.js +3 -0
- data/spec/dummy/app/assets/images/.keep +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +16 -0
- data/spec/dummy/app/assets/javascripts/cable.js +13 -0
- data/spec/dummy/app/assets/javascripts/channels/.keep +0 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
- data/spec/dummy/app/channels/application_cable/connection.rb +5 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/controllers/posts_controller.rb +21 -0
- data/spec/dummy/app/decorators/mongoid_post_decorator.rb +4 -0
- data/spec/dummy/app/decorators/post_decorator.rb +59 -0
- data/spec/dummy/app/helpers/application_helper.rb +5 -0
- data/spec/dummy/app/jobs/application_job.rb +2 -0
- data/spec/dummy/app/mailers/application_mailer.rb +4 -0
- data/spec/dummy/app/mailers/post_mailer.rb +18 -0
- data/spec/dummy/app/models/admin.rb +5 -0
- data/spec/dummy/app/models/application_record.rb +3 -0
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/models/mongoid_post.rb +5 -0
- data/spec/dummy/app/models/post.rb +3 -0
- data/spec/dummy/app/models/user.rb +5 -0
- data/spec/dummy/app/views/layouts/application.html.erb +9 -0
- data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/spec/dummy/app/views/post_mailer/decorated_email.html.erb +31 -0
- data/spec/dummy/app/views/posts/_post.html.erb +40 -0
- data/spec/dummy/app/views/posts/show.html.erb +1 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +9 -0
- data/spec/dummy/bin/rake +9 -0
- data/spec/dummy/bin/setup +34 -0
- data/spec/dummy/bin/spring +15 -0
- data/spec/dummy/bin/update +29 -0
- data/spec/dummy/config.ru +5 -0
- data/spec/dummy/config/application.rb +21 -0
- data/spec/dummy/config/boot.rb +2 -0
- data/spec/dummy/config/cable.yml +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +51 -0
- data/spec/dummy/config/environments/production.rb +91 -0
- data/spec/dummy/config/environments/test.rb +42 -0
- data/spec/dummy/config/initializers/active_record_belongs_to_required_by_default.rb +6 -0
- data/spec/dummy/config/initializers/application_controller_renderer.rb +6 -0
- data/spec/dummy/config/initializers/assets.rb +11 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/callback_terminator.rb +6 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
- data/spec/dummy/config/initializers/devise.rb +3 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/per_form_csrf_tokens.rb +4 -0
- data/spec/dummy/config/initializers/request_forgery_protection.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/ssl_options.rb +4 -0
- data/spec/dummy/config/initializers/to_time_preserves_timezone.rb +10 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/mongoid.yml +16 -0
- data/spec/dummy/config/puma.rb +47 -0
- data/spec/dummy/config/routes.rb +8 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/config/spring.rb +6 -0
- data/spec/dummy/db/migrate/20121019115657_create_posts.rb +7 -0
- data/spec/dummy/db/schema.rb +19 -0
- data/spec/dummy/db/seeds.rb +2 -0
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/lib/tasks/.keep +0 -0
- data/spec/dummy/lib/tasks/test.rake +16 -0
- data/spec/dummy/log/.keep +0 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
- data/spec/dummy/public/apple-touch-icon.png +0 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/public/robots.txt +5 -0
- data/spec/dummy/spec/decorators/active_model_serializers_spec.rb +12 -0
- data/spec/dummy/spec/decorators/devise_spec.rb +64 -0
- data/spec/dummy/spec/decorators/helpers_spec.rb +21 -0
- data/spec/dummy/spec/decorators/post_decorator_spec.rb +66 -0
- data/spec/dummy/spec/decorators/spec_type_spec.rb +7 -0
- data/spec/dummy/spec/decorators/view_context_spec.rb +22 -0
- data/spec/dummy/spec/mailers/post_mailer_spec.rb +33 -0
- data/spec/dummy/spec/models/mongoid_post_spec.rb +8 -0
- data/spec/dummy/spec/models/post_spec.rb +6 -0
- data/spec/dummy/spec/shared_examples/decoratable.rb +26 -0
- data/spec/dummy/spec/spec_helper.rb +8 -0
- data/spec/dummy/test/controllers/.keep +0 -0
- data/spec/dummy/test/fixtures/.keep +0 -0
- data/spec/dummy/test/fixtures/files/.keep +0 -0
- data/spec/dummy/test/helpers/.keep +0 -0
- data/spec/dummy/test/integration/.keep +0 -0
- data/spec/dummy/test/mailers/.keep +0 -0
- data/spec/dummy/test/models/.keep +0 -0
- data/spec/dummy/test/test_helper.rb +10 -0
- data/spec/dummy/vendor/assets/javascripts/.keep +0 -0
- data/spec/dummy/vendor/assets/stylesheets/.keep +0 -0
- data/spec/generators/controller/controller_generator_spec.rb +24 -0
- data/spec/generators/decorator/decorator_generator_spec.rb +94 -0
- data/spec/integration/integration_spec.rb +68 -0
- data/spec/performance/active_record.rb +4 -0
- data/spec/performance/benchmark.rb +57 -0
- data/spec/performance/decorators.rb +41 -0
- data/spec/performance/models.rb +20 -0
- data/spec/spec_helper.rb +41 -0
- data/spec/support/dummy_app.rb +88 -0
- data/spec/support/matchers/have_text.rb +50 -0
- data/spec/support/shared_examples/decoratable_equality.rb +40 -0
- data/spec/support/shared_examples/view_helpers.rb +39 -0
- metadata +497 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module Drape
|
|
2
|
+
# Provides automatically-decorated finder methods for your decorators. You
|
|
3
|
+
# do not have to extend this module directly; it is extended by
|
|
4
|
+
# {Decorator.decorates_finders}.
|
|
5
|
+
module Finders
|
|
6
|
+
def find(id, options = {})
|
|
7
|
+
decorate(object_class.find(id), options)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def all(options = {})
|
|
11
|
+
decorate_collection(object_class.all, options)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def first(options = {})
|
|
15
|
+
decorate(object_class.first, options)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def last(options = {})
|
|
19
|
+
decorate(object_class.last, options)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Decorates dynamic finder methods (`find_all_by_` and friends).
|
|
23
|
+
def method_missing(method, *args, &block)
|
|
24
|
+
return super unless method =~ /^find_(all_|last_|or_(initialize_|create_))?by_/
|
|
25
|
+
|
|
26
|
+
result = object_class.send(method, *args, &block)
|
|
27
|
+
options = args.extract_options!
|
|
28
|
+
|
|
29
|
+
if method =~ /^find_all/
|
|
30
|
+
decorate_collection(result, options)
|
|
31
|
+
else
|
|
32
|
+
decorate(result, options)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module Drape
|
|
2
|
+
# Provides access to helper methods - both Rails built-in helpers, and those
|
|
3
|
+
# defined in your application.
|
|
4
|
+
class HelperProxy
|
|
5
|
+
# @overload initialize(view_context)
|
|
6
|
+
def initialize(view_context = nil)
|
|
7
|
+
view_context ||= current_view_context # backwards compatibility
|
|
8
|
+
|
|
9
|
+
@view_context = view_context
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Sends helper methods to the view context.
|
|
13
|
+
def method_missing(method, *args, &block)
|
|
14
|
+
self.class.define_proxy method
|
|
15
|
+
send(method, *args, &block)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Checks if the context responds to an instance method, or is able to
|
|
19
|
+
# proxy it to the view context.
|
|
20
|
+
def respond_to_missing?(method, include_private = false)
|
|
21
|
+
super || view_context.respond_to?(method)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
delegate :capture, to: :view_context
|
|
25
|
+
|
|
26
|
+
def self.define_proxy(name)
|
|
27
|
+
define_method name do |*args, &block|
|
|
28
|
+
view_context.send(name, *args, &block)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
protected
|
|
33
|
+
|
|
34
|
+
attr_reader :view_context
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def current_view_context
|
|
39
|
+
ActiveSupport::Deprecation.warn('wrong number of arguments (0 for 1) passed to Drape::HelperProxy.new', caller[1..-1])
|
|
40
|
+
Drape::ViewContext.current.view_context
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module Drape
|
|
2
|
+
# Include this module in your decorators to get direct access to the helpers
|
|
3
|
+
# so that you can stop typing `h.` everywhere, at the cost of mixing in a
|
|
4
|
+
# bazillion methods.
|
|
5
|
+
module LazyHelpers
|
|
6
|
+
# Sends missing methods to the {HelperProxy}.
|
|
7
|
+
def method_missing(method, *args, &block)
|
|
8
|
+
helpers.send(method, *args, &block)
|
|
9
|
+
rescue NoMethodError
|
|
10
|
+
super
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
require 'rails/railtie'
|
|
2
|
+
|
|
3
|
+
module ActiveModel
|
|
4
|
+
class Railtie < Rails::Railtie
|
|
5
|
+
generators do |app|
|
|
6
|
+
app ||= Rails.application # Rails 3.0.x does not yield `app`
|
|
7
|
+
|
|
8
|
+
Rails::Generators.configure! app.config.generators
|
|
9
|
+
require_relative '../generators/controller_override'
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
module Drape
|
|
15
|
+
class Railtie < Rails::Railtie
|
|
16
|
+
config.after_initialize do |app|
|
|
17
|
+
app.config.paths.add 'app/decorators', eager_load: true
|
|
18
|
+
|
|
19
|
+
if Rails.env.test?
|
|
20
|
+
require 'drape/test_case'
|
|
21
|
+
require 'drape/test/rspec_integration' if defined?(RSpec) && RSpec.respond_to?(:configure)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
initializer 'drape.setup_action_controller' do |_app|
|
|
26
|
+
ActiveSupport.on_load :action_controller do
|
|
27
|
+
Drape.setup_action_controller self
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
initializer 'drape.setup_action_mailer' do |_app|
|
|
32
|
+
ActiveSupport.on_load :action_mailer do
|
|
33
|
+
Drape.setup_action_mailer self
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
initializer 'drape.setup_orm' do |_app|
|
|
38
|
+
[:active_record, :mongoid].each do |orm|
|
|
39
|
+
ActiveSupport.on_load orm do
|
|
40
|
+
Drape.setup_orm self
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
initializer 'drape.setup_active_model_serializers' do |_app|
|
|
46
|
+
ActiveSupport.on_load :active_model_serializers do
|
|
47
|
+
if defined?(ActiveModel::ArraySerializerSupport)
|
|
48
|
+
Drape::CollectionDecorator.send :include, ActiveModel::ArraySerializerSupport
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
initializer 'drape.minitest-rails_integration' do |_app|
|
|
54
|
+
ActiveSupport.on_load :minitest do
|
|
55
|
+
require 'drape/test/minitest_integration'
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
console do
|
|
60
|
+
require 'action_controller/test_case'
|
|
61
|
+
ApplicationController.new.view_context
|
|
62
|
+
Drape::ViewContext.build
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
rake_tasks do
|
|
66
|
+
Dir[File.join(File.dirname(__FILE__), 'tasks/*.rake')].each { |f| load f }
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module Drape
|
|
2
|
+
module DeviseHelper
|
|
3
|
+
def sign_in(resource_or_scope, resource = nil)
|
|
4
|
+
scope = begin
|
|
5
|
+
Devise::Mapping.find_scope!(resource_or_scope)
|
|
6
|
+
rescue RuntimeError => e
|
|
7
|
+
# Drape 1.0 didn't require the mapping to exist
|
|
8
|
+
ActiveSupport::Deprecation.warn("#{e.message}.\nUse `sign_in :user, mock_user` instead.", caller)
|
|
9
|
+
:user
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
_stub_current_scope scope, resource || resource_or_scope
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def sign_out(resource_or_scope)
|
|
16
|
+
scope = Devise::Mapping.find_scope!(resource_or_scope)
|
|
17
|
+
_stub_current_scope scope, nil
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def _stub_current_scope(scope, resource)
|
|
23
|
+
Drape::ViewContext.current.controller.singleton_class.class_eval do
|
|
24
|
+
define_method "current_#{scope}" do
|
|
25
|
+
resource
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Drape
|
|
2
|
+
module DecoratorExampleGroup
|
|
3
|
+
include Drape::TestCase::Behavior
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
|
|
6
|
+
included { metadata[:type] = :decorator }
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
RSpec.configure do |config|
|
|
10
|
+
if RSpec::Core::Version::STRING.starts_with?('3')
|
|
11
|
+
config.include DecoratorExampleGroup, file_path: %r{spec/decorators}, type: :decorator
|
|
12
|
+
else
|
|
13
|
+
config.include DecoratorExampleGroup, example_group: { file_path: %r{spec/decorators} }, type: :decorator
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
[:decorator, :controller, :mailer].each do |type|
|
|
17
|
+
config.before(:each, type: type) { Drape::ViewContext.clear! }
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
module Drape
|
|
2
|
+
require 'active_support/test_case'
|
|
3
|
+
|
|
4
|
+
class TestCase < ::ActiveSupport::TestCase
|
|
5
|
+
module ViewContextTeardown
|
|
6
|
+
def teardown
|
|
7
|
+
super
|
|
8
|
+
Drape::ViewContext.clear!
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
module Behavior
|
|
13
|
+
if defined?(::Devise)
|
|
14
|
+
require 'drape/test/devise_helper'
|
|
15
|
+
include Drape::DeviseHelper
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
if defined?(::Capybara) && (defined?(::RSpec) || defined?(::MiniTest::Matchers))
|
|
19
|
+
require 'capybara/rspec/matchers'
|
|
20
|
+
include ::Capybara::RSpecMatchers
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
include Drape::ViewHelpers::ClassMethods
|
|
24
|
+
alias helper helpers
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
include Behavior
|
|
28
|
+
include ViewContextTeardown
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
if defined?(ActionController::TestCase)
|
|
33
|
+
class ActionController::TestCase
|
|
34
|
+
include Drape::TestCase::ViewContextTeardown
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
if defined?(ActionMailer::TestCase)
|
|
39
|
+
class ActionMailer::TestCase
|
|
40
|
+
include Drape::TestCase::ViewContextTeardown
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
require 'drape/view_context/build_strategy'
|
|
2
|
+
require 'request_store'
|
|
3
|
+
|
|
4
|
+
module Drape
|
|
5
|
+
module ViewContext
|
|
6
|
+
# Hooks into a controller or mailer to save the view context in {current}.
|
|
7
|
+
def view_context
|
|
8
|
+
super.tap do |context|
|
|
9
|
+
Drape::ViewContext.current = context
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Set the current controller
|
|
14
|
+
def activate_drape
|
|
15
|
+
Drape::ViewContext.controller = self
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Returns the current controller.
|
|
19
|
+
def self.controller
|
|
20
|
+
RequestStore.store[:current_controller]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Sets the current controller.
|
|
24
|
+
def self.controller=(controller)
|
|
25
|
+
RequestStore.store[:current_controller] = controller
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Returns the current view context, or builds one if none is saved.
|
|
29
|
+
#
|
|
30
|
+
# @return [HelperProxy]
|
|
31
|
+
def self.current
|
|
32
|
+
RequestStore.store.fetch(:current_view_context) { build! }
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Sets the current view context.
|
|
36
|
+
def self.current=(view_context)
|
|
37
|
+
RequestStore.store[:current_view_context] = Drape::HelperProxy.new(view_context)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Clears the saved controller and view context.
|
|
41
|
+
def self.clear!
|
|
42
|
+
RequestStore.store.delete :current_controller
|
|
43
|
+
RequestStore.store.delete :current_view_context
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Builds a new view context for usage in tests. See {test_strategy} for
|
|
47
|
+
# details of how the view context is built.
|
|
48
|
+
def self.build
|
|
49
|
+
build_strategy.call
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Builds a new view context and sets it as the current view context.
|
|
53
|
+
#
|
|
54
|
+
# @return [HelperProxy]
|
|
55
|
+
def self.build!
|
|
56
|
+
# send because we want to return the HelperProxy returned from #current=
|
|
57
|
+
send :current=, build
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Configures the strategy used to build view contexts in tests, which
|
|
61
|
+
# defaults to `:full` if `test_strategy` has not been called. Evaluates
|
|
62
|
+
# the block, if given, in the context of the view context's class.
|
|
63
|
+
#
|
|
64
|
+
# @example Pass a block to add helper methods to the view context:
|
|
65
|
+
# Drape::ViewContext.test_strategy :fast do
|
|
66
|
+
# include ApplicationHelper
|
|
67
|
+
# end
|
|
68
|
+
#
|
|
69
|
+
# @param [:full, :fast] name
|
|
70
|
+
# the strategy to use:
|
|
71
|
+
#
|
|
72
|
+
# `:full` - build a fully-working view context. Your Rails environment
|
|
73
|
+
# must be loaded, including your `ApplicationController`.
|
|
74
|
+
#
|
|
75
|
+
# `:fast` - build a minimal view context in tests, with no dependencies
|
|
76
|
+
# on other components of your application.
|
|
77
|
+
def self.test_strategy(name, &block)
|
|
78
|
+
@build_strategy = Drape::ViewContext::BuildStrategy.new(name, &block)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# @private
|
|
82
|
+
def self.build_strategy
|
|
83
|
+
@build_strategy ||= Drape::ViewContext::BuildStrategy.new(:full)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# @deprecated Use {controller} instead.
|
|
87
|
+
def self.current_controller
|
|
88
|
+
ActiveSupport::Deprecation.warn('Drape::ViewContext.current_controller is deprecated (use controller instead)', caller)
|
|
89
|
+
controller || ApplicationController.new
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# @deprecated Use {controller=} instead.
|
|
93
|
+
def self.current_controller=(controller)
|
|
94
|
+
ActiveSupport::Deprecation.warn('Drape::ViewContext.current_controller= is deprecated (use controller instead)', caller)
|
|
95
|
+
self.controller = controller
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# @deprecated Use {build} instead.
|
|
99
|
+
def self.build_view_context
|
|
100
|
+
ActiveSupport::Deprecation.warn('Drape::ViewContext.build_view_context is deprecated (use build instead)', caller)
|
|
101
|
+
build
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module Drape
|
|
2
|
+
module ViewContext
|
|
3
|
+
# @private
|
|
4
|
+
module BuildStrategy
|
|
5
|
+
def self.new(name, &block)
|
|
6
|
+
const_get(name.to_s.camelize).new(&block)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
class Fast
|
|
10
|
+
def initialize(&block)
|
|
11
|
+
@view_context_class = Class.new(ActionView::Base, &block)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def call
|
|
15
|
+
view_context_class.new
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
attr_reader :view_context_class
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
class Full
|
|
24
|
+
def initialize(&block)
|
|
25
|
+
@block = block
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def call
|
|
29
|
+
controller.view_context.tap do |context|
|
|
30
|
+
context.singleton_class.class_eval(&block) if block
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
attr_reader :block
|
|
37
|
+
|
|
38
|
+
def controller
|
|
39
|
+
(Drape::ViewContext.controller || ApplicationController.new).tap do |controller|
|
|
40
|
+
controller.request ||= ActionController::TestRequest.create if defined?(ActionController::TestRequest)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|