surrealist 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +13 -1
- data/.travis.yml +4 -4
- data/CHANGELOG.md +13 -1
- data/Gemfile +1 -1
- data/README.md +20 -3
- data/lib/surrealist.rb +9 -5
- data/lib/surrealist/builder.rb +1 -1
- data/lib/surrealist/copier.rb +2 -99
- data/lib/surrealist/hash_utils.rb +2 -0
- data/lib/surrealist/helper.rb +1 -1
- data/lib/surrealist/serializer.rb +6 -2
- data/lib/surrealist/value_assigner.rb +5 -3
- data/lib/surrealist/version.rb +1 -1
- data/lib/surrealist/wrapper.rb +102 -0
- data/surrealist.gemspec +1 -1
- metadata +5 -4
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 4029b143bcc01a58f0b5a38d64a457f9a781ef7da37eaa3bc335be8d2ddafcfa
         | 
| 4 | 
            +
              data.tar.gz: 4f88b4c0b4224fddfe8fa7f6d16f2d0d2618609f280a7fdfd7bea2e4f46aa2b8
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 369823e9f4d78b1c48aa7878f76e69f7381bfacffd79653ba667f747f8c2c23802dc2126eab7ba3b2e0ab6a3ce04878745b12f42c5dbcdb36ac307e953c9b259
         | 
| 7 | 
            +
              data.tar.gz: 8c7f310b4150ce62e568bfb8d0d4c0e5da187fff1fbbb11f338098ca17cf1c4e83646bbb6b05e9c0ff6d5d9790a7bcc59a00d6dd70d07fa1e61014f0dc4be0d9
         | 
    
        data/.rubocop.yml
    CHANGED
    
    | @@ -33,6 +33,9 @@ Layout/MultilineOperationIndentation: | |
| 33 33 | 
             
            Layout/SpaceInLambdaLiteral:
         | 
| 34 34 | 
             
              EnforcedStyle: require_space
         | 
| 35 35 |  | 
| 36 | 
            +
            Layout/ClosingParenthesisIndentation:
         | 
| 37 | 
            +
              Enabled: true
         | 
| 38 | 
            +
             | 
| 36 39 | 
             
            # Lint
         | 
| 37 40 | 
             
            Lint/AmbiguousBlockAssociation:
         | 
| 38 41 | 
             
              Enabled: false
         | 
| @@ -98,6 +101,9 @@ Performance/UnfreezeString: | |
| 98 101 | 
             
            Style/AsciiComments:
         | 
| 99 102 | 
             
              Enabled: false
         | 
| 100 103 |  | 
| 104 | 
            +
            Style/AccessModifierDeclarations:
         | 
| 105 | 
            +
              Enabled: false
         | 
| 106 | 
            +
             | 
| 101 107 | 
             
            Style/MixinUsage:
         | 
| 102 108 | 
             
              Exclude:
         | 
| 103 109 | 
             
                - spec/**/*rb
         | 
| @@ -154,9 +160,15 @@ Style/TrailingCommaInArrayLiteral: | |
| 154 160 | 
             
            Style/TrailingCommaInHashLiteral:
         | 
| 155 161 | 
             
              EnforcedStyleForMultiline: comma
         | 
| 156 162 |  | 
| 157 | 
            -
            Style/ | 
| 163 | 
            +
            Style/MissingRespondToMissing:
         | 
| 164 | 
            +
              Enabled: false
         | 
| 165 | 
            +
             | 
| 166 | 
            +
            Style/MethodMissingSuper:
         | 
| 158 167 | 
             
              Enabled: false
         | 
| 159 168 |  | 
| 160 169 | 
             
            Style/EvalWithLocation:
         | 
| 161 170 | 
             
              Exclude:
         | 
| 162 171 | 
             
                - spec/**/*.rb
         | 
| 172 | 
            +
             | 
| 173 | 
            +
            Style/AccessModifierDeclarations:
         | 
| 174 | 
            +
              Enabled: false
         | 
    
        data/.travis.yml
    CHANGED
    
    | @@ -8,12 +8,12 @@ matrix: | |
| 8 8 | 
             
              include:
         | 
| 9 9 | 
             
                - rvm: ruby-head
         | 
| 10 10 | 
             
                  gemfile: Gemfile
         | 
| 11 | 
            -
                - rvm: 2.5 | 
| 11 | 
            +
                - rvm: 2.5
         | 
| 12 12 | 
             
                  gemfile: Gemfile
         | 
| 13 | 
            -
                - rvm: 2.4 | 
| 13 | 
            +
                - rvm: 2.4
         | 
| 14 14 | 
             
                  gemfile: Gemfile
         | 
| 15 | 
            -
                - rvm: 2.3 | 
| 15 | 
            +
                - rvm: 2.3
         | 
| 16 16 | 
             
                  gemfile: Gemfile
         | 
| 17 | 
            -
                - rvm: 2.2 | 
| 17 | 
            +
                - rvm: 2.2
         | 
| 18 18 | 
             
                  gemfile: gemfiles/activerecord42.gemfile
         | 
| 19 19 |  | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,3 +1,14 @@ | |
| 1 | 
            +
            # 1.3.0
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            ## Added
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            * Hash serialization ([@stefkin][]) [#106](https://github.com/nesaulov/surrealist/pull/106)
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            ## Fixed
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            * Conflict when root and object property share the same name ([@akxcv][]) [#99](https://github.com/nesaulov/surrealist/pull/99)
         | 
| 10 | 
            +
            * Precedence was given to object method instead of serializer one ([@gjhenrique][] & [@nesaulov][]) [#110](https://github.com/nesaulov/surrealist/pull/110) & [#111](https://github.com/nesaulov/surrealist/pull/111)
         | 
| 11 | 
            +
             | 
| 1 12 | 
             
            # 1.2.0
         | 
| 2 13 |  | 
| 3 14 | 
             
            ## Added
         | 
| @@ -102,4 +113,5 @@ | |
| 102 113 | 
             
            [@azhi]: https://github.com/azhi
         | 
| 103 114 | 
             
            [@chrisatanasian]: https://github.com/chrisatanasian
         | 
| 104 115 | 
             
            [@past-one]: https://github.com/past-one
         | 
| 105 | 
            -
             | 
| 116 | 
            +
            [@stefkin]: https://github.com/stefkin
         | 
| 117 | 
            +
            [@gjhenrique]: https://github.com/gjhenrique
         | 
    
        data/Gemfile
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -40,6 +40,7 @@ to serialize nested objects and structures. [Introductory blogpost.](https://med | |
| 40 40 | 
             
                * [Root](#root)
         | 
| 41 41 | 
             
                * [Include namespaces](#include-namespaces)
         | 
| 42 42 | 
             
              * [Configuration](#configuration)
         | 
| 43 | 
            +
              * [Hash serialization](#hash-serialization)
         | 
| 43 44 | 
             
              * [Bool and Any](#bool-and-any)
         | 
| 44 45 | 
             
              * [Type errors](#type-errors)
         | 
| 45 46 | 
             
              * [Undefined methods in schema](#undefined-methods-in-schema)
         | 
| @@ -687,7 +688,7 @@ withdraws.surrealize(include_namespaces: true, namespaces_nesting_level: 2) | |
| 687 688 |  | 
| 688 689 | 
             
            There are two ways of setting default arguments for serialization,
         | 
| 689 690 | 
             
            by passing a block to `Surrealist.configure`:
         | 
| 690 | 
            -
            ```ruby
         | 
| 691 | 
            +
            ``` ruby
         | 
| 691 692 | 
             
            Surrealist.configure do |config|
         | 
| 692 693 | 
             
              config.camelize = true
         | 
| 693 694 | 
             
              config.namespaces_nesting_level = 2
         | 
| @@ -700,13 +701,28 @@ And by passing a hash: | |
| 700 701 | 
             
            These arguments will be applied to all calls of `#build_schema` and `#surrealize`.
         | 
| 701 702 | 
             
            If these methods will be called with arguments, they will be merged with respect to explicitly passed ones:
         | 
| 702 703 |  | 
| 703 | 
            -
            ```ruby
         | 
| 704 | 
            +
            ``` ruby
         | 
| 704 705 | 
             
            Surrealist.configure(camelize: true, include_root: true)
         | 
| 705 706 |  | 
| 706 707 | 
             
            Something.new.surrealize(camelize: false)
         | 
| 707 708 | 
             
            # will result in Something.new.surrealize(camelize: false, include_root: true)
         | 
| 708 709 | 
             
            ```
         | 
| 709 710 |  | 
| 711 | 
            +
            ### Hash serialization
         | 
| 712 | 
            +
             | 
| 713 | 
            +
            You can pass a hash to serializer and it will use the keys instead of methods.
         | 
| 714 | 
            +
             | 
| 715 | 
            +
            ``` ruby
         | 
| 716 | 
            +
            class HashSerializer < Surrealist::Serializer
         | 
| 717 | 
            +
              json_schema { { string: String, int: Integer } }
         | 
| 718 | 
            +
            end
         | 
| 719 | 
            +
             | 
| 720 | 
            +
            HashSerializer.new(string: 'string', int: 4).surrealize
         | 
| 721 | 
            +
            # => '{ "string": "string", "int": 4}'
         | 
| 722 | 
            +
             | 
| 723 | 
            +
            HashSerializer.new(string: 'string', int: 'not int').surrealize
         | 
| 724 | 
            +
            # => Surrealist::InvalidTypeError: Wrong type for key `int`. Expected Integer, got String.
         | 
| 725 | 
            +
            ```
         | 
| 710 726 |  | 
| 711 727 | 
             
            ### Bool and Any
         | 
| 712 728 | 
             
            If you have a parameter that is of boolean type, or if you don't care about the type, you
         | 
| @@ -769,7 +785,8 @@ type check will be passed. If you want to be strict about `nil`s consider using | |
| 769 785 |  | 
| 770 786 | 
             
            ## Roadmap
         | 
| 771 787 | 
             
            Here is a list of features that are not implemented yet (contributions are welcome):
         | 
| 772 | 
            -
            *  | 
| 788 | 
            +
            * Automatic endpoint documentation
         | 
| 789 | 
            +
            * API for validating (contracts) without actually serializing to JSON (maybe with deserialization from JSON)
         | 
| 773 790 |  | 
| 774 791 | 
             
            ## Contributing
         | 
| 775 792 | 
             
            Bug reports and pull requests are welcome on GitHub at https://github.com/nesaulov/surrealist.
         | 
    
        data/lib/surrealist.rb
    CHANGED
    
    | @@ -18,6 +18,7 @@ require_relative 'surrealist/string_utils' | |
| 18 18 | 
             
            require_relative 'surrealist/type_helper'
         | 
| 19 19 | 
             
            require_relative 'surrealist/value_assigner'
         | 
| 20 20 | 
             
            require_relative 'surrealist/vars_helper'
         | 
| 21 | 
            +
            require_relative 'surrealist/wrapper'
         | 
| 21 22 |  | 
| 22 23 | 
             
            # Main module that provides the +json_schema+ class method and +surrealize+ instance method.
         | 
| 23 24 | 
             
            module Surrealist
         | 
| @@ -128,10 +129,13 @@ module Surrealist | |
| 128 129 | 
             
                  Surrealist::ExceptionRaiser.raise_unknown_schema!(instance) if schema.nil?
         | 
| 129 130 |  | 
| 130 131 | 
             
                  parameters = config ? config.merge(args) : args
         | 
| 132 | 
            +
             | 
| 133 | 
            +
                  # TODO: Refactor (something pipeline-like would do here, perhaps a builder of some sort)
         | 
| 131 134 | 
             
                  carrier = Surrealist::Carrier.call(parameters)
         | 
| 132 | 
            -
                   | 
| 133 | 
            -
                   | 
| 134 | 
            -
                   | 
| 135 | 
            +
                  copied_schema = Surrealist::Copier.deep_copy(schema)
         | 
| 136 | 
            +
                  built_schema = Builder.new(carrier, copied_schema, instance).call
         | 
| 137 | 
            +
                  wrapped_schema = Surrealist::Wrapper.wrap(built_schema, carrier, instance.class.name)
         | 
| 138 | 
            +
                  carrier.camelize ? Surrealist::HashUtils.camelize_hash(wrapped_schema) : wrapped_schema
         | 
| 135 139 | 
             
                end
         | 
| 136 140 | 
             
                # rubocop:enable Metrics/AbcSize
         | 
| 137 141 |  | 
| @@ -139,7 +143,7 @@ module Surrealist | |
| 139 143 | 
             
                #
         | 
| 140 144 | 
             
                # @return [Hash] default arguments (@see Surrealist::Carrier)
         | 
| 141 145 | 
             
                def config
         | 
| 142 | 
            -
                  @default_args || Surrealist:: | 
| 146 | 
            +
                  @default_args || Surrealist::HashUtils::EMPTY_HASH
         | 
| 143 147 | 
             
                end
         | 
| 144 148 |  | 
| 145 149 | 
             
                # Sets default serialization arguments with a block
         | 
| @@ -158,7 +162,7 @@ module Surrealist | |
| 158 162 | 
             
                    yield(carrier)
         | 
| 159 163 | 
             
                    @default_args = carrier.parameters
         | 
| 160 164 | 
             
                  else
         | 
| 161 | 
            -
                    @default_args = hash.nil? ? Surrealist:: | 
| 165 | 
            +
                    @default_args = hash.nil? ? Surrealist::HashUtils::EMPTY_HASH : hash
         | 
| 162 166 | 
             
                  end
         | 
| 163 167 | 
             
                end
         | 
| 164 168 |  | 
    
        data/lib/surrealist/builder.rb
    CHANGED
    
    | @@ -80,7 +80,7 @@ module Surrealist | |
| 80 80 | 
             
                # @return [Hash] the schema hash
         | 
| 81 81 | 
             
                def construct_collection(schema, instance, key, value)
         | 
| 82 82 | 
             
                  schema[key] = instance.send(key).map do |inst|
         | 
| 83 | 
            -
                    call(Copier.deep_copy(value | 
| 83 | 
            +
                    call(Copier.deep_copy(value), inst)
         | 
| 84 84 | 
             
                  end
         | 
| 85 85 | 
             
                end
         | 
| 86 86 | 
             
              end
         | 
    
        data/lib/surrealist/copier.rb
    CHANGED
    
    | @@ -3,113 +3,16 @@ | |
| 3 3 | 
             
            module Surrealist
         | 
| 4 4 | 
             
              # A helper class for deep copying and wrapping hashes.
         | 
| 5 5 | 
             
              module Copier
         | 
| 6 | 
            -
                EMPTY_HASH = {}.freeze
         | 
| 7 | 
            -
             | 
| 8 6 | 
             
                class << self
         | 
| 9 | 
            -
                  # Deeply copies the schema hash and wraps it if there is a need to.
         | 
| 10 | 
            -
                  #
         | 
| 11 | 
            -
                  # @param [Object] hash object to be copied.
         | 
| 12 | 
            -
                  # @param [String] klass instance's class name.
         | 
| 13 | 
            -
                  # @param [Object] carrier instance of Carrier class that carries arguments passed to +surrealize+
         | 
| 14 | 
            -
                  #
         | 
| 15 | 
            -
                  # @return [Hash] a copied hash.
         | 
| 16 | 
            -
                  def deep_copy(hash, carrier, klass = false)
         | 
| 17 | 
            -
                    namespaces_condition = carrier.include_namespaces || carrier.namespaces_nesting_level != DEFAULT_NESTING_LEVEL # rubocop:disable Metrics/LineLength
         | 
| 18 | 
            -
             | 
| 19 | 
            -
                    if !klass && (carrier.include_root || namespaces_condition)
         | 
| 20 | 
            -
                      Surrealist::ExceptionRaiser.raise_unknown_root!
         | 
| 21 | 
            -
                    end
         | 
| 22 | 
            -
             | 
| 23 | 
            -
                    copied_and_possibly_wrapped_hash(hash, klass, carrier, namespaces_condition)
         | 
| 24 | 
            -
                  end
         | 
| 25 | 
            -
             | 
| 26 | 
            -
                  private
         | 
| 27 | 
            -
             | 
| 28 | 
            -
                  # Deeply copies the schema hash and wraps it if there is a need to.
         | 
| 29 | 
            -
                  #
         | 
| 30 | 
            -
                  # @param [Object] hash object to be copied.
         | 
| 31 | 
            -
                  # @param [String] klass instance's class name.
         | 
| 32 | 
            -
                  # @param [Object] carrier instance of Carrier class that carries arguments passed to +surrealize+
         | 
| 33 | 
            -
                  # @param [Bool] namespaces_condition whether to wrap into namespace.
         | 
| 34 | 
            -
                  #
         | 
| 35 | 
            -
                  # @return [Hash] deeply copied hash, possibly wrapped.
         | 
| 36 | 
            -
                  def copied_and_possibly_wrapped_hash(hash, klass, carrier, namespaces_condition)
         | 
| 37 | 
            -
                    return copy_hash(hash) if carrier.no_args_provided?
         | 
| 38 | 
            -
             | 
| 39 | 
            -
                    if carrier.root
         | 
| 40 | 
            -
                      wrap_schema_into_root(hash, carrier, carrier.root.to_s)
         | 
| 41 | 
            -
                    elsif namespaces_condition
         | 
| 42 | 
            -
                      wrap_schema_into_namespace(hash, carrier, klass)
         | 
| 43 | 
            -
                    elsif carrier.include_root
         | 
| 44 | 
            -
                      actual_class = Surrealist::StringUtils.extract_class(klass)
         | 
| 45 | 
            -
                      wrap_schema_into_root(hash, carrier, actual_class)
         | 
| 46 | 
            -
                    else
         | 
| 47 | 
            -
                      copy_hash(hash)
         | 
| 48 | 
            -
                    end
         | 
| 49 | 
            -
                  end
         | 
| 50 | 
            -
             | 
| 51 7 | 
             
                  # Goes through the hash recursively and deeply copies it.
         | 
| 52 8 | 
             
                  #
         | 
| 53 9 | 
             
                  # @param [Hash] hash the hash to be copied.
         | 
| 54 10 | 
             
                  # @param [Hash] wrapper the wrapper of the resulting hash.
         | 
| 55 11 | 
             
                  #
         | 
| 56 12 | 
             
                  # @return [Hash] deeply copied hash.
         | 
| 57 | 
            -
                  def  | 
| 13 | 
            +
                  def deep_copy(hash, wrapper = {})
         | 
| 58 14 | 
             
                    hash.each_with_object(wrapper) do |(key, value), new|
         | 
| 59 | 
            -
                      new[key] = value.is_a?(Hash) ?  | 
| 60 | 
            -
                    end
         | 
| 61 | 
            -
                  end
         | 
| 62 | 
            -
             | 
| 63 | 
            -
                  # Wraps schema into a root key if `include_root` is passed to Surrealist.
         | 
| 64 | 
            -
                  #
         | 
| 65 | 
            -
                  # @param [Hash] schema schema hash.
         | 
| 66 | 
            -
                  # @param [Object] carrier instance of Carrier class that carries arguments passed to +surrealize+
         | 
| 67 | 
            -
                  # @param [String] root what the schema will be wrapped into
         | 
| 68 | 
            -
                  #
         | 
| 69 | 
            -
                  # @return [Hash] a hash with schema wrapped inside a root key.
         | 
| 70 | 
            -
                  def wrap_schema_into_root(schema, carrier, root)
         | 
| 71 | 
            -
                    root_key = if carrier.camelize
         | 
| 72 | 
            -
                                 Surrealist::StringUtils.camelize(root, false).to_sym
         | 
| 73 | 
            -
                               else
         | 
| 74 | 
            -
                                 Surrealist::StringUtils.underscore(root).to_sym
         | 
| 75 | 
            -
                               end
         | 
| 76 | 
            -
                    result = Hash[root_key => {}]
         | 
| 77 | 
            -
                    copy_hash(schema, result[root_key])
         | 
| 78 | 
            -
             | 
| 79 | 
            -
                    result
         | 
| 80 | 
            -
                  end
         | 
| 81 | 
            -
             | 
| 82 | 
            -
                  # Wraps schema into a nested hash of namespaces.
         | 
| 83 | 
            -
                  #
         | 
| 84 | 
            -
                  # @param [Hash] schema main schema.
         | 
| 85 | 
            -
                  # @param [String] klass name of the class where schema is defined.
         | 
| 86 | 
            -
                  # @param [Object] carrier instance of Carrier class that carries arguments passed to +surrealize+
         | 
| 87 | 
            -
                  #
         | 
| 88 | 
            -
                  # @return [Hash] nested hash (see +inject_schema+)
         | 
| 89 | 
            -
                  def wrap_schema_into_namespace(schema, carrier, klass)
         | 
| 90 | 
            -
                    nested_hash = Surrealist::StringUtils.break_namespaces(
         | 
| 91 | 
            -
                      klass, carrier.camelize, carrier.namespaces_nesting_level
         | 
| 92 | 
            -
                    )
         | 
| 93 | 
            -
             | 
| 94 | 
            -
                    inject_schema(nested_hash, copy_hash(schema))
         | 
| 95 | 
            -
                  end
         | 
| 96 | 
            -
             | 
| 97 | 
            -
                  # Injects one hash into another nested hash.
         | 
| 98 | 
            -
                  #
         | 
| 99 | 
            -
                  # @param [Hash] hash wrapper-hash.
         | 
| 100 | 
            -
                  # @param [Hash] sub_hash hash to be injected.
         | 
| 101 | 
            -
                  #
         | 
| 102 | 
            -
                  # @example wrapping hash
         | 
| 103 | 
            -
                  #  hash = { one: { two: { three: {} } } }
         | 
| 104 | 
            -
                  #  sub_hash = { four: '4' }
         | 
| 105 | 
            -
                  #
         | 
| 106 | 
            -
                  #  inject_schema(hash, sub_hash)
         | 
| 107 | 
            -
                  #  # => { one: { two: { three: { four: '4' } } } }
         | 
| 108 | 
            -
                  #
         | 
| 109 | 
            -
                  # @return [Hash] resulting hash.
         | 
| 110 | 
            -
                  def inject_schema(hash, sub_hash)
         | 
| 111 | 
            -
                    hash.each do |k, v|
         | 
| 112 | 
            -
                      v == EMPTY_HASH ? hash[k] = sub_hash : inject_schema(v, sub_hash)
         | 
| 15 | 
            +
                      new[key] = value.is_a?(Hash) ? deep_copy(value) : value
         | 
| 113 16 | 
             
                    end
         | 
| 114 17 | 
             
                  end
         | 
| 115 18 | 
             
                end
         | 
    
        data/lib/surrealist/helper.rb
    CHANGED
    
    | @@ -16,7 +16,7 @@ module Surrealist | |
| 16 16 | 
             
                  # 4.2 AR relation object did not include Enumerable (it defined
         | 
| 17 17 | 
             
                  # all necessary method through ActiveRecord::Delegation module),
         | 
| 18 18 | 
             
                  # so we need to explicitly check for this
         | 
| 19 | 
            -
                  object.is_a?(Enumerable) || ar_relation?(object)
         | 
| 19 | 
            +
                  (object.is_a?(Enumerable) && !object.instance_of?(Hash)) || ar_relation?(object)
         | 
| 20 20 | 
             
                end
         | 
| 21 21 |  | 
| 22 22 | 
             
                def self.ar_relation?(object)
         | 
| @@ -54,7 +54,7 @@ module Surrealist | |
| 54 54 | 
             
                #   e.g `CatSerializer.new(Cat.new(3), food: CatFood.new)`
         | 
| 55 55 | 
             
                #   And then food will be available inside serializer via `context[:food]`
         | 
| 56 56 | 
             
                def initialize(object, **context)
         | 
| 57 | 
            -
                  @object = object
         | 
| 57 | 
            +
                  @object = wrap_hash_into_struct(object)
         | 
| 58 58 | 
             
                  @context = context
         | 
| 59 59 | 
             
                end
         | 
| 60 60 |  | 
| @@ -87,12 +87,16 @@ module Surrealist | |
| 87 87 |  | 
| 88 88 | 
             
                # Methods not found inside serializer will be invoked on the object
         | 
| 89 89 | 
             
                def method_missing(method, *args, &block)
         | 
| 90 | 
            -
                  object.public_send(method, *args, &block)
         | 
| 90 | 
            +
                  object.public_send(method, *args, &block) || super
         | 
| 91 91 | 
             
                end
         | 
| 92 92 |  | 
| 93 93 | 
             
                # Methods not found inside serializer will be invoked on the object
         | 
| 94 94 | 
             
                def respond_to_missing?(method, include_private = false)
         | 
| 95 95 | 
             
                  object.respond_to?(method) || super
         | 
| 96 96 | 
             
                end
         | 
| 97 | 
            +
             | 
| 98 | 
            +
                def wrap_hash_into_struct(object)
         | 
| 99 | 
            +
                  object.instance_of?(Hash) ? OpenStruct.new(object) : object
         | 
| 100 | 
            +
                end
         | 
| 97 101 | 
             
              end
         | 
| 98 102 | 
             
            end
         | 
| @@ -39,7 +39,7 @@ module Surrealist | |
| 39 39 | 
             
                  end
         | 
| 40 40 |  | 
| 41 41 | 
             
                  # Checks if there is a custom serializer defined for the object and invokes the method
         | 
| 42 | 
            -
                  #   on it first.
         | 
| 42 | 
            +
                  #   on it first only if the serializer has not defined the same method.
         | 
| 43 43 | 
             
                  #
         | 
| 44 44 | 
             
                  # @param [Object] instance an instance of a model or a serializer
         | 
| 45 45 | 
             
                  # @param [Symbol] method the schema key that represents the method to be invoked
         | 
| @@ -47,8 +47,10 @@ module Surrealist | |
| 47 47 | 
             
                  # @return [Object] the return value of the method
         | 
| 48 48 | 
             
                  def invoke_method(instance, method)
         | 
| 49 49 | 
             
                    object = instance.instance_variable_get(:@object)
         | 
| 50 | 
            -
             | 
| 51 | 
            -
             | 
| 50 | 
            +
                    instance_method = instance.class.instance_methods(false).include?(method) ||
         | 
| 51 | 
            +
                      instance.class.private_instance_methods(false).include?(method)
         | 
| 52 | 
            +
                    invoke_object = !instance_method && object && object.respond_to?(method, true)
         | 
| 53 | 
            +
                    invoke_object ? object.send(method) : instance.send(method)
         | 
| 52 54 | 
             
                  end
         | 
| 53 55 |  | 
| 54 56 | 
             
                  # Coerces value if type check is passed
         | 
    
        data/lib/surrealist/version.rb
    CHANGED
    
    
| @@ -0,0 +1,102 @@ | |
| 1 | 
            +
            module Surrealist
         | 
| 2 | 
            +
              # A helper class for wrapphing hashes.
         | 
| 3 | 
            +
              module Wrapper
         | 
| 4 | 
            +
                class << self
         | 
| 5 | 
            +
                  # Wraps the schema hash into root/namespaces if there is a need to.
         | 
| 6 | 
            +
                  #
         | 
| 7 | 
            +
                  # @param [Object] hash to be wrapped.
         | 
| 8 | 
            +
                  # @param [Object] carrier instance of Carrier class that carries arguments passed to +surrealize+
         | 
| 9 | 
            +
                  # @param [String] klass instance's class name.
         | 
| 10 | 
            +
                  #
         | 
| 11 | 
            +
                  # @return [Hash] a wrapped hash.
         | 
| 12 | 
            +
                  def wrap(hash, carrier, klass = false)
         | 
| 13 | 
            +
                    namespaces_condition = carrier.include_namespaces || carrier.namespaces_nesting_level != DEFAULT_NESTING_LEVEL # rubocop:disable Metrics/LineLength
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                    if !klass && (carrier.include_root || namespaces_condition)
         | 
| 16 | 
            +
                      Surrealist::ExceptionRaiser.raise_unknown_root!
         | 
| 17 | 
            +
                    end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                    possibly_wrapped_hash(hash, klass, carrier, namespaces_condition)
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  private
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                  # Deeply copies the schema hash and wraps it if there is a need to.
         | 
| 25 | 
            +
                  # TODO: refactor
         | 
| 26 | 
            +
                  #
         | 
| 27 | 
            +
                  # @param [Object] hash object to be copied.
         | 
| 28 | 
            +
                  # @param [String] klass instance's class name.
         | 
| 29 | 
            +
                  # @param [Object] carrier instance of Carrier class that carries arguments passed to +surrealize+
         | 
| 30 | 
            +
                  # @param [Bool] namespaces_condition whether to wrap into namespace.
         | 
| 31 | 
            +
                  #
         | 
| 32 | 
            +
                  # @return [Hash] deeply copied hash, possibly wrapped.
         | 
| 33 | 
            +
                  def possibly_wrapped_hash(hash, klass, carrier, namespaces_condition)
         | 
| 34 | 
            +
                    return hash if carrier.no_args_provided?
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                    if carrier.root
         | 
| 37 | 
            +
                      wrap_schema_into_root(hash, carrier, carrier.root.to_s)
         | 
| 38 | 
            +
                    elsif namespaces_condition
         | 
| 39 | 
            +
                      wrap_schema_into_namespace(hash, carrier, klass)
         | 
| 40 | 
            +
                    elsif carrier.include_root
         | 
| 41 | 
            +
                      actual_class = Surrealist::StringUtils.extract_class(klass)
         | 
| 42 | 
            +
                      wrap_schema_into_root(hash, carrier, actual_class)
         | 
| 43 | 
            +
                    else
         | 
| 44 | 
            +
                      hash
         | 
| 45 | 
            +
                    end
         | 
| 46 | 
            +
                  end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  # Wraps schema into a root key if `include_root` is passed to Surrealist.
         | 
| 49 | 
            +
                  #
         | 
| 50 | 
            +
                  # @param [Hash] schema schema hash.
         | 
| 51 | 
            +
                  # @param [Object] carrier instance of Carrier class that carries arguments passed to +surrealize+
         | 
| 52 | 
            +
                  # @param [String] root what the schema will be wrapped into
         | 
| 53 | 
            +
                  #
         | 
| 54 | 
            +
                  # @return [Hash] a hash with schema wrapped inside a root key.
         | 
| 55 | 
            +
                  def wrap_schema_into_root(schema, carrier, root)
         | 
| 56 | 
            +
                    root_key = if carrier.camelize
         | 
| 57 | 
            +
                                 Surrealist::StringUtils.camelize(root, false).to_sym
         | 
| 58 | 
            +
                               else
         | 
| 59 | 
            +
                                 Surrealist::StringUtils.underscore(root).to_sym
         | 
| 60 | 
            +
                               end
         | 
| 61 | 
            +
                    result = Hash[root_key => {}]
         | 
| 62 | 
            +
                    Surrealist::Copier.deep_copy(schema, result[root_key])
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                    result
         | 
| 65 | 
            +
                  end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                  # Wraps schema into a nested hash of namespaces.
         | 
| 68 | 
            +
                  #
         | 
| 69 | 
            +
                  # @param [Hash] schema main schema.
         | 
| 70 | 
            +
                  # @param [String] klass name of the class where schema is defined.
         | 
| 71 | 
            +
                  # @param [Object] carrier instance of Carrier class that carries arguments passed to +surrealize+
         | 
| 72 | 
            +
                  #
         | 
| 73 | 
            +
                  # @return [Hash] nested hash (see +inject_schema+)
         | 
| 74 | 
            +
                  def wrap_schema_into_namespace(schema, carrier, klass)
         | 
| 75 | 
            +
                    nested_hash = Surrealist::StringUtils.break_namespaces(
         | 
| 76 | 
            +
                      klass, carrier.camelize, carrier.namespaces_nesting_level
         | 
| 77 | 
            +
                    )
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                    inject_schema(nested_hash, Surrealist::Copier.deep_copy(schema))
         | 
| 80 | 
            +
                  end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                  # Injects one hash into another nested hash.
         | 
| 83 | 
            +
                  #
         | 
| 84 | 
            +
                  # @param [Hash] hash wrapper-hash.
         | 
| 85 | 
            +
                  # @param [Hash] sub_hash hash to be injected.
         | 
| 86 | 
            +
                  #
         | 
| 87 | 
            +
                  # @example wrapping hash
         | 
| 88 | 
            +
                  #  hash = { one: { two: { three: {} } } }
         | 
| 89 | 
            +
                  #  sub_hash = { four: '4' }
         | 
| 90 | 
            +
                  #
         | 
| 91 | 
            +
                  #  inject_schema(hash, sub_hash)
         | 
| 92 | 
            +
                  #  # => { one: { two: { three: { four: '4' } } } }
         | 
| 93 | 
            +
                  #
         | 
| 94 | 
            +
                  # @return [Hash] resulting hash.
         | 
| 95 | 
            +
                  def inject_schema(hash, sub_hash)
         | 
| 96 | 
            +
                    hash.each do |k, v|
         | 
| 97 | 
            +
                      v == Surrealist::HashUtils::EMPTY_HASH ? hash[k] = sub_hash : inject_schema(v, sub_hash)
         | 
| 98 | 
            +
                    end
         | 
| 99 | 
            +
                  end
         | 
| 100 | 
            +
                end
         | 
| 101 | 
            +
              end
         | 
| 102 | 
            +
            end
         | 
    
        data/surrealist.gemspec
    CHANGED
    
    | @@ -30,5 +30,5 @@ Gem::Specification.new do |spec| | |
| 30 30 | 
             
              spec.add_development_dependency 'pry', '~> 0.11'
         | 
| 31 31 | 
             
              spec.add_development_dependency 'rake', '~> 12.3'
         | 
| 32 32 | 
             
              spec.add_development_dependency 'rspec', '~> 3.7'
         | 
| 33 | 
            -
              spec.add_development_dependency 'rubocop', '~> 0. | 
| 33 | 
            +
              spec.add_development_dependency 'rubocop', '~> 0.57'
         | 
| 34 34 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: surrealist
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1. | 
| 4 | 
            +
              version: 1.3.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Nikita Esaulov
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: exe
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2018- | 
| 11 | 
            +
            date: 2018-07-09 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: oj
         | 
| @@ -86,14 +86,14 @@ dependencies: | |
| 86 86 | 
             
                requirements:
         | 
| 87 87 | 
             
                - - "~>"
         | 
| 88 88 | 
             
                  - !ruby/object:Gem::Version
         | 
| 89 | 
            -
                    version: '0. | 
| 89 | 
            +
                    version: '0.57'
         | 
| 90 90 | 
             
              type: :development
         | 
| 91 91 | 
             
              prerelease: false
         | 
| 92 92 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 93 93 | 
             
                requirements:
         | 
| 94 94 | 
             
                - - "~>"
         | 
| 95 95 | 
             
                  - !ruby/object:Gem::Version
         | 
| 96 | 
            -
                    version: '0. | 
| 96 | 
            +
                    version: '0.57'
         | 
| 97 97 | 
             
            description: A gem that provides DSL for serialization of plain old Ruby objects to
         | 
| 98 98 | 
             
              JSON in a declarative style by defining a `schema`. It also provides a trivial type
         | 
| 99 99 | 
             
              checking in the runtime before serialization.
         | 
| @@ -136,6 +136,7 @@ files: | |
| 136 136 | 
             
            - lib/surrealist/value_assigner.rb
         | 
| 137 137 | 
             
            - lib/surrealist/vars_helper.rb
         | 
| 138 138 | 
             
            - lib/surrealist/version.rb
         | 
| 139 | 
            +
            - lib/surrealist/wrapper.rb
         | 
| 139 140 | 
             
            - surrealist-icon.png
         | 
| 140 141 | 
             
            - surrealist.gemspec
         | 
| 141 142 | 
             
            homepage: https://github.com/nesaulov/surrealist
         |