grape-entity 0.5.2 → 0.6.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_todo.yml +14 -11
- data/.travis.yml +11 -12
- data/CHANGELOG.md +4 -3
- data/Gemfile +7 -22
- data/Rakefile +9 -11
- data/UPGRADING.md +13 -3
- data/grape-entity.gemspec +9 -4
- data/lib/grape_entity/condition/base.rb +2 -2
- data/lib/grape_entity/entity.rb +15 -9
- data/lib/grape_entity/exposure/base.rb +2 -2
- data/lib/grape_entity/exposure/nesting_exposure.rb +1 -5
- data/lib/grape_entity/exposure/nesting_exposure/output_builder.rb +6 -9
- data/lib/grape_entity/options.rb +33 -33
- data/lib/grape_entity/version.rb +1 -1
- data/spec/grape_entity/entity_spec.rb +44 -17
- metadata +93 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 230adb183db517d87581a13ad117183b6ed035a0
|
4
|
+
data.tar.gz: 9a7b29b6b1418f08367304c0413ebcf7a15945cf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7c09517473a2401944335070e9d9d9f48ef32358c47b936627d8997f18bcefe08692d64d8e6caa88b1e4fbc4e914c5e26a7b4af76eec2e5525fe27434395b98b
|
7
|
+
data.tar.gz: 034ba7079bc7dc1e5d1a42d011d92130ea83cef5f673137c1e4622eace4c614fdf4f695bb7614bd2c576df4369990af79c6f14423ef9c03129182810fb9ff0fa
|
data/.rubocop_todo.yml
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
# This configuration was generated by
|
2
|
-
#
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2016-11-20 10:04:42 -0500 using RuboCop version 0.45.0.
|
3
4
|
# The point is for the user to remove these configuration records
|
4
5
|
# one by one as the offenses are removed from the code base.
|
5
6
|
# Note that changes in the inspected code, or installation of new
|
@@ -7,36 +8,38 @@
|
|
7
8
|
|
8
9
|
# Offense count: 6
|
9
10
|
Metrics/AbcSize:
|
10
|
-
Max:
|
11
|
+
Max: 32
|
11
12
|
|
12
13
|
# Offense count: 2
|
13
14
|
# Configuration parameters: CountComments.
|
14
15
|
Metrics/ClassLength:
|
15
|
-
Max:
|
16
|
+
Max: 206
|
16
17
|
|
17
18
|
# Offense count: 3
|
18
19
|
Metrics/CyclomaticComplexity:
|
19
20
|
Max: 11
|
20
21
|
|
21
|
-
# Offense count:
|
22
|
-
# Configuration parameters: AllowURI, URISchemes.
|
22
|
+
# Offense count: 237
|
23
|
+
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives.
|
24
|
+
# URISchemes: http, https
|
23
25
|
Metrics/LineLength:
|
24
26
|
Max: 146
|
25
27
|
|
26
|
-
# Offense count:
|
28
|
+
# Offense count: 6
|
27
29
|
# Configuration parameters: CountComments.
|
28
30
|
Metrics/MethodLength:
|
29
31
|
Max: 28
|
30
32
|
|
31
|
-
# Offense count:
|
33
|
+
# Offense count: 2
|
32
34
|
Metrics/PerceivedComplexity:
|
33
35
|
Max: 13
|
34
36
|
|
35
|
-
# Offense count:
|
37
|
+
# Offense count: 33
|
36
38
|
Style/Documentation:
|
37
39
|
Enabled: false
|
38
40
|
|
39
41
|
# Offense count: 1
|
40
|
-
# Configuration parameters:
|
42
|
+
# Configuration parameters: ExpectMatchingDefinition, Regex, IgnoreExecutableScripts.
|
41
43
|
Style/FileName:
|
42
|
-
|
44
|
+
Exclude:
|
45
|
+
- 'lib/grape-entity.rb'
|
data/.travis.yml
CHANGED
@@ -3,25 +3,24 @@ sudo: false
|
|
3
3
|
language: ruby
|
4
4
|
|
5
5
|
cache: bundler
|
6
|
-
|
7
|
-
bundler_args: --without development
|
8
|
-
|
9
|
-
rvm:
|
10
|
-
- 2.3.1
|
11
|
-
- 2.3.0
|
12
|
-
- 2.2
|
13
|
-
- 2.1
|
14
|
-
- 2.0.0
|
15
|
-
- ruby-head
|
16
|
-
- jruby-head
|
17
|
-
- rbx-2
|
6
|
+
bundler_args: --without test
|
18
7
|
|
19
8
|
matrix:
|
20
9
|
include:
|
21
10
|
- rvm: 2.3.1
|
22
11
|
script:
|
23
12
|
- bundle exec danger
|
13
|
+
- rvm: 2.3.1
|
14
|
+
- rvm: 2.3.0
|
15
|
+
- rvm: 2.2
|
16
|
+
- rvm: 2.1
|
17
|
+
- rvm: ruby-head
|
18
|
+
- rvm: jruby-9.1.2.0
|
19
|
+
- rvm: jruby-head
|
20
|
+
- rvm: rbx-2
|
21
|
+
|
24
22
|
allow_failures:
|
25
23
|
- rvm: ruby-head
|
24
|
+
- rvm: jruby-9.1.2.0
|
26
25
|
- rvm: jruby-head
|
27
26
|
- rvm: rbx-2
|
data/CHANGELOG.md
CHANGED
@@ -1,12 +1,13 @@
|
|
1
|
-
###
|
1
|
+
### 0.6.0 (2016-11-20)
|
2
2
|
|
3
3
|
#### Features
|
4
4
|
|
5
|
-
*
|
5
|
+
* [#247](https://github.com/ruby-grape/grape-entity/pull/247): Updates dependencies; refactores to make specs green - [@LeFnord](https://github.com/LeFnord).
|
6
6
|
|
7
7
|
#### Fixes
|
8
8
|
|
9
|
-
*
|
9
|
+
* [#249](https://github.com/ruby-grape/grape-entity/issues/249): Fix leaking of options and internals in default serialization - [@dblock](https://github.com/dblock), [@KingsleyKelly](https://github.com/KingsleyKelly).
|
10
|
+
* [#248](https://github.com/ruby-grape/grape-entity/pull/248): Fix `nil` values causing errors when `merge` option passed - [@arempe93](https://github.com/arempe93).
|
10
11
|
|
11
12
|
### 0.5.2 (2016-11-14)
|
12
13
|
|
data/Gemfile
CHANGED
@@ -2,34 +2,19 @@ source 'http://rubygems.org'
|
|
2
2
|
|
3
3
|
gemspec
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
gem 'activesupport', '~> 5.0'
|
9
|
-
gem 'rack', '~> 2.0', group: [:development, :test]
|
10
|
-
else
|
11
|
-
gem 'activesupport', '~> 4.0'
|
12
|
-
gem 'rack', '< 2', group: [:development, :test]
|
5
|
+
if RUBY_VERSION < '2.2.2'
|
6
|
+
gem 'rack', '<2.0.0'
|
7
|
+
gem 'activesupport', '<5.0.0'
|
13
8
|
end
|
14
9
|
|
15
|
-
|
10
|
+
group :development, :test do
|
11
|
+
gem 'ruby-grape-danger', '~> 0.1.0', require: false
|
12
|
+
end
|
16
13
|
|
17
|
-
group :
|
18
|
-
gem 'pry'
|
14
|
+
group :test do
|
19
15
|
gem 'guard'
|
20
16
|
gem 'guard-rspec'
|
21
17
|
gem 'guard-bundler'
|
22
18
|
gem 'rb-fsevent'
|
23
19
|
gem 'growl'
|
24
20
|
end
|
25
|
-
|
26
|
-
group :development, :test do
|
27
|
-
gem 'rake'
|
28
|
-
gem 'rspec'
|
29
|
-
gem 'rack-test', '~> 0.6.2', require: 'rack/test'
|
30
|
-
gem 'rubocop', '0.31.0'
|
31
|
-
end
|
32
|
-
|
33
|
-
group :test do
|
34
|
-
gem 'ruby-grape-danger', '~> 0.1.0', require: false
|
35
|
-
end
|
data/Rakefile
CHANGED
@@ -1,22 +1,20 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
require 'rubygems'
|
2
4
|
require 'bundler'
|
3
|
-
|
5
|
+
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
|
8
|
+
require 'rake'
|
4
9
|
|
5
10
|
Bundler::GemHelper.install_tasks
|
6
11
|
|
12
|
+
require 'rspec/core'
|
7
13
|
require 'rspec/core/rake_task'
|
8
|
-
RSpec::Core::RakeTask.new(:spec) do |spec|
|
9
|
-
spec.pattern = 'spec/**/*_spec.rb'
|
10
|
-
end
|
11
14
|
|
12
|
-
RSpec::Core::RakeTask.new(:
|
13
|
-
spec.pattern = 'spec/**/*_spec.rb'
|
14
|
-
spec.rcov = true
|
15
|
-
end
|
15
|
+
RSpec::Core::RakeTask.new(:spec)
|
16
16
|
|
17
|
-
task :spec
|
18
|
-
require 'rainbow/ext/string' unless String.respond_to?(:color)
|
19
17
|
require 'rubocop/rake_task'
|
20
18
|
RuboCop::RakeTask.new(:rubocop)
|
21
19
|
|
22
|
-
task default: [:
|
20
|
+
task default: [:rubocop, :spec]
|
data/UPGRADING.md
CHANGED
@@ -1,8 +1,18 @@
|
|
1
1
|
Upgrading Grape Entity
|
2
2
|
===============
|
3
3
|
|
4
|
+
### Upgrading to >= 0.6.0
|
5
|
+
|
6
|
+
#### Changes in Grape::Entity#inspect
|
7
|
+
|
8
|
+
The `Grape::Entity#inspect` method will no longer serialize the entity presenter with its options and delegator, but the exposed entity itself, using `#serializable_hash`.
|
9
|
+
|
10
|
+
See [#250](https://github.com/ruby-grape/grape-entity/pull/250) for more information.
|
11
|
+
|
4
12
|
### Upgrading to >= 0.5.1
|
5
13
|
|
6
|
-
|
7
|
-
|
8
|
-
`nil` in negative case)
|
14
|
+
#### Changes in NestedExposures.delete_if
|
15
|
+
|
16
|
+
`Grape::Entity::Exposure::NestingExposure::NestedExposures.delete_if` always returns exposures, regardless of delete result (used to be `nil` in negative case).
|
17
|
+
|
18
|
+
See [#203](https://github.com/ruby-grape/grape-entity/pull/203) for more information.
|
data/grape-entity.gemspec
CHANGED
@@ -15,14 +15,19 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.rubyforge_project = 'grape-entity'
|
16
16
|
|
17
17
|
s.add_runtime_dependency 'multi_json', '>= 1.3.2'
|
18
|
+
s.add_runtime_dependency 'activesupport'
|
18
19
|
|
20
|
+
s.add_development_dependency 'bundler'
|
21
|
+
s.add_development_dependency 'rake'
|
22
|
+
s.add_development_dependency 'rubocop', '~> 0.40'
|
23
|
+
s.add_development_dependency 'rspec', '~> 3.0'
|
24
|
+
s.add_development_dependency 'rack-test'
|
19
25
|
s.add_development_dependency 'maruku'
|
20
26
|
s.add_development_dependency 'yard'
|
21
|
-
s.add_development_dependency '
|
22
|
-
s.add_development_dependency '
|
27
|
+
s.add_development_dependency 'pry' unless RUBY_PLATFORM.eql?('java') || RUBY_ENGINE.eql?('rbx')
|
28
|
+
s.add_development_dependency 'pry-byebug' unless RUBY_PLATFORM.eql?('java') || RUBY_ENGINE.eql?('rbx')
|
23
29
|
|
24
30
|
s.files = `git ls-files`.split("\n")
|
25
|
-
s.test_files = `git ls-files -- {test,spec
|
26
|
-
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
31
|
+
s.test_files = `git ls-files -- {test,spec}/*`.split("\n")
|
27
32
|
s.require_paths = ['lib']
|
28
33
|
end
|
@@ -11,7 +11,7 @@ module Grape
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def ==(other)
|
14
|
-
(self.class == other.class) && (
|
14
|
+
(self.class == other.class) && (inversed? == other.inversed?)
|
15
15
|
end
|
16
16
|
|
17
17
|
def inversed?
|
@@ -23,7 +23,7 @@ module Grape
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def if_value(_entity, _options)
|
26
|
-
|
26
|
+
raise NotImplementedError
|
27
27
|
end
|
28
28
|
|
29
29
|
def unless_value(entity, options)
|
data/lib/grape_entity/entity.rb
CHANGED
@@ -151,11 +151,11 @@ module Grape
|
|
151
151
|
options = merge_options(args.last.is_a?(Hash) ? args.pop : {})
|
152
152
|
|
153
153
|
if args.size > 1
|
154
|
-
|
155
|
-
|
154
|
+
raise ArgumentError, 'You may not use the :as option on multi-attribute exposures.' if options[:as]
|
155
|
+
raise ArgumentError, 'You may not use block-setting on multi-attribute exposures.' if block_given?
|
156
156
|
end
|
157
157
|
|
158
|
-
|
158
|
+
raise ArgumentError, 'You may not use block-setting when also using format_with' if block_given? && options[:format_with].respond_to?(:call)
|
159
159
|
|
160
160
|
if block_given?
|
161
161
|
if block.parameters.any?
|
@@ -214,7 +214,7 @@ module Grape
|
|
214
214
|
end
|
215
215
|
|
216
216
|
def self.cannot_unexpose!
|
217
|
-
|
217
|
+
raise "You cannot call 'unexpose` inside of nesting exposure!"
|
218
218
|
end
|
219
219
|
|
220
220
|
# Set options that will be applied to any exposures declared inside the block.
|
@@ -270,7 +270,7 @@ module Grape
|
|
270
270
|
# end
|
271
271
|
#
|
272
272
|
def self.format_with(name, &block)
|
273
|
-
|
273
|
+
raise ArgumentError, 'You must pass a block for formatters' unless block_given?
|
274
274
|
formatters[name.to_sym] = block
|
275
275
|
end
|
276
276
|
|
@@ -392,8 +392,8 @@ module Grape
|
|
392
392
|
# @option options :only [Array] all the fields that should be returned
|
393
393
|
# @option options :except [Array] all the fields that should not be returned
|
394
394
|
def self.represent(objects, options = {})
|
395
|
-
if objects.respond_to?(:to_ary) &&
|
396
|
-
root_element =
|
395
|
+
if objects.respond_to?(:to_ary) && !@present_collection
|
396
|
+
root_element = root_element(:collection_root)
|
397
397
|
inner = objects.to_ary.map { |object| new(object, options.reverse_merge(collection: true)).presented }
|
398
398
|
else
|
399
399
|
objects = { @collection_name => objects } if @present_collection
|
@@ -424,6 +424,12 @@ module Grape
|
|
424
424
|
end
|
425
425
|
end
|
426
426
|
|
427
|
+
# Prevent default serialization of :options or :delegator.
|
428
|
+
def inspect
|
429
|
+
fields = serializable_hash.map { |k, v| "#{k}=#{v}" }
|
430
|
+
"#<#{self.class.name}:#{object_id} #{fields.join(' ')}>"
|
431
|
+
end
|
432
|
+
|
427
433
|
def initialize(object, options = {})
|
428
434
|
@object = object
|
429
435
|
@delegator = Delegator.new object
|
@@ -485,7 +491,7 @@ module Grape
|
|
485
491
|
end
|
486
492
|
end
|
487
493
|
|
488
|
-
|
494
|
+
alias as_json serializable_hash
|
489
495
|
|
490
496
|
def to_json(options = {})
|
491
497
|
options = options.to_h if options && options.respond_to?(:to_h)
|
@@ -536,7 +542,7 @@ module Grape
|
|
536
542
|
# @param options [Hash] Exposure options.
|
537
543
|
def self.valid_options(options)
|
538
544
|
options.keys.each do |key|
|
539
|
-
|
545
|
+
raise ArgumentError, "#{key.inspect} is not a valid option." unless OPTIONS.include?(key)
|
540
546
|
end
|
541
547
|
|
542
548
|
options[:using] = options.delete(:with) if options.key?(:with)
|
@@ -51,12 +51,12 @@ module Grape
|
|
51
51
|
if @is_safe
|
52
52
|
is_delegatable
|
53
53
|
else
|
54
|
-
is_delegatable ||
|
54
|
+
is_delegatable || raise(NoMethodError, "#{entity.class.name} missing attribute `#{@attribute}' on #{entity.object}")
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
58
|
def value(_entity, _options)
|
59
|
-
|
59
|
+
raise NotImplementedError
|
60
60
|
end
|
61
61
|
|
62
62
|
def serializable_value(entity, options)
|
@@ -107,11 +107,7 @@ module Grape
|
|
107
107
|
# For the given key if the last candidates for exposing are nesting then combine them.
|
108
108
|
nesting_tail = []
|
109
109
|
exposures.reverse_each do |exposure|
|
110
|
-
if exposure.nesting?
|
111
|
-
nesting_tail.unshift exposure
|
112
|
-
else
|
113
|
-
break
|
114
|
-
end
|
110
|
+
nesting_tail.unshift exposure if exposure.nesting?
|
115
111
|
end
|
116
112
|
new_nested_exposures = nesting_tail.flat_map(&:nested_exposures)
|
117
113
|
NestingExposure.new(key, {}, [], new_nested_exposures).tap do |new_exposure|
|
@@ -12,23 +12,20 @@ module Grape
|
|
12
12
|
# Save a result array in collections' array if it should be merged
|
13
13
|
if result.is_a?(Array) && exposure.for_merge
|
14
14
|
@output_collection << result
|
15
|
-
|
16
|
-
|
15
|
+
elsif exposure.for_merge
|
17
16
|
# If we have an array which should not be merged - save it with a key as a hash
|
18
17
|
# If we have hash which should be merged - save it without a key (merge)
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
end
|
24
|
-
|
18
|
+
return unless result
|
19
|
+
@output_hash.merge! result, &merge_strategy(exposure.for_merge)
|
20
|
+
else
|
21
|
+
@output_hash[exposure.key] = result
|
25
22
|
end
|
26
23
|
end
|
27
24
|
|
28
25
|
def kind_of?(klass)
|
29
26
|
klass == output.class || super
|
30
27
|
end
|
31
|
-
|
28
|
+
alias is_a? kind_of?
|
32
29
|
|
33
30
|
def __getobj__
|
34
31
|
output
|
data/lib/grape_entity/options.rb
CHANGED
@@ -54,11 +54,11 @@ module Grape
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def ==(other)
|
57
|
-
if other.is_a? Options
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
57
|
+
@opts_hash == if other.is_a? Options
|
58
|
+
other.opts_hash
|
59
|
+
else
|
60
|
+
other
|
61
|
+
end
|
62
62
|
end
|
63
63
|
|
64
64
|
def should_return_key?(key)
|
@@ -79,42 +79,20 @@ module Grape
|
|
79
79
|
return nil unless @has_only
|
80
80
|
|
81
81
|
@only_fields ||= @opts_hash[:only].each_with_object({}) do |attribute, allowed_fields|
|
82
|
-
|
83
|
-
attribute.each do |attr, nested_attrs|
|
84
|
-
allowed_fields[attr] ||= []
|
85
|
-
allowed_fields[attr] += nested_attrs
|
86
|
-
end
|
87
|
-
else
|
88
|
-
allowed_fields[attribute] = true
|
89
|
-
end
|
90
|
-
end.symbolize_keys
|
91
|
-
|
92
|
-
if for_key && @only_fields[for_key].is_a?(Array)
|
93
|
-
@only_fields[for_key]
|
94
|
-
elsif for_key.nil?
|
95
|
-
@only_fields
|
82
|
+
build_symbolized_hash(attribute, allowed_fields)
|
96
83
|
end
|
84
|
+
|
85
|
+
only_for_given(for_key, @only_fields)
|
97
86
|
end
|
98
87
|
|
99
88
|
def except_fields(for_key = nil)
|
100
89
|
return nil unless @has_except
|
101
90
|
|
102
91
|
@except_fields ||= @opts_hash[:except].each_with_object({}) do |attribute, allowed_fields|
|
103
|
-
|
104
|
-
attribute.each do |attr, nested_attrs|
|
105
|
-
allowed_fields[attr] ||= []
|
106
|
-
allowed_fields[attr] += nested_attrs
|
107
|
-
end
|
108
|
-
else
|
109
|
-
allowed_fields[attribute] = true
|
110
|
-
end
|
111
|
-
end.symbolize_keys
|
112
|
-
|
113
|
-
if for_key && @except_fields[for_key].is_a?(Array)
|
114
|
-
@except_fields[for_key]
|
115
|
-
elsif for_key.nil?
|
116
|
-
@except_fields
|
92
|
+
build_symbolized_hash(attribute, allowed_fields)
|
117
93
|
end
|
94
|
+
|
95
|
+
only_for_given(for_key, @except_fields)
|
118
96
|
end
|
119
97
|
|
120
98
|
def with_attr_path(part)
|
@@ -141,6 +119,28 @@ module Grape
|
|
141
119
|
|
142
120
|
Options.new(new_opts_hash)
|
143
121
|
end
|
122
|
+
|
123
|
+
def build_symbolized_hash(attribute, hash)
|
124
|
+
if attribute.is_a?(Hash)
|
125
|
+
attribute.each do |attr, nested_attrs|
|
126
|
+
hash[attr.to_sym] = build_symbolized_hash(nested_attrs, {})
|
127
|
+
end
|
128
|
+
elsif attribute.is_a?(Array)
|
129
|
+
return attribute.each { |x| build_symbolized_hash(x, {}) }
|
130
|
+
else
|
131
|
+
hash[attribute.to_sym] = true
|
132
|
+
end
|
133
|
+
|
134
|
+
hash
|
135
|
+
end
|
136
|
+
|
137
|
+
def only_for_given(key, fields)
|
138
|
+
if key && fields[key].is_a?(Array)
|
139
|
+
fields[key]
|
140
|
+
elsif key.nil?
|
141
|
+
fields
|
142
|
+
end
|
143
|
+
end
|
144
144
|
end
|
145
145
|
end
|
146
146
|
end
|
data/lib/grape_entity/version.rb
CHANGED
@@ -50,6 +50,18 @@ describe Grape::Entity do
|
|
50
50
|
subject.expose(:special, merge: ->(_, v1, v2) { v1 && v2 ? 'brand new val' : v2 })
|
51
51
|
expect(subject.represent(nested_hash).serializable_hash).to eq(like_nested_hash: 'brand new val')
|
52
52
|
end
|
53
|
+
|
54
|
+
context 'and nested object is nil' do
|
55
|
+
let(:nested_hash) do
|
56
|
+
{ something: nil, special: { like_nested_hash: '12' } }
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'adds nothing to output' do
|
60
|
+
subject.expose(:something, merge: true)
|
61
|
+
subject.expose(:special)
|
62
|
+
expect(subject.represent(nested_hash).serializable_hash).to eq(special: { like_nested_hash: '12' })
|
63
|
+
end
|
64
|
+
end
|
53
65
|
end
|
54
66
|
|
55
67
|
context 'with a block' do
|
@@ -277,8 +289,7 @@ describe Grape::Entity do
|
|
277
289
|
end
|
278
290
|
|
279
291
|
additional_hash = { users: [{ id: 1, name: 'John' }, { id: 2, name: 'Jay' }],
|
280
|
-
admins: [{ id: 3, name: 'Jack' }, { id: 4, name: 'James' }]
|
281
|
-
}
|
292
|
+
admins: [{ id: 3, name: 'Jack' }, { id: 4, name: 'James' }] }
|
282
293
|
expect(subject.represent(additional_hash).serializable_hash).to eq(
|
283
294
|
profiles: additional_hash[:users] + additional_hash[:admins],
|
284
295
|
awesome: { just_a_key: 'value', just_another_key: 'value' }
|
@@ -342,20 +353,20 @@ describe Grape::Entity do
|
|
342
353
|
|
343
354
|
subject.expose :birthday, format_with: :timestamp
|
344
355
|
|
345
|
-
model
|
356
|
+
model = { birthday: Time.gm(2012, 2, 27) }
|
346
357
|
expect(subject.new(double(model)).as_json[:birthday]).to eq '02/27/2012'
|
347
358
|
end
|
348
359
|
|
349
360
|
it 'formats an exposure with a :format_with lambda that returns a value from the entity instance' do
|
350
361
|
object = {}
|
351
362
|
|
352
|
-
subject.expose(:size, format_with: ->(_value) {
|
363
|
+
subject.expose(:size, format_with: ->(_value) { object.class.to_s })
|
353
364
|
expect(subject.represent(object).value_for(:size)).to eq object.class.to_s
|
354
365
|
end
|
355
366
|
|
356
367
|
it 'formats an exposure with a :format_with symbol that returns a value from the entity instance' do
|
357
368
|
subject.format_with :size_formatter do |_date|
|
358
|
-
|
369
|
+
object.class.to_s
|
359
370
|
end
|
360
371
|
|
361
372
|
object = {}
|
@@ -366,7 +377,7 @@ describe Grape::Entity do
|
|
366
377
|
|
367
378
|
it 'works global on Grape::Entity' do
|
368
379
|
Grape::Entity.format_with :size_formatter do |_date|
|
369
|
-
|
380
|
+
object.class.to_s
|
370
381
|
end
|
371
382
|
object = {}
|
372
383
|
|
@@ -597,14 +608,14 @@ describe Grape::Entity do
|
|
597
608
|
end
|
598
609
|
|
599
610
|
it 'returns multiple entities if called with a collection' do
|
600
|
-
representation = subject.represent(4
|
611
|
+
representation = subject.represent(Array.new(4) { Object.new })
|
601
612
|
expect(representation).to be_kind_of Array
|
602
613
|
expect(representation.size).to eq(4)
|
603
614
|
expect(representation.reject { |r| r.is_a?(subject) }).to be_empty
|
604
615
|
end
|
605
616
|
|
606
617
|
it 'adds the collection: true option if called with a collection' do
|
607
|
-
representation = subject.represent(4
|
618
|
+
representation = subject.represent(Array.new(4) { Object.new })
|
608
619
|
representation.each { |r| expect(r.options[:collection]).to be true }
|
609
620
|
end
|
610
621
|
|
@@ -616,7 +627,7 @@ describe Grape::Entity do
|
|
616
627
|
|
617
628
|
it 'returns a serialized array of hashes of multiple objects if serializable: true' do
|
618
629
|
subject.expose(:awesome) { |_| true }
|
619
|
-
representation = subject.represent(2
|
630
|
+
representation = subject.represent(Array.new(2) { Object.new }, serializable: true)
|
620
631
|
expect(representation).to eq([{ awesome: true }, { awesome: true }])
|
621
632
|
end
|
622
633
|
|
@@ -891,7 +902,7 @@ describe Grape::Entity do
|
|
891
902
|
subject.present_collection true
|
892
903
|
subject.expose :items
|
893
904
|
|
894
|
-
representation = subject.represent(4
|
905
|
+
representation = subject.represent(Array.new(4) { Object.new })
|
895
906
|
expect(representation).to be_kind_of(subject)
|
896
907
|
expect(representation.object).to be_kind_of(Hash)
|
897
908
|
expect(representation.object).to have_key :items
|
@@ -903,7 +914,7 @@ describe Grape::Entity do
|
|
903
914
|
subject.present_collection true, :my_items
|
904
915
|
subject.expose :my_items
|
905
916
|
|
906
|
-
representation = subject.represent(4
|
917
|
+
representation = subject.represent(Array.new(4) { Object.new }, serializable: true)
|
907
918
|
expect(representation).to be_kind_of(Grape::Entity::Exposure::NestingExposure::OutputBuilder)
|
908
919
|
expect(representation).to be_kind_of(Hash)
|
909
920
|
expect(representation).to have_key :my_items
|
@@ -929,7 +940,7 @@ describe Grape::Entity do
|
|
929
940
|
|
930
941
|
context 'with an array of objects' do
|
931
942
|
it 'allows a root element name to be specified' do
|
932
|
-
representation = subject.represent(4
|
943
|
+
representation = subject.represent(Array.new(4) { Object.new })
|
933
944
|
expect(representation).to be_kind_of Hash
|
934
945
|
expect(representation).to have_key 'things'
|
935
946
|
expect(representation['things']).to be_kind_of Array
|
@@ -940,13 +951,13 @@ describe Grape::Entity do
|
|
940
951
|
|
941
952
|
context 'it can be overridden' do
|
942
953
|
it 'can be disabled' do
|
943
|
-
representation = subject.represent(4
|
954
|
+
representation = subject.represent(Array.new(4) { Object.new }, root: false)
|
944
955
|
expect(representation).to be_kind_of Array
|
945
956
|
expect(representation.size).to eq 4
|
946
957
|
expect(representation.reject { |r| r.is_a?(subject) }).to be_empty
|
947
958
|
end
|
948
959
|
it 'can use a different name' do
|
949
|
-
representation = subject.represent(4
|
960
|
+
representation = subject.represent(Array.new(4) { Object.new }, root: 'others')
|
950
961
|
expect(representation).to be_kind_of Hash
|
951
962
|
expect(representation).to have_key 'others'
|
952
963
|
expect(representation['others']).to be_kind_of Array
|
@@ -972,7 +983,7 @@ describe Grape::Entity do
|
|
972
983
|
|
973
984
|
context 'with an array of objects' do
|
974
985
|
it 'allows a root element name to be specified' do
|
975
|
-
representation = subject.represent(4
|
986
|
+
representation = subject.represent(Array.new(4) { Object.new })
|
976
987
|
expect(representation).to be_kind_of Array
|
977
988
|
expect(representation.size).to eq 4
|
978
989
|
expect(representation.reject { |r| r.is_a?(subject) }).to be_empty
|
@@ -993,7 +1004,7 @@ describe Grape::Entity do
|
|
993
1004
|
|
994
1005
|
context 'with an array of objects' do
|
995
1006
|
it 'allows a root element name to be specified' do
|
996
|
-
representation = subject.represent(4
|
1007
|
+
representation = subject.represent(Array.new(4) { Object.new })
|
997
1008
|
expect(representation).to be_kind_of Hash
|
998
1009
|
expect(representation).to have_key('things')
|
999
1010
|
expect(representation['things']).to be_kind_of Array
|
@@ -1018,7 +1029,7 @@ describe Grape::Entity do
|
|
1018
1029
|
|
1019
1030
|
it 'inherits array root root' do
|
1020
1031
|
child_class = Class.new(subject)
|
1021
|
-
representation = child_class.represent(4
|
1032
|
+
representation = child_class.represent(Array.new(4) { Object.new })
|
1022
1033
|
expect(representation).to be_kind_of Hash
|
1023
1034
|
expect(representation).to have_key('things')
|
1024
1035
|
expect(representation['things']).to be_kind_of Array
|
@@ -1336,6 +1347,22 @@ describe Grape::Entity do
|
|
1336
1347
|
end
|
1337
1348
|
end
|
1338
1349
|
|
1350
|
+
describe '#inspect' do
|
1351
|
+
before do
|
1352
|
+
fresh_class.class_eval do
|
1353
|
+
expose :name, :email
|
1354
|
+
end
|
1355
|
+
end
|
1356
|
+
|
1357
|
+
it 'does not serialize delegator or options' do
|
1358
|
+
data = subject.inspect
|
1359
|
+
expect(data).to include 'name='
|
1360
|
+
expect(data).to include 'email='
|
1361
|
+
expect(data).to_not include '@options'
|
1362
|
+
expect(data).to_not include '@delegator'
|
1363
|
+
end
|
1364
|
+
end
|
1365
|
+
|
1339
1366
|
describe '#value_for' do
|
1340
1367
|
before do
|
1341
1368
|
fresh_class.class_eval do
|
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.6.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: 2016-11-
|
11
|
+
date: 2016-11-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: multi_json
|
@@ -25,7 +25,21 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 1.3.2
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: activesupport
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
30
44
|
requirements:
|
31
45
|
- - ">="
|
@@ -39,7 +53,7 @@ dependencies:
|
|
39
53
|
- !ruby/object:Gem::Version
|
40
54
|
version: '0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
56
|
+
name: rake
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
44
58
|
requirements:
|
45
59
|
- - ">="
|
@@ -52,22 +66,92 @@ dependencies:
|
|
52
66
|
- - ">="
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.40'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.40'
|
55
83
|
- !ruby/object:Gem::Dependency
|
56
84
|
name: rspec
|
57
85
|
requirement: !ruby/object:Gem::Requirement
|
58
86
|
requirements:
|
59
87
|
- - "~>"
|
60
88
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
89
|
+
version: '3.0'
|
62
90
|
type: :development
|
63
91
|
prerelease: false
|
64
92
|
version_requirements: !ruby/object:Gem::Requirement
|
65
93
|
requirements:
|
66
94
|
- - "~>"
|
67
95
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
96
|
+
version: '3.0'
|
69
97
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
98
|
+
name: rack-test
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: maruku
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: yard
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: pry
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: pry-byebug
|
71
155
|
requirement: !ruby/object:Gem::Requirement
|
72
156
|
requirements:
|
73
157
|
- - ">="
|
@@ -158,7 +242,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
158
242
|
version: '0'
|
159
243
|
requirements: []
|
160
244
|
rubyforge_project: grape-entity
|
161
|
-
rubygems_version: 2.
|
245
|
+
rubygems_version: 2.5.1
|
162
246
|
signing_key:
|
163
247
|
specification_version: 4
|
164
248
|
summary: A simple facade for managing the relationship between your model and API.
|
@@ -169,3 +253,4 @@ test_files:
|
|
169
253
|
- spec/grape_entity/exposure_spec.rb
|
170
254
|
- spec/grape_entity/hash_spec.rb
|
171
255
|
- spec/spec_helper.rb
|
256
|
+
has_rdoc:
|