grape-entity 0.8.0 → 0.10.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/.github/dependabot.yml +14 -0
- data/.github/workflows/rubocop.yml +26 -0
- data/.github/workflows/ruby.yml +26 -0
- data/.rubocop.yml +42 -4
- data/.rubocop_todo.yml +2 -8
- data/CHANGELOG.md +55 -1
- data/Gemfile +2 -2
- data/README.md +53 -3
- data/UPGRADING.md +19 -2
- data/bench/serializing.rb +5 -0
- data/grape-entity.gemspec +1 -1
- data/lib/grape_entity/condition/base.rb +1 -1
- data/lib/grape_entity/delegator/fetchable_object.rb +1 -1
- data/lib/grape_entity/delegator/openstruct_object.rb +1 -1
- data/lib/grape_entity/delegator/plain_object.rb +1 -1
- data/lib/grape_entity/deprecated.rb +13 -0
- data/lib/grape_entity/entity.rb +20 -7
- data/lib/grape_entity/exposure/base.rb +7 -5
- data/lib/grape_entity/exposure/nesting_exposure/nested_exposures.rb +2 -0
- data/lib/grape_entity/exposure/nesting_exposure/output_builder.rb +2 -0
- data/lib/grape_entity/exposure/nesting_exposure.rb +1 -0
- data/lib/grape_entity/options.rb +3 -2
- data/lib/grape_entity/version.rb +1 -1
- data/lib/grape_entity.rb +1 -0
- data/spec/grape_entity/entity_spec.rb +177 -16
- data/spec/spec_helper.rb +1 -1
- metadata +11 -8
- data/.travis.yml +0 -25
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 7c0080bab47d3cd3667c29ef580dcca4977ba5572d95c56304dd55cc444456fc
         | 
| 4 | 
            +
              data.tar.gz: 40b564ee118de1a2a5b36dcff7526ca6bb1c54d738b7ac2191b1a208a583add1
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 06564de07c6a909a3dbd4c3839902f529c5c44291f1a0669bcbc3dca7ea1e015db71887ca9f46132ef5bf4bb01fd10fced74b09ac392f3678903d39875816b63
         | 
| 7 | 
            +
              data.tar.gz: 3e22b1382012b543d50a256e1792f9f79e3b02d49e42420353a351d49f549f021cd3dede90c576f657f0e61df862c0d8879cfb9c0a1d4578ef77a5648845ff6e
         | 
| @@ -0,0 +1,14 @@ | |
| 1 | 
            +
            # To get started with Dependabot version updates, you'll need to specify which
         | 
| 2 | 
            +
            # package ecosystems to update and where the package manifests are located.
         | 
| 3 | 
            +
            # Please see the documentation for all configuration options:
         | 
| 4 | 
            +
            # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            version: 2
         | 
| 7 | 
            +
            updates:
         | 
| 8 | 
            +
              - package-ecosystem: "bundler" # See documentation for possible values
         | 
| 9 | 
            +
                directory: "/" # Location of package manifests
         | 
| 10 | 
            +
                schedule:
         | 
| 11 | 
            +
                  interval: "weekly"
         | 
| 12 | 
            +
                  day: "friday"
         | 
| 13 | 
            +
                assignees:
         | 
| 14 | 
            +
                  - "LeFnord"
         | 
| @@ -0,0 +1,26 @@ | |
| 1 | 
            +
            name: Rubocop
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            on:
         | 
| 4 | 
            +
              push:
         | 
| 5 | 
            +
                branches:
         | 
| 6 | 
            +
                  - '*'
         | 
| 7 | 
            +
              pull_request:
         | 
| 8 | 
            +
                branches:
         | 
| 9 | 
            +
                  - '*'
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            jobs:
         | 
| 12 | 
            +
              rubocop:
         | 
| 13 | 
            +
                name: Rubocop
         | 
| 14 | 
            +
                runs-on: ubuntu-latest
         | 
| 15 | 
            +
                steps:
         | 
| 16 | 
            +
                  - uses: actions/checkout@v2
         | 
| 17 | 
            +
                  - uses: actions/setup-ruby@v1
         | 
| 18 | 
            +
                    with:
         | 
| 19 | 
            +
                      ruby-version: '3.0'
         | 
| 20 | 
            +
                  - run: gem install rubocop --no-doc
         | 
| 21 | 
            +
                  - run: rubocop --format progress --format json --out rubocop.json
         | 
| 22 | 
            +
                    id: rubocop
         | 
| 23 | 
            +
                  - uses: duderman/rubocop-annotate-action@v0.1.0
         | 
| 24 | 
            +
                    with:
         | 
| 25 | 
            +
                      path: rubocop.json
         | 
| 26 | 
            +
                    if: ${{ failure() }}
         | 
| @@ -0,0 +1,26 @@ | |
| 1 | 
            +
            name: Ruby
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            on:
         | 
| 4 | 
            +
              push:
         | 
| 5 | 
            +
                branches:
         | 
| 6 | 
            +
                  - '*'
         | 
| 7 | 
            +
              pull_request:
         | 
| 8 | 
            +
                branches:
         | 
| 9 | 
            +
                  - '*'
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            jobs:
         | 
| 12 | 
            +
              spec:
         | 
| 13 | 
            +
                runs-on: ubuntu-latest
         | 
| 14 | 
            +
                strategy:
         | 
| 15 | 
            +
                  matrix:
         | 
| 16 | 
            +
                    ruby-version: ['2.6', '2.7', '3.0', head, jruby, truffleruby]
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                steps:
         | 
| 19 | 
            +
                - uses: actions/checkout@v2
         | 
| 20 | 
            +
                - name: Set up Ruby
         | 
| 21 | 
            +
                  uses: ruby/setup-ruby@v1
         | 
| 22 | 
            +
                  with:
         | 
| 23 | 
            +
                    ruby-version: ${{ matrix.ruby-version }}
         | 
| 24 | 
            +
                    bundler-cache: true
         | 
| 25 | 
            +
                - name: Run rspec
         | 
| 26 | 
            +
                  run: bundle exec rspec
         | 
    
        data/.rubocop.yml
    CHANGED
    
    | @@ -4,11 +4,18 @@ AllCops: | |
| 4 4 | 
             
              Exclude:
         | 
| 5 5 | 
             
                - vendor/**/*
         | 
| 6 6 | 
             
                - example/**/*
         | 
| 7 | 
            -
               | 
| 7 | 
            +
              NewCops: enable
         | 
| 8 | 
            +
              TargetRubyVersion: 3.0
         | 
| 9 | 
            +
              SuggestExtensions: false
         | 
| 8 10 |  | 
| 11 | 
            +
            #  Layout stuff
         | 
| 12 | 
            +
            #
         | 
| 9 13 | 
             
            Layout/EmptyLinesAroundArguments:
         | 
| 10 14 | 
             
              Enabled: false
         | 
| 11 15 |  | 
| 16 | 
            +
            Layout/EmptyLinesAroundAttributeAccessor:
         | 
| 17 | 
            +
              Enabled: true
         | 
| 18 | 
            +
             | 
| 12 19 | 
             
            Layout/FirstHashElementIndentation:
         | 
| 13 20 | 
             
              EnforcedStyle: consistent
         | 
| 14 21 |  | 
| @@ -17,15 +24,30 @@ Layout/LineLength: | |
| 17 24 | 
             
              Exclude:
         | 
| 18 25 | 
             
                - spec/**/*
         | 
| 19 26 |  | 
| 27 | 
            +
            Layout/SpaceAroundMethodCallOperator:
         | 
| 28 | 
            +
              Enabled: true
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            #  Lint stuff
         | 
| 31 | 
            +
            #
         | 
| 32 | 
            +
            Lint/ConstantDefinitionInBlock:
         | 
| 33 | 
            +
              Enabled: true
         | 
| 34 | 
            +
              Exclude:
         | 
| 35 | 
            +
                - spec/**/*
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            #  Metrics stuff
         | 
| 38 | 
            +
            #
         | 
| 20 39 | 
             
            Metrics/AbcSize:
         | 
| 21 40 | 
             
              Max: 25
         | 
| 41 | 
            +
              IgnoredMethods:
         | 
| 42 | 
            +
                # from lib/grape_entity/exposure/nesting_exposure.rb
         | 
| 43 | 
            +
                - 'normalized_exposures'
         | 
| 22 44 |  | 
| 23 45 | 
             
            Metrics/BlockLength:
         | 
| 24 46 | 
             
              Exclude:
         | 
| 25 47 | 
             
                - spec/**/*
         | 
| 26 48 |  | 
| 27 49 | 
             
            Metrics/CyclomaticComplexity:
         | 
| 28 | 
            -
              Max:  | 
| 50 | 
            +
              Max: 13
         | 
| 29 51 |  | 
| 30 52 | 
             
            Metrics/ClassLength:
         | 
| 31 53 | 
             
              Max: 300
         | 
| @@ -37,12 +59,28 @@ Metrics/MethodLength: | |
| 37 59 |  | 
| 38 60 | 
             
            Metrics/PerceivedComplexity:
         | 
| 39 61 | 
             
              Max: 11
         | 
| 62 | 
            +
              IgnoredMethods:
         | 
| 63 | 
            +
                # from lib/grape_entity/entity.rb
         | 
| 64 | 
            +
                - 'expose'
         | 
| 65 | 
            +
                - 'merge_options'
         | 
| 66 | 
            +
                # from lib/grape_entity/exposure/nesting_exposure.rb
         | 
| 67 | 
            +
                - 'normalized_exposures'
         | 
| 68 | 
            +
             | 
| 69 | 
            +
            #  Naming stuff
         | 
| 70 | 
            +
            #
         | 
| 40 71 |  | 
| 41 72 | 
             
            Naming:
         | 
| 42 73 | 
             
              Enabled: false
         | 
| 43 74 |  | 
| 75 | 
            +
            #  Style stuff
         | 
| 76 | 
            +
            #
         | 
| 44 77 | 
             
            Style/Documentation:
         | 
| 45 78 | 
             
              Enabled: false
         | 
| 46 79 |  | 
| 47 | 
            -
            Style/ | 
| 48 | 
            -
               | 
| 80 | 
            +
            Style/OptionalBooleanParameter:
         | 
| 81 | 
            +
              AllowedMethods:
         | 
| 82 | 
            +
                # from lib/grape_entity/condition/base.rb
         | 
| 83 | 
            +
                - 'initialize'
         | 
| 84 | 
            +
                # form lib/grape_entity/entity.rb
         | 
| 85 | 
            +
                - 'entity_class'
         | 
| 86 | 
            +
                - 'present_collection'
         | 
    
        data/.rubocop_todo.yml
    CHANGED
    
    | @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            # This configuration was generated by
         | 
| 2 2 | 
             
            # `rubocop --auto-gen-config`
         | 
| 3 | 
            -
            # on 2020- | 
| 3 | 
            +
            # on 2020-11-07 00:01:40 UTC using RuboCop version 1.2.0.
         | 
| 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
         | 
| @@ -14,17 +14,11 @@ Gemspec/RequiredRubyVersion: | |
| 14 14 | 
             
                - 'grape-entity.gemspec'
         | 
| 15 15 |  | 
| 16 16 | 
             
            # Offense count: 6
         | 
| 17 | 
            +
            # Cop supports --auto-correct.
         | 
| 17 18 | 
             
            Lint/BooleanSymbol:
         | 
| 18 19 | 
             
              Exclude:
         | 
| 19 20 | 
             
                - 'spec/grape_entity/exposure_spec.rb'
         | 
| 20 21 |  | 
| 21 | 
            -
            # Offense count: 1
         | 
| 22 | 
            -
            # Configuration parameters: EnforcedStyle.
         | 
| 23 | 
            -
            # SupportedStyles: inline, group
         | 
| 24 | 
            -
            Style/AccessModifierDeclarations:
         | 
| 25 | 
            -
              Exclude:
         | 
| 26 | 
            -
                - 'spec/grape_entity/entity_spec.rb'
         | 
| 27 | 
            -
             | 
| 28 22 | 
             
            # Offense count: 1
         | 
| 29 23 | 
             
            # Cop supports --auto-correct.
         | 
| 30 24 | 
             
            # Configuration parameters: IgnoredMethods.
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -8,7 +8,42 @@ | |
| 8 8 |  | 
| 9 9 | 
             
            * Your contribution here.
         | 
| 10 10 |  | 
| 11 | 
            -
             | 
| 11 | 
            +
             | 
| 12 | 
            +
            ### 0.10.0 (2021-09-15)
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            #### Features
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            * [#352](https://github.com/ruby-grape/grape-entity/pull/352): Add Default value option - [@ahmednaguib](https://github.com/ahmednaguib).
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            #### Fixes
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            * [#355](https://github.com/ruby-grape/grape-entity/pull/355): Fix infinite loop problem with the `NameErrors` in block exposures - [@meinac](https://github.com/meinac).
         | 
| 21 | 
            +
             | 
| 22 | 
            +
             | 
| 23 | 
            +
            ### 0.9.0 (2021-03-20)
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            #### Features
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            * [#346](https://github.com/ruby-grape/grape-entity/pull/346): Ruby 3 support - [@LeFnord](https://github.com/LeFnord).
         | 
| 28 | 
            +
             | 
| 29 | 
            +
             | 
| 30 | 
            +
            ### 0.8.2 (2020-11-08)
         | 
| 31 | 
            +
             | 
| 32 | 
            +
            #### Fixes
         | 
| 33 | 
            +
             | 
| 34 | 
            +
            * [#340](https://github.com/ruby-grape/grape-entity/pull/340): Preparations for 3.0 - [@LeFnord](https://github.com/LeFnord).
         | 
| 35 | 
            +
            * [#338](https://github.com/ruby-grape/grape-entity/pull/338): Fix ruby 2.7 deprecation warning - [@begotten63](https://github.com/begotten63).
         | 
| 36 | 
            +
             | 
| 37 | 
            +
             | 
| 38 | 
            +
            ### 0.8.1 (2020-07-15)
         | 
| 39 | 
            +
             | 
| 40 | 
            +
            #### Fixes
         | 
| 41 | 
            +
             | 
| 42 | 
            +
            * [#336](https://github.com/ruby-grape/grape-entity/pull/336): Pass options to delegators when they accept it - [@dnesteryuk](https://github.com/dnesteryuk).
         | 
| 43 | 
            +
            * [#333](https://github.com/ruby-grape/grape-entity/pull/333): Fix typo in CHANGELOG.md - [@eitoball](https://github.com/eitoball).
         | 
| 44 | 
            +
             | 
| 45 | 
            +
             | 
| 46 | 
            +
            ### 0.8.0 (2020-02-18)
         | 
| 12 47 |  | 
| 13 48 | 
             
            #### Features
         | 
| 14 49 |  | 
| @@ -23,12 +58,14 @@ | |
| 23 58 | 
             
            * [#320](https://github.com/ruby-grape/grape-entity/pull/320): Gemspec: drop eol'd property rubyforge_project - [@olleolleolle](https://github.com/olleolleolle).
         | 
| 24 59 | 
             
            * [#307](https://github.com/ruby-grape/grape-entity/pull/307): Allow exposures to call methods defined in modules included in an entity - [@robertoz-01](https://github.com/robertoz-01).
         | 
| 25 60 |  | 
| 61 | 
            +
             | 
| 26 62 | 
             
            ### 0.7.1 (2018-01-30)
         | 
| 27 63 |  | 
| 28 64 | 
             
            #### Features
         | 
| 29 65 |  | 
| 30 66 | 
             
            * [#297](https://github.com/ruby-grape/grape-entity/pull/297): Introduce `override` option for expose (fixes [#286](https://github.com/ruby-grape/grape-entity/issues/296)) - [@DmitryTsepelev](https://github.com/DmitryTsepelev).
         | 
| 31 67 |  | 
| 68 | 
            +
             | 
| 32 69 | 
             
            ### 0.7.0 (2018-01-25)
         | 
| 33 70 |  | 
| 34 71 | 
             
            #### Features
         | 
| @@ -47,6 +84,7 @@ | |
| 47 84 | 
             
            * [#291](https://github.com/ruby-grape/grape-entity/pull/291): Refactor and simplify various classes and modules  - [@DmitryTsepelev](https://github.com/DmitryTsepelev).
         | 
| 48 85 | 
             
            * [#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).
         | 
| 49 86 |  | 
| 87 | 
            +
             | 
| 50 88 | 
             
            ### 0.6.1 (2017-01-09)
         | 
| 51 89 |  | 
| 52 90 | 
             
            #### Features
         | 
| @@ -57,6 +95,7 @@ | |
| 57 95 |  | 
| 58 96 | 
             
            * [#251](https://github.com/ruby-grape/grape-entity/pull/251): Avoid noise when code runs with Ruby warnings - [@cpetschnig](https://github.com/cpetschnig).
         | 
| 59 97 |  | 
| 98 | 
            +
             | 
| 60 99 | 
             
            ### 0.6.0 (2016-11-20)
         | 
| 61 100 |  | 
| 62 101 | 
             
            #### Features
         | 
| @@ -68,6 +107,7 @@ | |
| 68 107 | 
             
            * [#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).
         | 
| 69 108 | 
             
            * [#248](https://github.com/ruby-grape/grape-entity/pull/248): Fix `nil` values causing errors when `merge` option passed - [@arempe93](https://github.com/arempe93).
         | 
| 70 109 |  | 
| 110 | 
            +
             | 
| 71 111 | 
             
            ### 0.5.2 (2016-11-14)
         | 
| 72 112 |  | 
| 73 113 | 
             
            #### Features
         | 
| @@ -83,6 +123,7 @@ | |
| 83 123 | 
             
            * [#219](https://github.com/ruby-grape/grape-entity/pull/219): Double pass options in `serializable_hash` - [@sbatykov](https://github.com/sbatykov).
         | 
| 84 124 | 
             
            * [#231](https://github.com/ruby-grape/grape-entity/pull/231), [#215](https://github.com/ruby-grape/grape-entity/issues/215): Allow `delegate_attribute` for derived entity - [@sbatykov](https://github.com/sbatykov).
         | 
| 85 125 |  | 
| 126 | 
            +
             | 
| 86 127 | 
             
            ### 0.5.1 (2016-4-4)
         | 
| 87 128 |  | 
| 88 129 | 
             
            #### Features
         | 
| @@ -94,6 +135,7 @@ | |
| 94 135 |  | 
| 95 136 | 
             
            * [#202](https://github.com/ruby-grape/grape-entity/pull/202): Reset `@using_class` memoization on `.setup` - [@rngtng](https://github.com/rngtng).
         | 
| 96 137 |  | 
| 138 | 
            +
             | 
| 97 139 | 
             
            ### 0.5.0 (2015-12-07)
         | 
| 98 140 |  | 
| 99 141 | 
             
            #### Features
         | 
| @@ -114,18 +156,21 @@ | |
| 114 156 | 
             
            * [#151](https://github.com/ruby-grape/grape-entity/pull/151): Serializing of deeply nested presenter exposures: [#155](https://github.com/ruby-grape/grape-entity/issues/155) - [@marshall-lee](https://github.com/marshall-lee).
         | 
| 115 157 | 
             
            * [#151](https://github.com/ruby-grape/grape-entity/pull/151): Deep projections (`:only`, `:except`) were unaware of nesting: [#156](https://github.com/ruby-grape/grape-entity/issues/156) - [@marshall-lee](https://github.com/marshall-lee).
         | 
| 116 158 |  | 
| 159 | 
            +
             | 
| 117 160 | 
             
            ### 0.4.8 (2015-08-10)
         | 
| 118 161 |  | 
| 119 162 | 
             
            #### Features
         | 
| 120 163 |  | 
| 121 164 | 
             
            * [#167](https://github.com/ruby-grape/grape-entity/pull/167), [#166](https://github.com/ruby-grape/grape-entity/issues/166): Regression with global settings (exposures, formatters) on `Grape::Entity` - [@marshall-lee](https://github.com/marshall-lee).
         | 
| 122 165 |  | 
| 166 | 
            +
             | 
| 123 167 | 
             
            ### 0.4.7 (2015-08-03)
         | 
| 124 168 |  | 
| 125 169 | 
             
            #### Features
         | 
| 126 170 |  | 
| 127 171 | 
             
            * [#164](https://github.com/ruby-grape/grape-entity/pull/164): Regression: entity instance methods were exposed with `NoMethodError`: [#163](https://github.com/ruby-grape/grape-entity/issues/163) - [@marshall-lee](https://github.com/marshall-lee).
         | 
| 128 172 |  | 
| 173 | 
            +
             | 
| 129 174 | 
             
            ### 0.4.6 (2015-07-27)
         | 
| 130 175 |  | 
| 131 176 | 
             
            #### Features
         | 
| @@ -144,6 +189,7 @@ | |
| 144 189 |  | 
| 145 190 | 
             
            * [#147](https://github.com/ruby-grape/grape-entity/pull/147), [#142](https://github.com/ruby-grape/grape-entity/pull/142): Private method values were not exposed with `safe` option - [@marshall-lee](https://github.com/marshall-lee).
         | 
| 146 191 |  | 
| 192 | 
            +
             | 
| 147 193 | 
             
            ### 0.4.5 (2015-03-10)
         | 
| 148 194 |  | 
| 149 195 | 
             
            #### Features
         | 
| @@ -158,6 +204,7 @@ | |
| 158 204 | 
             
            * [#110](https://github.com/ruby-grape/grape-entity/pull/110): Safe exposure when using `Hash` models - [@croeck](https://github.com/croeck).
         | 
| 159 205 | 
             
            * [#91](https://github.com/ruby-grape/grape-entity/pull/91): OpenStruct serializing - [@etehtsea](https://github.com/etehtsea).
         | 
| 160 206 |  | 
| 207 | 
            +
             | 
| 161 208 | 
             
            ### 0.4.4 (2014-08-17)
         | 
| 162 209 |  | 
| 163 210 | 
             
            #### Features
         | 
| @@ -165,6 +212,7 @@ | |
| 165 212 | 
             
            * [#85](https://github.com/ruby-grape/grape-entity/pull/85): Added `present_collection` to indicate that an `Entity` presents an entire Collection - [@dspaeth-faber](https://github.com/dspaeth-faber).
         | 
| 166 213 | 
             
            * [#85](https://github.com/ruby-grape/grape-entity/pull/85): Hashes can now be passed as object to be presented and the `Hash` keys can be referenced by expose - [@dspaeth-faber](https://github.com/dspaeth-faber).
         | 
| 167 214 |  | 
| 215 | 
            +
             | 
| 168 216 | 
             
            ### 0.4.3 (2014-06-12)
         | 
| 169 217 |  | 
| 170 218 | 
             
            #### Features
         | 
| @@ -175,6 +223,7 @@ | |
| 175 223 |  | 
| 176 224 | 
             
            * [#77](https://github.com/ruby-grape/grape-entity/pull/77): Compatibility with Rspec 3 - [@justfalter](https://github.com/justfalter).
         | 
| 177 225 |  | 
| 226 | 
            +
             | 
| 178 227 | 
             
            ### 0.4.2 (2014-04-03)
         | 
| 179 228 |  | 
| 180 229 | 
             
            #### Features
         | 
| @@ -182,12 +231,14 @@ | |
| 182 231 | 
             
            * [#60](https://github.com/ruby-grape/grape-entity/issues/59): Performance issues introduced by nested exposures - [@AlexYankee](https://github.com/AlexYankee).
         | 
| 183 232 | 
             
            * [#60](https://github.com/ruby-grape/grape-entity/issues/57): Nested exposure double-exposes a field - [@AlexYankee](https://github.com/AlexYankee).
         | 
| 184 233 |  | 
| 234 | 
            +
             | 
| 185 235 | 
             
            ### 0.4.1 (2014-02-13)
         | 
| 186 236 |  | 
| 187 237 | 
             
            #### Fixes
         | 
| 188 238 |  | 
| 189 239 | 
             
            * [#54](https://github.com/ruby-grape/grape-entity/issues/54): Fix: undefined method `to_set` - [@aj0strow](https://github.com/aj0strow).
         | 
| 190 240 |  | 
| 241 | 
            +
             | 
| 191 242 | 
             
            ### 0.4.0 (2014-01-27)
         | 
| 192 243 |  | 
| 193 244 | 
             
            #### Features
         | 
| @@ -207,6 +258,7 @@ | |
| 207 258 | 
             
            * [#51](https://github.com/ruby-grape/grape-entity/pull/51): Raise `ArgumentError` if an unknown option is used with `expose` - [@aj0strow](https://github.com/aj0strow).
         | 
| 208 259 | 
             
            * [#51](https://github.com/ruby-grape/grape-entity/pull/51): Alias `:with` to `:using`, consistently with the Grape api endpoints - [@aj0strow](https://github.com/aj0strow).
         | 
| 209 260 |  | 
| 261 | 
            +
             | 
| 210 262 | 
             
            ### 0.3.0 (2013-03-29)
         | 
| 211 263 |  | 
| 212 264 | 
             
            #### Features
         | 
| @@ -215,12 +267,14 @@ | |
| 215 267 | 
             
            * The `instance.entity` method now optionally accepts `options` - [@mbleigh](https://github.com/mbleigh).
         | 
| 216 268 | 
             
            * You can pass symbols to `:if` and `:unless` to simply check for truthiness/falsiness of the specified options key - [@mbleigh](https://github.com/mbleigh).
         | 
| 217 269 |  | 
| 270 | 
            +
             | 
| 218 271 | 
             
            ### 0.2.0 (2013-01-11)
         | 
| 219 272 |  | 
| 220 273 | 
             
            #### Features
         | 
| 221 274 |  | 
| 222 275 | 
             
            * Moved the namespace back to `Grape::Entity` to preserve compatibility with Grape - [@dblock](https://github.com/dblock).
         | 
| 223 276 |  | 
| 277 | 
            +
             | 
| 224 278 | 
             
            ### 0.1.0 (2013-01-11)
         | 
| 225 279 |  | 
| 226 280 | 
             
            * Initial public release - [@agileanimal](https://github.com/agileanimal).
         | 
    
        data/Gemfile
    CHANGED
    
    | @@ -5,7 +5,7 @@ source 'http://rubygems.org' | |
| 5 5 | 
             
            gemspec
         | 
| 6 6 |  | 
| 7 7 | 
             
            group :development, :test do
         | 
| 8 | 
            -
              gem 'rubocop', '~>  | 
| 8 | 
            +
              gem 'rubocop', '~> 1.0', require: false
         | 
| 9 9 | 
             
            end
         | 
| 10 10 |  | 
| 11 11 | 
             
            group :test do
         | 
| @@ -15,6 +15,6 @@ group :test do | |
| 15 15 | 
             
              gem 'guard-bundler'
         | 
| 16 16 | 
             
              gem 'guard-rspec'
         | 
| 17 17 | 
             
              gem 'rb-fsevent'
         | 
| 18 | 
            -
              gem 'ruby-grape-danger', '~> 0. | 
| 18 | 
            +
              gem 'ruby-grape-danger', '~> 0.2', require: false
         | 
| 19 19 | 
             
              gem 'simplecov', require: false
         | 
| 20 20 | 
             
            end
         | 
    
        data/README.md
    CHANGED
    
    | @@ -1,10 +1,47 @@ | |
| 1 | 
            -
            # Grape::Entity
         | 
| 2 | 
            -
             | 
| 3 1 | 
             
            [](http://badge.fury.io/rb/grape-entity)
         | 
| 4 | 
            -
             | 
| 2 | 
            +
            
         | 
| 5 3 | 
             
            [](https://coveralls.io/github/ruby-grape/grape-entity?branch=master)
         | 
| 6 4 | 
             
            [](https://codeclimate.com/github/ruby-grape/grape-entity)
         | 
| 7 5 |  | 
| 6 | 
            +
            # Table of Contents
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            - [Grape::Entity](#grapeentity)
         | 
| 9 | 
            +
              - [Introduction](#introduction)
         | 
| 10 | 
            +
                - [Example](#example)
         | 
| 11 | 
            +
              - [Reusable Responses with Entities](#reusable-responses-with-entities)
         | 
| 12 | 
            +
                - [Defining Entities](#defining-entities)
         | 
| 13 | 
            +
                  - [Basic Exposure](#basic-exposure)
         | 
| 14 | 
            +
                  - [Exposing with a Presenter](#exposing-with-a-presenter)
         | 
| 15 | 
            +
                  - [Conditional Exposure](#conditional-exposure)
         | 
| 16 | 
            +
                  - [Safe Exposure](#safe-exposure)
         | 
| 17 | 
            +
                  - [Nested Exposure](#nested-exposure)
         | 
| 18 | 
            +
                  - [Collection Exposure](#collection-exposure)
         | 
| 19 | 
            +
                  - [Merge Fields](#merge-fields)
         | 
| 20 | 
            +
                  - [Runtime Exposure](#runtime-exposure)
         | 
| 21 | 
            +
                  - [Unexpose](#unexpose)
         | 
| 22 | 
            +
                  - [Overriding exposures](#overriding-exposures)
         | 
| 23 | 
            +
                  - [Returning only the fields you want](#returning-only-the-fields-you-want)
         | 
| 24 | 
            +
                  - [Aliases](#aliases)
         | 
| 25 | 
            +
                  - [Format Before Exposing](#format-before-exposing)
         | 
| 26 | 
            +
                  - [Expose Nil](#expose-nil)
         | 
| 27 | 
            +
                  - [Default Value](#default-value)
         | 
| 28 | 
            +
                  - [Documentation](#documentation)
         | 
| 29 | 
            +
                - [Options Hash](#options-hash)
         | 
| 30 | 
            +
                  - [Passing Additional Option To Nested Exposure](#passing-additional-option-to-nested-exposure)
         | 
| 31 | 
            +
                  - [Attribute Path Tracking](#attribute-path-tracking)
         | 
| 32 | 
            +
                - [Using the Exposure DSL](#using-the-exposure-dsl)
         | 
| 33 | 
            +
                - [Using Entities](#using-entities)
         | 
| 34 | 
            +
                - [Entity Organization](#entity-organization)
         | 
| 35 | 
            +
                - [Caveats](#caveats)
         | 
| 36 | 
            +
              - [Installation](#installation)
         | 
| 37 | 
            +
              - [Testing with Entities](#testing-with-entities)
         | 
| 38 | 
            +
              - [Project Resources](#project-resources)
         | 
| 39 | 
            +
              - [Contributing](#contributing)
         | 
| 40 | 
            +
              - [License](#license)
         | 
| 41 | 
            +
              - [Copyright](#copyright)
         | 
| 42 | 
            +
             | 
| 43 | 
            +
            # Grape::Entity
         | 
| 44 | 
            +
             | 
| 8 45 | 
             
            ## Introduction
         | 
| 9 46 |  | 
| 10 47 | 
             
            This gem adds Entity support to API frameworks, such as [Grape](https://github.com/ruby-grape/grape). Grape's Entity is an API focused facade that sits on top of an object model.
         | 
| @@ -446,6 +483,19 @@ module  Entities | |
| 446 483 | 
             
            end
         | 
| 447 484 | 
             
            ```
         | 
| 448 485 |  | 
| 486 | 
            +
            #### Default Value
         | 
| 487 | 
            +
             | 
| 488 | 
            +
            This option can be used to provide a default value in case the return value is nil or empty.
         | 
| 489 | 
            +
             | 
| 490 | 
            +
            ```ruby
         | 
| 491 | 
            +
            module  Entities
         | 
| 492 | 
            +
              class MyModel < Grape::Entity
         | 
| 493 | 
            +
                expose :name, default: ''
         | 
| 494 | 
            +
                expose :age, default: 60
         | 
| 495 | 
            +
              end
         | 
| 496 | 
            +
            end
         | 
| 497 | 
            +
            ```
         | 
| 498 | 
            +
             | 
| 449 499 | 
             
            #### Documentation
         | 
| 450 500 |  | 
| 451 501 | 
             
            Expose documentation with the field. Gets bubbled up when used with Grape and various API documentation systems.
         | 
    
        data/UPGRADING.md
    CHANGED
    
    | @@ -1,5 +1,22 @@ | |
| 1 | 
            -
            Upgrading Grape Entity
         | 
| 2 | 
            -
             | 
| 1 | 
            +
            # Upgrading Grape Entity
         | 
| 2 | 
            +
             | 
| 3 | 
            +
             | 
| 4 | 
            +
            ### Upgrading to >= 0.8.2
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            Official support for ruby < 2.5 removed, ruby 2.5 only in testing mode, but no support.
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            In Ruby 3.0: the block handling will be changed
         | 
| 9 | 
            +
            [language-changes point 3, Proc](https://github.com/ruby/ruby/blob/v3_0_0_preview1/NEWS.md#language-changes).
         | 
| 10 | 
            +
            This:
         | 
| 11 | 
            +
            ```ruby
         | 
| 12 | 
            +
            expose :that_method_without_args, &:method_without_args
         | 
| 13 | 
            +
            ```
         | 
| 14 | 
            +
            will be deprecated.
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            Prefer to use this pattern for simple setting a value
         | 
| 17 | 
            +
            ```ruby
         | 
| 18 | 
            +
            expose :method_without_args, as: :that_method_without_args
         | 
| 19 | 
            +
            ```
         | 
| 3 20 |  | 
| 4 21 | 
             
            ### Upgrading to >= 0.6.0
         | 
| 5 22 |  | 
    
        data/bench/serializing.rb
    CHANGED
    
    | @@ -7,6 +7,7 @@ require 'benchmark' | |
| 7 7 | 
             
            module Models
         | 
| 8 8 | 
             
              class School
         | 
| 9 9 | 
             
                attr_reader :classrooms
         | 
| 10 | 
            +
             | 
| 10 11 | 
             
                def initialize
         | 
| 11 12 | 
             
                  @classrooms = []
         | 
| 12 13 | 
             
                end
         | 
| @@ -15,6 +16,7 @@ module Models | |
| 15 16 | 
             
              class ClassRoom
         | 
| 16 17 | 
             
                attr_reader :students
         | 
| 17 18 | 
             
                attr_accessor :teacher
         | 
| 19 | 
            +
             | 
| 18 20 | 
             
                def initialize(opts = {})
         | 
| 19 21 | 
             
                  @teacher = opts[:teacher]
         | 
| 20 22 | 
             
                  @students = []
         | 
| @@ -23,6 +25,7 @@ module Models | |
| 23 25 |  | 
| 24 26 | 
             
              class Person
         | 
| 25 27 | 
             
                attr_accessor :name
         | 
| 28 | 
            +
             | 
| 26 29 | 
             
                def initialize(opts = {})
         | 
| 27 30 | 
             
                  @name = opts[:name]
         | 
| 28 31 | 
             
                end
         | 
| @@ -30,6 +33,7 @@ module Models | |
| 30 33 |  | 
| 31 34 | 
             
              class Teacher < Models::Person
         | 
| 32 35 | 
             
                attr_accessor :tenure
         | 
| 36 | 
            +
             | 
| 33 37 | 
             
                def initialize(opts = {})
         | 
| 34 38 | 
             
                  super(opts)
         | 
| 35 39 | 
             
                  @tenure = opts[:tenure]
         | 
| @@ -38,6 +42,7 @@ module Models | |
| 38 42 |  | 
| 39 43 | 
             
              class Student < Models::Person
         | 
| 40 44 | 
             
                attr_reader :grade
         | 
| 45 | 
            +
             | 
| 41 46 | 
             
                def initialize(opts = {})
         | 
| 42 47 | 
             
                  super(opts)
         | 
| 43 48 | 
             
                  @grade = opts[:grade]
         | 
    
        data/grape-entity.gemspec
    CHANGED
    
    | @@ -14,7 +14,7 @@ Gem::Specification.new do |s| | |
| 14 14 | 
             
              s.description = 'Extracted from Grape, A Ruby framework for rapid API development with great conventions.'
         | 
| 15 15 | 
             
              s.license     = 'MIT'
         | 
| 16 16 |  | 
| 17 | 
            -
              s.required_ruby_version = '>= 2. | 
| 17 | 
            +
              s.required_ruby_version = '>= 2.5'
         | 
| 18 18 |  | 
| 19 19 | 
             
              s.add_runtime_dependency 'activesupport', '>= 3.0.0'
         | 
| 20 20 | 
             
              # FIXME: remove dependecy
         | 
    
        data/lib/grape_entity/entity.rb
    CHANGED
    
    | @@ -105,7 +105,7 @@ module Grape | |
| 105 105 | 
             
                    @root_exposure ||= Exposure.new(nil, nesting: true)
         | 
| 106 106 | 
             
                  end
         | 
| 107 107 |  | 
| 108 | 
            -
                  attr_writer :root_exposure
         | 
| 108 | 
            +
                  attr_writer :root_exposure, :formatters
         | 
| 109 109 |  | 
| 110 110 | 
             
                  # Returns all formatters that are registered for this and it's ancestors
         | 
| 111 111 | 
             
                  # @return [Hash] of formatters
         | 
| @@ -113,8 +113,6 @@ module Grape | |
| 113 113 | 
             
                    @formatters ||= {}
         | 
| 114 114 | 
             
                  end
         | 
| 115 115 |  | 
| 116 | 
            -
                  attr_writer :formatters
         | 
| 117 | 
            -
             | 
| 118 116 | 
             
                  def hash_access
         | 
| 119 117 | 
             
                    @hash_access ||= :to_sym
         | 
| 120 118 | 
             
                  end
         | 
| @@ -124,12 +122,14 @@ module Grape | |
| 124 122 | 
             
                      case value
         | 
| 125 123 | 
             
                      when :to_s, :str, :string
         | 
| 126 124 | 
             
                        :to_s
         | 
| 127 | 
            -
                      when :to_sym, :sym, :symbol
         | 
| 128 | 
            -
                        :to_sym
         | 
| 129 125 | 
             
                      else
         | 
| 130 126 | 
             
                        :to_sym
         | 
| 131 127 | 
             
                      end
         | 
| 132 128 | 
             
                  end
         | 
| 129 | 
            +
             | 
| 130 | 
            +
                  def delegation_opts
         | 
| 131 | 
            +
                    @delegation_opts ||= { hash_access: hash_access }
         | 
| 132 | 
            +
                  end
         | 
| 133 133 | 
             
                end
         | 
| 134 134 |  | 
| 135 135 | 
             
                @formatters = {}
         | 
| @@ -137,6 +137,8 @@ module Grape | |
| 137 137 | 
             
                def self.inherited(subclass)
         | 
| 138 138 | 
             
                  subclass.root_exposure = root_exposure.dup
         | 
| 139 139 | 
             
                  subclass.formatters = formatters.dup
         | 
| 140 | 
            +
             | 
| 141 | 
            +
                  super
         | 
| 140 142 | 
             
                end
         | 
| 141 143 |  | 
| 142 144 | 
             
                # This method is the primary means by which you will declare what attributes
         | 
| @@ -151,7 +153,7 @@ module Grape | |
| 151 153 | 
             
                #
         | 
| 152 154 | 
             
                # @example as: a proc or lambda
         | 
| 153 155 | 
             
                #
         | 
| 154 | 
            -
                #   object = OpenStruct( | 
| 156 | 
            +
                #   object = OpenStruct(awesomeness: 'awesome_key', awesome: 'not-my-key', other: 'other-key' )
         | 
| 155 157 | 
             
                #
         | 
| 156 158 | 
             
                #   class MyEntity < Grape::Entity
         | 
| 157 159 | 
             
                #     expose :awesome, as: proc { object.awesomeness }
         | 
| @@ -479,6 +481,9 @@ module Grape | |
| 479 481 | 
             
                  @object = object
         | 
| 480 482 | 
             
                  @options = options.is_a?(Options) ? options : Options.new(options)
         | 
| 481 483 | 
             
                  @delegator = Delegator.new(object)
         | 
| 484 | 
            +
             | 
| 485 | 
            +
                  # Why not `arity > 1`? It might be negative https://ruby-doc.org/core-2.6.6/Method.html#method-i-arity
         | 
| 486 | 
            +
                  @delegator_accepts_opts = @delegator.method(:delegate).arity != 1
         | 
| 482 487 | 
             
                end
         | 
| 483 488 |  | 
| 484 489 | 
             
                def root_exposures
         | 
| @@ -518,6 +523,11 @@ module Grape | |
| 518 523 | 
             
                  else
         | 
| 519 524 | 
             
                    instance_exec(object, options, &block)
         | 
| 520 525 | 
             
                  end
         | 
| 526 | 
            +
                rescue StandardError => e
         | 
| 527 | 
            +
                  # it handles: https://github.com/ruby/ruby/blob/v3_0_0_preview1/NEWS.md#language-changes point 3, Proc
         | 
| 528 | 
            +
                  raise Grape::Entity::Deprecated.new e.message, 'in ruby 3.0' if e.is_a?(ArgumentError)
         | 
| 529 | 
            +
             | 
| 530 | 
            +
                  raise e
         | 
| 521 531 | 
             
                end
         | 
| 522 532 |  | 
| 523 533 | 
             
                def exec_with_attribute(attribute, &block)
         | 
| @@ -531,8 +541,10 @@ module Grape | |
| 531 541 | 
             
                def delegate_attribute(attribute)
         | 
| 532 542 | 
             
                  if is_defined_in_entity?(attribute)
         | 
| 533 543 | 
             
                    send(attribute)
         | 
| 544 | 
            +
                  elsif @delegator_accepts_opts
         | 
| 545 | 
            +
                    delegator.delegate(attribute, **self.class.delegation_opts)
         | 
| 534 546 | 
             
                  else
         | 
| 535 | 
            -
                    delegator.delegate(attribute | 
| 547 | 
            +
                    delegator.delegate(attribute)
         | 
| 536 548 | 
             
                  end
         | 
| 537 549 | 
             
                end
         | 
| 538 550 |  | 
| @@ -573,6 +585,7 @@ module Grape | |
| 573 585 | 
             
                  merge
         | 
| 574 586 | 
             
                  expose_nil
         | 
| 575 587 | 
             
                  override
         | 
| 588 | 
            +
                  default
         | 
| 576 589 | 
             
                ].to_set.freeze
         | 
| 577 590 |  | 
| 578 591 | 
             
                # Merges the given options with current block options.
         | 
| @@ -16,6 +16,7 @@ module Grape | |
| 16 16 | 
             
                      key = options[:as] || attribute
         | 
| 17 17 | 
             
                      @key = key.respond_to?(:to_sym) ? key.to_sym : key
         | 
| 18 18 | 
             
                      @is_safe = options[:safe]
         | 
| 19 | 
            +
                      @default_value = options[:default]
         | 
| 19 20 | 
             
                      @for_merge = options[:merge]
         | 
| 20 21 | 
             
                      @attr_path_proc = options[:attr_path]
         | 
| 21 22 | 
             
                      @documentation = options[:documentation]
         | 
| @@ -82,7 +83,10 @@ module Grape | |
| 82 83 | 
             
                    end
         | 
| 83 84 |  | 
| 84 85 | 
             
                    def valid_value(entity, options)
         | 
| 85 | 
            -
                       | 
| 86 | 
            +
                      return unless valid?(entity)
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                      output = value(entity, options)
         | 
| 89 | 
            +
                      output.blank? && @default_value.present? ? @default_value : output
         | 
| 86 90 | 
             
                    end
         | 
| 87 91 |  | 
| 88 92 | 
             
                    def should_return_key?(options)
         | 
| @@ -113,11 +117,9 @@ module Grape | |
| 113 117 | 
             
                      @key.respond_to?(:call) ? entity.exec_with_object(@options, &@key) : @key
         | 
| 114 118 | 
             
                    end
         | 
| 115 119 |  | 
| 116 | 
            -
                    def with_attr_path(entity, options)
         | 
| 120 | 
            +
                    def with_attr_path(entity, options, &block)
         | 
| 117 121 | 
             
                      path_part = attr_path(entity, options)
         | 
| 118 | 
            -
                      options.with_attr_path(path_part) | 
| 119 | 
            -
                        yield
         | 
| 120 | 
            -
                      end
         | 
| 122 | 
            +
                      options.with_attr_path(path_part, &block)
         | 
| 121 123 | 
             
                    end
         | 
| 122 124 |  | 
| 123 125 | 
             
                    def override?
         | 
| @@ -36,6 +36,7 @@ module Grape | |
| 36 36 | 
             
                        @exposures.clear
         | 
| 37 37 | 
             
                      end
         | 
| 38 38 |  | 
| 39 | 
            +
                      # rubocop:disable Style/DocumentDynamicEvalDefinition
         | 
| 39 40 | 
             
                      %i[
         | 
| 40 41 | 
             
                        each
         | 
| 41 42 | 
             
                        to_ary to_a
         | 
| @@ -55,6 +56,7 @@ module Grape | |
| 55 56 | 
             
                          end
         | 
| 56 57 | 
             
                        RUBY
         | 
| 57 58 | 
             
                      end
         | 
| 59 | 
            +
                      # rubocop:enable Style/DocumentDynamicEvalDefinition
         | 
| 58 60 |  | 
| 59 61 | 
             
                      # Determine if we have any nesting exposures with the same name.
         | 
| 60 62 | 
             
                      def deep_complex_nesting?(entity)
         | 
    
        data/lib/grape_entity/options.rb
    CHANGED
    
    | @@ -106,11 +106,12 @@ module Grape | |
| 106 106 | 
             
                  end
         | 
| 107 107 |  | 
| 108 108 | 
             
                  def build_symbolized_hash(attribute, hash)
         | 
| 109 | 
            -
                     | 
| 109 | 
            +
                    case attribute
         | 
| 110 | 
            +
                    when Hash
         | 
| 110 111 | 
             
                      attribute.each do |attr, nested_attrs|
         | 
| 111 112 | 
             
                        hash[attr.to_sym] = build_symbolized_hash(nested_attrs, {})
         | 
| 112 113 | 
             
                      end
         | 
| 113 | 
            -
                     | 
| 114 | 
            +
                    when Array
         | 
| 114 115 | 
             
                      return attribute.each { |x| build_symbolized_hash(x, {}) }
         | 
| 115 116 | 
             
                    else
         | 
| 116 117 | 
             
                      hash[attribute.to_sym] = true
         | 
    
        data/lib/grape_entity/version.rb
    CHANGED
    
    
    
        data/lib/grape_entity.rb
    CHANGED
    
    
| @@ -212,6 +212,130 @@ describe Grape::Entity do | |
| 212 212 | 
             
                    end
         | 
| 213 213 | 
             
                  end
         | 
| 214 214 |  | 
| 215 | 
            +
                  context 'with :default option' do
         | 
| 216 | 
            +
                    let(:a) { nil }
         | 
| 217 | 
            +
                    let(:b) { nil }
         | 
| 218 | 
            +
                    let(:c) { 'value' }
         | 
| 219 | 
            +
             | 
| 220 | 
            +
                    context 'when model is a PORO' do
         | 
| 221 | 
            +
                      let(:model) { Model.new(a, b, c) }
         | 
| 222 | 
            +
             | 
| 223 | 
            +
                      before do
         | 
| 224 | 
            +
                        stub_const 'Model', Class.new
         | 
| 225 | 
            +
                        Model.class_eval do
         | 
| 226 | 
            +
                          attr_accessor :a, :b, :c
         | 
| 227 | 
            +
             | 
| 228 | 
            +
                          def initialize(a, b, c)
         | 
| 229 | 
            +
                            @a = a
         | 
| 230 | 
            +
                            @b = b
         | 
| 231 | 
            +
                            @c = c
         | 
| 232 | 
            +
                          end
         | 
| 233 | 
            +
                        end
         | 
| 234 | 
            +
                      end
         | 
| 235 | 
            +
             | 
| 236 | 
            +
                      context 'when default option is not provided' do
         | 
| 237 | 
            +
                        it 'exposes attributes values' do
         | 
| 238 | 
            +
                          subject.expose(:a)
         | 
| 239 | 
            +
                          subject.expose(:b)
         | 
| 240 | 
            +
                          subject.expose(:c)
         | 
| 241 | 
            +
                          expect(subject.represent(model).serializable_hash).to eq(a: nil, b: nil, c: 'value')
         | 
| 242 | 
            +
                        end
         | 
| 243 | 
            +
                      end
         | 
| 244 | 
            +
             | 
| 245 | 
            +
                      context 'when default option is set' do
         | 
| 246 | 
            +
                        it 'exposes default values for attributes' do
         | 
| 247 | 
            +
                          subject.expose(:a, default: 'a')
         | 
| 248 | 
            +
                          subject.expose(:b, default: 'b')
         | 
| 249 | 
            +
                          subject.expose(:c, default: 'c')
         | 
| 250 | 
            +
                          expect(subject.represent(model).serializable_hash).to eq(a: 'a', b: 'b', c: 'value')
         | 
| 251 | 
            +
                        end
         | 
| 252 | 
            +
                      end
         | 
| 253 | 
            +
             | 
| 254 | 
            +
                      context 'when default option is set and block passed' do
         | 
| 255 | 
            +
                        it 'return default value if block returns nil' do
         | 
| 256 | 
            +
                          subject.expose(:a, default: 'a') do |_obj, _options|
         | 
| 257 | 
            +
                            nil
         | 
| 258 | 
            +
                          end
         | 
| 259 | 
            +
                          subject.expose(:b)
         | 
| 260 | 
            +
                          subject.expose(:c)
         | 
| 261 | 
            +
                          expect(subject.represent(model).serializable_hash).to eq(a: 'a', b: nil, c: 'value')
         | 
| 262 | 
            +
                        end
         | 
| 263 | 
            +
             | 
| 264 | 
            +
                        it 'return value from block if block returns a value' do
         | 
| 265 | 
            +
                          subject.expose(:a, default: 'a') do |_obj, _options|
         | 
| 266 | 
            +
                            100
         | 
| 267 | 
            +
                          end
         | 
| 268 | 
            +
                          subject.expose(:b)
         | 
| 269 | 
            +
                          subject.expose(:c)
         | 
| 270 | 
            +
                          expect(subject.represent(model).serializable_hash).to eq(a: 100, b: nil, c: 'value')
         | 
| 271 | 
            +
                        end
         | 
| 272 | 
            +
                      end
         | 
| 273 | 
            +
                    end
         | 
| 274 | 
            +
             | 
| 275 | 
            +
                    context 'when model is a hash' do
         | 
| 276 | 
            +
                      let(:model) { { a: a, b: b, c: c } }
         | 
| 277 | 
            +
             | 
| 278 | 
            +
                      context 'when expose_nil option is not provided' do
         | 
| 279 | 
            +
                        it 'exposes nil attributes' do
         | 
| 280 | 
            +
                          subject.expose(:a)
         | 
| 281 | 
            +
                          subject.expose(:b)
         | 
| 282 | 
            +
                          subject.expose(:c)
         | 
| 283 | 
            +
                          expect(subject.represent(model).serializable_hash).to eq(a: nil, b: nil, c: 'value')
         | 
| 284 | 
            +
                        end
         | 
| 285 | 
            +
                      end
         | 
| 286 | 
            +
             | 
| 287 | 
            +
                      context 'when expose_nil option is true' do
         | 
| 288 | 
            +
                        it 'exposes nil attributes' do
         | 
| 289 | 
            +
                          subject.expose(:a, expose_nil: true)
         | 
| 290 | 
            +
                          subject.expose(:b, expose_nil: true)
         | 
| 291 | 
            +
                          subject.expose(:c)
         | 
| 292 | 
            +
                          expect(subject.represent(model).serializable_hash).to eq(a: nil, b: nil, c: 'value')
         | 
| 293 | 
            +
                        end
         | 
| 294 | 
            +
                      end
         | 
| 295 | 
            +
             | 
| 296 | 
            +
                      context 'when expose_nil option is false' do
         | 
| 297 | 
            +
                        it 'does not expose nil attributes' do
         | 
| 298 | 
            +
                          subject.expose(:a, expose_nil: false)
         | 
| 299 | 
            +
                          subject.expose(:b, expose_nil: false)
         | 
| 300 | 
            +
                          subject.expose(:c)
         | 
| 301 | 
            +
                          expect(subject.represent(model).serializable_hash).to eq(c: 'value')
         | 
| 302 | 
            +
                        end
         | 
| 303 | 
            +
             | 
| 304 | 
            +
                        it 'is only applied per attribute' do
         | 
| 305 | 
            +
                          subject.expose(:a, expose_nil: false)
         | 
| 306 | 
            +
                          subject.expose(:b)
         | 
| 307 | 
            +
                          subject.expose(:c)
         | 
| 308 | 
            +
                          expect(subject.represent(model).serializable_hash).to eq(b: nil, c: 'value')
         | 
| 309 | 
            +
                        end
         | 
| 310 | 
            +
             | 
| 311 | 
            +
                        it 'raises an error when applied to multiple attribute exposures' do
         | 
| 312 | 
            +
                          expect { subject.expose(:a, :b, :c, expose_nil: false) }.to raise_error ArgumentError
         | 
| 313 | 
            +
                        end
         | 
| 314 | 
            +
                      end
         | 
| 315 | 
            +
                    end
         | 
| 316 | 
            +
             | 
| 317 | 
            +
                    context 'with nested structures' do
         | 
| 318 | 
            +
                      let(:model) { { a: a, b: b, c: { d: nil, e: nil, f: { g: nil, h: nil } } } }
         | 
| 319 | 
            +
             | 
| 320 | 
            +
                      context 'when expose_nil option is false' do
         | 
| 321 | 
            +
                        it 'does not expose nil attributes' do
         | 
| 322 | 
            +
                          subject.expose(:a, expose_nil: false)
         | 
| 323 | 
            +
                          subject.expose(:b)
         | 
| 324 | 
            +
                          subject.expose(:c) do
         | 
| 325 | 
            +
                            subject.expose(:d, expose_nil: false)
         | 
| 326 | 
            +
                            subject.expose(:e)
         | 
| 327 | 
            +
                            subject.expose(:f) do
         | 
| 328 | 
            +
                              subject.expose(:g, expose_nil: false)
         | 
| 329 | 
            +
                              subject.expose(:h)
         | 
| 330 | 
            +
                            end
         | 
| 331 | 
            +
                          end
         | 
| 332 | 
            +
             | 
| 333 | 
            +
                          expect(subject.represent(model).serializable_hash).to eq(b: nil, c: { e: nil, f: { h: nil } })
         | 
| 334 | 
            +
                        end
         | 
| 335 | 
            +
                      end
         | 
| 336 | 
            +
                    end
         | 
| 337 | 
            +
                  end
         | 
| 338 | 
            +
             | 
| 215 339 | 
             
                  context 'with a block' do
         | 
| 216 340 | 
             
                    it 'errors out if called with multiple attributes' do
         | 
| 217 341 | 
             
                      expect { subject.expose(:name, :email) { true } }.to raise_error ArgumentError
         | 
| @@ -260,27 +384,50 @@ describe Grape::Entity do | |
| 260 384 | 
             
                      end
         | 
| 261 385 | 
             
                    end
         | 
| 262 386 |  | 
| 263 | 
            -
                     | 
| 264 | 
            -
                       | 
| 265 | 
            -
                         | 
| 266 | 
            -
                           | 
| 267 | 
            -
                            'result'
         | 
| 268 | 
            -
                          end
         | 
| 387 | 
            +
                    describe 'blocks' do
         | 
| 388 | 
            +
                      class SomeObject
         | 
| 389 | 
            +
                        def method_without_args
         | 
| 390 | 
            +
                          'result'
         | 
| 269 391 | 
             
                        end
         | 
| 392 | 
            +
                      end
         | 
| 270 393 |  | 
| 271 | 
            -
             | 
| 272 | 
            -
             | 
| 394 | 
            +
                      describe 'with block passed in' do
         | 
| 395 | 
            +
                        specify do
         | 
| 396 | 
            +
                          subject.expose :that_method_without_args do |object|
         | 
| 397 | 
            +
                            object.method_without_args
         | 
| 398 | 
            +
                          end
         | 
| 399 | 
            +
             | 
| 400 | 
            +
                          object = SomeObject.new
         | 
| 401 | 
            +
             | 
| 402 | 
            +
                          value = subject.represent(object).value_for(:that_method_without_args)
         | 
| 403 | 
            +
                          expect(value).to eq('result')
         | 
| 273 404 | 
             
                        end
         | 
| 405 | 
            +
                      end
         | 
| 274 406 |  | 
| 275 | 
            -
             | 
| 407 | 
            +
                      context 'with block passed in via &' do
         | 
| 408 | 
            +
                        if RUBY_VERSION.start_with?('3')
         | 
| 409 | 
            +
                          specify do
         | 
| 410 | 
            +
                            subject.expose :that_method_without_args, &:method_without_args
         | 
| 411 | 
            +
                            subject.expose :method_without_args, as: :that_method_without_args_again
         | 
| 276 412 |  | 
| 277 | 
            -
             | 
| 413 | 
            +
                            object = SomeObject.new
         | 
| 414 | 
            +
                            expect do
         | 
| 415 | 
            +
                              subject.represent(object).value_for(:that_method_without_args)
         | 
| 416 | 
            +
                            end.to raise_error Grape::Entity::Deprecated
         | 
| 278 417 |  | 
| 279 | 
            -
             | 
| 280 | 
            -
             | 
| 418 | 
            +
                            value2 = subject.represent(object).value_for(:that_method_without_args_again)
         | 
| 419 | 
            +
                            expect(value2).to eq('result')
         | 
| 420 | 
            +
                          end
         | 
| 421 | 
            +
                        else
         | 
| 422 | 
            +
                          specify do
         | 
| 423 | 
            +
                            subject.expose :that_method_without_args_again, &:method_without_args
         | 
| 424 | 
            +
             | 
| 425 | 
            +
                            object = SomeObject.new
         | 
| 281 426 |  | 
| 282 | 
            -
             | 
| 283 | 
            -
             | 
| 427 | 
            +
                            value2 = subject.represent(object).value_for(:that_method_without_args_again)
         | 
| 428 | 
            +
                            expect(value2).to eq('result')
         | 
| 429 | 
            +
                          end
         | 
| 430 | 
            +
                        end
         | 
| 284 431 | 
             
                      end
         | 
| 285 432 | 
             
                    end
         | 
| 286 433 |  | 
| @@ -977,7 +1124,7 @@ describe Grape::Entity do | |
| 977 1124 | 
             
                      subject.expose(:user, using: user_entity)
         | 
| 978 1125 |  | 
| 979 1126 | 
             
                      representation = subject.represent(OpenStruct.new(user: {}),
         | 
| 980 | 
            -
                                                         only: [:id, :name, :phone, user: %i[id name email]],
         | 
| 1127 | 
            +
                                                         only: [:id, :name, :phone, { user: %i[id name email] }],
         | 
| 981 1128 | 
             
                                                         except: [:phone, { user: [:id] }], serializable: true)
         | 
| 982 1129 | 
             
                      expect(representation).to eq(id: nil, name: nil, user: { name: nil, email: nil })
         | 
| 983 1130 | 
             
                    end
         | 
| @@ -1112,6 +1259,18 @@ describe Grape::Entity do | |
| 1112 1259 | 
             
                        expect(representation).to eq(id: nil, name: nil, user: { id: nil, name: nil, email: nil })
         | 
| 1113 1260 | 
             
                      end
         | 
| 1114 1261 | 
             
                    end
         | 
| 1262 | 
            +
             | 
| 1263 | 
            +
                    context 'when NameError happens in a parameterized block_exposure' do
         | 
| 1264 | 
            +
                      before do
         | 
| 1265 | 
            +
                        subject.expose :raise_no_method_error do |_|
         | 
| 1266 | 
            +
                          foo
         | 
| 1267 | 
            +
                        end
         | 
| 1268 | 
            +
                      end
         | 
| 1269 | 
            +
             | 
| 1270 | 
            +
                      it 'does not cause infinite loop' do
         | 
| 1271 | 
            +
                        expect { subject.represent({}, serializable: true) }.to raise_error(NameError)
         | 
| 1272 | 
            +
                      end
         | 
| 1273 | 
            +
                    end
         | 
| 1115 1274 | 
             
                  end
         | 
| 1116 1275 | 
             
                end
         | 
| 1117 1276 |  | 
| @@ -1556,7 +1715,7 @@ describe Grape::Entity do | |
| 1556 1715 | 
             
                      end
         | 
| 1557 1716 |  | 
| 1558 1717 | 
             
                      fresh_class.class_eval do
         | 
| 1559 | 
            -
                        expose :characteristics, using: EntitySpec::NoPathCharacterEntity, attr_path: proc { | 
| 1718 | 
            +
                        expose :characteristics, using: EntitySpec::NoPathCharacterEntity, attr_path: proc {}
         | 
| 1560 1719 | 
             
                      end
         | 
| 1561 1720 |  | 
| 1562 1721 | 
             
                      expect(subject.serializable_hash).to eq(
         | 
| @@ -1693,10 +1852,12 @@ describe Grape::Entity do | |
| 1693 1852 | 
             
                        end
         | 
| 1694 1853 | 
             
                      end
         | 
| 1695 1854 |  | 
| 1855 | 
            +
                      # rubocop:disable Lint/EmptyBlock
         | 
| 1696 1856 | 
             
                      fresh_class.class_eval do
         | 
| 1697 1857 | 
             
                        expose :first_friend, using: EntitySpec::FriendEntity do |_user, _opts|
         | 
| 1698 1858 | 
             
                        end
         | 
| 1699 1859 | 
             
                      end
         | 
| 1860 | 
            +
                      # rubocop:enable Lint/EmptyBlock
         | 
| 1700 1861 |  | 
| 1701 1862 | 
             
                      rep = subject.value_for(:first_friend)
         | 
| 1702 1863 | 
             
                      expect(rep).to be_kind_of EntitySpec::FriendEntity
         | 
    
        data/spec/spec_helper.rb
    CHANGED
    
    
    
        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.10.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Michael Bleigh
         | 
| 8 | 
            -
            autorequire: | 
| 8 | 
            +
            autorequire:
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 11 | 
            +
            date: 2021-09-15 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: activesupport
         | 
| @@ -159,11 +159,13 @@ extensions: [] | |
| 159 159 | 
             
            extra_rdoc_files: []
         | 
| 160 160 | 
             
            files:
         | 
| 161 161 | 
             
            - ".coveralls.yml"
         | 
| 162 | 
            +
            - ".github/dependabot.yml"
         | 
| 163 | 
            +
            - ".github/workflows/rubocop.yml"
         | 
| 164 | 
            +
            - ".github/workflows/ruby.yml"
         | 
| 162 165 | 
             
            - ".gitignore"
         | 
| 163 166 | 
             
            - ".rspec"
         | 
| 164 167 | 
             
            - ".rubocop.yml"
         | 
| 165 168 | 
             
            - ".rubocop_todo.yml"
         | 
| 166 | 
            -
            - ".travis.yml"
         | 
| 167 169 | 
             
            - ".yardopts"
         | 
| 168 170 | 
             
            - CHANGELOG.md
         | 
| 169 171 | 
             
            - CONTRIBUTING.md
         | 
| @@ -190,6 +192,7 @@ files: | |
| 190 192 | 
             
            - lib/grape_entity/delegator/hash_object.rb
         | 
| 191 193 | 
             
            - lib/grape_entity/delegator/openstruct_object.rb
         | 
| 192 194 | 
             
            - lib/grape_entity/delegator/plain_object.rb
         | 
| 195 | 
            +
            - lib/grape_entity/deprecated.rb
         | 
| 193 196 | 
             
            - lib/grape_entity/entity.rb
         | 
| 194 197 | 
             
            - lib/grape_entity/exposure.rb
         | 
| 195 198 | 
             
            - lib/grape_entity/exposure/base.rb
         | 
| @@ -214,7 +217,7 @@ homepage: https://github.com/ruby-grape/grape-entity | |
| 214 217 | 
             
            licenses:
         | 
| 215 218 | 
             
            - MIT
         | 
| 216 219 | 
             
            metadata: {}
         | 
| 217 | 
            -
            post_install_message: | 
| 220 | 
            +
            post_install_message:
         | 
| 218 221 | 
             
            rdoc_options: []
         | 
| 219 222 | 
             
            require_paths:
         | 
| 220 223 | 
             
            - lib
         | 
| @@ -222,15 +225,15 @@ required_ruby_version: !ruby/object:Gem::Requirement | |
| 222 225 | 
             
              requirements:
         | 
| 223 226 | 
             
              - - ">="
         | 
| 224 227 | 
             
                - !ruby/object:Gem::Version
         | 
| 225 | 
            -
                  version: '2. | 
| 228 | 
            +
                  version: '2.5'
         | 
| 226 229 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 227 230 | 
             
              requirements:
         | 
| 228 231 | 
             
              - - ">="
         | 
| 229 232 | 
             
                - !ruby/object:Gem::Version
         | 
| 230 233 | 
             
                  version: '0'
         | 
| 231 234 | 
             
            requirements: []
         | 
| 232 | 
            -
            rubygems_version: 3. | 
| 233 | 
            -
            signing_key: | 
| 235 | 
            +
            rubygems_version: 3.2.22
         | 
| 236 | 
            +
            signing_key:
         | 
| 234 237 | 
             
            specification_version: 4
         | 
| 235 238 | 
             
            summary: A simple facade for managing the relationship between your model and API.
         | 
| 236 239 | 
             
            test_files:
         | 
    
        data/.travis.yml
    DELETED
    
    | @@ -1,25 +0,0 @@ | |
| 1 | 
            -
            language: ruby
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            before_install:
         | 
| 4 | 
            -
              - gem install bundler
         | 
| 5 | 
            -
             | 
| 6 | 
            -
            after_success:
         | 
| 7 | 
            -
              - bundle exec danger
         | 
| 8 | 
            -
             | 
| 9 | 
            -
            rvm:
         | 
| 10 | 
            -
              - 2.5.7
         | 
| 11 | 
            -
              - 2.6.5
         | 
| 12 | 
            -
              - 2.7.0
         | 
| 13 | 
            -
              - ruby-head
         | 
| 14 | 
            -
              - jruby-head
         | 
| 15 | 
            -
             | 
| 16 | 
            -
            matrix:
         | 
| 17 | 
            -
              fast_finish: true
         | 
| 18 | 
            -
             | 
| 19 | 
            -
              include:
         | 
| 20 | 
            -
                - rvm: 2.4.9
         | 
| 21 | 
            -
             | 
| 22 | 
            -
              allow_failures:
         | 
| 23 | 
            -
                - rvm: 2.4.9
         | 
| 24 | 
            -
                - rvm: ruby-head
         | 
| 25 | 
            -
                - rvm: jruby-head
         |