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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f98548d9171133e0bf95ba1e4ce84b148a124e7e3b6927054bdd748986e833fb
4
- data.tar.gz: 641d9453158181536d24f5f9c907e8e5eee45bbf76ad746db94bd77815329749
3
+ metadata.gz: 8beeb296491f1be5721d415c0a3b9a3bfc5caeede002c8bc4a2e009fc83706f1
4
+ data.tar.gz: 5d219fab3a94ecae43c7f253682fc3d6640723ad27e4e75020b9cecc359ae7d1
5
5
  SHA512:
6
- metadata.gz: 7df4614a5dddfc479d691b5d6e4c1c7644bb7cfe11ec8ac5256d962d63551530ccaed1eb8c56c70218eba0ec370a37f15e83aae148753cc29036148bdea43514
7
- data.tar.gz: 985b7ad4f9a2d9f70d5fe5c207fc5ab1cf78529c0cf62bed66b22274038d36e4fb6ffe5c0af7367b5c3c6e13093799130c875e29c9d33ea462f3e9cb721d4ff4
6
+ metadata.gz: 4063dd57bec2dd189ee05e492fc6a1d36dceb45be1e5c02f16749dba303557490494e874d8f302ae668e51b846035efb5e8e10977273127f57e05d175390cd3b
7
+ data.tar.gz: 06d176afda782549915c74f0085f641047e0077270e507725fbd1c1c9ad7f929b75362d54c73e20626e0643ef4c3c54de2f75cf1ed678d72ee868406deaa1226
@@ -15,10 +15,10 @@ jobs:
15
15
  rubocop:
16
16
  runs-on: ubuntu-latest
17
17
  steps:
18
- - uses: actions/checkout@v3
18
+ - uses: actions/checkout@v6
19
19
  - uses: ruby/setup-ruby@v1
20
20
  with:
21
- ruby-version: '3.2'
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', 'head']
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@v3
34
+ uses: actions/checkout@v6
35
35
  - name: Set up Ruby
36
36
  uses: ruby/setup-ruby@v1
37
37
  with:
data/.rspec CHANGED
@@ -1,3 +1,4 @@
1
+ --require spec_helper
1
2
  --color
2
3
  --profile
3
4
  --format documentation
data/.rubocop.yml CHANGED
@@ -5,7 +5,7 @@ AllCops:
5
5
  - vendor/**/*
6
6
  - example/**/*
7
7
  NewCops: enable
8
- TargetRubyVersion: 3.2
8
+ TargetRubyVersion: 3.0
9
9
  SuggestExtensions: false
10
10
 
11
11
  # Layout stuff
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
- #### Features
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
- * Your contribution here.
11
+ ### 1.0.1 (2024-04-10)
6
12
 
7
13
  #### Fixes
8
14
 
9
- * Your contribution here.
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
- ### ### 1.0.0 (2023-02-16)
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(opts)
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(opts)
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 = '>= 2.7'
17
+ s.required_ruby_version = '>= 3.0'
18
18
 
19
- s.add_runtime_dependency 'activesupport', '>= 3.0.0'
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, *args, &block)
8
- super(inverse).tap { |e| e.setup(*args, &block) }
7
+ def self.new(inverse, ...)
8
+ super(inverse).tap { |e| e.setup(...) }
9
9
  end
10
10
 
11
11
  def initialize(inverse = false)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'multi_json'
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
- fields = serializable_hash.map { |k, v| "#{k}=#{v}" }
476
- "#<#{self.class.name}:#{object_id} #{fields.join(' ')}>"
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.parameters.count == 1
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
- rescue StandardError => e
523
- # it handles: https://github.com/ruby/ruby/blob/v3_0_0_preview1/NEWS.md#language-changes point 3, Proc
524
- # accounting for expose :foo, &:bar
525
- if e.is_a?(ArgumentError) && block.parameters == [[:req], [:rest]]
526
- raise Grape::Entity::Deprecated.new e.message, 'in ruby 3.0'
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
- raise e
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
- MultiJson.dump(serializable_hash(options))
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".to_sym] ||= []) << existing_val
640
+ (opts[:"#{key}_extras"] ||= []) << existing_val
602
641
  new_val
603
642
  else
604
- (opts["#{key}_extras".to_sym] ||= []) << new_val
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, *args, &block)
13
- super(attribute, options, conditions).tap { |e| e.setup(*args, &block) }
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, _options|
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(options, &options[:proc]).nil?
66
+ exec_with_object(entity_options, &options[:proc]).nil?
67
67
  end
68
68
  end
69
69
  )
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grape
4
+ class Entity
5
+ if defined?(::MultiJson)
6
+ Json = ::MultiJson
7
+ else
8
+ Json = ::JSON
9
+ Json::ParseError = Json::ParserError
10
+ end
11
+ end
12
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GrapeEntity
4
- VERSION = '1.0.0'
4
+ VERSION = '1.0.2'
5
5
  end
@@ -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
- # rubocop:disable Lint/Debugger
34
- expect { subject.expose :name, format_with: proc {} do p 'hi' end }.to raise_error ArgumentError
35
- # rubocop:enable Lint/Debugger
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, _options|
135
- nil
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, _options|
144
- 100
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
- if RUBY_VERSION.start_with?('3')
426
- specify do
427
- subject.expose :that_method_without_args, &:method_without_args
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
- object = SomeObject.new
438
+ object = SomeObject.new
443
439
 
444
- value2 = subject.represent(object).value_for(:that_method_without_args_again)
445
- expect(value2).to eq('result')
446
- end
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.reject { |r| r.is_a?(subject) }).to be_empty
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'].reject { |r| r.is_a?(subject) }).to be_empty
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.reject { |r| r.is_a?(subject) }).to be_empty
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'].reject { |r| r.is_a?(subject) }).to be_empty
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.reject { |r| r.is_a?(subject) }).to be_empty
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'].reject { |r| r.is_a?(subject) }).to be_empty
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'].reject { |r| r.is_a?(child_class) }).to be_empty
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.reject { |r| r.is_a?(fresh_class) }).to be_empty
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.reject { |r| r.is_a?(EntitySpec::FriendEntity) }).to be_empty
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.reject { |r| r.is_a?(EntitySpec::FriendEntity) }).to be_empty
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.reject { |r| r.is_a?(EntitySpec::CharacteristicsEntity) }).to be_empty
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.reject { |r| r.is_a?(EntitySpec::FriendEntity) }).to be_empty
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.reject { |r| r.is_a?(EntitySpec::FriendEntity) }).to be_empty
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.reject { |r| r.is_a?(EntitySpec::FriendEntity) }).to be_empty
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? { |r| r.is_a?(EntitySpec::UserEntity) }).to be true
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? { |r| r.is_a?(EntitySpec::UserEntity) }).to be true
2095
+ expect(rep.all?(EntitySpec::UserEntity)).to be true
2035
2096
  end
2036
2097
  end
2037
2098
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Entity::Exposure::NestingExposure::NestedExposures do
6
4
  subject(:nested_exposures) { described_class.new([]) }
7
5
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Entity::Exposure::RepresentExposure do
6
4
  subject(:exposure) { described_class.new(:foo, {}, {}, double, double) }
7
5
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Entity::Exposure do
6
4
  let(:fresh_class) { Class.new(Grape::Entity) }
7
5
  let(:model) { double(attributes) }
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Entity do
6
4
  it 'except option for nested entity', :aggregate_failures do
7
5
  module EntitySpec
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe Grape::Entity::Json do
4
+ subject { described_class }
5
+
6
+ it { is_expected.to eq(JSON) }
7
+ end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Entity::Options do
6
4
  module EntitySpec
7
5
  class Crystalline
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.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: 2023-02-16 00:00:00.000000000 Z
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: '2.7'
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.4.6
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