grape-entity 1.0.0 → 1.0.2
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/.github/workflows/ci.yml +4 -4
- data/.rspec +1 -0
- data/.rubocop.yml +1 -1
- data/.rubocop_todo.yml +5 -0
- data/CHANGELOG.md +10 -4
- data/README.md +5 -0
- data/bench/serializing.rb +2 -2
- data/grape-entity.gemspec +2 -4
- data/lib/grape_entity/condition/base.rb +2 -2
- data/lib/grape_entity/entity.rb +52 -13
- data/lib/grape_entity/exposure/base.rb +2 -2
- data/lib/grape_entity/exposure.rb +2 -2
- data/lib/grape_entity/json.rb +12 -0
- data/lib/grape_entity/version.rb +1 -1
- data/spec/grape_entity/entity_spec.rb +106 -45
- data/spec/grape_entity/exposure/nesting_exposure/nested_exposures_spec.rb +0 -2
- data/spec/grape_entity/exposure/represent_exposure_spec.rb +0 -2
- data/spec/grape_entity/exposure_spec.rb +0 -2
- data/spec/grape_entity/hash_spec.rb +0 -2
- data/spec/grape_entity/json_spec.rb +7 -0
- data/spec/grape_entity/options_spec.rb +0 -2
- metadata +7 -18
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8beeb296491f1be5721d415c0a3b9a3bfc5caeede002c8bc4a2e009fc83706f1
|
|
4
|
+
data.tar.gz: 5d219fab3a94ecae43c7f253682fc3d6640723ad27e4e75020b9cecc359ae7d1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4063dd57bec2dd189ee05e492fc6a1d36dceb45be1e5c02f16749dba303557490494e874d8f302ae668e51b846035efb5e8e10977273127f57e05d175390cd3b
|
|
7
|
+
data.tar.gz: 06d176afda782549915c74f0085f641047e0077270e507725fbd1c1c9ad7f929b75362d54c73e20626e0643ef4c3c54de2f75cf1ed678d72ee868406deaa1226
|
data/.github/workflows/ci.yml
CHANGED
|
@@ -15,10 +15,10 @@ jobs:
|
|
|
15
15
|
rubocop:
|
|
16
16
|
runs-on: ubuntu-latest
|
|
17
17
|
steps:
|
|
18
|
-
- uses: actions/checkout@
|
|
18
|
+
- uses: actions/checkout@v6
|
|
19
19
|
- uses: ruby/setup-ruby@v1
|
|
20
20
|
with:
|
|
21
|
-
ruby-version: '3.
|
|
21
|
+
ruby-version: '3.0'
|
|
22
22
|
bundler-cache: true
|
|
23
23
|
- name: Run rubocop
|
|
24
24
|
run: bundle exec rubocop --parallel --format progress
|
|
@@ -28,10 +28,10 @@ jobs:
|
|
|
28
28
|
needs: ['rubocop']
|
|
29
29
|
strategy:
|
|
30
30
|
matrix:
|
|
31
|
-
ruby-version: ['3.0', '3.1', '3.2', '
|
|
31
|
+
ruby-version: ['3.0', '3.1', '3.2', '3.3', '3.4']
|
|
32
32
|
steps:
|
|
33
33
|
- name: Check out branch
|
|
34
|
-
uses: actions/checkout@
|
|
34
|
+
uses: actions/checkout@v6
|
|
35
35
|
- name: Set up Ruby
|
|
36
36
|
uses: ruby/setup-ruby@v1
|
|
37
37
|
with:
|
data/.rspec
CHANGED
data/.rubocop.yml
CHANGED
data/.rubocop_todo.yml
CHANGED
|
@@ -29,6 +29,11 @@ Gemspec/RequiredRubyVersion:
|
|
|
29
29
|
Exclude:
|
|
30
30
|
- 'grape-entity.gemspec'
|
|
31
31
|
|
|
32
|
+
# Offense count: 1
|
|
33
|
+
Style/OneClassPerFile:
|
|
34
|
+
Exclude:
|
|
35
|
+
- 'bench/serializing.rb'
|
|
36
|
+
|
|
32
37
|
# Offense count: 6
|
|
33
38
|
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
34
39
|
Lint/BooleanSymbol:
|
data/CHANGELOG.md
CHANGED
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
### Next
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
### 1.0.2 (2026-04-13)
|
|
4
|
+
|
|
5
|
+
#### Fixes
|
|
6
|
+
|
|
7
|
+
* [#394](https://github.com/ruby-grape/grape-entity/pull/394): Add `Entity.[]` for Grape >= 3.2 param type compatibility - [@numbata](https://github.com/numbata).
|
|
8
|
+
* [#388](https://github.com/ruby-grape/grape-entity/pull/388): Drop ruby-head from test matrix - [@numbata](https://github.com/numbata).
|
|
9
|
+
* [#384](https://github.com/ruby-grape/grape-entity/pull/384): Fix `inspect` to correctly handle `nil` values - [@fcce](https://github.com/fcce).
|
|
4
10
|
|
|
5
|
-
|
|
11
|
+
### 1.0.1 (2024-04-10)
|
|
6
12
|
|
|
7
13
|
#### Fixes
|
|
8
14
|
|
|
9
|
-
*
|
|
15
|
+
* [#381](https://github.com/ruby-grape/grape-entity/pull/381): Fix `expose_nil: false` when using a block - [@magni-](https://github.com/magni-).
|
|
10
16
|
|
|
11
17
|
|
|
12
|
-
###
|
|
18
|
+
### 1.0.0 (2023-02-16)
|
|
13
19
|
|
|
14
20
|
#### Fixes
|
|
15
21
|
|
data/README.md
CHANGED
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
- [Using Entities](#using-entities)
|
|
34
34
|
- [Entity Organization](#entity-organization)
|
|
35
35
|
- [Caveats](#caveats)
|
|
36
|
+
- [Preloading Associations](#preloading-associations)
|
|
36
37
|
- [Installation](#installation)
|
|
37
38
|
- [Testing with Entities](#testing-with-entities)
|
|
38
39
|
- [Project Resources](#project-resources)
|
|
@@ -674,6 +675,10 @@ end
|
|
|
674
675
|
|
|
675
676
|
Also note that an `ArgumentError` is raised when unknown options are passed to either `expose` or `with_options`.
|
|
676
677
|
|
|
678
|
+
### Preloading Associations
|
|
679
|
+
|
|
680
|
+
Use [Grape::Entity::Preloader](https://github.com/OuYangJinTing/grape-entity-preloader) to preload associations and callbacks and avoid N+1 operations.
|
|
681
|
+
|
|
677
682
|
## Installation
|
|
678
683
|
|
|
679
684
|
Add this line to your application's Gemfile:
|
data/bench/serializing.rb
CHANGED
|
@@ -35,7 +35,7 @@ module Models
|
|
|
35
35
|
attr_accessor :tenure
|
|
36
36
|
|
|
37
37
|
def initialize(opts = {})
|
|
38
|
-
super
|
|
38
|
+
super
|
|
39
39
|
@tenure = opts[:tenure]
|
|
40
40
|
end
|
|
41
41
|
end
|
|
@@ -44,7 +44,7 @@ module Models
|
|
|
44
44
|
attr_reader :grade
|
|
45
45
|
|
|
46
46
|
def initialize(opts = {})
|
|
47
|
-
super
|
|
47
|
+
super
|
|
48
48
|
@grade = opts[:grade]
|
|
49
49
|
end
|
|
50
50
|
end
|
data/grape-entity.gemspec
CHANGED
|
@@ -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 = '>=
|
|
17
|
+
s.required_ruby_version = '>= 3.0'
|
|
18
18
|
|
|
19
|
-
s.
|
|
20
|
-
# FIXME: remove dependecy
|
|
21
|
-
s.add_runtime_dependency 'multi_json', '>= 1.3.2'
|
|
19
|
+
s.add_dependency 'activesupport', '>= 3.0.0'
|
|
22
20
|
|
|
23
21
|
s.files = `git ls-files`.split("\n")
|
|
24
22
|
s.test_files = `git ls-files -- {test,spec}/*`.split("\n")
|
|
@@ -4,8 +4,8 @@ module Grape
|
|
|
4
4
|
class Entity
|
|
5
5
|
module Condition
|
|
6
6
|
class Base
|
|
7
|
-
def self.new(inverse,
|
|
8
|
-
super(inverse).tap { |e| e.setup(
|
|
7
|
+
def self.new(inverse, ...)
|
|
8
|
+
super(inverse).tap { |e| e.setup(...) }
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def initialize(inverse = false)
|
data/lib/grape_entity/entity.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require '
|
|
3
|
+
require 'grape_entity/json'
|
|
4
4
|
|
|
5
5
|
module Grape
|
|
6
6
|
# An Entity is a lightweight structure that allows you to easily
|
|
@@ -129,6 +129,12 @@ module Grape
|
|
|
129
129
|
def delegation_opts
|
|
130
130
|
@delegation_opts ||= { hash_access: hash_access }
|
|
131
131
|
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
|
|
132
138
|
end
|
|
133
139
|
|
|
134
140
|
@formatters = {}
|
|
@@ -472,8 +478,13 @@ module Grape
|
|
|
472
478
|
|
|
473
479
|
# Prevent default serialization of :options or :delegator.
|
|
474
480
|
def inspect
|
|
475
|
-
|
|
476
|
-
|
|
481
|
+
object = serializable_hash
|
|
482
|
+
if object.nil?
|
|
483
|
+
"#<#{self.class.name}:#{object_id} nil>"
|
|
484
|
+
else
|
|
485
|
+
fields = object.map { |k, v| "#{k}=#{v}" }
|
|
486
|
+
"#<#{self.class.name}:#{object_id} #{fields.join(' ')}>"
|
|
487
|
+
end
|
|
477
488
|
end
|
|
478
489
|
|
|
479
490
|
def initialize(object, options = {})
|
|
@@ -514,19 +525,47 @@ module Grape
|
|
|
514
525
|
end
|
|
515
526
|
|
|
516
527
|
def exec_with_object(options, &block)
|
|
517
|
-
if block
|
|
528
|
+
arity = if symbol_to_proc_wrapper?(block)
|
|
529
|
+
ensure_block_arity!(block)
|
|
530
|
+
else
|
|
531
|
+
block.arity
|
|
532
|
+
end
|
|
533
|
+
|
|
534
|
+
if arity.zero?
|
|
518
535
|
instance_exec(object, &block)
|
|
519
536
|
else
|
|
520
537
|
instance_exec(object, options, &block)
|
|
521
538
|
end
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
539
|
+
end
|
|
540
|
+
|
|
541
|
+
def ensure_block_arity!(block)
|
|
542
|
+
# MRI currently always includes "( &:foo )" for symbol-to-proc wrappers.
|
|
543
|
+
# If this format changes in a new Ruby version, this logic must be updated.
|
|
544
|
+
origin_method_name = block.to_s.scan(/(?<=\(&:)[^)]+(?=\))/).first&.to_sym
|
|
545
|
+
return 0 unless origin_method_name
|
|
546
|
+
|
|
547
|
+
unless object.respond_to?(origin_method_name, true)
|
|
548
|
+
raise ArgumentError, <<~MSG
|
|
549
|
+
Cannot use `&:#{origin_method_name}` because that method is not defined in the object.
|
|
550
|
+
MSG
|
|
527
551
|
end
|
|
528
552
|
|
|
529
|
-
|
|
553
|
+
arity = object.method(origin_method_name).arity
|
|
554
|
+
return 0 if arity.zero?
|
|
555
|
+
|
|
556
|
+
raise ArgumentError, <<~MSG
|
|
557
|
+
Cannot use `&:#{origin_method_name}` because that method expects #{arity} argument#{'s' if arity != 1}.
|
|
558
|
+
Symbol‐to‐proc shorthand only works for zero‐argument methods.
|
|
559
|
+
MSG
|
|
560
|
+
end
|
|
561
|
+
|
|
562
|
+
def symbol_to_proc_wrapper?(block)
|
|
563
|
+
params = block.parameters
|
|
564
|
+
|
|
565
|
+
return false unless block.lambda? && block.source_location.nil?
|
|
566
|
+
return false unless params.size >= 2
|
|
567
|
+
|
|
568
|
+
params[0].first == :req && params[1].first == :rest
|
|
530
569
|
end
|
|
531
570
|
|
|
532
571
|
def exec_with_attribute(attribute, &block)
|
|
@@ -558,7 +597,7 @@ module Grape
|
|
|
558
597
|
|
|
559
598
|
def to_json(options = {})
|
|
560
599
|
options = options.to_h if options&.respond_to?(:to_h)
|
|
561
|
-
|
|
600
|
+
Grape::Entity::Json.dump(serializable_hash(options))
|
|
562
601
|
end
|
|
563
602
|
|
|
564
603
|
def to_xml(options = {})
|
|
@@ -598,10 +637,10 @@ module Grape
|
|
|
598
637
|
if existing_val.is_a?(Hash) && new_val.is_a?(Hash)
|
|
599
638
|
existing_val.merge(new_val)
|
|
600
639
|
elsif new_val.is_a?(Hash)
|
|
601
|
-
(opts["#{key}_extras"
|
|
640
|
+
(opts[:"#{key}_extras"] ||= []) << existing_val
|
|
602
641
|
new_val
|
|
603
642
|
else
|
|
604
|
-
(opts["#{key}_extras"
|
|
643
|
+
(opts[:"#{key}_extras"] ||= []) << new_val
|
|
605
644
|
existing_val
|
|
606
645
|
end
|
|
607
646
|
else
|
|
@@ -9,8 +9,8 @@ module Grape
|
|
|
9
9
|
class Base
|
|
10
10
|
attr_reader :attribute, :is_safe, :documentation, :override, :conditions, :for_merge
|
|
11
11
|
|
|
12
|
-
def self.new(attribute, options, conditions,
|
|
13
|
-
super(attribute, options, conditions).tap { |e| e.setup(
|
|
12
|
+
def self.new(attribute, options, conditions, ...)
|
|
13
|
+
super(attribute, options, conditions).tap { |e| e.setup(...) }
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def initialize(attribute, options, conditions)
|
|
@@ -54,7 +54,7 @@ module Grape
|
|
|
54
54
|
|
|
55
55
|
def expose_nil_condition(attribute, options)
|
|
56
56
|
Condition.new_unless(
|
|
57
|
-
proc do |object,
|
|
57
|
+
proc do |object, entity_options|
|
|
58
58
|
if options[:proc].nil?
|
|
59
59
|
delegator = Delegator.new(object)
|
|
60
60
|
if is_a?(Grape::Entity) && delegator.accepts_options?
|
|
@@ -63,7 +63,7 @@ module Grape
|
|
|
63
63
|
delegator.delegate(attribute).nil?
|
|
64
64
|
end
|
|
65
65
|
else
|
|
66
|
-
exec_with_object(
|
|
66
|
+
exec_with_object(entity_options, &options[:proc]).nil?
|
|
67
67
|
end
|
|
68
68
|
end
|
|
69
69
|
)
|
data/lib/grape_entity/version.rb
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'spec_helper'
|
|
4
3
|
require 'ostruct'
|
|
5
4
|
|
|
6
5
|
describe Grape::Entity do
|
|
@@ -30,9 +29,11 @@ describe Grape::Entity do
|
|
|
30
29
|
|
|
31
30
|
it 'makes sure that :format_with as a proc cannot be used with a block' do
|
|
32
31
|
# rubocop:disable Style/BlockDelimiters
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
expect {
|
|
33
|
+
subject.expose :name, format_with: proc {} do
|
|
34
|
+
p 'hi'
|
|
35
|
+
end
|
|
36
|
+
}.to raise_error ArgumentError
|
|
36
37
|
# rubocop:enable Style/BlockDelimiters
|
|
37
38
|
end
|
|
38
39
|
|
|
@@ -131,8 +132,8 @@ describe Grape::Entity do
|
|
|
131
132
|
|
|
132
133
|
context 'when expose_nil option is false and block passed' do
|
|
133
134
|
it 'does not expose if block returns nil' do
|
|
134
|
-
subject.expose(:a, expose_nil: false) do |_obj,
|
|
135
|
-
|
|
135
|
+
subject.expose(:a, expose_nil: false) do |_obj, options|
|
|
136
|
+
options[:option_a]
|
|
136
137
|
end
|
|
137
138
|
subject.expose(:b)
|
|
138
139
|
subject.expose(:c)
|
|
@@ -140,12 +141,12 @@ describe Grape::Entity do
|
|
|
140
141
|
end
|
|
141
142
|
|
|
142
143
|
it 'exposes is block returns a value' do
|
|
143
|
-
subject.expose(:a, expose_nil: false) do |_obj,
|
|
144
|
-
|
|
144
|
+
subject.expose(:a, expose_nil: false) do |_obj, options|
|
|
145
|
+
options[:option_a]
|
|
145
146
|
end
|
|
146
147
|
subject.expose(:b)
|
|
147
148
|
subject.expose(:c)
|
|
148
|
-
expect(subject.represent(model).serializable_hash).to eq(a: 100, b: nil, c: 'value')
|
|
149
|
+
expect(subject.represent(model, option_a: 100).serializable_hash).to eq(a: 100, b: nil, c: 'value')
|
|
149
150
|
end
|
|
150
151
|
end
|
|
151
152
|
end
|
|
@@ -392,6 +393,14 @@ describe Grape::Entity do
|
|
|
392
393
|
'result'
|
|
393
394
|
end
|
|
394
395
|
|
|
396
|
+
def method_with_one_arg(_object)
|
|
397
|
+
'result'
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
def method_with_multiple_args(_object, _options)
|
|
401
|
+
'result'
|
|
402
|
+
end
|
|
403
|
+
|
|
395
404
|
def raises_argument_error
|
|
396
405
|
raise ArgumentError, 'something different'
|
|
397
406
|
end
|
|
@@ -422,28 +431,49 @@ describe Grape::Entity do
|
|
|
422
431
|
end
|
|
423
432
|
|
|
424
433
|
context 'with block passed in via &' do
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
subject.expose :method_without_args, as: :that_method_without_args_again
|
|
429
|
-
|
|
430
|
-
object = SomeObject.new
|
|
431
|
-
expect do
|
|
432
|
-
subject.represent(object).value_for(:that_method_without_args)
|
|
433
|
-
end.to raise_error Grape::Entity::Deprecated
|
|
434
|
-
|
|
435
|
-
value2 = subject.represent(object).value_for(:that_method_without_args_again)
|
|
436
|
-
expect(value2).to eq('result')
|
|
437
|
-
end
|
|
438
|
-
else
|
|
439
|
-
specify do
|
|
440
|
-
subject.expose :that_method_without_args_again, &:method_without_args
|
|
434
|
+
specify do
|
|
435
|
+
subject.expose :that_method_without_args, &:method_without_args
|
|
436
|
+
subject.expose :method_without_args, as: :that_method_without_args_again
|
|
441
437
|
|
|
442
|
-
|
|
438
|
+
object = SomeObject.new
|
|
443
439
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
440
|
+
value = subject.represent(object).value_for(:method_without_args)
|
|
441
|
+
expect(value).to be_nil
|
|
442
|
+
|
|
443
|
+
value = subject.represent(object).value_for(:that_method_without_args)
|
|
444
|
+
expect(value).to eq('result')
|
|
445
|
+
|
|
446
|
+
value = subject.represent(object).value_for(:that_method_without_args_again)
|
|
447
|
+
expect(value).to eq('result')
|
|
448
|
+
end
|
|
449
|
+
end
|
|
450
|
+
|
|
451
|
+
context 'with block passed in via &' do
|
|
452
|
+
specify do
|
|
453
|
+
subject.expose :that_method_with_one_arg, &:method_with_one_arg
|
|
454
|
+
subject.expose :that_method_with_multple_args, &:method_with_multiple_args
|
|
455
|
+
|
|
456
|
+
object = SomeObject.new
|
|
457
|
+
|
|
458
|
+
expect do
|
|
459
|
+
subject.represent(object).value_for(:that_method_with_one_arg)
|
|
460
|
+
end.to raise_error ArgumentError, match(/method expects 1 argument/)
|
|
461
|
+
|
|
462
|
+
expect do
|
|
463
|
+
subject.represent(object).value_for(:that_method_with_multple_args)
|
|
464
|
+
end.to raise_error ArgumentError, match(/method expects 2 arguments/)
|
|
465
|
+
end
|
|
466
|
+
end
|
|
467
|
+
|
|
468
|
+
context 'with symbol-to-proc passed in via &' do
|
|
469
|
+
specify do
|
|
470
|
+
subject.expose :that_undefined_method, &:unknown_method
|
|
471
|
+
|
|
472
|
+
object = SomeObject.new
|
|
473
|
+
|
|
474
|
+
expect do
|
|
475
|
+
subject.represent(object).value_for(:that_undefined_method)
|
|
476
|
+
end.to raise_error ArgumentError, match(/method is not defined in the object/)
|
|
447
477
|
end
|
|
448
478
|
end
|
|
449
479
|
end
|
|
@@ -980,6 +1010,22 @@ describe Grape::Entity do
|
|
|
980
1010
|
end
|
|
981
1011
|
end
|
|
982
1012
|
|
|
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
|
+
|
|
983
1029
|
describe '.represent' do
|
|
984
1030
|
it 'returns a single entity if called with one object' do
|
|
985
1031
|
expect(subject.represent(Object.new)).to be_kind_of(subject)
|
|
@@ -993,7 +1039,7 @@ describe Grape::Entity do
|
|
|
993
1039
|
representation = subject.represent(Array.new(4) { Object.new })
|
|
994
1040
|
expect(representation).to be_kind_of Array
|
|
995
1041
|
expect(representation.size).to eq(4)
|
|
996
|
-
expect(representation.
|
|
1042
|
+
expect(representation.grep_v(subject)).to be_empty
|
|
997
1043
|
end
|
|
998
1044
|
|
|
999
1045
|
it 'adds the collection: true option if called with a collection' do
|
|
@@ -1339,7 +1385,7 @@ describe Grape::Entity do
|
|
|
1339
1385
|
expect(representation).to have_key 'things'
|
|
1340
1386
|
expect(representation['things']).to be_kind_of Array
|
|
1341
1387
|
expect(representation['things'].size).to eq 4
|
|
1342
|
-
expect(representation['things'].
|
|
1388
|
+
expect(representation['things'].grep_v(subject)).to be_empty
|
|
1343
1389
|
end
|
|
1344
1390
|
end
|
|
1345
1391
|
|
|
@@ -1348,7 +1394,7 @@ describe Grape::Entity do
|
|
|
1348
1394
|
representation = subject.represent(Array.new(4) { Object.new }, root: false)
|
|
1349
1395
|
expect(representation).to be_kind_of Array
|
|
1350
1396
|
expect(representation.size).to eq 4
|
|
1351
|
-
expect(representation.
|
|
1397
|
+
expect(representation.grep_v(subject)).to be_empty
|
|
1352
1398
|
end
|
|
1353
1399
|
it 'can use a different name' do
|
|
1354
1400
|
representation = subject.represent(Array.new(4) { Object.new }, root: 'others')
|
|
@@ -1356,7 +1402,7 @@ describe Grape::Entity do
|
|
|
1356
1402
|
expect(representation).to have_key 'others'
|
|
1357
1403
|
expect(representation['others']).to be_kind_of Array
|
|
1358
1404
|
expect(representation['others'].size).to eq 4
|
|
1359
|
-
expect(representation['others'].
|
|
1405
|
+
expect(representation['others'].grep_v(subject)).to be_empty
|
|
1360
1406
|
end
|
|
1361
1407
|
end
|
|
1362
1408
|
end
|
|
@@ -1380,7 +1426,7 @@ describe Grape::Entity do
|
|
|
1380
1426
|
representation = subject.represent(Array.new(4) { Object.new })
|
|
1381
1427
|
expect(representation).to be_kind_of Array
|
|
1382
1428
|
expect(representation.size).to eq 4
|
|
1383
|
-
expect(representation.
|
|
1429
|
+
expect(representation.grep_v(subject)).to be_empty
|
|
1384
1430
|
end
|
|
1385
1431
|
end
|
|
1386
1432
|
end
|
|
@@ -1403,7 +1449,7 @@ describe Grape::Entity do
|
|
|
1403
1449
|
expect(representation).to have_key('things')
|
|
1404
1450
|
expect(representation['things']).to be_kind_of Array
|
|
1405
1451
|
expect(representation['things'].size).to eq 4
|
|
1406
|
-
expect(representation['things'].
|
|
1452
|
+
expect(representation['things'].grep_v(subject)).to be_empty
|
|
1407
1453
|
end
|
|
1408
1454
|
end
|
|
1409
1455
|
end
|
|
@@ -1428,7 +1474,7 @@ describe Grape::Entity do
|
|
|
1428
1474
|
expect(representation).to have_key('things')
|
|
1429
1475
|
expect(representation['things']).to be_kind_of Array
|
|
1430
1476
|
expect(representation['things'].size).to eq 4
|
|
1431
|
-
expect(representation['things'].
|
|
1477
|
+
expect(representation['things'].grep_v(child_class)).to be_empty
|
|
1432
1478
|
end
|
|
1433
1479
|
end
|
|
1434
1480
|
end
|
|
@@ -1753,6 +1799,16 @@ describe Grape::Entity do
|
|
|
1753
1799
|
end
|
|
1754
1800
|
end
|
|
1755
1801
|
|
|
1802
|
+
describe '#to_json' do
|
|
1803
|
+
before do
|
|
1804
|
+
fresh_class.expose :name
|
|
1805
|
+
end
|
|
1806
|
+
|
|
1807
|
+
it 'returns a json' do
|
|
1808
|
+
expect(fresh_class.new(model).to_json).to eq(JSON.generate(attributes.slice(:name)))
|
|
1809
|
+
end
|
|
1810
|
+
end
|
|
1811
|
+
|
|
1756
1812
|
describe '#inspect' do
|
|
1757
1813
|
before do
|
|
1758
1814
|
fresh_class.class_eval do
|
|
@@ -1767,6 +1823,11 @@ describe Grape::Entity do
|
|
|
1767
1823
|
expect(data).to_not include '@options'
|
|
1768
1824
|
expect(data).to_not include '@delegator'
|
|
1769
1825
|
end
|
|
1826
|
+
|
|
1827
|
+
it 'returns a nil string when subject is nil' do
|
|
1828
|
+
data = subject.class.new(nil).inspect
|
|
1829
|
+
expect(data).to include 'nil'
|
|
1830
|
+
end
|
|
1770
1831
|
end
|
|
1771
1832
|
|
|
1772
1833
|
describe '#value_for' do
|
|
@@ -1794,7 +1855,7 @@ describe Grape::Entity do
|
|
|
1794
1855
|
|
|
1795
1856
|
it 'instantiates a representation if that is called for' do
|
|
1796
1857
|
rep = subject.value_for(:friends)
|
|
1797
|
-
expect(rep.
|
|
1858
|
+
expect(rep.grep_v(fresh_class)).to be_empty
|
|
1798
1859
|
expect(rep.first.serializable_hash[:name]).to eq 'Friend 1'
|
|
1799
1860
|
expect(rep.last.serializable_hash[:name]).to eq 'Friend 2'
|
|
1800
1861
|
end
|
|
@@ -1816,7 +1877,7 @@ describe Grape::Entity do
|
|
|
1816
1877
|
|
|
1817
1878
|
rep = subject.value_for(:friends)
|
|
1818
1879
|
expect(rep).to be_kind_of Array
|
|
1819
|
-
expect(rep.
|
|
1880
|
+
expect(rep.grep_v(EntitySpec::FriendEntity)).to be_empty
|
|
1820
1881
|
expect(rep.first.serializable_hash[:name]).to eq 'Friend 1'
|
|
1821
1882
|
expect(rep.last.serializable_hash[:name]).to eq 'Friend 2'
|
|
1822
1883
|
end
|
|
@@ -1837,7 +1898,7 @@ describe Grape::Entity do
|
|
|
1837
1898
|
|
|
1838
1899
|
rep = subject.value_for(:custom_friends)
|
|
1839
1900
|
expect(rep).to be_kind_of Array
|
|
1840
|
-
expect(rep.
|
|
1901
|
+
expect(rep.grep_v(EntitySpec::FriendEntity)).to be_empty
|
|
1841
1902
|
expect(rep.first.serializable_hash).to eq(name: 'Friend 1', email: 'friend1@example.com')
|
|
1842
1903
|
expect(rep.last.serializable_hash).to eq(name: 'Friend 2', email: 'friend2@example.com')
|
|
1843
1904
|
end
|
|
@@ -1895,7 +1956,7 @@ describe Grape::Entity do
|
|
|
1895
1956
|
|
|
1896
1957
|
rep = subject.value_for(:characteristics)
|
|
1897
1958
|
expect(rep).to be_kind_of Array
|
|
1898
|
-
expect(rep.
|
|
1959
|
+
expect(rep.grep_v(EntitySpec::CharacteristicsEntity)).to be_empty
|
|
1899
1960
|
expect(rep.first.serializable_hash[:key]).to eq 'hair_color'
|
|
1900
1961
|
expect(rep.first.serializable_hash[:value]).to eq 'brown'
|
|
1901
1962
|
end
|
|
@@ -1915,13 +1976,13 @@ describe Grape::Entity do
|
|
|
1915
1976
|
|
|
1916
1977
|
rep = subject.value_for(:friends)
|
|
1917
1978
|
expect(rep).to be_kind_of Array
|
|
1918
|
-
expect(rep.
|
|
1979
|
+
expect(rep.grep_v(EntitySpec::FriendEntity)).to be_empty
|
|
1919
1980
|
expect(rep.first.serializable_hash[:email]).to be_nil
|
|
1920
1981
|
expect(rep.last.serializable_hash[:email]).to be_nil
|
|
1921
1982
|
|
|
1922
1983
|
rep = subject.value_for(:friends, Grape::Entity::Options.new(user_type: :admin))
|
|
1923
1984
|
expect(rep).to be_kind_of Array
|
|
1924
|
-
expect(rep.
|
|
1985
|
+
expect(rep.grep_v(EntitySpec::FriendEntity)).to be_empty
|
|
1925
1986
|
expect(rep.first.serializable_hash[:email]).to eq 'friend1@example.com'
|
|
1926
1987
|
expect(rep.last.serializable_hash[:email]).to eq 'friend2@example.com'
|
|
1927
1988
|
end
|
|
@@ -1941,7 +2002,7 @@ describe Grape::Entity do
|
|
|
1941
2002
|
|
|
1942
2003
|
rep = subject.value_for(:friends, Grape::Entity::Options.new(collection: false))
|
|
1943
2004
|
expect(rep).to be_kind_of Array
|
|
1944
|
-
expect(rep.
|
|
2005
|
+
expect(rep.grep_v(EntitySpec::FriendEntity)).to be_empty
|
|
1945
2006
|
expect(rep.first.serializable_hash[:email]).to eq 'friend1@example.com'
|
|
1946
2007
|
expect(rep.last.serializable_hash[:email]).to eq 'friend2@example.com'
|
|
1947
2008
|
end
|
|
@@ -2020,7 +2081,7 @@ describe Grape::Entity do
|
|
|
2020
2081
|
rep = subject.value_for(:friends)
|
|
2021
2082
|
expect(rep).to be_kind_of Array
|
|
2022
2083
|
expect(rep.size).to eq 2
|
|
2023
|
-
expect(rep.all?
|
|
2084
|
+
expect(rep.all?(EntitySpec::UserEntity)).to be true
|
|
2024
2085
|
end
|
|
2025
2086
|
|
|
2026
2087
|
it 'class' do
|
|
@@ -2031,7 +2092,7 @@ describe Grape::Entity do
|
|
|
2031
2092
|
rep = subject.value_for(:friends)
|
|
2032
2093
|
expect(rep).to be_kind_of Array
|
|
2033
2094
|
expect(rep.size).to eq 2
|
|
2034
|
-
expect(rep.all?
|
|
2095
|
+
expect(rep.all?(EntitySpec::UserEntity)).to be true
|
|
2035
2096
|
end
|
|
2036
2097
|
end
|
|
2037
2098
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: grape-entity
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- LeFnord
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date:
|
|
12
|
+
date: 2026-04-13 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: activesupport
|
|
@@ -25,20 +25,6 @@ dependencies:
|
|
|
25
25
|
- - ">="
|
|
26
26
|
- !ruby/object:Gem::Version
|
|
27
27
|
version: 3.0.0
|
|
28
|
-
- !ruby/object:Gem::Dependency
|
|
29
|
-
name: multi_json
|
|
30
|
-
requirement: !ruby/object:Gem::Requirement
|
|
31
|
-
requirements:
|
|
32
|
-
- - ">="
|
|
33
|
-
- !ruby/object:Gem::Version
|
|
34
|
-
version: 1.3.2
|
|
35
|
-
type: :runtime
|
|
36
|
-
prerelease: false
|
|
37
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
38
|
-
requirements:
|
|
39
|
-
- - ">="
|
|
40
|
-
- !ruby/object:Gem::Version
|
|
41
|
-
version: 1.3.2
|
|
42
28
|
description: Extracted from Grape, A Ruby framework for rapid API development with
|
|
43
29
|
great conventions.
|
|
44
30
|
email:
|
|
@@ -92,6 +78,7 @@ files:
|
|
|
92
78
|
- lib/grape_entity/exposure/nesting_exposure/nested_exposures.rb
|
|
93
79
|
- lib/grape_entity/exposure/nesting_exposure/output_builder.rb
|
|
94
80
|
- lib/grape_entity/exposure/represent_exposure.rb
|
|
81
|
+
- lib/grape_entity/json.rb
|
|
95
82
|
- lib/grape_entity/options.rb
|
|
96
83
|
- lib/grape_entity/version.rb
|
|
97
84
|
- spec/grape_entity/entity_spec.rb
|
|
@@ -99,6 +86,7 @@ files:
|
|
|
99
86
|
- spec/grape_entity/exposure/represent_exposure_spec.rb
|
|
100
87
|
- spec/grape_entity/exposure_spec.rb
|
|
101
88
|
- spec/grape_entity/hash_spec.rb
|
|
89
|
+
- spec/grape_entity/json_spec.rb
|
|
102
90
|
- spec/grape_entity/options_spec.rb
|
|
103
91
|
- spec/spec_helper.rb
|
|
104
92
|
homepage: https://github.com/ruby-grape/grape-entity
|
|
@@ -113,14 +101,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
113
101
|
requirements:
|
|
114
102
|
- - ">="
|
|
115
103
|
- !ruby/object:Gem::Version
|
|
116
|
-
version: '
|
|
104
|
+
version: '3.0'
|
|
117
105
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
118
106
|
requirements:
|
|
119
107
|
- - ">="
|
|
120
108
|
- !ruby/object:Gem::Version
|
|
121
109
|
version: '0'
|
|
122
110
|
requirements: []
|
|
123
|
-
rubygems_version: 3.
|
|
111
|
+
rubygems_version: 3.5.22
|
|
124
112
|
signing_key:
|
|
125
113
|
specification_version: 4
|
|
126
114
|
summary: A simple facade for managing the relationship between your model and API.
|
|
@@ -130,5 +118,6 @@ test_files:
|
|
|
130
118
|
- spec/grape_entity/exposure/represent_exposure_spec.rb
|
|
131
119
|
- spec/grape_entity/exposure_spec.rb
|
|
132
120
|
- spec/grape_entity/hash_spec.rb
|
|
121
|
+
- spec/grape_entity/json_spec.rb
|
|
133
122
|
- spec/grape_entity/options_spec.rb
|
|
134
123
|
- spec/spec_helper.rb
|