WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit e8421b7

Browse files
authored
Merge pull request #953 from drapergem/release-4.0.6
Release v4.0.6
2 parents 0fc2821 + 4c3a88f commit e8421b7

File tree

6 files changed

+81
-3
lines changed

6 files changed

+81
-3
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Draper Changelog
22

3+
## 4.0.6 - 2025-11-15
4+
5+
### Fixes
6+
* Revert breaking change from v4.0.5
7+
38
## 4.0.5 - 2025-11-12
49

510
### Fixes

lib/draper/collection_decorator.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ def decorated?
6161

6262
alias :decorated_with? :instance_of?
6363

64+
def kind_of?(klass)
65+
decorated_collection.kind_of?(klass) || super
66+
end
67+
68+
alias_method :is_a?, :kind_of?
69+
6470
def replace(other)
6571
decorated_collection.replace(other)
6672
self

lib/draper/decorator.rb

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def initialize(object, options = {})
3333
options.assert_valid_keys(:context)
3434
@object = object
3535
@context = options.fetch(:context, {})
36-
handle_multiple_decoration(options) if object.is_a?(Draper::Decorator)
36+
handle_multiple_decoration(options) if object.instance_of?(self.class)
3737
end
3838

3939
class << self
@@ -185,6 +185,22 @@ def hash
185185
self.class.hash ^ object.hash
186186
end
187187

188+
# Checks if `self.kind_of?(klass)` or `object.kind_of?(klass)`
189+
#
190+
# @param [Class] klass
191+
def kind_of?(klass)
192+
super || object.kind_of?(klass)
193+
end
194+
195+
alias :is_a? :kind_of?
196+
197+
# Checks if `self.instance_of?(klass)` or `object.instance_of?(klass)`
198+
#
199+
# @param [Class] klass
200+
def instance_of?(klass)
201+
super || object.instance_of?(klass)
202+
end
203+
188204
delegate :to_s
189205

190206
# In case object is nil
@@ -251,7 +267,7 @@ def handle_multiple_decoration(options)
251267
if object.applied_decorators.last == self.class
252268
@context = object.context unless options.has_key?(:context)
253269
@object = object.object
254-
elsif object.applied_decorators.include?(self.class)
270+
else
255271
warn "Reapplying #{self.class} decorator to target that is already decorated with it. Call stack:\n#{caller(1).join("\n")}"
256272
end
257273
end

lib/draper/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
module Draper
2-
VERSION = '4.0.5'
2+
VERSION = '4.0.6'
33
end

spec/draper/collection_decorator_spec.rb

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,29 @@ module Draper
249249
end
250250
end
251251

252+
describe '#kind_of?' do
253+
it 'asks the kind of its decorated collection' do
254+
decorator = ProductsDecorator.new([])
255+
expect(decorator.decorated_collection).to receive(:kind_of?).with(Array).and_return("true")
256+
expect(decorator.kind_of?(Array)).to eq "true"
257+
end
258+
259+
context 'when asking the underlying collection returns false' do
260+
it 'asks the CollectionDecorator instance itself' do
261+
decorator = ProductsDecorator.new([])
262+
allow(decorator.decorated_collection).to receive(:kind_of?).with(::Draper::CollectionDecorator).and_return(false)
263+
expect(decorator.kind_of?(::Draper::CollectionDecorator)).to be true
264+
end
265+
end
266+
end
267+
268+
describe '#is_a?' do
269+
it 'aliases to #kind_of?' do
270+
decorator = ProductsDecorator.new([])
271+
expect(decorator.method(:kind_of?)).to eq decorator.method(:is_a?)
272+
end
273+
end
274+
252275
describe "#replace" do
253276
it "replaces the decorated collection" do
254277
decorator = CollectionDecorator.new([Product.new])

spec/draper/decorator_spec.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,34 @@ def hello_world
800800
end
801801
end
802802

803+
describe "class spoofing" do
804+
it "pretends to be a kind of the object class" do
805+
decorator = Decorator.new(Model.new)
806+
807+
expect(decorator.kind_of?(Model)).to be_truthy
808+
expect(decorator.is_a?(Model)).to be_truthy
809+
end
810+
811+
it "is still a kind of its own class" do
812+
decorator = Decorator.new(Model.new)
813+
814+
expect(decorator.kind_of?(Decorator)).to be_truthy
815+
expect(decorator.is_a?(Decorator)).to be_truthy
816+
end
817+
818+
it "pretends to be an instance of the object class" do
819+
decorator = Decorator.new(Model.new)
820+
821+
expect(decorator.instance_of?(Model)).to be_truthy
822+
end
823+
824+
it "is still an instance of its own class" do
825+
decorator = Decorator.new(Model.new)
826+
827+
expect(decorator.instance_of?(Decorator)).to be_truthy
828+
end
829+
end
830+
803831
describe ".decorates_finders" do
804832
protect_class Decorator
805833

0 commit comments

Comments
 (0)