grape-entity 0.8.2 → 0.10.1

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: aa38cbc30d489d88e91c10c688c581251392a448330eca12ff79ebe22958bd9c
4
- data.tar.gz: a96f1d0ada161d659f71aaca4e44588afc2727f4966e3f46058189483d46aa0c
3
+ metadata.gz: 9e3db71fd839585d80faac0980ec028b1204def600b6ce36101e2986e0be3cbf
4
+ data.tar.gz: 7bfcb78548991ed3ab73bfc1f23a51e1e32c2af7ccba472e87b9a767a9499c79
5
5
  SHA512:
6
- metadata.gz: 12f8a447cf4f297bb4c07375d08efa41e5d1691a907ccbfdc7cef8c2f394cfc03a041318f76ab2475089b5d1b7438414cd00dca6305105bf616b3c2465b1c000
7
- data.tar.gz: 0a7c13fec63e43adb8269d0639c1e4abfef77cba02a3a7b234716588e968116e1875e94bab08f68cdec60e656b65f159d42f308342eeac6f42846a6f5aec9b27
6
+ metadata.gz: 1ba1bf0a642f56275e8279b34d433591a21c7849ede46d0718fd6496831d4f5b5bd676bda0af6bf435beebe5c717ace6c0b53c1c90db92fdecccb8d88cdbe044
7
+ data.tar.gz: c06a650f7c29dd918fa8b83ab62dd04b91448bcddc440a43e48d055f5499982b6c4532f18abc7429f71f464895b083f8e551748c9d9fdf0f8072c2cd1af0e438
@@ -0,0 +1,14 @@
1
+ # To get started with Dependabot version updates, you'll need to specify which
2
+ # package ecosystems to update and where the package manifests are located.
3
+ # Please see the documentation for all configuration options:
4
+ # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5
+
6
+ version: 2
7
+ updates:
8
+ - package-ecosystem: "bundler" # See documentation for possible values
9
+ directory: "/" # Location of package manifests
10
+ schedule:
11
+ interval: "weekly"
12
+ day: "friday"
13
+ assignees:
14
+ - "LeFnord"
@@ -0,0 +1,26 @@
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() }}
@@ -0,0 +1,26 @@
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
data/.rspec CHANGED
@@ -1,2 +1,3 @@
1
- --format documentation
2
1
  --color
2
+ --profile
3
+ --format documentation
data/.rubocop.yml CHANGED
@@ -4,9 +4,9 @@ AllCops:
4
4
  Exclude:
5
5
  - vendor/**/*
6
6
  - example/**/*
7
- TargetRubyVersion: 2.7
8
- UseCache: true
9
7
  NewCops: enable
8
+ TargetRubyVersion: 3.0
9
+ SuggestExtensions: false
10
10
 
11
11
  # Layout stuff
12
12
  #
data/CHANGELOG.md CHANGED
@@ -9,6 +9,31 @@
9
9
  * Your contribution here.
10
10
 
11
11
 
12
+ ### 0.10.1 (2021-10-22)
13
+
14
+ #### Fixes
15
+
16
+ * [#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-).
17
+
18
+
19
+ ### 0.10.0 (2021-09-15)
20
+
21
+ #### Features
22
+
23
+ * [#352](https://github.com/ruby-grape/grape-entity/pull/352): Add Default value option - [@ahmednaguib](https://github.com/ahmednaguib).
24
+
25
+ #### Fixes
26
+
27
+ * [#355](https://github.com/ruby-grape/grape-entity/pull/355): Fix infinite loop problem with the `NameErrors` in block exposures - [@meinac](https://github.com/meinac).
28
+
29
+
30
+ ### 0.9.0 (2021-03-20)
31
+
32
+ #### Features
33
+
34
+ * [#346](https://github.com/ruby-grape/grape-entity/pull/346): Ruby 3 support - [@LeFnord](https://github.com/LeFnord).
35
+
36
+
12
37
  ### 0.8.2 (2020-11-08)
13
38
 
14
39
  #### Fixes
data/Gemfile CHANGED
@@ -15,6 +15,6 @@ group :test do
15
15
  gem 'guard-bundler'
16
16
  gem 'guard-rspec'
17
17
  gem 'rb-fsevent'
18
- gem 'ruby-grape-danger', '~> 0.1.1', require: false
18
+ gem 'ruby-grape-danger', '~> 0.2', require: false
19
19
  gem 'simplecov', require: false
20
20
  end
data/README.md CHANGED
@@ -1,10 +1,47 @@
1
- # Grape::Entity
2
-
3
1
  [![Gem Version](http://img.shields.io/gem/v/grape-entity.svg)](http://badge.fury.io/rb/grape-entity)
4
- [![Build Status](http://img.shields.io/travis/ruby-grape/grape-entity.svg)](https://travis-ci.org/ruby-grape/grape-entity)
2
+ ![Ruby](https://github.com/ruby-grape/grape-entity/workflows/Ruby/badge.svg)
5
3
  [![Coverage Status](https://coveralls.io/repos/github/ruby-grape/grape-entity/badge.svg?branch=master)](https://coveralls.io/github/ruby-grape/grape-entity?branch=master)
6
4
  [![Code Climate](https://codeclimate.com/github/ruby-grape/grape-entity.svg)](https://codeclimate.com/github/ruby-grape/grape-entity)
7
5
 
6
+ # Table of Contents
7
+
8
+ - [Grape::Entity](#grapeentity)
9
+ - [Introduction](#introduction)
10
+ - [Example](#example)
11
+ - [Reusable Responses with Entities](#reusable-responses-with-entities)
12
+ - [Defining Entities](#defining-entities)
13
+ - [Basic Exposure](#basic-exposure)
14
+ - [Exposing with a Presenter](#exposing-with-a-presenter)
15
+ - [Conditional Exposure](#conditional-exposure)
16
+ - [Safe Exposure](#safe-exposure)
17
+ - [Nested Exposure](#nested-exposure)
18
+ - [Collection Exposure](#collection-exposure)
19
+ - [Merge Fields](#merge-fields)
20
+ - [Runtime Exposure](#runtime-exposure)
21
+ - [Unexpose](#unexpose)
22
+ - [Overriding exposures](#overriding-exposures)
23
+ - [Returning only the fields you want](#returning-only-the-fields-you-want)
24
+ - [Aliases](#aliases)
25
+ - [Format Before Exposing](#format-before-exposing)
26
+ - [Expose Nil](#expose-nil)
27
+ - [Default Value](#default-value)
28
+ - [Documentation](#documentation)
29
+ - [Options Hash](#options-hash)
30
+ - [Passing Additional Option To Nested Exposure](#passing-additional-option-to-nested-exposure)
31
+ - [Attribute Path Tracking](#attribute-path-tracking)
32
+ - [Using the Exposure DSL](#using-the-exposure-dsl)
33
+ - [Using Entities](#using-entities)
34
+ - [Entity Organization](#entity-organization)
35
+ - [Caveats](#caveats)
36
+ - [Installation](#installation)
37
+ - [Testing with Entities](#testing-with-entities)
38
+ - [Project Resources](#project-resources)
39
+ - [Contributing](#contributing)
40
+ - [License](#license)
41
+ - [Copyright](#copyright)
42
+
43
+ # Grape::Entity
44
+
8
45
  ## Introduction
9
46
 
10
47
  This gem adds Entity support to API frameworks, such as [Grape](https://github.com/ruby-grape/grape). Grape's Entity is an API focused facade that sits on top of an object model.
@@ -74,6 +111,20 @@ The field lookup takes several steps
74
111
  * next try `object.fetch(exposure)`
75
112
  * last raise an Exception
76
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
+
77
128
  #### Exposing with a Presenter
78
129
 
79
130
  Don't derive your model classes from `Grape::Entity`, expose them using a presenter.
@@ -446,6 +497,19 @@ module Entities
446
497
  end
447
498
  ```
448
499
 
500
+ #### Default Value
501
+
502
+ This option can be used to provide a default value in case the return value is nil or empty.
503
+
504
+ ```ruby
505
+ module Entities
506
+ class MyModel < Grape::Entity
507
+ expose :name, default: ''
508
+ expose :age, default: 60
509
+ end
510
+ end
511
+ ```
512
+
449
513
  #### Documentation
450
514
 
451
515
  Expose documentation with the field. Gets bubbled up when used with Grape and various API documentation systems.
data/UPGRADING.md CHANGED
@@ -1,22 +1,10 @@
1
1
  # Upgrading Grape Entity
2
2
 
3
- ### Upgrading to >= 0.8.2
4
-
5
- In Ruby 3.0: the block handling will be changed
6
- [language-changes point 3, Proc](https://github.com/ruby/ruby/blob/v3_0_0_preview1/NEWS.md#language-changes).
7
- This:
8
- ```ruby
9
- expose :that_method_without_args, &:method_without_args
10
- ```
11
- will be deprecated.
12
-
13
- Prefer to use this pattern for simple setting a value
14
- ```ruby
15
- expose :method_without_args, as: :that_method_without_args
16
- ```
17
3
 
18
4
  ### Upgrading to >= 0.8.2
19
5
 
6
+ Official support for ruby < 2.5 removed, ruby 2.5 only in testing mode, but no support.
7
+
20
8
  In Ruby 3.0: the block handling will be changed
21
9
  [language-changes point 3, Proc](https://github.com/ruby/ruby/blob/v3_0_0_preview1/NEWS.md#language-changes).
22
10
  This:
data/grape-entity.gemspec CHANGED
@@ -14,7 +14,7 @@ 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.4'
17
+ s.required_ruby_version = '>= 2.5'
18
18
 
19
19
  s.add_runtime_dependency 'activesupport', '>= 3.0.0'
20
20
  # FIXME: remove dependecy
@@ -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)
@@ -122,8 +122,6 @@ module Grape
122
122
  case value
123
123
  when :to_s, :str, :string
124
124
  :to_s
125
- when :to_sym, :sym, :symbol
126
- :to_sym
127
125
  else
128
126
  :to_sym
129
127
  end
@@ -155,7 +153,7 @@ module Grape
155
153
  #
156
154
  # @example as: a proc or lambda
157
155
  #
158
- # object = OpenStruct(awesomness: 'awesome_key', awesome: 'not-my-key', other: 'other-key' )
156
+ # object = OpenStruct(awesomeness: 'awesome_key', awesome: 'not-my-key', other: 'other-key' )
159
157
  #
160
158
  # class MyEntity < Grape::Entity
161
159
  # expose :awesome, as: proc { object.awesomeness }
@@ -483,9 +481,6 @@ module Grape
483
481
  @object = object
484
482
  @options = options.is_a?(Options) ? options : Options.new(options)
485
483
  @delegator = Delegator.new(object)
486
-
487
- # Why not `arity > 1`? It might be negative https://ruby-doc.org/core-2.6.6/Method.html#method-i-arity
488
- @delegator_accepts_opts = @delegator.method(:delegate).arity != 1
489
484
  end
490
485
 
491
486
  def root_exposures
@@ -529,7 +524,7 @@ module Grape
529
524
  # it handles: https://github.com/ruby/ruby/blob/v3_0_0_preview1/NEWS.md#language-changes point 3, Proc
530
525
  raise Grape::Entity::Deprecated.new e.message, 'in ruby 3.0' if e.is_a?(ArgumentError)
531
526
 
532
- raise e.class, e.message
527
+ raise e
533
528
  end
534
529
 
535
530
  def exec_with_attribute(attribute, &block)
@@ -543,7 +538,7 @@ module Grape
543
538
  def delegate_attribute(attribute)
544
539
  if is_defined_in_entity?(attribute)
545
540
  send(attribute)
546
- elsif @delegator_accepts_opts
541
+ elsif delegator.accepts_options?
547
542
  delegator.delegate(attribute, **self.class.delegation_opts)
548
543
  else
549
544
  delegator.delegate(attribute)
@@ -587,6 +582,7 @@ module Grape
587
582
  merge
588
583
  expose_nil
589
584
  override
585
+ default
590
586
  ].to_set.freeze
591
587
 
592
588
  # Merges the given options with current block options.
@@ -16,6 +16,7 @@ module Grape
16
16
  key = options[:as] || attribute
17
17
  @key = key.respond_to?(:to_sym) ? key.to_sym : key
18
18
  @is_safe = options[:safe]
19
+ @default_value = options[:default]
19
20
  @for_merge = options[:merge]
20
21
  @attr_path_proc = options[:attr_path]
21
22
  @documentation = options[:documentation]
@@ -82,7 +83,10 @@ module Grape
82
83
  end
83
84
 
84
85
  def valid_value(entity, options)
85
- value(entity, options) if valid?(entity)
86
+ return unless valid?(entity)
87
+
88
+ output = value(entity, options)
89
+ output.blank? && @default_value.present? ? @default_value : output
86
90
  end
87
91
 
88
92
  def should_return_key?(options)
@@ -51,7 +51,6 @@ module Grape
51
51
  output
52
52
  end
53
53
 
54
- # rubocop:disable Lint/EmptyBlock
55
54
  # In case if we want to solve collisions providing lambda to :merge option
56
55
  def merge_strategy(for_merge)
57
56
  if for_merge.respond_to? :call
@@ -60,7 +59,6 @@ module Grape
60
59
  -> {}
61
60
  end
62
61
  end
63
- # rubocop:enable Lint/EmptyBlock
64
62
  end
65
63
  end
66
64
  end
@@ -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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GrapeEntity
4
- VERSION = '0.8.2'
4
+ VERSION = '0.10.1'
5
5
  end
@@ -30,9 +30,7 @@ describe Grape::Entity do
30
30
 
31
31
  it 'makes sure that :format_with as a proc cannot be used with a block' do
32
32
  # rubocop:disable Style/BlockDelimiters
33
- # rubocop:disable Lint/EmptyBlock
34
33
  expect { subject.expose :name, format_with: proc {} do p 'hi' end }.to raise_error ArgumentError
35
- # rubocop:enable Lint/EmptyBlock
36
34
  # rubocop:enable Style/BlockDelimiters
37
35
  end
38
36
 
@@ -214,6 +212,130 @@ describe Grape::Entity do
214
212
  end
215
213
  end
216
214
 
215
+ context 'with :default option' do
216
+ let(:a) { nil }
217
+ let(:b) { nil }
218
+ let(:c) { 'value' }
219
+
220
+ context 'when model is a PORO' do
221
+ let(:model) { Model.new(a, b, c) }
222
+
223
+ before do
224
+ stub_const 'Model', Class.new
225
+ Model.class_eval do
226
+ attr_accessor :a, :b, :c
227
+
228
+ def initialize(a, b, c)
229
+ @a = a
230
+ @b = b
231
+ @c = c
232
+ end
233
+ end
234
+ end
235
+
236
+ context 'when default option is not provided' do
237
+ it 'exposes attributes values' do
238
+ subject.expose(:a)
239
+ subject.expose(:b)
240
+ subject.expose(:c)
241
+ expect(subject.represent(model).serializable_hash).to eq(a: nil, b: nil, c: 'value')
242
+ end
243
+ end
244
+
245
+ context 'when default option is set' do
246
+ it 'exposes default values for attributes' do
247
+ subject.expose(:a, default: 'a')
248
+ subject.expose(:b, default: 'b')
249
+ subject.expose(:c, default: 'c')
250
+ expect(subject.represent(model).serializable_hash).to eq(a: 'a', b: 'b', c: 'value')
251
+ end
252
+ end
253
+
254
+ context 'when default option is set and block passed' do
255
+ it 'return default value if block returns nil' do
256
+ subject.expose(:a, default: 'a') do |_obj, _options|
257
+ nil
258
+ end
259
+ subject.expose(:b)
260
+ subject.expose(:c)
261
+ expect(subject.represent(model).serializable_hash).to eq(a: 'a', b: nil, c: 'value')
262
+ end
263
+
264
+ it 'return value from block if block returns a value' do
265
+ subject.expose(:a, default: 'a') do |_obj, _options|
266
+ 100
267
+ end
268
+ subject.expose(:b)
269
+ subject.expose(:c)
270
+ expect(subject.represent(model).serializable_hash).to eq(a: 100, b: nil, c: 'value')
271
+ end
272
+ end
273
+ end
274
+
275
+ context 'when model is a hash' do
276
+ let(:model) { { a: a, b: b, c: c } }
277
+
278
+ context 'when expose_nil option is not provided' do
279
+ it 'exposes nil attributes' do
280
+ subject.expose(:a)
281
+ subject.expose(:b)
282
+ subject.expose(:c)
283
+ expect(subject.represent(model).serializable_hash).to eq(a: nil, b: nil, c: 'value')
284
+ end
285
+ end
286
+
287
+ context 'when expose_nil option is true' do
288
+ it 'exposes nil attributes' do
289
+ subject.expose(:a, expose_nil: true)
290
+ subject.expose(:b, expose_nil: true)
291
+ subject.expose(:c)
292
+ expect(subject.represent(model).serializable_hash).to eq(a: nil, b: nil, c: 'value')
293
+ end
294
+ end
295
+
296
+ context 'when expose_nil option is false' do
297
+ it 'does not expose nil attributes' do
298
+ subject.expose(:a, expose_nil: false)
299
+ subject.expose(:b, expose_nil: false)
300
+ subject.expose(:c)
301
+ expect(subject.represent(model).serializable_hash).to eq(c: 'value')
302
+ end
303
+
304
+ it 'is only applied per attribute' do
305
+ subject.expose(:a, expose_nil: false)
306
+ subject.expose(:b)
307
+ subject.expose(:c)
308
+ expect(subject.represent(model).serializable_hash).to eq(b: nil, c: 'value')
309
+ end
310
+
311
+ it 'raises an error when applied to multiple attribute exposures' do
312
+ expect { subject.expose(:a, :b, :c, expose_nil: false) }.to raise_error ArgumentError
313
+ end
314
+ end
315
+ end
316
+
317
+ context 'with nested structures' do
318
+ let(:model) { { a: a, b: b, c: { d: nil, e: nil, f: { g: nil, h: nil } } } }
319
+
320
+ context 'when expose_nil option is false' do
321
+ it 'does not expose nil attributes' do
322
+ subject.expose(:a, expose_nil: false)
323
+ subject.expose(:b)
324
+ subject.expose(:c) do
325
+ subject.expose(:d, expose_nil: false)
326
+ subject.expose(:e)
327
+ subject.expose(:f) do
328
+ subject.expose(:g, expose_nil: false)
329
+ subject.expose(:h)
330
+ end
331
+ end
332
+
333
+ expect(subject.represent(model).serializable_hash).to eq(b: nil, c: { e: nil, f: { h: nil } })
334
+ end
335
+ end
336
+ end
337
+ end
338
+
217
339
  context 'with a block' do
218
340
  it 'errors out if called with multiple attributes' do
219
341
  expect { subject.expose(:name, :email) { true } }.to raise_error ArgumentError
@@ -1137,6 +1259,18 @@ describe Grape::Entity do
1137
1259
  expect(representation).to eq(id: nil, name: nil, user: { id: nil, name: nil, email: nil })
1138
1260
  end
1139
1261
  end
1262
+
1263
+ context 'when NameError happens in a parameterized block_exposure' do
1264
+ before do
1265
+ subject.expose :raise_no_method_error do |_|
1266
+ foo
1267
+ end
1268
+ end
1269
+
1270
+ it 'does not cause infinite loop' do
1271
+ expect { subject.represent({}, serializable: true) }.to raise_error(NameError)
1272
+ end
1273
+ end
1140
1274
  end
1141
1275
  end
1142
1276
 
@@ -1581,7 +1715,7 @@ describe Grape::Entity do
1581
1715
  end
1582
1716
 
1583
1717
  fresh_class.class_eval do
1584
- expose :characteristics, using: EntitySpec::NoPathCharacterEntity, attr_path: proc { nil }
1718
+ expose :characteristics, using: EntitySpec::NoPathCharacterEntity, attr_path: proc {}
1585
1719
  end
1586
1720
 
1587
1721
  expect(subject.serializable_hash).to eq(
@@ -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
 
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.8.2
4
+ version: 0.10.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Bleigh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-08 00:00:00.000000000 Z
11
+ date: 2021-10-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -159,11 +159,13 @@ extensions: []
159
159
  extra_rdoc_files: []
160
160
  files:
161
161
  - ".coveralls.yml"
162
+ - ".github/dependabot.yml"
163
+ - ".github/workflows/rubocop.yml"
164
+ - ".github/workflows/ruby.yml"
162
165
  - ".gitignore"
163
166
  - ".rspec"
164
167
  - ".rubocop.yml"
165
168
  - ".rubocop_todo.yml"
166
- - ".travis.yml"
167
169
  - ".yardopts"
168
170
  - CHANGELOG.md
169
171
  - CONTRIBUTING.md
@@ -223,14 +225,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
223
225
  requirements:
224
226
  - - ">="
225
227
  - !ruby/object:Gem::Version
226
- version: '2.4'
228
+ version: '2.5'
227
229
  required_rubygems_version: !ruby/object:Gem::Requirement
228
230
  requirements:
229
231
  - - ">="
230
232
  - !ruby/object:Gem::Version
231
233
  version: '0'
232
234
  requirements: []
233
- rubygems_version: 3.2.0.rc.1
235
+ rubygems_version: 3.2.22
234
236
  signing_key:
235
237
  specification_version: 4
236
238
  summary: A simple facade for managing the relationship between your model and API.
data/.travis.yml DELETED
@@ -1,26 +0,0 @@
1
- language: ruby
2
-
3
- before_install:
4
- - gem install bundler
5
-
6
- after_success:
7
- - bundle exec danger
8
-
9
- rvm:
10
- - 2.5.8
11
- - 2.6.6
12
- - 2.7.2
13
- - ruby-head
14
- - jruby-head
15
- - truffleruby-head
16
- - 2.4.10
17
-
18
-
19
- matrix:
20
- fast_finish: true
21
-
22
- allow_failures:
23
- - rvm: 2.4.10
24
- - rvm: ruby-head
25
- - rvm: jruby-head
26
- - rvm: truffleruby-head