grape-entity 0.10.0 → 0.10.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7c0080bab47d3cd3667c29ef580dcca4977ba5572d95c56304dd55cc444456fc
4
- data.tar.gz: 40b564ee118de1a2a5b36dcff7526ca6bb1c54d738b7ac2191b1a208a583add1
3
+ metadata.gz: 4a89222a95fe66dc86d907762352275aa328a0423a461e2f5a7c8fc806a92f09
4
+ data.tar.gz: a06ad75430e568a7e4cd2e9b6b329011e8382003c5882f690199403be58928c7
5
5
  SHA512:
6
- metadata.gz: 06564de07c6a909a3dbd4c3839902f529c5c44291f1a0669bcbc3dca7ea1e015db71887ca9f46132ef5bf4bb01fd10fced74b09ac392f3678903d39875816b63
7
- data.tar.gz: 3e22b1382012b543d50a256e1792f9f79e3b02d49e42420353a351d49f549f021cd3dede90c576f657f0e61df862c0d8879cfb9c0a1d4578ef77a5648845ff6e
6
+ metadata.gz: 1bc3419fea51eb0c7c7c78f8f4e510c9d73bfe210cee2aa1f2aaaee92725d02334ab235818a37300c733c0970c9ee40cf56a022b421937ec6662d3e67da3e85f
7
+ data.tar.gz: 4f31cb8e01fbba21883bbf432fa557d0ca7f85d3c1d42a0aac0e4143c4add3af37e7f24b4fc315ff55502a640bffa0d185e8c3081d8a8b5492d45dc1b0102233
@@ -12,3 +12,9 @@ updates:
12
12
  day: "friday"
13
13
  assignees:
14
14
  - "LeFnord"
15
+ - package-ecosystem: "github-actions"
16
+ directory: "/"
17
+ schedule:
18
+ interval: weekly
19
+ assignees:
20
+ - "LeFnord"
@@ -0,0 +1,41 @@
1
+ name: Ruby
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - '*'
7
+ pull_request:
8
+ branches:
9
+ - '*'
10
+
11
+ permissions:
12
+ contents: read
13
+
14
+ jobs:
15
+ rubocop:
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - uses: actions/checkout@v3
19
+ - uses: ruby/setup-ruby@v1
20
+ with:
21
+ ruby-version: '3.1'
22
+ bundler-cache: true
23
+ - name: Run rubocop
24
+ run: bundle exec rubocop --parallel --format progress
25
+
26
+ rspec:
27
+ runs-on: ubuntu-latest
28
+ needs: ['rubocop']
29
+ strategy:
30
+ matrix:
31
+ ruby-version: ['2.7', '3.0', '3.1', 'head', jruby, truffleruby]
32
+ steps:
33
+ - name: Check out branch
34
+ uses: actions/checkout@v3
35
+ - name: Set up Ruby
36
+ uses: ruby/setup-ruby@v1
37
+ with:
38
+ ruby-version: ${{ matrix.ruby-version }}
39
+ bundler-cache: true
40
+ - name: Run rspec rest of the suite
41
+ run: bundle exec rspec
data/.rspec CHANGED
@@ -1,2 +1,3 @@
1
- --format documentation
2
1
  --color
2
+ --profile
3
+ --format documentation
data/.rubocop.yml CHANGED
@@ -5,7 +5,7 @@ AllCops:
5
5
  - vendor/**/*
6
6
  - example/**/*
7
7
  NewCops: enable
8
- TargetRubyVersion: 3.0
8
+ TargetRubyVersion: 3.1
9
9
  SuggestExtensions: false
10
10
 
11
11
  # Layout stuff
@@ -77,6 +77,9 @@ Naming:
77
77
  Style/Documentation:
78
78
  Enabled: false
79
79
 
80
+ Style/HashSyntax:
81
+ Enabled: false
82
+
80
83
  Style/OptionalBooleanParameter:
81
84
  AllowedMethods:
82
85
  # from lib/grape_entity/condition/base.rb
data/.rubocop_todo.yml CHANGED
@@ -1,11 +1,27 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2020-11-07 00:01:40 UTC using RuboCop version 1.2.0.
3
+ # on 2022-07-26 21:29:59 UTC using RuboCop version 1.32.0.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
+ # Offense count: 1
10
+ # This cop supports safe autocorrection (--autocorrect).
11
+ # Configuration parameters: Include.
12
+ # Include: **/*.gemspec
13
+ Gemspec/DeprecatedAttributeAssignment:
14
+ Exclude:
15
+ - 'grape-entity.gemspec'
16
+
17
+ # Offense count: 1
18
+ # This cop supports safe autocorrection (--autocorrect).
19
+ # Configuration parameters: Include.
20
+ # Include: **/*.gemspec
21
+ Gemspec/RequireMFA:
22
+ Exclude:
23
+ - 'grape-entity.gemspec'
24
+
9
25
  # Offense count: 1
10
26
  # Configuration parameters: Include.
11
27
  # Include: **/*.gemspec
@@ -14,14 +30,20 @@ Gemspec/RequiredRubyVersion:
14
30
  - 'grape-entity.gemspec'
15
31
 
16
32
  # Offense count: 6
17
- # Cop supports --auto-correct.
33
+ # This cop supports unsafe autocorrection (--autocorrect-all).
18
34
  Lint/BooleanSymbol:
19
35
  Exclude:
20
36
  - 'spec/grape_entity/exposure_spec.rb'
21
37
 
22
- # Offense count: 1
23
- # Cop supports --auto-correct.
24
- # Configuration parameters: IgnoredMethods.
38
+ # Offense count: 15
39
+ Style/OpenStructUse:
40
+ Exclude:
41
+ - 'lib/grape_entity/delegator.rb'
42
+ - 'spec/grape_entity/entity_spec.rb'
43
+
44
+ # Offense count: 2
45
+ # This cop supports unsafe autocorrection (--autocorrect-all).
46
+ # Configuration parameters: AllowMethodsWithArguments, IgnoredMethods, AllowComments.
25
47
  # IgnoredMethods: respond_to, define_method
26
48
  Style/SymbolProc:
27
49
  Exclude:
data/CHANGELOG.md CHANGED
@@ -9,6 +9,22 @@
9
9
  * Your contribution here.
10
10
 
11
11
 
12
+ ### 0.10.2 (2022-07-29)
13
+
14
+ #### Fixes
15
+
16
+ * [#366](https://github.com/ruby-grape/grape-entity/pull/366): Don't suppress regular ArgumentError exceptions - [splattael](https://github.com/splattael).
17
+ * [#363](https://github.com/ruby-grape/grape-entity/pull/338): Fix typo - [@OuYangJinTing](https://github.com/OuYangJinTing).
18
+ * [#361](https://github.com/ruby-grape/grape-entity/pull/361): Require 'active_support/core_ext' - [@pravi](https://github.com/pravi).
19
+
20
+
21
+ ### 0.10.1 (2021-10-22)
22
+
23
+ #### Fixes
24
+
25
+ * [#359](https://github.com/ruby-grape/grape-entity/pull/359): Respect `hash_access` setting when using `expose_nil: false` option - [@magni-](https://github.com/magni-).
26
+
27
+
12
28
  ### 0.10.0 (2021-09-15)
13
29
 
14
30
  #### Features
data/CONTRIBUTING.md CHANGED
@@ -78,7 +78,7 @@ git push origin my-feature-branch
78
78
 
79
79
  #### Make a Pull Request
80
80
 
81
- Go to https://github.com/contributor/grape-entity and select your feature branch. Click the 'Pull Request' button and fill out the form. Pull requests are usually reviewed within a few days.
81
+ Go to https://github.com/ruby-grape/grape-entity and select your feature branch. Click the 'Pull Request' button and fill out the form. Pull requests are usually reviewed within a few days.
82
82
 
83
83
  #### Rebase
84
84
 
data/README.md CHANGED
@@ -111,6 +111,20 @@ The field lookup takes several steps
111
111
  * next try `object.fetch(exposure)`
112
112
  * last raise an Exception
113
113
 
114
+ `exposure` is a Symbol by default. If `object` is a Hash with stringified keys, you can set the hash accessor at the entity-class level to properly expose its members:
115
+
116
+ ```ruby
117
+ class Status < GrapeEntity
118
+ self.hash_access = :to_s
119
+
120
+ expose :code
121
+ expose :message
122
+ end
123
+
124
+ Status.represent({ 'code' => 418, 'message' => "I'm a teapot" }).as_json
125
+ #=> { code: 418, message: "I'm a teapot" }
126
+ ```
127
+
114
128
  #### Exposing with a Presenter
115
129
 
116
130
  Don't derive your model classes from `Grape::Entity`, expose them using a presenter.
@@ -13,6 +13,11 @@ module Grape
13
13
  def delegatable?(_attribute)
14
14
  true
15
15
  end
16
+
17
+ def accepts_options?
18
+ # Why not `arity > 1`? It might be negative https://ruby-doc.org/core-2.6.6/Method.html#method-i-arity
19
+ method(:delegate).arity != 1
20
+ end
16
21
  end
17
22
  end
18
23
  end
@@ -11,10 +11,14 @@ module Grape
11
11
  module Delegator
12
12
  def self.new(object)
13
13
  delegator_klass =
14
- if object.is_a?(Hash) then HashObject
15
- elsif defined?(OpenStruct) && object.is_a?(OpenStruct) then OpenStructObject
16
- elsif object.respond_to?(:fetch, true) then FetchableObject
17
- else PlainObject
14
+ if object.is_a?(Hash)
15
+ HashObject
16
+ elsif defined?(OpenStruct) && object.is_a?(OpenStruct)
17
+ OpenStructObject
18
+ elsif object.respond_to?(:fetch, true)
19
+ FetchableObject
20
+ else
21
+ PlainObject
18
22
  end
19
23
 
20
24
  delegator_klass.new(object)
@@ -481,9 +481,6 @@ module Grape
481
481
  @object = object
482
482
  @options = options.is_a?(Options) ? options : Options.new(options)
483
483
  @delegator = Delegator.new(object)
484
-
485
- # Why not `arity > 1`? It might be negative https://ruby-doc.org/core-2.6.6/Method.html#method-i-arity
486
- @delegator_accepts_opts = @delegator.method(:delegate).arity != 1
487
484
  end
488
485
 
489
486
  def root_exposures
@@ -525,7 +522,10 @@ module Grape
525
522
  end
526
523
  rescue StandardError => e
527
524
  # it handles: https://github.com/ruby/ruby/blob/v3_0_0_preview1/NEWS.md#language-changes point 3, Proc
528
- raise Grape::Entity::Deprecated.new e.message, 'in ruby 3.0' if e.is_a?(ArgumentError)
525
+ # accounting for expose :foo, &:bar
526
+ if e.is_a?(ArgumentError) && block.parameters == [[:req], [:rest]]
527
+ raise Grape::Entity::Deprecated.new e.message, 'in ruby 3.0'
528
+ end
529
529
 
530
530
  raise e
531
531
  end
@@ -541,7 +541,7 @@ module Grape
541
541
  def delegate_attribute(attribute)
542
542
  if is_defined_in_entity?(attribute)
543
543
  send(attribute)
544
- elsif @delegator_accepts_opts
544
+ elsif delegator.accepts_options?
545
545
  delegator.delegate(attribute, **self.class.delegation_opts)
546
546
  else
547
547
  delegator.delegate(attribute)
@@ -1,5 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'active_support'
4
+ require 'active_support/core_ext'
5
+
3
6
  module Grape
4
7
  class Entity
5
8
  module Exposure
@@ -56,7 +56,12 @@ module Grape
56
56
  Condition.new_unless(
57
57
  proc do |object, _options|
58
58
  if options[:proc].nil?
59
- Delegator.new(object).delegate(attribute).nil?
59
+ delegator = Delegator.new(object)
60
+ if is_a?(Grape::Entity) && delegator.accepts_options?
61
+ delegator.delegate(attribute, **self.class.delegation_opts).nil?
62
+ else
63
+ delegator.delegate(attribute).nil?
64
+ end
60
65
  else
61
66
  exec_with_object(options, &options[:proc]).nil?
62
67
  end
@@ -9,7 +9,7 @@ module Grape
9
9
 
10
10
  attr_reader :opts_hash
11
11
 
12
- def_delegators :opts_hash, :dig, :key?, :fetch, :[], :empty
12
+ def_delegators :opts_hash, :dig, :key?, :fetch, :[], :empty?
13
13
 
14
14
  def initialize(opts_hash = {})
15
15
  @opts_hash = opts_hash
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GrapeEntity
4
- VERSION = '0.10.0'
4
+ VERSION = '0.10.2'
5
5
  end
@@ -389,6 +389,10 @@ describe Grape::Entity do
389
389
  def method_without_args
390
390
  'result'
391
391
  end
392
+
393
+ def raises_argument_error
394
+ raise ArgumentError, 'something different'
395
+ end
392
396
  end
393
397
 
394
398
  describe 'with block passed in' do
@@ -402,6 +406,17 @@ describe Grape::Entity do
402
406
  value = subject.represent(object).value_for(:that_method_without_args)
403
407
  expect(value).to eq('result')
404
408
  end
409
+
410
+ it 'does not suppress ArgumentError' do
411
+ subject.expose :raises_argument_error do |object|
412
+ object.raises_argument_error
413
+ end
414
+
415
+ object = SomeObject.new
416
+ expect do
417
+ subject.represent(object).value_for(:raises_argument_error)
418
+ end.to raise_error(ArgumentError, 'something different')
419
+ end
405
420
  end
406
421
 
407
422
  context 'with block passed in via &' do
@@ -17,7 +17,7 @@ describe Grape::Entity do
17
17
  expose :post, if: :full
18
18
  expose :city
19
19
  expose :street
20
- expose :house
20
+ expose :house, expose_nil: false
21
21
  end
22
22
 
23
23
  class Company < Grape::Entity
@@ -62,9 +62,23 @@ describe Grape::Entity do
62
62
  }
63
63
  }
64
64
 
65
+ company_without_house_with_string = {
66
+ 'full_name' => 'full_name',
67
+ 'name' => 'name',
68
+ 'address' => {
69
+ 'post' => '123456',
70
+ 'city' => 'city',
71
+ 'street' => 'street',
72
+ 'something_else' => 'something_else'
73
+ }
74
+ }
75
+
65
76
  expect(EntitySpec::CompanyWithString.represent(company_with_string).serializable_hash).to eq \
66
77
  company.slice(:name).merge(address: company[:address].slice(:city, :street, :house))
67
78
 
79
+ expect(EntitySpec::CompanyWithString.represent(company_without_house_with_string).serializable_hash).to eq \
80
+ company.slice(:name).merge(address: company[:address].slice(:city, :street))
81
+
68
82
  expect(EntitySpec::CompanyWithString.represent(company_with_string, full: true).serializable_hash).to eq \
69
83
  company.slice(:full_name, :name).merge(address: company[:address].slice(:city, :street, :house))
70
84
 
data/spec/spec_helper.rb CHANGED
@@ -9,12 +9,16 @@ require 'active_support/core_ext/hash' if ActiveSupport::VERSION &&
9
9
  ActiveSupport::VERSION::MAJOR &&
10
10
  ActiveSupport::VERSION::MAJOR < 4
11
11
 
12
- SimpleCov.start do
13
- add_filter 'spec/'
12
+ # Skip code covarge on Ruby >= 3.1
13
+ # See https://github.com/simplecov-ruby/simplecov/issues/1003
14
+ unless RUBY_VERSION >= '3.1'
15
+ SimpleCov.start do
16
+ add_filter 'spec/'
17
+ end
18
+
19
+ Coveralls.wear! unless RUBY_PLATFORM.eql? 'java'
14
20
  end
15
21
 
16
- Coveralls.wear! unless RUBY_PLATFORM.eql? 'java'
17
-
18
22
  $LOAD_PATH.unshift(File.dirname(__FILE__))
19
23
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
20
24
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'support'))
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grape-entity
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.10.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Bleigh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-15 00:00:00.000000000 Z
11
+ date: 2022-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -160,8 +160,7 @@ extra_rdoc_files: []
160
160
  files:
161
161
  - ".coveralls.yml"
162
162
  - ".github/dependabot.yml"
163
- - ".github/workflows/rubocop.yml"
164
- - ".github/workflows/ruby.yml"
163
+ - ".github/workflows/ci.yml"
165
164
  - ".gitignore"
166
165
  - ".rspec"
167
166
  - ".rubocop.yml"
@@ -232,7 +231,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
232
231
  - !ruby/object:Gem::Version
233
232
  version: '0'
234
233
  requirements: []
235
- rubygems_version: 3.2.22
234
+ rubygems_version: 3.3.7
236
235
  signing_key:
237
236
  specification_version: 4
238
237
  summary: A simple facade for managing the relationship between your model and API.
@@ -1,26 +0,0 @@
1
- name: Rubocop
2
-
3
- on:
4
- push:
5
- branches:
6
- - '*'
7
- pull_request:
8
- branches:
9
- - '*'
10
-
11
- jobs:
12
- rubocop:
13
- name: Rubocop
14
- runs-on: ubuntu-latest
15
- steps:
16
- - uses: actions/checkout@v2
17
- - uses: actions/setup-ruby@v1
18
- with:
19
- ruby-version: '3.0'
20
- - run: gem install rubocop --no-doc
21
- - run: rubocop --format progress --format json --out rubocop.json
22
- id: rubocop
23
- - uses: duderman/rubocop-annotate-action@v0.1.0
24
- with:
25
- path: rubocop.json
26
- if: ${{ failure() }}
@@ -1,26 +0,0 @@
1
- name: Ruby
2
-
3
- on:
4
- push:
5
- branches:
6
- - '*'
7
- pull_request:
8
- branches:
9
- - '*'
10
-
11
- jobs:
12
- spec:
13
- runs-on: ubuntu-latest
14
- strategy:
15
- matrix:
16
- ruby-version: ['2.6', '2.7', '3.0', head, jruby, truffleruby]
17
-
18
- steps:
19
- - uses: actions/checkout@v2
20
- - name: Set up Ruby
21
- uses: ruby/setup-ruby@v1
22
- with:
23
- ruby-version: ${{ matrix.ruby-version }}
24
- bundler-cache: true
25
- - name: Run rspec
26
- run: bundle exec rspec