Skip to content

Commit 28eebab

Browse files
authored
Merge pull request #394 from ruby-grape/fix/grape-3.2-coercion-compat
Add Entity.[] for Grape >= 3.2 param type compatibility
2 parents 99c2ffe + 8ba13a7 commit 28eebab

4 files changed

Lines changed: 44 additions & 16 deletions

File tree

.rubocop_todo.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ Gemspec/RequiredRubyVersion:
2929
Exclude:
3030
- 'grape-entity.gemspec'
3131

32+
# Offense count: 1
33+
Style/OneClassPerFile:
34+
Exclude:
35+
- 'bench/serializing.rb'
36+
3237
# Offense count: 6
3338
# This cop supports unsafe autocorrection (--autocorrect-all).
3439
Lint/BooleanSymbol:

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#### Fixes
88

9+
* [#394](https://github.com/ruby-grape/grape-entity/pull/394): Add `Entity.[]` for Grape >= 3.2 param type compatibility - [@numbata](https://github.com/numbata).
910
* [#388](https://github.com/ruby-grape/grape-entity/pull/388): Drop ruby-head from test matrix - [@numbata](https://github.com/numbata).
1011
* [#384](https://github.com/ruby-grape/grape-entity/pull/384): Fix `inspect` to correctly handle `nil` values - [@fcce](https://github.com/fcce).
1112
* Your contribution here.

lib/grape_entity/entity.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,12 @@ def hash_access=(value)
129129
def delegation_opts
130130
@delegation_opts ||= { hash_access: hash_access }
131131
end
132+
133+
# Satisfies the respond_to?(:[]) check in Grape::DryTypes (>= 3.2)
134+
# so Entity subclasses can be used as param types.
135+
def [](val)
136+
val
137+
end
132138
end
133139

134140
@formatters = {}

spec/grape_entity/entity_spec.rb

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,6 +1010,22 @@ class Parent < Person
10101010
end
10111011
end
10121012

1013+
describe '.[]' do
1014+
it 'returns the input unchanged' do
1015+
hash = { name: 'Test' }
1016+
expect(subject[hash]).to eq(hash)
1017+
end
1018+
1019+
it 'returns nil unchanged' do
1020+
expect(subject[nil]).to be_nil
1021+
end
1022+
1023+
it 'is inherited by subclasses' do
1024+
subclass = Class.new(subject)
1025+
expect(subclass[{ id: 1 }]).to eq(id: 1)
1026+
end
1027+
end
1028+
10131029
describe '.represent' do
10141030
it 'returns a single entity if called with one object' do
10151031
expect(subject.represent(Object.new)).to be_kind_of(subject)
@@ -1023,7 +1039,7 @@ class Parent < Person
10231039
representation = subject.represent(Array.new(4) { Object.new })
10241040
expect(representation).to be_kind_of Array
10251041
expect(representation.size).to eq(4)
1026-
expect(representation.reject { |r| r.is_a?(subject) }).to be_empty
1042+
expect(representation.grep_v(subject)).to be_empty
10271043
end
10281044

10291045
it 'adds the collection: true option if called with a collection' do
@@ -1369,7 +1385,7 @@ class Parent < Person
13691385
expect(representation).to have_key 'things'
13701386
expect(representation['things']).to be_kind_of Array
13711387
expect(representation['things'].size).to eq 4
1372-
expect(representation['things'].reject { |r| r.is_a?(subject) }).to be_empty
1388+
expect(representation['things'].grep_v(subject)).to be_empty
13731389
end
13741390
end
13751391

@@ -1378,15 +1394,15 @@ class Parent < Person
13781394
representation = subject.represent(Array.new(4) { Object.new }, root: false)
13791395
expect(representation).to be_kind_of Array
13801396
expect(representation.size).to eq 4
1381-
expect(representation.reject { |r| r.is_a?(subject) }).to be_empty
1397+
expect(representation.grep_v(subject)).to be_empty
13821398
end
13831399
it 'can use a different name' do
13841400
representation = subject.represent(Array.new(4) { Object.new }, root: 'others')
13851401
expect(representation).to be_kind_of Hash
13861402
expect(representation).to have_key 'others'
13871403
expect(representation['others']).to be_kind_of Array
13881404
expect(representation['others'].size).to eq 4
1389-
expect(representation['others'].reject { |r| r.is_a?(subject) }).to be_empty
1405+
expect(representation['others'].grep_v(subject)).to be_empty
13901406
end
13911407
end
13921408
end
@@ -1410,7 +1426,7 @@ class Parent < Person
14101426
representation = subject.represent(Array.new(4) { Object.new })
14111427
expect(representation).to be_kind_of Array
14121428
expect(representation.size).to eq 4
1413-
expect(representation.reject { |r| r.is_a?(subject) }).to be_empty
1429+
expect(representation.grep_v(subject)).to be_empty
14141430
end
14151431
end
14161432
end
@@ -1433,7 +1449,7 @@ class Parent < Person
14331449
expect(representation).to have_key('things')
14341450
expect(representation['things']).to be_kind_of Array
14351451
expect(representation['things'].size).to eq 4
1436-
expect(representation['things'].reject { |r| r.is_a?(subject) }).to be_empty
1452+
expect(representation['things'].grep_v(subject)).to be_empty
14371453
end
14381454
end
14391455
end
@@ -1458,7 +1474,7 @@ class Parent < Person
14581474
expect(representation).to have_key('things')
14591475
expect(representation['things']).to be_kind_of Array
14601476
expect(representation['things'].size).to eq 4
1461-
expect(representation['things'].reject { |r| r.is_a?(child_class) }).to be_empty
1477+
expect(representation['things'].grep_v(child_class)).to be_empty
14621478
end
14631479
end
14641480
end
@@ -1839,7 +1855,7 @@ def timestamp(date)
18391855

18401856
it 'instantiates a representation if that is called for' do
18411857
rep = subject.value_for(:friends)
1842-
expect(rep.reject { |r| r.is_a?(fresh_class) }).to be_empty
1858+
expect(rep.grep_v(fresh_class)).to be_empty
18431859
expect(rep.first.serializable_hash[:name]).to eq 'Friend 1'
18441860
expect(rep.last.serializable_hash[:name]).to eq 'Friend 2'
18451861
end
@@ -1861,7 +1877,7 @@ class FriendEntity < Grape::Entity
18611877

18621878
rep = subject.value_for(:friends)
18631879
expect(rep).to be_kind_of Array
1864-
expect(rep.reject { |r| r.is_a?(EntitySpec::FriendEntity) }).to be_empty
1880+
expect(rep.grep_v(EntitySpec::FriendEntity)).to be_empty
18651881
expect(rep.first.serializable_hash[:name]).to eq 'Friend 1'
18661882
expect(rep.last.serializable_hash[:name]).to eq 'Friend 2'
18671883
end
@@ -1882,7 +1898,7 @@ class FriendEntity < Grape::Entity
18821898

18831899
rep = subject.value_for(:custom_friends)
18841900
expect(rep).to be_kind_of Array
1885-
expect(rep.reject { |r| r.is_a?(EntitySpec::FriendEntity) }).to be_empty
1901+
expect(rep.grep_v(EntitySpec::FriendEntity)).to be_empty
18861902
expect(rep.first.serializable_hash).to eq(name: 'Friend 1', email: 'friend1@example.com')
18871903
expect(rep.last.serializable_hash).to eq(name: 'Friend 2', email: 'friend2@example.com')
18881904
end
@@ -1940,7 +1956,7 @@ class CharacteristicsEntity < Grape::Entity
19401956

19411957
rep = subject.value_for(:characteristics)
19421958
expect(rep).to be_kind_of Array
1943-
expect(rep.reject { |r| r.is_a?(EntitySpec::CharacteristicsEntity) }).to be_empty
1959+
expect(rep.grep_v(EntitySpec::CharacteristicsEntity)).to be_empty
19441960
expect(rep.first.serializable_hash[:key]).to eq 'hair_color'
19451961
expect(rep.first.serializable_hash[:value]).to eq 'brown'
19461962
end
@@ -1960,13 +1976,13 @@ class FriendEntity < Grape::Entity
19601976

19611977
rep = subject.value_for(:friends)
19621978
expect(rep).to be_kind_of Array
1963-
expect(rep.reject { |r| r.is_a?(EntitySpec::FriendEntity) }).to be_empty
1979+
expect(rep.grep_v(EntitySpec::FriendEntity)).to be_empty
19641980
expect(rep.first.serializable_hash[:email]).to be_nil
19651981
expect(rep.last.serializable_hash[:email]).to be_nil
19661982

19671983
rep = subject.value_for(:friends, Grape::Entity::Options.new(user_type: :admin))
19681984
expect(rep).to be_kind_of Array
1969-
expect(rep.reject { |r| r.is_a?(EntitySpec::FriendEntity) }).to be_empty
1985+
expect(rep.grep_v(EntitySpec::FriendEntity)).to be_empty
19701986
expect(rep.first.serializable_hash[:email]).to eq 'friend1@example.com'
19711987
expect(rep.last.serializable_hash[:email]).to eq 'friend2@example.com'
19721988
end
@@ -1986,7 +2002,7 @@ class FriendEntity < Grape::Entity
19862002

19872003
rep = subject.value_for(:friends, Grape::Entity::Options.new(collection: false))
19882004
expect(rep).to be_kind_of Array
1989-
expect(rep.reject { |r| r.is_a?(EntitySpec::FriendEntity) }).to be_empty
2005+
expect(rep.grep_v(EntitySpec::FriendEntity)).to be_empty
19902006
expect(rep.first.serializable_hash[:email]).to eq 'friend1@example.com'
19912007
expect(rep.last.serializable_hash[:email]).to eq 'friend2@example.com'
19922008
end
@@ -2065,7 +2081,7 @@ class UserEntity < Grape::Entity
20652081
rep = subject.value_for(:friends)
20662082
expect(rep).to be_kind_of Array
20672083
expect(rep.size).to eq 2
2068-
expect(rep.all? { |r| r.is_a?(EntitySpec::UserEntity) }).to be true
2084+
expect(rep.all?(EntitySpec::UserEntity)).to be true
20692085
end
20702086

20712087
it 'class' do
@@ -2076,7 +2092,7 @@ class UserEntity < Grape::Entity
20762092
rep = subject.value_for(:friends)
20772093
expect(rep).to be_kind_of Array
20782094
expect(rep.size).to eq 2
2079-
expect(rep.all? { |r| r.is_a?(EntitySpec::UserEntity) }).to be true
2095+
expect(rep.all?(EntitySpec::UserEntity)).to be true
20802096
end
20812097
end
20822098
end

0 commit comments

Comments
 (0)