grape-entity 0.7.1 → 0.8.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 +4 -4
- data/.rubocop.yml +34 -23
- data/.rubocop_todo.yml +12 -36
- data/.travis.yml +7 -12
- data/CHANGELOG.md +16 -1
- data/Gemfile +2 -2
- data/Guardfile +4 -2
- data/README.md +4 -4
- data/grape-entity.gemspec +4 -6
- data/lib/grape_entity/delegator/fetchable_object.rb +1 -1
- data/lib/grape_entity/delegator/hash_object.rb +2 -2
- data/lib/grape_entity/delegator/openstruct_object.rb +1 -1
- data/lib/grape_entity/delegator/plain_object.rb +1 -1
- data/lib/grape_entity/entity.rb +53 -8
- data/lib/grape_entity/exposure.rb +9 -3
- data/lib/grape_entity/exposure/base.rb +4 -1
- data/lib/grape_entity/exposure/nesting_exposure.rb +1 -0
- data/lib/grape_entity/exposure/nesting_exposure/nested_exposures.rb +1 -1
- data/lib/grape_entity/exposure/nesting_exposure/output_builder.rb +1 -0
- data/lib/grape_entity/version.rb +1 -1
- data/spec/grape_entity/entity_spec.rb +32 -0
- data/spec/grape_entity/exposure/represent_exposure_spec.rb +3 -3
- data/spec/grape_entity/hash_spec.rb +36 -1
- data/spec/spec_helper.rb +6 -0
- metadata +8 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 619c4d253ef6fbfde4f5c3bff0a0a309a67ef6ce49d408de9f3912bf12c4f690
|
|
4
|
+
data.tar.gz: e4c3f773ba0b6c1751abdbc0642e730c325be409b6d0d55dae1c1b2ce075b7e2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8937886f91fe82d37eb9a8eca7b6d4542b8dcb12b8ea241d8b08c4116305e351c3acc980722fe60dead828140c6c56425763854287b6e0736134e994da2b1f5e
|
|
7
|
+
data.tar.gz: 3073993606e0f950e39ed8417bbc33aaff7d21544bbdb3797b3e0325ee01c0c8f71c9a63295630af21006698fae585b0bd1a5139dd6241221e2aac07442f1ac6
|
data/.rubocop.yml
CHANGED
|
@@ -1,37 +1,48 @@
|
|
|
1
|
-
|
|
2
|
-
TargetRubyVersion: 2.4
|
|
3
|
-
Include:
|
|
4
|
-
- Dangerfile
|
|
1
|
+
inherit_from: .rubocop_todo.yml
|
|
5
2
|
|
|
3
|
+
AllCops:
|
|
6
4
|
Exclude:
|
|
7
5
|
- vendor/**/*
|
|
8
|
-
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
inherit_from: .rubocop_todo.yml
|
|
6
|
+
- example/**/*
|
|
7
|
+
TargetRubyVersion: 2.7
|
|
12
8
|
|
|
13
|
-
|
|
9
|
+
Layout/EmptyLinesAroundArguments:
|
|
14
10
|
Enabled: false
|
|
15
11
|
|
|
16
|
-
|
|
12
|
+
Layout/FirstHashElementIndentation:
|
|
13
|
+
EnforcedStyle: consistent
|
|
14
|
+
|
|
15
|
+
Layout/LineLength:
|
|
16
|
+
Max: 120
|
|
17
17
|
Exclude:
|
|
18
|
-
-
|
|
19
|
-
- 'Rakefile'
|
|
20
|
-
- 'grape-entity.gemspec'
|
|
21
|
-
- 'lib/grape-entity.rb'
|
|
18
|
+
- spec/**/*
|
|
22
19
|
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
Metrics/AbcSize:
|
|
21
|
+
Max: 25
|
|
25
22
|
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
Metrics/BlockLength:
|
|
24
|
+
Exclude:
|
|
25
|
+
- spec/**/*
|
|
28
26
|
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
Metrics/CyclomaticComplexity:
|
|
28
|
+
Max: 10
|
|
29
|
+
|
|
30
|
+
Metrics/ClassLength:
|
|
31
|
+
Max: 300
|
|
31
32
|
|
|
32
|
-
|
|
33
|
+
Metrics/MethodLength:
|
|
34
|
+
Max: 26
|
|
33
35
|
Exclude:
|
|
34
|
-
-
|
|
36
|
+
- spec/**/*
|
|
37
|
+
|
|
38
|
+
Metrics/PerceivedComplexity:
|
|
39
|
+
Max: 11
|
|
40
|
+
|
|
41
|
+
Naming:
|
|
42
|
+
Enabled: false
|
|
43
|
+
|
|
44
|
+
Style/Documentation:
|
|
45
|
+
Enabled: false
|
|
35
46
|
|
|
36
|
-
|
|
47
|
+
Style/RegexpLiteral:
|
|
37
48
|
Enabled: false
|
data/.rubocop_todo.yml
CHANGED
|
@@ -1,47 +1,29 @@
|
|
|
1
1
|
# This configuration was generated by
|
|
2
2
|
# `rubocop --auto-gen-config`
|
|
3
|
-
# on
|
|
3
|
+
# on 2020-02-18 16:38:42 +0100 using RuboCop version 0.79.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
9
|
# Offense count: 1
|
|
10
|
-
|
|
10
|
+
# Configuration parameters: Include.
|
|
11
|
+
# Include: **/*.gemspec
|
|
12
|
+
Gemspec/RequiredRubyVersion:
|
|
11
13
|
Exclude:
|
|
12
|
-
- '
|
|
14
|
+
- 'grape-entity.gemspec'
|
|
13
15
|
|
|
14
16
|
# Offense count: 6
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
# Offense count: 35
|
|
19
|
-
# Configuration parameters: CountComments, ExcludedMethods.
|
|
20
|
-
Metrics/BlockLength:
|
|
21
|
-
Max: 1632
|
|
22
|
-
|
|
23
|
-
# Offense count: 2
|
|
24
|
-
# Configuration parameters: CountComments.
|
|
25
|
-
Metrics/ClassLength:
|
|
26
|
-
Max: 210
|
|
27
|
-
|
|
28
|
-
# Offense count: 2
|
|
29
|
-
Metrics/CyclomaticComplexity:
|
|
30
|
-
Max: 11
|
|
31
|
-
|
|
32
|
-
# Offense count: 7
|
|
33
|
-
# Configuration parameters: CountComments.
|
|
34
|
-
Metrics/MethodLength:
|
|
35
|
-
Max: 28
|
|
36
|
-
|
|
37
|
-
# Offense count: 2
|
|
38
|
-
Metrics/PerceivedComplexity:
|
|
39
|
-
Max: 13
|
|
17
|
+
Lint/BooleanSymbol:
|
|
18
|
+
Exclude:
|
|
19
|
+
- 'spec/grape_entity/exposure_spec.rb'
|
|
40
20
|
|
|
41
21
|
# Offense count: 1
|
|
42
|
-
|
|
22
|
+
# Configuration parameters: EnforcedStyle.
|
|
23
|
+
# SupportedStyles: inline, group
|
|
24
|
+
Style/AccessModifierDeclarations:
|
|
43
25
|
Exclude:
|
|
44
|
-
- '
|
|
26
|
+
- 'spec/grape_entity/entity_spec.rb'
|
|
45
27
|
|
|
46
28
|
# Offense count: 1
|
|
47
29
|
# Cop supports --auto-correct.
|
|
@@ -50,9 +32,3 @@ Style/EvalWithLocation:
|
|
|
50
32
|
Style/SymbolProc:
|
|
51
33
|
Exclude:
|
|
52
34
|
- 'spec/grape_entity/entity_spec.rb'
|
|
53
|
-
|
|
54
|
-
# Offense count: 250
|
|
55
|
-
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
|
56
|
-
# URISchemes: http, https
|
|
57
|
-
Metrics/LineLength:
|
|
58
|
-
Max: 146
|
data/.travis.yml
CHANGED
|
@@ -1,30 +1,25 @@
|
|
|
1
|
-
sudo: false
|
|
2
|
-
|
|
3
1
|
language: ruby
|
|
4
2
|
|
|
5
3
|
before_install:
|
|
6
|
-
- gem update --system
|
|
7
4
|
- gem install bundler
|
|
8
5
|
|
|
9
6
|
after_success:
|
|
10
|
-
- coveralls
|
|
11
7
|
- bundle exec danger
|
|
12
8
|
|
|
13
9
|
rvm:
|
|
14
|
-
- 2.5.
|
|
15
|
-
- 2.
|
|
10
|
+
- 2.5.7
|
|
11
|
+
- 2.6.5
|
|
12
|
+
- 2.7.0
|
|
13
|
+
- ruby-head
|
|
14
|
+
- jruby-head
|
|
16
15
|
|
|
17
16
|
matrix:
|
|
18
17
|
fast_finish: true
|
|
19
18
|
|
|
20
19
|
include:
|
|
21
|
-
- rvm: 2.
|
|
22
|
-
- rvm: ruby-head
|
|
23
|
-
- rvm: jruby-head
|
|
24
|
-
- rvm: rbx-2
|
|
20
|
+
- rvm: 2.4.9
|
|
25
21
|
|
|
26
22
|
allow_failures:
|
|
27
|
-
- rvm: 2.
|
|
23
|
+
- rvm: 2.4.9
|
|
28
24
|
- rvm: ruby-head
|
|
29
25
|
- rvm: jruby-head
|
|
30
|
-
- rvm: rbx-2
|
data/CHANGELOG.md
CHANGED
|
@@ -8,11 +8,26 @@
|
|
|
8
8
|
|
|
9
9
|
* Your contribution here.
|
|
10
10
|
|
|
11
|
+
### 0.9.0 (2020-02-18)
|
|
12
|
+
|
|
13
|
+
#### Features
|
|
14
|
+
|
|
15
|
+
* [#307](https://github.com/ruby-grape/grape-entity/pull/307): Allow exposures to call methods defined in modules included in an entity - [@robertoz-01](https://github.com/robertoz-01).
|
|
16
|
+
* [#319](https://github.com/ruby-grape/grape-entity/pull/319): Support hashes with string keys - [@mhenrixon](https://github.com/mhenrixon).
|
|
17
|
+
* [#300](https://github.com/ruby-grape/grape-entity/pull/300): Loosens activesupport to 3 - [@ericschultz](https://github.com/ericschultz).
|
|
18
|
+
|
|
19
|
+
#### Fixes
|
|
20
|
+
|
|
21
|
+
* [#330](https://github.com/ruby-grape/grape-entity/pull/330): CI: use Ruby 2.5.7, 2.6.5, 2.7.0 - [@budnik](https://github.com/budnik).
|
|
22
|
+
* [#329](https://github.com/ruby-grape/grape-entity/pull/329): Option expose_nil doesn't work when block is passed - [@serbiant](https://github.com/serbiant).
|
|
23
|
+
* [#320](https://github.com/ruby-grape/grape-entity/pull/320): Gemspec: drop eol'd property rubyforge_project - [@olleolleolle](https://github.com/olleolleolle).
|
|
24
|
+
* [#307](https://github.com/ruby-grape/grape-entity/pull/307): Allow exposures to call methods defined in modules included in an entity - [@robertoz-01](https://github.com/robertoz-01).
|
|
25
|
+
|
|
11
26
|
### 0.7.1 (2018-01-30)
|
|
12
27
|
|
|
13
28
|
#### Features
|
|
14
29
|
|
|
15
|
-
* [#
|
|
30
|
+
* [#297](https://github.com/ruby-grape/grape-entity/pull/297): Introduce `override` option for expose (fixes [#286](https://github.com/ruby-grape/grape-entity/issues/296)) - [@DmitryTsepelev](https://github.com/DmitryTsepelev).
|
|
16
31
|
|
|
17
32
|
### 0.7.0 (2018-01-25)
|
|
18
33
|
|
data/Gemfile
CHANGED
|
@@ -5,11 +5,11 @@ source 'http://rubygems.org'
|
|
|
5
5
|
gemspec
|
|
6
6
|
|
|
7
7
|
group :development, :test do
|
|
8
|
-
gem 'rubocop', '~> 0.
|
|
8
|
+
gem 'rubocop', '~> 0.79.0', require: false
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
group :test do
|
|
12
|
-
gem '
|
|
12
|
+
gem 'coveralls_reborn', require: false
|
|
13
13
|
gem 'growl'
|
|
14
14
|
gem 'guard'
|
|
15
15
|
gem 'guard-bundler'
|
data/Guardfile
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
# A sample Guardfile
|
|
2
4
|
# More info at https://github.com/guard/guard#readme
|
|
3
5
|
|
|
4
6
|
guard 'rspec', version: 2 do
|
|
5
7
|
watch(%r{^spec/.+_spec\.rb$})
|
|
6
|
-
watch(%r{^lib/(.+)\.rb$})
|
|
8
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
|
7
9
|
watch(%r{^spec/support/shared_versioning_examples.rb$}) { |_m| 'spec/' }
|
|
8
|
-
watch('spec/spec_helper.rb')
|
|
10
|
+
watch('spec/spec_helper.rb') { 'spec/' }
|
|
9
11
|
end
|
|
10
12
|
|
|
11
13
|
guard 'bundler' do
|
data/README.md
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
[](http://badge.fury.io/rb/grape-entity)
|
|
4
4
|
[](https://travis-ci.org/ruby-grape/grape-entity)
|
|
5
5
|
[](https://coveralls.io/github/ruby-grape/grape-entity?branch=master)
|
|
6
|
-
[](https://gemnasium.com/ruby-grape/grape-entity)
|
|
7
6
|
[](https://codeclimate.com/github/ruby-grape/grape-entity)
|
|
8
7
|
|
|
9
8
|
## Introduction
|
|
@@ -221,7 +220,8 @@ class ExampleEntity < Grape::Entity
|
|
|
221
220
|
end
|
|
222
221
|
```
|
|
223
222
|
|
|
224
|
-
You have
|
|
223
|
+
You always have access to the presented instance (`object`) and the top-level
|
|
224
|
+
entity options (`options`).
|
|
225
225
|
|
|
226
226
|
```ruby
|
|
227
227
|
class ExampleEntity < Grape::Entity
|
|
@@ -230,7 +230,7 @@ class ExampleEntity < Grape::Entity
|
|
|
230
230
|
private
|
|
231
231
|
|
|
232
232
|
def formatted_value
|
|
233
|
-
"+ X #{object.value}"
|
|
233
|
+
"+ X #{object.value} #{options[:y]}"
|
|
234
234
|
end
|
|
235
235
|
end
|
|
236
236
|
```
|
|
@@ -265,7 +265,7 @@ class User < Grape::Entity
|
|
|
265
265
|
expose :name
|
|
266
266
|
end
|
|
267
267
|
|
|
268
|
-
class Employee <
|
|
268
|
+
class Employee < User
|
|
269
269
|
expose :name, as: :employee_name, override: true
|
|
270
270
|
end
|
|
271
271
|
```
|
data/grape-entity.gemspec
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
$LOAD_PATH.push File.expand_path('
|
|
3
|
+
$LOAD_PATH.push File.expand_path('lib', __dir__)
|
|
4
4
|
require 'grape_entity/version'
|
|
5
5
|
|
|
6
6
|
Gem::Specification.new do |s|
|
|
@@ -14,11 +14,9 @@ Gem::Specification.new do |s|
|
|
|
14
14
|
s.description = 'Extracted from Grape, A Ruby framework for rapid API development with great conventions.'
|
|
15
15
|
s.license = 'MIT'
|
|
16
16
|
|
|
17
|
-
s.required_ruby_version = '>= 2.
|
|
17
|
+
s.required_ruby_version = '>= 2.4'
|
|
18
18
|
|
|
19
|
-
s.
|
|
20
|
-
|
|
21
|
-
s.add_runtime_dependency 'activesupport', '>=4.0'
|
|
19
|
+
s.add_runtime_dependency 'activesupport', '>= 3.0.0'
|
|
22
20
|
# FIXME: remove dependecy
|
|
23
21
|
s.add_runtime_dependency 'multi_json', '>= 1.3.2'
|
|
24
22
|
|
|
@@ -28,7 +26,7 @@ Gem::Specification.new do |s|
|
|
|
28
26
|
s.add_development_dependency 'pry-byebug' unless RUBY_PLATFORM.eql?('java') || RUBY_ENGINE.eql?('rbx')
|
|
29
27
|
s.add_development_dependency 'rack-test'
|
|
30
28
|
s.add_development_dependency 'rake'
|
|
31
|
-
s.add_development_dependency 'rspec', '~> 3.
|
|
29
|
+
s.add_development_dependency 'rspec', '~> 3.9'
|
|
32
30
|
s.add_development_dependency 'yard'
|
|
33
31
|
|
|
34
32
|
s.files = `git ls-files`.split("\n")
|
data/lib/grape_entity/entity.rb
CHANGED
|
@@ -114,6 +114,22 @@ module Grape
|
|
|
114
114
|
end
|
|
115
115
|
|
|
116
116
|
attr_writer :formatters
|
|
117
|
+
|
|
118
|
+
def hash_access
|
|
119
|
+
@hash_access ||= :to_sym
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def hash_access=(value)
|
|
123
|
+
@hash_access =
|
|
124
|
+
case value
|
|
125
|
+
when :to_s, :str, :string
|
|
126
|
+
:to_s
|
|
127
|
+
when :to_sym, :sym, :symbol
|
|
128
|
+
:to_sym
|
|
129
|
+
else
|
|
130
|
+
:to_sym
|
|
131
|
+
end
|
|
132
|
+
end
|
|
117
133
|
end
|
|
118
134
|
|
|
119
135
|
@formatters = {}
|
|
@@ -168,18 +184,23 @@ module Grape
|
|
|
168
184
|
# @option options :documentation Define documenation for an exposed
|
|
169
185
|
# field, typically the value is a hash with two fields, type and desc.
|
|
170
186
|
# @option options :merge This option allows you to merge an exposed field to the root
|
|
187
|
+
#
|
|
188
|
+
# rubocop:disable Layout/LineLength
|
|
171
189
|
def self.expose(*args, &block)
|
|
172
190
|
options = merge_options(args.last.is_a?(Hash) ? args.pop : {})
|
|
173
191
|
|
|
174
192
|
if args.size > 1
|
|
193
|
+
|
|
175
194
|
raise ArgumentError, 'You may not use the :as option on multi-attribute exposures.' if options[:as]
|
|
176
195
|
raise ArgumentError, 'You may not use the :expose_nil on multi-attribute exposures.' if options.key?(:expose_nil)
|
|
177
196
|
raise ArgumentError, 'You may not use block-setting on multi-attribute exposures.' if block_given?
|
|
178
197
|
end
|
|
179
198
|
|
|
180
|
-
raise ArgumentError, 'You may not use block-setting when also using format_with' if block_given? && options[:format_with].respond_to?(:call)
|
|
181
|
-
|
|
182
199
|
if block_given?
|
|
200
|
+
if options[:format_with].respond_to?(:call)
|
|
201
|
+
raise ArgumentError, 'You may not use block-setting when also using format_with'
|
|
202
|
+
end
|
|
203
|
+
|
|
183
204
|
if block.parameters.any?
|
|
184
205
|
options[:proc] = block
|
|
185
206
|
else
|
|
@@ -191,6 +212,7 @@ module Grape
|
|
|
191
212
|
@nesting_stack ||= []
|
|
192
213
|
args.each { |attribute| build_exposure_for_attribute(attribute, @nesting_stack, options, block) }
|
|
193
214
|
end
|
|
215
|
+
# rubocop:enable Layout/LineLength
|
|
194
216
|
|
|
195
217
|
def self.build_exposure_for_attribute(attribute, nesting_stack, options, block)
|
|
196
218
|
exposure_list = nesting_stack.empty? ? root_exposures : nesting_stack.last.nested_exposures
|
|
@@ -291,6 +313,7 @@ module Grape
|
|
|
291
313
|
#
|
|
292
314
|
def self.format_with(name, &block)
|
|
293
315
|
raise ArgumentError, 'You must pass a block for formatters' unless block_given?
|
|
316
|
+
|
|
294
317
|
formatters[name.to_sym] = block
|
|
295
318
|
end
|
|
296
319
|
|
|
@@ -454,8 +477,8 @@ module Grape
|
|
|
454
477
|
|
|
455
478
|
def initialize(object, options = {})
|
|
456
479
|
@object = object
|
|
457
|
-
@delegator = Delegator.new(object)
|
|
458
480
|
@options = options.is_a?(Options) ? options : Options.new(options)
|
|
481
|
+
@delegator = Delegator.new(object)
|
|
459
482
|
end
|
|
460
483
|
|
|
461
484
|
def root_exposures
|
|
@@ -506,28 +529,50 @@ module Grape
|
|
|
506
529
|
end
|
|
507
530
|
|
|
508
531
|
def delegate_attribute(attribute)
|
|
509
|
-
if
|
|
532
|
+
if is_defined_in_entity?(attribute)
|
|
510
533
|
send(attribute)
|
|
511
534
|
else
|
|
512
|
-
delegator.delegate(attribute)
|
|
535
|
+
delegator.delegate(attribute, hash_access: self.class.hash_access)
|
|
513
536
|
end
|
|
514
537
|
end
|
|
515
538
|
|
|
539
|
+
def is_defined_in_entity?(attribute)
|
|
540
|
+
return false unless respond_to?(attribute, true)
|
|
541
|
+
|
|
542
|
+
ancestors = self.class.ancestors
|
|
543
|
+
ancestors.index(Grape::Entity) > ancestors.index(method(attribute).owner)
|
|
544
|
+
end
|
|
545
|
+
|
|
516
546
|
alias as_json serializable_hash
|
|
517
547
|
|
|
518
548
|
def to_json(options = {})
|
|
519
|
-
options = options.to_h if options
|
|
549
|
+
options = options.to_h if options&.respond_to?(:to_h)
|
|
520
550
|
MultiJson.dump(serializable_hash(options))
|
|
521
551
|
end
|
|
522
552
|
|
|
523
553
|
def to_xml(options = {})
|
|
524
|
-
options = options.to_h if options
|
|
554
|
+
options = options.to_h if options&.respond_to?(:to_h)
|
|
525
555
|
serializable_hash(options).to_xml(options)
|
|
526
556
|
end
|
|
527
557
|
|
|
528
558
|
# All supported options.
|
|
529
559
|
OPTIONS = %i[
|
|
530
|
-
rewrite
|
|
560
|
+
rewrite
|
|
561
|
+
as
|
|
562
|
+
if
|
|
563
|
+
unless
|
|
564
|
+
using
|
|
565
|
+
with
|
|
566
|
+
proc
|
|
567
|
+
documentation
|
|
568
|
+
format_with
|
|
569
|
+
safe
|
|
570
|
+
attr_path
|
|
571
|
+
if_extras
|
|
572
|
+
unless_extras
|
|
573
|
+
merge
|
|
574
|
+
expose_nil
|
|
575
|
+
override
|
|
531
576
|
].to_set.freeze
|
|
532
577
|
|
|
533
578
|
# Merges the given options with current block options.
|
|
@@ -47,14 +47,20 @@ module Grape
|
|
|
47
47
|
options[:unless]
|
|
48
48
|
].compact.flatten.map { |cond| Condition.new_unless(cond) }
|
|
49
49
|
|
|
50
|
-
unless_conditions << expose_nil_condition(attribute) if options[:expose_nil] == false
|
|
50
|
+
unless_conditions << expose_nil_condition(attribute, options) if options[:expose_nil] == false
|
|
51
51
|
|
|
52
52
|
if_conditions + unless_conditions
|
|
53
53
|
end
|
|
54
54
|
|
|
55
|
-
def expose_nil_condition(attribute)
|
|
55
|
+
def expose_nil_condition(attribute, options)
|
|
56
56
|
Condition.new_unless(
|
|
57
|
-
proc
|
|
57
|
+
proc do |object, _options|
|
|
58
|
+
if options[:proc].nil?
|
|
59
|
+
Delegator.new(object).delegate(attribute).nil?
|
|
60
|
+
else
|
|
61
|
+
exec_with_object(options, &options[:proc]).nil?
|
|
62
|
+
end
|
|
63
|
+
end
|
|
58
64
|
)
|
|
59
65
|
end
|
|
60
66
|
|
|
@@ -54,7 +54,10 @@ module Grape
|
|
|
54
54
|
if @is_safe
|
|
55
55
|
is_delegatable
|
|
56
56
|
else
|
|
57
|
-
is_delegatable || raise(
|
|
57
|
+
is_delegatable || raise(
|
|
58
|
+
NoMethodError,
|
|
59
|
+
"#{entity.class.name} missing attribute `#{@attribute}' on #{entity.object}"
|
|
60
|
+
)
|
|
58
61
|
end
|
|
59
62
|
end
|
|
60
63
|
|
|
@@ -19,6 +19,7 @@ module Grape
|
|
|
19
19
|
# If we have an array which should not be merged - save it with a key as a hash
|
|
20
20
|
# If we have hash which should be merged - save it without a key (merge)
|
|
21
21
|
return unless result
|
|
22
|
+
|
|
22
23
|
@output_hash.merge! result, &merge_strategy(exposure.for_merge)
|
|
23
24
|
else
|
|
24
25
|
@output_hash[exposure.key(@entity)] = result
|
data/lib/grape_entity/version.rb
CHANGED
|
@@ -126,6 +126,26 @@ describe Grape::Entity do
|
|
|
126
126
|
expect { subject.expose(:a, :b, :c, expose_nil: false) }.to raise_error ArgumentError
|
|
127
127
|
end
|
|
128
128
|
end
|
|
129
|
+
|
|
130
|
+
context 'when expose_nil option is false and block passed' do
|
|
131
|
+
it 'does not expose if block returns nil' do
|
|
132
|
+
subject.expose(:a, expose_nil: false) do |_obj, _options|
|
|
133
|
+
nil
|
|
134
|
+
end
|
|
135
|
+
subject.expose(:b)
|
|
136
|
+
subject.expose(:c)
|
|
137
|
+
expect(subject.represent(model).serializable_hash).to eq(b: nil, c: 'value')
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
it 'exposes is block returns a value' do
|
|
141
|
+
subject.expose(:a, expose_nil: false) do |_obj, _options|
|
|
142
|
+
100
|
|
143
|
+
end
|
|
144
|
+
subject.expose(:b)
|
|
145
|
+
subject.expose(:c)
|
|
146
|
+
expect(subject.represent(model).serializable_hash).to eq(a: 100, b: nil, c: 'value')
|
|
147
|
+
end
|
|
148
|
+
end
|
|
129
149
|
end
|
|
130
150
|
|
|
131
151
|
context 'when model is a hash' do
|
|
@@ -1376,6 +1396,18 @@ describe Grape::Entity do
|
|
|
1376
1396
|
expect(res).to have_key :nonexistent_attribute
|
|
1377
1397
|
end
|
|
1378
1398
|
|
|
1399
|
+
it 'exposes attributes defined through module inclusion' do
|
|
1400
|
+
module SharedAttributes
|
|
1401
|
+
def a_value
|
|
1402
|
+
3.14
|
|
1403
|
+
end
|
|
1404
|
+
end
|
|
1405
|
+
fresh_class.include(SharedAttributes)
|
|
1406
|
+
fresh_class.expose :a_value
|
|
1407
|
+
res = fresh_class.new(model).serializable_hash
|
|
1408
|
+
expect(res[:a_value]).to eq(3.14)
|
|
1409
|
+
end
|
|
1410
|
+
|
|
1379
1411
|
it 'does not expose attributes that are generated by a block but have not passed criteria' do
|
|
1380
1412
|
fresh_class.expose :nonexistent_attribute,
|
|
1381
1413
|
proc: ->(_, _) { 'I exist, but it is not yet my time to shine' },
|
|
@@ -12,11 +12,11 @@ describe Grape::Entity::Exposure::RepresentExposure do
|
|
|
12
12
|
let(:subexposure) { double(:subexposure) }
|
|
13
13
|
|
|
14
14
|
it 'sets using_class_name' do
|
|
15
|
-
expect { subject }.to change
|
|
15
|
+
expect { subject }.to change(exposure, :using_class_name).to(using_class_name)
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
it 'sets subexposure' do
|
|
19
|
-
expect { subject }.to change
|
|
19
|
+
expect { subject }.to change(exposure, :subexposure).to(subexposure)
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
context 'when using_class is set' do
|
|
@@ -25,7 +25,7 @@ describe Grape::Entity::Exposure::RepresentExposure do
|
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
it 'resets using_class' do
|
|
28
|
-
expect { subject }.to change
|
|
28
|
+
expect { subject }.to change(exposure, :using_class)
|
|
29
29
|
end
|
|
30
30
|
end
|
|
31
31
|
end
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
require 'spec_helper'
|
|
4
4
|
|
|
5
5
|
describe Grape::Entity do
|
|
6
|
-
it 'except option for nested entity' do
|
|
6
|
+
it 'except option for nested entity', :aggregate_failures do
|
|
7
7
|
module EntitySpec
|
|
8
8
|
class Address < Grape::Entity
|
|
9
9
|
expose :post, if: :full
|
|
@@ -12,6 +12,14 @@ describe Grape::Entity do
|
|
|
12
12
|
expose :house
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
+
class AddressWithString < Grape::Entity
|
|
16
|
+
self.hash_access = :string
|
|
17
|
+
expose :post, if: :full
|
|
18
|
+
expose :city
|
|
19
|
+
expose :street
|
|
20
|
+
expose :house
|
|
21
|
+
end
|
|
22
|
+
|
|
15
23
|
class Company < Grape::Entity
|
|
16
24
|
expose :full_name, if: :full
|
|
17
25
|
expose :name
|
|
@@ -19,6 +27,15 @@ describe Grape::Entity do
|
|
|
19
27
|
Address.represent c[:address], Grape::Entity::Options.new(o.opts_hash.except(:full))
|
|
20
28
|
end
|
|
21
29
|
end
|
|
30
|
+
|
|
31
|
+
class CompanyWithString < Grape::Entity
|
|
32
|
+
self.hash_access = :string
|
|
33
|
+
expose :full_name, if: :full
|
|
34
|
+
expose :name
|
|
35
|
+
expose :address do |c, o|
|
|
36
|
+
AddressWithString.represent c['address'], Grape::Entity::Options.new(o.opts_hash.except(:full))
|
|
37
|
+
end
|
|
38
|
+
end
|
|
22
39
|
end
|
|
23
40
|
|
|
24
41
|
company = {
|
|
@@ -33,6 +50,24 @@ describe Grape::Entity do
|
|
|
33
50
|
}
|
|
34
51
|
}
|
|
35
52
|
|
|
53
|
+
company_with_string = {
|
|
54
|
+
'full_name' => 'full_name',
|
|
55
|
+
'name' => 'name',
|
|
56
|
+
'address' => {
|
|
57
|
+
'post' => '123456',
|
|
58
|
+
'city' => 'city',
|
|
59
|
+
'street' => 'street',
|
|
60
|
+
'house' => 'house',
|
|
61
|
+
'something_else' => 'something_else'
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
expect(EntitySpec::CompanyWithString.represent(company_with_string).serializable_hash).to eq \
|
|
66
|
+
company.slice(:name).merge(address: company[:address].slice(:city, :street, :house))
|
|
67
|
+
|
|
68
|
+
expect(EntitySpec::CompanyWithString.represent(company_with_string, full: true).serializable_hash).to eq \
|
|
69
|
+
company.slice(:full_name, :name).merge(address: company[:address].slice(:city, :street, :house))
|
|
70
|
+
|
|
36
71
|
expect(EntitySpec::Company.represent(company).serializable_hash).to eq \
|
|
37
72
|
company.slice(:name).merge(address: company[:address].slice(:city, :street, :house))
|
|
38
73
|
|
data/spec/spec_helper.rb
CHANGED
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
require 'simplecov'
|
|
4
4
|
require 'coveralls'
|
|
5
5
|
|
|
6
|
+
# This works around the hash extensions not being automatically included in ActiveSupport < 4
|
|
7
|
+
require 'active_support/version'
|
|
8
|
+
require 'active_support/core_ext/hash' if ActiveSupport::VERSION &&
|
|
9
|
+
ActiveSupport::VERSION::MAJOR &&
|
|
10
|
+
ActiveSupport::VERSION::MAJOR < 4
|
|
11
|
+
|
|
6
12
|
SimpleCov.start do
|
|
7
13
|
add_filter 'spec/'
|
|
8
14
|
end
|
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.
|
|
4
|
+
version: 0.8.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Michael Bleigh
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2020-02-18 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -16,14 +16,14 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version:
|
|
19
|
+
version: 3.0.0
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - ">="
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version:
|
|
26
|
+
version: 3.0.0
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: multi_json
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -128,14 +128,14 @@ dependencies:
|
|
|
128
128
|
requirements:
|
|
129
129
|
- - "~>"
|
|
130
130
|
- !ruby/object:Gem::Version
|
|
131
|
-
version: '3.
|
|
131
|
+
version: '3.9'
|
|
132
132
|
type: :development
|
|
133
133
|
prerelease: false
|
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
|
135
135
|
requirements:
|
|
136
136
|
- - "~>"
|
|
137
137
|
- !ruby/object:Gem::Version
|
|
138
|
-
version: '3.
|
|
138
|
+
version: '3.9'
|
|
139
139
|
- !ruby/object:Gem::Dependency
|
|
140
140
|
name: yard
|
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -222,15 +222,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
222
222
|
requirements:
|
|
223
223
|
- - ">="
|
|
224
224
|
- !ruby/object:Gem::Version
|
|
225
|
-
version: '2.
|
|
225
|
+
version: '2.4'
|
|
226
226
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
227
227
|
requirements:
|
|
228
228
|
- - ">="
|
|
229
229
|
- !ruby/object:Gem::Version
|
|
230
230
|
version: '0'
|
|
231
231
|
requirements: []
|
|
232
|
-
|
|
233
|
-
rubygems_version: 2.7.3
|
|
232
|
+
rubygems_version: 3.1.2
|
|
234
233
|
signing_key:
|
|
235
234
|
specification_version: 4
|
|
236
235
|
summary: A simple facade for managing the relationship between your model and API.
|