grape-entity 0.6.1 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +5 -5
  2. data/.coveralls.yml +1 -0
  3. data/.gitignore +5 -1
  4. data/.rubocop.yml +31 -0
  5. data/.rubocop_todo.yml +29 -16
  6. data/.travis.yml +15 -10
  7. data/CHANGELOG.md +18 -0
  8. data/Dangerfile +2 -0
  9. data/Gemfile +6 -1
  10. data/README.md +82 -1
  11. data/Rakefile +2 -2
  12. data/bench/serializing.rb +2 -0
  13. data/grape-entity.gemspec +9 -7
  14. data/lib/grape-entity.rb +2 -0
  15. data/lib/grape_entity.rb +2 -0
  16. data/lib/grape_entity/condition.rb +20 -11
  17. data/lib/grape_entity/condition/base.rb +2 -0
  18. data/lib/grape_entity/condition/block_condition.rb +3 -1
  19. data/lib/grape_entity/condition/hash_condition.rb +2 -0
  20. data/lib/grape_entity/condition/symbol_condition.rb +2 -0
  21. data/lib/grape_entity/delegator.rb +10 -9
  22. data/lib/grape_entity/delegator/base.rb +2 -0
  23. data/lib/grape_entity/delegator/fetchable_object.rb +2 -0
  24. data/lib/grape_entity/delegator/hash_object.rb +2 -0
  25. data/lib/grape_entity/delegator/openstruct_object.rb +2 -0
  26. data/lib/grape_entity/delegator/plain_object.rb +2 -0
  27. data/lib/grape_entity/entity.rb +49 -29
  28. data/lib/grape_entity/exposure.rb +58 -41
  29. data/lib/grape_entity/exposure/base.rb +14 -3
  30. data/lib/grape_entity/exposure/block_exposure.rb +2 -0
  31. data/lib/grape_entity/exposure/delegator_exposure.rb +2 -0
  32. data/lib/grape_entity/exposure/formatter_block_exposure.rb +2 -0
  33. data/lib/grape_entity/exposure/formatter_exposure.rb +2 -0
  34. data/lib/grape_entity/exposure/nesting_exposure.rb +34 -30
  35. data/lib/grape_entity/exposure/nesting_exposure/nested_exposures.rb +23 -14
  36. data/lib/grape_entity/exposure/nesting_exposure/output_builder.rb +5 -2
  37. data/lib/grape_entity/exposure/represent_exposure.rb +3 -1
  38. data/lib/grape_entity/options.rb +41 -56
  39. data/lib/grape_entity/version.rb +3 -1
  40. data/spec/grape_entity/entity_spec.rb +202 -47
  41. data/spec/grape_entity/exposure/nesting_exposure/nested_exposures_spec.rb +6 -4
  42. data/spec/grape_entity/exposure/represent_exposure_spec.rb +2 -0
  43. data/spec/grape_entity/exposure_spec.rb +14 -2
  44. data/spec/grape_entity/hash_spec.rb +2 -0
  45. data/spec/grape_entity/options_spec.rb +66 -0
  46. data/spec/spec_helper.rb +11 -0
  47. metadata +28 -39
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 04e39a2c99114bcf750f4ca63fa6119ffa0cd5ca
4
- data.tar.gz: 1875a1693ff3de51c40db11a8c755464a93f09bd
2
+ SHA256:
3
+ metadata.gz: ecd89442adb3e014be540761d005b20920e8aa847691a69a6c4e166d1ed63f21
4
+ data.tar.gz: c556531fdea49f03dfea0ce4d1388016736c7d3987db0957be30b27a82e21e40
5
5
  SHA512:
6
- metadata.gz: 3cc6b4795400645718b1228affae6067dabb1214a13d033f0b979e096d649d03d9b05897df537c7e7d0cba2991914e958fe3d26f96b58c4ae62bfc51a63a42e7
7
- data.tar.gz: 2cec009315195a548380c46fa057036a21f8e25b7da03a368f150a3cfe2a3e290c5c67b56ccce262db8a485a51b6b130d3d760e992a6aa7d863033af3a4494d7
6
+ metadata.gz: 5a48af786a0d681229aecd0765eccfafb9f28f6178dc5ade649d54b255df13e82f24f4f5243de7cdff9d45a423d101b851137ffb7920e3853529d88fbe23f67b
7
+ data.tar.gz: b9b89ee602c3804470c57e6519244e59b78fa5b10470fb2a5d0f1581e821847ab8a6f66145fcf57445090d654c442d33cfc6fa94c6eaea9e36f15ce1038eb362
@@ -0,0 +1 @@
1
+ service_name: travis-ci
data/.gitignore CHANGED
@@ -31,9 +31,13 @@ pkg
31
31
  dist
32
32
  Gemfile.lock
33
33
  tmp
34
+ coverage/
35
+ .byebug_history
36
+ .ruby-version
37
+ .ruby-gemset
34
38
 
35
39
  ## Rubinius
36
40
  .rbx
37
41
 
38
42
  ## PROJECT::SPECIFIC
39
- .project
43
+ .project
@@ -1,6 +1,37 @@
1
1
  AllCops:
2
+ TargetRubyVersion: 2.4
3
+ Include:
4
+ - Dangerfile
5
+
2
6
  Exclude:
3
7
  - vendor/**/*
8
+ - bin/**/*
4
9
  - Guardfile
5
10
 
6
11
  inherit_from: .rubocop_todo.yml
12
+
13
+ Gemspec/RequiredRubyVersion:
14
+ Enabled: false
15
+
16
+ Naming/FileName:
17
+ Exclude:
18
+ - 'Gemfile'
19
+ - 'Rakefile'
20
+ - 'grape-entity.gemspec'
21
+ - 'lib/grape-entity.rb'
22
+
23
+ Style/Documentation:
24
+ Enabled: false
25
+
26
+ Style/MultilineIfModifier:
27
+ Enabled: false
28
+
29
+ Style/RaiseArgs:
30
+ Enabled: false
31
+
32
+ Lint/BooleanSymbol:
33
+ Exclude:
34
+ - 'spec/grape_entity/exposure_spec.rb'
35
+
36
+ Lint/UnneededDisable:
37
+ Enabled: false
@@ -1,31 +1,35 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2016-11-20 10:04:42 -0500 using RuboCop version 0.45.0.
3
+ # on 2018-01-11 18:20:10 +0100 using RuboCop version 0.52.1.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
+ # Offense count: 1
10
+ Lint/AmbiguousBlockAssociation:
11
+ Exclude:
12
+ - 'spec/grape_entity/exposure/represent_exposure_spec.rb'
13
+
9
14
  # Offense count: 6
10
15
  Metrics/AbcSize:
11
16
  Max: 32
12
17
 
18
+ # Offense count: 35
19
+ # Configuration parameters: CountComments, ExcludedMethods.
20
+ Metrics/BlockLength:
21
+ Max: 1625
22
+
13
23
  # Offense count: 2
14
24
  # Configuration parameters: CountComments.
15
25
  Metrics/ClassLength:
16
- Max: 208
26
+ Max: 210
17
27
 
18
- # Offense count: 3
28
+ # Offense count: 2
19
29
  Metrics/CyclomaticComplexity:
20
30
  Max: 11
21
31
 
22
- # Offense count: 237
23
- # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives.
24
- # URISchemes: http, https
25
- Metrics/LineLength:
26
- Max: 146
27
-
28
- # Offense count: 6
32
+ # Offense count: 7
29
33
  # Configuration parameters: CountComments.
30
34
  Metrics/MethodLength:
31
35
  Max: 28
@@ -34,12 +38,21 @@ Metrics/MethodLength:
34
38
  Metrics/PerceivedComplexity:
35
39
  Max: 13
36
40
 
37
- # Offense count: 33
38
- Style/Documentation:
39
- Enabled: false
41
+ # Offense count: 1
42
+ Style/EvalWithLocation:
43
+ Exclude:
44
+ - 'lib/grape_entity/exposure/nesting_exposure/nested_exposures.rb'
40
45
 
41
46
  # Offense count: 1
42
- # Configuration parameters: ExpectMatchingDefinition, Regex, IgnoreExecutableScripts.
43
- Style/FileName:
47
+ # Cop supports --auto-correct.
48
+ # Configuration parameters: IgnoredMethods.
49
+ # IgnoredMethods: respond_to, define_method
50
+ Style/SymbolProc:
44
51
  Exclude:
45
- - 'lib/grape-entity.rb'
52
+ - 'spec/grape_entity/entity_spec.rb'
53
+
54
+ # Offense count: 250
55
+ # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
56
+ # URISchemes: http, https
57
+ Metrics/LineLength:
58
+ Max: 146
@@ -2,24 +2,29 @@ sudo: false
2
2
 
3
3
  language: ruby
4
4
 
5
- cache: bundler
6
- bundler_args: --without test
5
+ before_install:
6
+ - gem update --system
7
+ - gem install bundler
8
+
9
+ after_success:
10
+ - coveralls
11
+ - bundle exec danger
12
+
13
+ rvm:
14
+ - 2.5.0
15
+ - 2.4.3
7
16
 
8
17
  matrix:
18
+ fast_finish: true
19
+
9
20
  include:
10
- - rvm: 2.4.0
11
- script:
12
- - bundle exec danger
13
- - rvm: 2.4.0
14
- - rvm: 2.3.3
15
- - rvm: 2.2.6
21
+ - rvm: 2.3.6
16
22
  - rvm: ruby-head
17
- - rvm: jruby-9.1.6.0
18
23
  - rvm: jruby-head
19
24
  - rvm: rbx-2
20
25
 
21
26
  allow_failures:
27
+ - rvm: 2.3.6
22
28
  - rvm: ruby-head
23
- - rvm: jruby-9.1.6.0
24
29
  - rvm: jruby-head
25
30
  - rvm: rbx-2
@@ -8,6 +8,24 @@
8
8
 
9
9
  * Your contribution here.
10
10
 
11
+ ### 0.7.0 (2018-01-25)
12
+
13
+ #### Features
14
+
15
+ * [#287](https://github.com/ruby-grape/grape-entity/pull/287): Adds ruby 2.5, drops ruby 2.2 support - [@LeFnord](https://github.com/LeFnord).
16
+ * [#277](https://github.com/ruby-grape/grape-entity/pull/277): Provide grape::entity::options#dig - [@kachick](https://github.com/kachick).
17
+ * [#265](https://github.com/ruby-grape/grape-entity/pull/265): Adds ability to provide a proc to as: - [@james2m](https://github.com/james2m).
18
+ * [#264](https://github.com/ruby-grape/grape-entity/pull/264): Adds Rubocop config and todo list - [@james2m](https://github.com/james2m).
19
+ * [#255](https://github.com/ruby-grape/grape-entity/pull/255): Adds code coverage w/ coveralls - [@LeFnord](https://github.com/LeFnord).
20
+ * [#268](https://github.com/ruby-grape/grape-entity/pull/268): Loosens the version dependency for activesupport - [@anakinj](https://github.com/anakinj).
21
+ * [#293](https://github.com/ruby-grape/grape-entity/pull/293): Adds expose_nil option - [@b-boogaard](https://github.com/b-boogaard).
22
+
23
+ #### Fixes
24
+
25
+ * [#288](https://github.com/ruby-grape/grape-entity/pull/288): Fix wrong argument exception when `&:block` passed to the expose method - [@DmitryTsepelev](https://github.com/DmitryTsepelev).
26
+ * [#291](https://github.com/ruby-grape/grape-entity/pull/291): Refactor and simplify various classes and modules - [@DmitryTsepelev](https://github.com/DmitryTsepelev).
27
+ * [#292](https://github.com/ruby-grape/grape-entity/pull/292): Allow replace non-conditional non-nesting exposures in child classes (fixes [#286](https://github.com/ruby-grape/grape-entity/issues/286)) - [@DmitryTsepelev](https://github.com/DmitryTsepelev).
28
+
11
29
  ### 0.6.1 (2017-01-09)
12
30
 
13
31
  #### Features
data/Dangerfile CHANGED
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  danger.import_dangerfile(gem: 'ruby-grape-danger')
data/Gemfile CHANGED
@@ -1,15 +1,20 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'http://rubygems.org'
2
4
 
3
5
  gemspec
4
6
 
5
7
  group :development, :test do
6
- gem 'ruby-grape-danger', '~> 0.1.1', require: false
8
+ gem 'rubocop', '~> 0.51', require: false
7
9
  end
8
10
 
9
11
  group :test do
12
+ gem 'coveralls', require: false
10
13
  gem 'growl'
11
14
  gem 'guard'
12
15
  gem 'guard-bundler'
13
16
  gem 'guard-rspec'
14
17
  gem 'rb-fsevent'
18
+ gem 'ruby-grape-danger', '~> 0.1.1', require: false
19
+ gem 'simplecov', require: false
15
20
  end
data/README.md CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  [![Gem Version](http://img.shields.io/gem/v/grape-entity.svg)](http://badge.fury.io/rb/grape-entity)
4
4
  [![Build Status](http://img.shields.io/travis/ruby-grape/grape-entity.svg)](https://travis-ci.org/ruby-grape/grape-entity)
5
+ [![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)
5
6
  [![Dependency Status](https://gemnasium.com/ruby-grape/grape-entity.svg)](https://gemnasium.com/ruby-grape/grape-entity)
6
7
  [![Code Climate](https://codeclimate.com/github/ruby-grape/grape-entity.svg)](https://codeclimate.com/github/ruby-grape/grape-entity)
7
8
 
@@ -320,7 +321,7 @@ module Entities
320
321
  with_options(format_with: :iso_timestamp) do
321
322
  expose :created_at
322
323
  expose :updated_at
323
- end
324
+ end
324
325
  end
325
326
  end
326
327
  ```
@@ -349,6 +350,86 @@ module Entities
349
350
  end
350
351
  ```
351
352
 
353
+ #### Expose Nil
354
+
355
+ By default, exposures that contain `nil` values will be represented in the resulting JSON as `null`.
356
+
357
+ As an example, a hash with the following values:
358
+
359
+ ```ruby
360
+ {
361
+ name: nil,
362
+ age: 100
363
+ }
364
+ ```
365
+
366
+ will result in a JSON object that looks like:
367
+
368
+ ```javascript
369
+ {
370
+ "name": null,
371
+ "age": 100
372
+ }
373
+ ```
374
+
375
+ There are also times when, rather than displaying an attribute with a `null` value, it is more desirable to not display the attribute at all. Using the hash from above the desired JSON would look like:
376
+
377
+ ```javascript
378
+ {
379
+ "age": 100
380
+ }
381
+ ```
382
+
383
+ In order to turn on this behavior for an as-exposure basis, the option `expose_nil` can be used. By default, `expose_nil` is considered to be `true`, meaning that `nil` values will be represented in JSON as `null`. If `false` is provided, then attributes with `nil` values will be omitted from the resulting JSON completely.
384
+
385
+ ```ruby
386
+ module Entities
387
+ class MyModel < Grape::Entity
388
+ expose :name, expose_nil: false
389
+ expose :age, expose_nil: false
390
+ end
391
+ end
392
+ ```
393
+
394
+ `expose_nil` is per exposure, so you can suppress exposures from resulting in `null` or express `null` values on a per exposure basis as you need:
395
+
396
+ ```ruby
397
+ module Entities
398
+ class MyModel < Grape::Entity
399
+ expose :name, expose_nil: false
400
+ expose :age # since expose_nil is omitted nil values will be rendered as null
401
+ end
402
+ end
403
+ ```
404
+
405
+ It is also possible to use `expose_nil` with `with_options` if you want to add the configuration to multiple exposures at once.
406
+
407
+ ```ruby
408
+ module Entities
409
+ class MyModel < Grape::Entity
410
+ # None of the exposures in the with_options block will render nil values as null
411
+ with_options(expose_nil: false) do
412
+ expose :name
413
+ expose :age
414
+ end
415
+ end
416
+ end
417
+ ```
418
+
419
+ When using `with_options`, it is possible to again override which exposures will render `nil` as `null` by adding the option on a specific exposure.
420
+
421
+ ```ruby
422
+ module Entities
423
+ class MyModel < Grape::Entity
424
+ # None of the exposures in the with_options block will render nil values as null
425
+ with_options(expose_nil: false) do
426
+ expose :name
427
+ expose :age, expose_nil: true # nil values would be rendered as null in the JSON
428
+ end
429
+ end
430
+ end
431
+ ```
432
+
352
433
  #### Documentation
353
434
 
354
435
  Expose documentation with the field. Gets bubbled up when used with Grape and various API documentation systems.
data/Rakefile CHANGED
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'rubygems'
4
4
  require 'bundler'
@@ -17,4 +17,4 @@ RSpec::Core::RakeTask.new(:spec)
17
17
  require 'rubocop/rake_task'
18
18
  RuboCop::RakeTask.new(:rubocop)
19
19
 
20
- task default: [:spec, :rubocop]
20
+ task default: %i[spec rubocop]
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
4
  require 'grape-entity'
3
5
  require 'benchmark'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  $LOAD_PATH.push File.expand_path('../lib', __FILE__)
2
4
  require 'grape_entity/version'
3
5
 
@@ -12,22 +14,22 @@ Gem::Specification.new do |s|
12
14
  s.description = 'Extracted from Grape, A Ruby framework for rapid API development with great conventions.'
13
15
  s.license = 'MIT'
14
16
 
15
- s.required_ruby_version = '>= 2.2.6'
17
+ s.required_ruby_version = '>= 2.3'
16
18
 
17
19
  s.rubyforge_project = 'grape-entity'
18
20
 
21
+ s.add_runtime_dependency 'activesupport', '>=4.0'
22
+ # FIXME: remove dependecy
19
23
  s.add_runtime_dependency 'multi_json', '>= 1.3.2'
20
- s.add_runtime_dependency 'activesupport', '>= 5.0.0'
21
24
 
22
25
  s.add_development_dependency 'bundler'
23
- s.add_development_dependency 'rake'
24
- s.add_development_dependency 'rubocop', '~> 0.40'
25
- s.add_development_dependency 'rspec', '~> 3.0'
26
- s.add_development_dependency 'rack-test'
27
26
  s.add_development_dependency 'maruku'
28
- s.add_development_dependency 'yard'
29
27
  s.add_development_dependency 'pry' unless RUBY_PLATFORM.eql?('java') || RUBY_ENGINE.eql?('rbx')
30
28
  s.add_development_dependency 'pry-byebug' unless RUBY_PLATFORM.eql?('java') || RUBY_ENGINE.eql?('rbx')
29
+ s.add_development_dependency 'rack-test'
30
+ s.add_development_dependency 'rake'
31
+ s.add_development_dependency 'rspec', '~> 3.0'
32
+ s.add_development_dependency 'yard'
31
33
 
32
34
  s.files = `git ls-files`.split("\n")
33
35
  s.test_files = `git ls-files -- {test,spec}/*`.split("\n")
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'grape_entity'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_support/version'
2
4
  require 'active_support/core_ext/string/inflections'
3
5
  require 'active_support/core_ext/hash/reverse_merge'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'grape_entity/condition/base'
2
4
  require 'grape_entity/condition/block_condition'
3
5
  require 'grape_entity/condition/hash_condition'
@@ -6,19 +8,26 @@ require 'grape_entity/condition/symbol_condition'
6
8
  module Grape
7
9
  class Entity
8
10
  module Condition
9
- def self.new_if(arg)
10
- case arg
11
- when Hash then HashCondition.new false, arg
12
- when Proc then BlockCondition.new false, &arg
13
- when Symbol then SymbolCondition.new false, arg
11
+ class << self
12
+ def new_if(arg)
13
+ condition(false, arg)
14
14
  end
15
- end
16
15
 
17
- def self.new_unless(arg)
18
- case arg
19
- when Hash then HashCondition.new true, arg
20
- when Proc then BlockCondition.new true, &arg
21
- when Symbol then SymbolCondition.new true, arg
16
+ def new_unless(arg)
17
+ condition(true, arg)
18
+ end
19
+
20
+ private
21
+
22
+ def condition(inverse, arg)
23
+ condition_klass =
24
+ case arg
25
+ when Hash then HashCondition
26
+ when Proc then BlockCondition
27
+ when Symbol then SymbolCondition
28
+ end
29
+
30
+ condition_klass.new(inverse, arg)
22
31
  end
23
32
  end
24
33
  end