draper 3.1.0 → 4.0.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c323d66ea5eafcb8aac1d70bdbf02335a7460939bf6dc24a801a37a7c75f6691
4
- data.tar.gz: ebd93feddfba45e9c1596b320278bc3ae0886579dbfc6637f7025a6df6e3994c
3
+ metadata.gz: 39d1efc5af48e806f378bbd92b0d3dcf9e2811175b631e02e2aadd011d1cbf7c
4
+ data.tar.gz: d758263643cfccb3f4b1c2e1635f40aa540e194647e53e47792e735d433b6d88
5
5
  SHA512:
6
- metadata.gz: 5977d38ab1436a7dd00cb9e6e8854abdd78d2d21e2a15c00d1b40dade4490909a5d66c73fe64cbea610074096d7ece893fc70b16403fa9090b5de62a2eed2ff6
7
- data.tar.gz: b1d4f7faf5afafc5b4820b30bb8f2650fe8c8f936fdde22aedc3198d6b6c21d3299f067da23d96f23a835081bdbef2d71263725f72dce843723f14be3e7216f8
6
+ metadata.gz: 97b2c778d94f3ffa05a4cd232668f64e1646a7a47b582e9e09eaadaa0ae912f2edb3f5f91e9f8c698832be4990f751dc1359d2bf9bbffb034cffc26145e473ec
7
+ data.tar.gz: bbd454fb0379f0e7411680139a4fb3cafe5499ad6719bef19040fa93d595019dc8377820f546c8a38408ad0be81abdfd79457a446a9ded0faee04fb30bcb06e8
@@ -1,17 +1,28 @@
1
+ env:
2
+ global:
3
+ - CC_TEST_REPORTER_ID=b7ba588af2a540fa96c267b3655a2afe31ea29976dc25905a668dd28d5e88915
4
+
1
5
  language: ruby
2
- sudo: false
3
6
  cache: bundler
4
7
 
5
8
  services:
6
9
  - mongodb
7
10
 
8
11
  rvm:
9
- - 2.3.5
10
- - 2.4.3
11
- - 2.5.4
12
- - 2.6.2
12
+ - 2.4.9
13
+ - 2.5.7
14
+ - 2.6.5
15
+ - 2.7.0
13
16
  - ruby-head
14
17
 
15
18
  matrix:
16
19
  allow_failures:
17
20
  - rvm: ruby-head
21
+
22
+ before_script:
23
+ - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
24
+ - chmod +x ./cc-test-reporter
25
+ - ./cc-test-reporter before-build
26
+
27
+ after_script:
28
+ - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
@@ -1,5 +1,22 @@
1
1
  # Draper Changelog
2
2
 
3
+ ## 4.0.0 - 2020-02-05
4
+
5
+ ### Breaking Changes
6
+ * Drop support for Ruby < 2.4 [#852](https://github.com/drapergem/draper/pull/852), [#872](https://github.com/drapergem/draper/pull/872)
7
+ * Don't delegate public methods overridden by a private method in the decorator [#849](https://github.com/drapergem/draper/pull/849)
8
+
9
+ ### Fixes
10
+ * Add preservation of decorator options on QueryMethods [#868](https://github.com/drapergem/draper/pull/868)
11
+ * Add `#respond_to_missing?` to `CollectionDecorator` so it correctly responds to ORM methods [#850](https://github.com/drapergem/draper/pull/850)
12
+ * Fix deprecation warning with the new Rails 6 `ActionView::Base` constructor [#866](https://github.com/drapergem/draper/pull/866)
13
+ * Fix deprecation warning with Ruby 2.7 [#870](https://github.com/drapergem/draper/pull/870)
14
+
15
+ ### Other Changes
16
+ * Add SimpleCov for code coverage analysis [#851](https://github.com/drapergem/draper/pull/851)
17
+ * Update RSpec syntax in the README [#855](https://github.com/drapergem/draper/pull/855)
18
+ * Update continuous integration configuration [#861](https://github.com/drapergem/draper/pull/861), [#862](https://github.com/drapergem/draper/pull/862), [#863](https://github.com/drapergem/draper/pull/863), [#872](https://github.com/drapergem/draper/pull/872)
19
+
3
20
  ## 3.1.0
4
21
  * Rails 6 support [#841](https://github.com/drapergem/draper/pull/841)
5
22
  * Include ORM query methods in `CollectionDecorator` (e.g. `includes`) [#845](https://github.com/drapergem/draper/pull/845)
data/Gemfile CHANGED
@@ -3,7 +3,11 @@ source "https://rubygems.org"
3
3
  gemspec
4
4
 
5
5
  platforms :ruby do
6
- gem 'sqlite3', '~> 1.3.6'
6
+ if RUBY_VERSION >= "2.5.0"
7
+ gem 'sqlite3'
8
+ else
9
+ gem 'sqlite3', '~> 1.3.6'
10
+ end
7
11
  end
8
12
 
9
13
  platforms :jruby do
@@ -11,5 +15,9 @@ platforms :jruby do
11
15
  gem "activerecord-jdbcsqlite3-adapter"
12
16
  end
13
17
 
14
- gem "rails", "~> 5.0"
18
+ if RUBY_VERSION >= "2.5.0"
19
+ gem "rails", "~> 6.0"
20
+ else
21
+ gem "rails", "~> 5.0"
22
+ end
15
23
  gem "mongoid", github: "mongodb/mongoid"
data/README.md CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  [![TravisCI Build Status](https://travis-ci.org/drapergem/draper.svg?branch=master)](http://travis-ci.org/drapergem/draper)
4
4
  [![Code Climate](https://codeclimate.com/github/drapergem/draper.svg)](https://codeclimate.com/github/drapergem/draper)
5
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/0d40c43951d516bf6985/test_coverage)](https://codeclimate.com/github/drapergem/draper/test_coverage)
5
6
  [![Inline docs](http://inch-ci.org/github/drapergem/draper.svg?branch=master)](http://inch-ci.org/github/drapergem/draper)
6
7
 
7
8
  Draper adds an object-oriented layer of presentation logic to your Rails
@@ -107,7 +108,7 @@ Decorators are the ideal place to:
107
108
 
108
109
  ## Installation
109
110
 
110
- As of version 3.0.0, Draper is only compatible with Rails 5 / Ruby 2.2 and later. Add Draper to your Gemfile.
111
+ As of version 4.0.0, Draper only officially supports Rails 5.2 / Ruby 2.4 and later. Add Draper to your Gemfile.
111
112
 
112
113
  ```ruby
113
114
  gem 'draper'
@@ -379,7 +380,7 @@ can continue to use the `@article` instance variable to manipulate the model -
379
380
  for example, `@article.comments.build` to add a new blank comment for a form.
380
381
 
381
382
  ## Configuration
382
- Draper works out the box well, but also provides a hook for you to configure its
383
+ Draper works out the box well, but also provides a hook for you to configure its
383
384
  default functionality. For example, Draper assumes you have a base `ApplicationController`.
384
385
  If your base controller is named something different (e.g. `BaseController`),
385
386
  you can tell Draper to use it by adding the following to an initializer:
@@ -468,10 +469,13 @@ end
468
469
  ```
469
470
 
470
471
  Then you can stub the specific route helper functions you need using your
471
- preferred stubbing technique (this example uses RSpec's `stub` method):
472
+ preferred stubbing technique. This examples uses Rspec currently recommended API
473
+ available in RSpec 3.6+
472
474
 
473
475
  ```ruby
474
- helpers.stub(users_path: '/users')
476
+ without_partial_double_verification do
477
+ allow(helpers).to receive(:users_path).and_return('/users')
478
+ end
475
479
  ```
476
480
 
477
481
  ### View context leakage
@@ -645,7 +649,7 @@ you can include this module manually.
645
649
 
646
650
  ### Active Job Integration
647
651
 
648
- [Active Job](http://edgeguides.rubyonrails.org/active_job_basics.html) allows you to pass ActiveRecord
652
+ [Active Job](http://edgeguides.rubyonrails.org/active_job_basics.html) allows you to pass ActiveRecord
649
653
  objects to background tasks directly and performs the necessary serialization and deserialization. In
650
654
  order to do this, arguments to a background job must implement [Global ID](https://github.com/rails/globalid).
651
655
  Decorated objects implement Global ID by delegating to the object they are decorating. This means
@@ -30,4 +30,5 @@ Gem::Specification.new do |s|
30
30
  s.add_development_dependency 'capybara'
31
31
  s.add_development_dependency 'active_model_serializers', '>= 0.10'
32
32
  s.add_development_dependency 'rubocop'
33
+ s.add_development_dependency 'simplecov'
33
34
  end
@@ -20,6 +20,8 @@ module Draper
20
20
 
21
21
  # @private
22
22
  def delegatable?(method)
23
+ return if private_methods.include?(method)
24
+
23
25
  object.respond_to?(method)
24
26
  end
25
27
 
@@ -35,7 +35,7 @@ module Draper
35
35
  end
36
36
 
37
37
  class << self
38
- alias_method :decorate, :new
38
+ alias :decorate :new
39
39
  end
40
40
 
41
41
  # @return [Array] the decorated items.
@@ -59,11 +59,12 @@ module Draper
59
59
  true
60
60
  end
61
61
 
62
- alias_method :decorated_with?, :instance_of?
62
+ alias :decorated_with? :instance_of?
63
63
 
64
64
  def kind_of?(klass)
65
65
  decorated_collection.kind_of?(klass) || super
66
66
  end
67
+
67
68
  alias_method :is_a?, :kind_of?
68
69
 
69
70
  def replace(other)
@@ -14,9 +14,9 @@ module Draper
14
14
  extend ActiveSupport::Concern
15
15
 
16
16
  included do
17
- alias :previous_render_to_body :render_to_body
17
+ alias_method :previous_render_to_body, :render_to_body
18
18
  include ActionView::Rendering
19
- alias :render_to_body :previous_render_to_body
19
+ alias_method :render_to_body, :previous_render_to_body
20
20
  end
21
21
  end
22
22
  end
@@ -12,7 +12,8 @@ module Draper
12
12
 
13
13
  # @return the object being decorated.
14
14
  attr_reader :object
15
- alias_method :model, :object
15
+
16
+ alias :model :object
16
17
 
17
18
  # @return [Hash] extra data to be used in user-defined methods.
18
19
  attr_accessor :context
@@ -36,7 +37,7 @@ module Draper
36
37
  end
37
38
 
38
39
  class << self
39
- alias_method :decorate, :new
40
+ alias :decorate :new
40
41
  end
41
42
 
42
43
  # Automatically delegates instance methods to the source object. Class
@@ -190,7 +191,8 @@ module Draper
190
191
  def kind_of?(klass)
191
192
  super || object.kind_of?(klass)
192
193
  end
193
- alias_method :is_a?, :kind_of?
194
+
195
+ alias :is_a? :kind_of?
194
196
 
195
197
  # Checks if `self.instance_of?(klass)` or `object.instance_of?(klass)`
196
198
  #
@@ -225,7 +227,7 @@ module Draper
225
227
  # @return [Class] the class created by {decorate_collection}.
226
228
  def self.collection_decorator_class
227
229
  name = collection_decorator_name
228
- name_constant = name && name.safe_constantize
230
+ name_constant = name&.safe_constantize
229
231
 
230
232
  name_constant || Draper::CollectionDecorator
231
233
  end
@@ -248,7 +250,7 @@ module Draper
248
250
 
249
251
  def self.inferred_object_class
250
252
  name = object_class_name
251
- name_constant = name && name.safe_constantize
253
+ name_constant = name&.safe_constantize
252
254
  return name_constant unless name_constant.nil?
253
255
 
254
256
  raise Draper::UninferrableObjectError.new(self)
@@ -256,7 +258,7 @@ module Draper
256
258
 
257
259
  def self.collection_decorator_name
258
260
  singular = object_class_name
259
- plural = singular && singular.pluralize
261
+ plural = singular&.pluralize
260
262
 
261
263
  "#{plural}Decorator" unless plural == singular
262
264
  end
@@ -7,7 +7,7 @@ module Draper
7
7
  # @return [void]
8
8
  def delegate(*methods)
9
9
  options = methods.extract_options!
10
- super *methods, options.reverse_merge(to: :object)
10
+ super(*methods, **options.reverse_merge(to: :object))
11
11
  end
12
12
  end
13
13
  end
@@ -6,7 +6,11 @@ module Draper
6
6
  def method_missing(method, *args, &block)
7
7
  return super unless strategy.allowed? method
8
8
 
9
- object.send(method, *args, &block).decorate
9
+ object.send(method, *args, &block).decorate(with: decorator_class, context: context)
10
+ end
11
+
12
+ def respond_to_missing?(method, include_private = false)
13
+ strategy.allowed?(method) || super
10
14
  end
11
15
 
12
16
  private
@@ -21,7 +21,7 @@ module Draper
21
21
  end
22
22
 
23
23
  include Draper::ViewHelpers::ClassMethods
24
- alias_method :helper, :helpers
24
+ alias :helper :helpers
25
25
  end
26
26
 
27
27
  include Behavior
@@ -1,3 +1,3 @@
1
1
  module Draper
2
- VERSION = '3.1.0'
2
+ VERSION = '4.0.0'
3
3
  end
@@ -12,7 +12,7 @@ module Draper
12
12
  end
13
13
 
14
14
  def call
15
- view_context_class.new
15
+ view_context_class.respond_to?(:empty) ? view_context_class.empty : view_context_class.new
16
16
  end
17
17
 
18
18
  private
@@ -12,7 +12,8 @@ module Draper
12
12
  def helpers
13
13
  Draper::ViewContext.current
14
14
  end
15
- alias_method :h, :helpers
15
+
16
+ alias :h :helpers
16
17
  end
17
18
 
18
19
  # Access the helpers proxy to call built-in and user-defined
@@ -22,13 +23,15 @@ module Draper
22
23
  def helpers
23
24
  Draper::ViewContext.current
24
25
  end
25
- alias_method :h, :helpers
26
+
27
+ alias :h :helpers
26
28
 
27
29
  # Alias for `helpers.localize`, since localize is something that's used
28
30
  # quite often. Further aliased to `l` for convenience.
29
31
  def localize(*args)
30
32
  helpers.localize(*args)
31
33
  end
32
- alias_method :l, :localize
34
+
35
+ alias :l :localize
33
36
  end
34
37
  end
@@ -664,6 +664,26 @@ module Draper
664
664
  expect{decorator.hello_world}.to raise_error NoMethodError
665
665
  expect(decorator.methods).not_to include :hello_world
666
666
  end
667
+
668
+ context 'when decorator overrides a public method defined on the object with a private' do
669
+ let(:decorator_class) do
670
+ Class.new(Decorator) do
671
+ private
672
+
673
+ def hello_world
674
+ 'hello world'
675
+ end
676
+ end
677
+ end
678
+
679
+ let(:object) { Class.new { def hello_world; end }.new }
680
+
681
+ it 'does not delegate the public method defined on the object' do
682
+ decorator = decorator_class.new(object)
683
+
684
+ expect{ decorator.hello_world }.to raise_error NoMethodError
685
+ end
686
+ end
667
687
  end
668
688
 
669
689
  context ".method_missing" do
@@ -1,5 +1,6 @@
1
1
  require 'spec_helper'
2
2
  require 'support/shared_examples/view_helpers'
3
+ SimpleCov.command_name 'test:unit'
3
4
 
4
5
  module Draper
5
6
  describe Draper do
@@ -5,12 +5,14 @@ Post = Struct.new(:id) { }
5
5
 
6
6
  module Draper
7
7
  describe QueryMethods do
8
+ let(:fake_strategy) { instance_double(QueryMethods::LoadStrategy::ActiveRecord) }
9
+
10
+ before { allow(QueryMethods::LoadStrategy).to receive(:new).and_return(fake_strategy) }
11
+
8
12
  describe '#method_missing' do
9
13
  let(:collection) { [ Post.new, Post.new ] }
10
- let(:collection_decorator) { PostDecorator.decorate_collection(collection) }
11
- let(:fake_strategy) { instance_double(QueryMethods::LoadStrategy::ActiveRecord) }
12
-
13
- before { allow(QueryMethods::LoadStrategy).to receive(:new).and_return(fake_strategy) }
14
+ let(:collection_context) { { user: 'foo' } }
15
+ let(:collection_decorator) { PostDecorator.decorate_collection(collection, context: collection_context) }
14
16
 
15
17
  context 'when strategy allows collection to call the method' do
16
18
  let(:results) { spy(:results) }
@@ -25,6 +27,12 @@ module Draper
25
27
 
26
28
  expect(results).to have_received(:decorate)
27
29
  end
30
+
31
+ it 'calls the method on the collection and keeps the decoration options' do
32
+ collection_decorator.some_query_method
33
+
34
+ expect(results).to have_received(:decorate).with({ context: collection_context, with: PostDecorator })
35
+ end
28
36
  end
29
37
 
30
38
  context 'when strategy does not allow collection to call the method' do
@@ -35,5 +43,28 @@ module Draper
35
43
  end
36
44
  end
37
45
  end
46
+
47
+ describe "#respond_to?" do
48
+ let(:collection) { [ Post.new, Post.new ] }
49
+ let(:collection_decorator) { PostDecorator.decorate_collection(collection) }
50
+
51
+ subject { collection_decorator.respond_to?(:some_query_method) }
52
+
53
+ context 'when strategy allows collection to call the method' do
54
+ before do
55
+ allow(fake_strategy).to receive(:allowed?).with(:some_query_method).and_return(true)
56
+ end
57
+
58
+ it { is_expected.to eq(true) }
59
+ end
60
+
61
+ context 'when strategy does not allow collection to call the method' do
62
+ before do
63
+ allow(fake_strategy).to receive(:allowed?).with(:some_query_method).and_return(false)
64
+ end
65
+
66
+ it { is_expected.to eq(false) }
67
+ end
68
+ end
38
69
  end
39
70
  end
@@ -0,0 +1,3 @@
1
+ //= link_tree ../images
2
+ //= link_directory ../javascripts .js
3
+ //= link_directory ../stylesheets .css
@@ -0,0 +1,2 @@
1
+ class ApplicationController < ActionController::Base
2
+ end
@@ -3,6 +3,7 @@ require 'dummy/config/environment'
3
3
  require 'ammeter/init'
4
4
  require 'generators/controller_override'
5
5
  require 'generators/rails/decorator_generator'
6
+ SimpleCov.command_name 'test:generator'
6
7
 
7
8
  describe Rails::Generators::ControllerGenerator do
8
9
  destination File.expand_path("../tmp", __FILE__)
@@ -1,6 +1,7 @@
1
1
  require 'spec_helper'
2
2
  require 'support/dummy_app'
3
3
  require 'support/matchers/have_text'
4
+ SimpleCov.command_name 'test:integration'
4
5
 
5
6
  app = DummyApp.new(ENV["RAILS_ENV"])
6
7
  spec_types = {
@@ -1,3 +1,10 @@
1
+ require 'simplecov'
2
+ SimpleCov.start do
3
+ add_filter 'spec'
4
+ add_group 'Draper', 'lib/draper'
5
+ add_group 'Generators', 'lib/generators'
6
+ end
7
+
1
8
  require 'bundler/setup'
2
9
  require 'draper'
3
10
  require 'action_controller'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: draper
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Casimir
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2019-03-14 00:00:00.000000000 Z
12
+ date: 2020-02-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -179,6 +179,20 @@ dependencies:
179
179
  - - ">="
180
180
  - !ruby/object:Gem::Version
181
181
  version: '0'
182
+ - !ruby/object:Gem::Dependency
183
+ name: simplecov
184
+ requirement: !ruby/object:Gem::Requirement
185
+ requirements:
186
+ - - ">="
187
+ - !ruby/object:Gem::Version
188
+ version: '0'
189
+ type: :development
190
+ prerelease: false
191
+ version_requirements: !ruby/object:Gem::Requirement
192
+ requirements:
193
+ - - ">="
194
+ - !ruby/object:Gem::Version
195
+ version: '0'
182
196
  description: Draper adds an object-oriented layer of presentation logic to your Rails
183
197
  apps.
184
198
  email:
@@ -266,6 +280,8 @@ files:
266
280
  - spec/draper/view_helpers_spec.rb
267
281
  - spec/dummy/.rspec
268
282
  - spec/dummy/Rakefile
283
+ - spec/dummy/app/assets/config/manifest.js
284
+ - spec/dummy/app/controllers/application_controller.rb
269
285
  - spec/dummy/app/controllers/base_controller.rb
270
286
  - spec/dummy/app/controllers/localized_urls.rb
271
287
  - spec/dummy/app/controllers/posts_controller.rb
@@ -394,6 +410,8 @@ test_files:
394
410
  - spec/draper/view_helpers_spec.rb
395
411
  - spec/dummy/.rspec
396
412
  - spec/dummy/Rakefile
413
+ - spec/dummy/app/assets/config/manifest.js
414
+ - spec/dummy/app/controllers/application_controller.rb
397
415
  - spec/dummy/app/controllers/base_controller.rb
398
416
  - spec/dummy/app/controllers/localized_urls.rb
399
417
  - spec/dummy/app/controllers/posts_controller.rb