representable 1.8.5 → 2.0.0.rc1
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/.travis.yml +1 -1
- data/CHANGES.md +36 -0
- data/Gemfile +3 -3
- data/README.md +62 -2
- data/Rakefile +1 -1
- data/lib/representable.rb +32 -109
- data/lib/representable/TODO.getting_serious +7 -1
- data/lib/representable/autoload.rb +10 -0
- data/lib/representable/binding.rb +20 -16
- data/lib/representable/bindings/xml_bindings.rb +0 -1
- data/lib/representable/coercion.rb +23 -31
- data/lib/representable/config.rb +45 -46
- data/lib/representable/declarative.rb +78 -0
- data/lib/representable/decorator.rb +39 -10
- data/lib/representable/definition.rb +40 -33
- data/lib/representable/deserializer.rb +2 -0
- data/lib/representable/for_collection.rb +25 -0
- data/lib/representable/hash.rb +4 -8
- data/lib/representable/hash/collection.rb +2 -9
- data/lib/representable/hash_methods.rb +0 -7
- data/lib/representable/inheritable.rb +50 -0
- data/lib/representable/json.rb +3 -9
- data/lib/representable/json/collection.rb +1 -3
- data/lib/representable/json/hash.rb +4 -9
- data/lib/representable/mapper.rb +8 -5
- data/lib/representable/parse_strategies.rb +1 -0
- data/lib/representable/pipeline.rb +14 -0
- data/lib/representable/represent.rb +6 -0
- data/lib/representable/version.rb +1 -1
- data/lib/representable/xml.rb +3 -18
- data/lib/representable/xml/collection.rb +2 -4
- data/lib/representable/xml/hash.rb +2 -10
- data/lib/representable/yaml.rb +1 -20
- data/representable.gemspec +2 -2
- data/test/class_test.rb +5 -10
- data/test/coercion_test.rb +31 -92
- data/test/config/inherit_test.rb +128 -0
- data/test/config_test.rb +114 -80
- data/test/definition_test.rb +107 -64
- data/test/features_test.rb +41 -0
- data/test/filter_test.rb +59 -0
- data/test/for_collection_test.rb +74 -0
- data/test/inherit_test.rb +44 -3
- data/test/inheritable_test.rb +97 -0
- data/test/inline_test.rb +0 -18
- data/test/instance_test.rb +0 -19
- data/test/json_test.rb +9 -44
- data/test/lonely_test.rb +1 -0
- data/test/parse_strategy_test.rb +30 -0
- data/test/represent_test.rb +88 -0
- data/test/representable_test.rb +3 -50
- data/test/schema_test.rb +123 -0
- data/test/test_helper.rb +1 -1
- data/test/xml_test.rb +34 -38
- metadata +25 -15
- data/lib/representable/decorator/coercion.rb +0 -4
- data/lib/representable/readable_writeable.rb +0 -29
- data/test/inheritance_test.rb +0 -22
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: c06c246f8a877ca22b35b7e5f409be0f5b1d6922
         | 
| 4 | 
            +
              data.tar.gz: 57183b1d4597321d6ed84278407032b04ac3eb8a
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: ed0821431bd7bee01cf48dc470211a78cdaa80a6de27df4961bf9028f6824a5914bf16bf86ffd59ca4698f60c56362226421aa2ea011933de82aa3072c28d081
         | 
| 7 | 
            +
              data.tar.gz: df87389a3a4b6e7841915dbf9b5ae999942f2640e70c27d199cc1ded97f1d2d1f9d6df3c400a3c76110176b5cdc55acdb5c73bb97da6b0a6986321e41a8dfb0a
         | 
    
        data/.travis.yml
    CHANGED
    
    
    
        data/CHANGES.md
    CHANGED
    
    | @@ -1,3 +1,39 @@ | |
| 1 | 
            +
            # 2.0.0
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            ## Relevant
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            * Removed class methods `::from_json`, `::from_hash`, `::from_yaml` and `::from_xml`. Please build the instance yourself and use something along `Song.new.from_json`.
         | 
| 6 | 
            +
            * Inline representers in `Decorator` do *no longer inherit from `self`*. When defining an inline representer, they are always derived from `Representable::Decorator`. The base class can be changed by overriding `Decorator::default_inline_class` in the decorator class that defines an inline representer block.
         | 
| 7 | 
            +
            If you need to inherit common methods to all inline decorators, include the module using `::feature`: `Representer.feature(BetterProperty)`.
         | 
| 8 | 
            +
            * Removed behaviour for `instance: lambda { |*| nil }` which used to return `binding.get`. Simply do it yourself: `instance: lambda { |fragment, options| options.binding.get }` if you need this behaviour. If you use `:instance` and it returns `nil` it throws a `DeserializeError` now, which is way more understandable than `NoMethodError: undefined method `title=' for {"title"=>"Perpetual"}:Hash`.
         | 
| 9 | 
            +
            * Remove behaviour for `class: lambda { nil }` which used to return the fragment. This now throws a `DeserializeError`. Do it yourself with class: lambda { |fragment,*| fragment }.
         | 
| 10 | 
            +
            * Coercion now happens inside `:render_filter` and `:parse_filter` (new!) and doesn't block `:getter` and `:setter` anymore.
         | 
| 11 | 
            +
                We require virtus >=1.0 now.
         | 
| 12 | 
            +
            * `::representation_wrap=` in now properly inherited.
         | 
| 13 | 
            +
            * Including modules with representable `property .., inherit: true` into a `Decorator` crashed. This works fine now.
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            ## New Stuff
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            * Added `::for_collection` to automatically generate a collection representer for singular one. Thanks to @timoschilling for inspiring this years ago.
         | 
| 18 | 
            +
            * Added `::represent` that will detect collections and render the singular/collection with the respective representer.
         | 
| 19 | 
            +
            * Callable options
         | 
| 20 | 
            +
            * :parse_filter, :render_filter
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            ## Internals
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            * Added `Representable::feature` to include a module and register it to be included into inline representers.
         | 
| 25 | 
            +
            * New signature: `inline_representer(base, features, name, options, &block)`.
         | 
| 26 | 
            +
            * Removed `::representer_engine`, the module to include is just another `register_feature` now.
         | 
| 27 | 
            +
            * `Config` no longer is a Hash, it's API is limited to a few methods like `#<<`, `#[]` etc. It still supports the `Enumberable` interface.
         | 
| 28 | 
            +
            * Moved `Representable::ClassMethods::Declarations` to `Representable::Declarative`.
         | 
| 29 | 
            +
            * Moved `Representable::ClassMethods` to `Representable::Declarative`.
         | 
| 30 | 
            +
            * Fixed: Inline decorators now work with `inherit: true`.
         | 
| 31 | 
            +
            * Remove `:extend` in combination with inline representer. The `:extend` option is no longer considered. Include the module directly into the inline block.
         | 
| 32 | 
            +
            * Deprecated class methods `::from_json` and friends. Use the instance version on an instance.
         | 
| 33 | 
            +
            * Use uber 0.0.7 so we can use `Uber::Callable`.
         | 
| 34 | 
            +
            * Removed `Decorator::Coercion`.
         | 
| 35 | 
            +
            * Removed `Definition#skipable_nil_value?`.
         | 
| 36 | 
            +
             | 
| 1 37 | 
             
            # 1.8.5
         | 
| 2 38 |  | 
| 3 39 | 
             
            * Binding now uses `#method_missing` instead of SimpleDelegator for a significant performance boost of many 100%s. Thanks to @0x4a616d6573 for figuring this.
         | 
    
        data/Gemfile
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -4,7 +4,7 @@ Representable maps Ruby objects to documents and back. | |
| 4 4 |  | 
| 5 5 | 
             
            In other words: Take an object and decorate it with a representer module. This will allow you to render a JSON, XML or YAML document from that object. But that's only half of it! You can also use representers to parse a document and create or populate an object.
         | 
| 6 6 |  | 
| 7 | 
            -
            Representable is helpful for all kind of rendering and parsing workflows. However, it is mostly useful in API code. Are you planning to write a real REST API with representable? Then check out the [Roar](http://github.com/apotonick/roar) gem first, save work and time and make the world a better place instead.
         | 
| 7 | 
            +
            Representable is helpful for all kind of mappings, rendering and parsing workflows. However, it is mostly useful in API code. Are you planning to write a real REST API with representable? Then check out the [Roar](http://github.com/apotonick/roar) gem first, save work and time and make the world a better place instead.
         | 
| 8 8 |  | 
| 9 9 |  | 
| 10 10 | 
             
            ## Installation
         | 
| @@ -267,7 +267,7 @@ module AlbumRepresenter | |
| 267 267 |  | 
| 268 268 | 
             
            This works both for representer modules and decorators.
         | 
| 269 269 |  | 
| 270 | 
            -
            An inline representer is just a Ruby module. You can include other representer modules. This is handy when having a base representer that needs to be extended in the inline block.
         | 
| 270 | 
            +
            An inline representer is just a Ruby module (or a `Decorator` class). You can include other representer modules. This is handy when having a base representer that needs to be extended in the inline block.
         | 
| 271 271 |  | 
| 272 272 | 
             
            ```ruby
         | 
| 273 273 | 
             
            module AlbumRepresenter
         | 
| @@ -280,6 +280,66 @@ module AlbumRepresenter | |
| 280 280 | 
             
              end
         | 
| 281 281 | 
             
            ```
         | 
| 282 282 |  | 
| 283 | 
            +
            If you need to include modules in all inline representers automatically, register it as a feature.
         | 
| 284 | 
            +
             | 
| 285 | 
            +
            ```ruby
         | 
| 286 | 
            +
            module AlbumRepresenter
         | 
| 287 | 
            +
              include Representable::JSON
         | 
| 288 | 
            +
              feature Link # imports ::link
         | 
| 289 | 
            +
             | 
| 290 | 
            +
              link "/album/1"
         | 
| 291 | 
            +
             | 
| 292 | 
            +
              property :hit do
         | 
| 293 | 
            +
                link "/hit/1" # link method imported automatically.
         | 
| 294 | 
            +
              end
         | 
| 295 | 
            +
            ```
         | 
| 296 | 
            +
             | 
| 297 | 
            +
             | 
| 298 | 
            +
            ## Representing Singular Models And Collections
         | 
| 299 | 
            +
             | 
| 300 | 
            +
            You can explicitly define representers for collections of models using a ["Lonely Collection"](#lonely-collections). Or you can let representable  do that for you.
         | 
| 301 | 
            +
             | 
| 302 | 
            +
            Rendering a collection of objects comes for free, using `::for_collection`.
         | 
| 303 | 
            +
             | 
| 304 | 
            +
            ```ruby
         | 
| 305 | 
            +
              Song.all.extend(SongRepresenter.for_collection).to_hash
         | 
| 306 | 
            +
              #=> [{title: "Sevens"}, {title: "Eric"}]
         | 
| 307 | 
            +
            ```
         | 
| 308 | 
            +
             | 
| 309 | 
            +
            For parsing, you need to provide the class constant to which the items should be deserialized to.
         | 
| 310 | 
            +
             | 
| 311 | 
            +
            ```ruby
         | 
| 312 | 
            +
            module SongRepresenter
         | 
| 313 | 
            +
              include Representable::Hash
         | 
| 314 | 
            +
              property :title
         | 
| 315 | 
            +
             | 
| 316 | 
            +
              collection_representer class: Song
         | 
| 317 | 
            +
            end
         | 
| 318 | 
            +
            ```
         | 
| 319 | 
            +
             | 
| 320 | 
            +
            You can now parse collections to `Song` instances.
         | 
| 321 | 
            +
             | 
| 322 | 
            +
            ```ruby
         | 
| 323 | 
            +
            [].extend(SongRepresenter.for_collection).from_hash([{title: "Sevens"}, {title: "Eric"}])
         | 
| 324 | 
            +
            ```
         | 
| 325 | 
            +
             | 
| 326 | 
            +
            As always, this works for decorators _and_ modules.
         | 
| 327 | 
            +
             | 
| 328 | 
            +
            In case you don't want to know whether or not you're working with a collection or singular model, use `::represent`.
         | 
| 329 | 
            +
             | 
| 330 | 
            +
            ```ruby
         | 
| 331 | 
            +
            # singular
         | 
| 332 | 
            +
            SongRepresenter.represent(Song.find(1)).to_hash #=> {title: "Sevens"}
         | 
| 333 | 
            +
             | 
| 334 | 
            +
            # collection
         | 
| 335 | 
            +
            SongRepresenter.represent(Song.all).to_hash #=> [{title: "Sevens"}, {title: "Eric"}]
         | 
| 336 | 
            +
            ```
         | 
| 337 | 
            +
             | 
| 338 | 
            +
            As you can see, `::represent` figures out the correct representer for you (works also for parsing!).
         | 
| 339 | 
            +
             | 
| 340 | 
            +
            Note: the implicit collection representer internally is implemented using a lonely collection. Everything you pass to `::collection_representer` is simply provided to the `::items` call in the lonely collection. That allows you to use `:parse_strategy` and all the other goodies, too.
         | 
| 341 | 
            +
             | 
| 342 | 
            +
             | 
| 283 343 | 
             
            ## Document Nesting
         | 
| 284 344 |  | 
| 285 345 | 
             
            Not always does the structure of the desired document map to your objects. The `::nested` method allows you to structure properties in a separate section while still mapping the properties to the outer object.
         | 
    
        data/Rakefile
    CHANGED
    
    
    
        data/lib/representable.rb
    CHANGED
    
    | @@ -1,16 +1,27 @@ | |
| 1 | 
            +
            require 'representable/inheritable'
         | 
| 2 | 
            +
            require 'representable/config'
         | 
| 1 3 | 
             
            require 'representable/definition'
         | 
| 2 4 | 
             
            require 'representable/mapper'
         | 
| 3 | 
            -
            require 'representable/ | 
| 5 | 
            +
            require 'representable/for_collection'
         | 
| 6 | 
            +
            require 'representable/represent'
         | 
| 7 | 
            +
            require 'representable/declarative'
         | 
| 8 | 
            +
             | 
| 9 | 
            +
             | 
| 10 | 
            +
            require 'uber/callable'
         | 
| 11 | 
            +
            require 'representable/pipeline'
         | 
| 4 12 |  | 
| 5 13 | 
             
            module Representable
         | 
| 6 14 | 
             
              attr_writer :representable_attrs
         | 
| 7 15 |  | 
| 8 16 | 
             
              def self.included(base)
         | 
| 9 17 | 
             
                base.class_eval do
         | 
| 18 | 
            +
                  extend Declarative
         | 
| 10 19 | 
             
                  extend ClassInclusions, ModuleExtensions
         | 
| 11 20 | 
             
                  extend ClassMethods
         | 
| 12 | 
            -
                  extend  | 
| 13 | 
            -
                  extend  | 
| 21 | 
            +
                  extend Feature
         | 
| 22 | 
            +
                  extend ForCollection
         | 
| 23 | 
            +
                  extend Represent
         | 
| 24 | 
            +
                  # register_feature Representable # Representable gets included automatically when creating inline representer.
         | 
| 14 25 | 
             
                end
         | 
| 15 26 | 
             
              end
         | 
| 16 27 |  | 
| @@ -40,7 +51,7 @@ private | |
| 40 51 | 
             
              end
         | 
| 41 52 |  | 
| 42 53 | 
             
              def representable_attrs
         | 
| 43 | 
            -
                @representable_attrs ||= self.class.representable_attrs # DISCUSS: copy, or better not?
         | 
| 54 | 
            +
                @representable_attrs ||= self.class.representable_attrs # DISCUSS: copy, or better not? what about "freezing"?
         | 
| 44 55 | 
             
              end
         | 
| 45 56 |  | 
| 46 57 | 
             
              def representable_mapper(format, options)
         | 
| @@ -60,17 +71,18 @@ private | |
| 60 71 | 
             
              module ClassInclusions
         | 
| 61 72 | 
             
                def included(base)
         | 
| 62 73 | 
             
                  super
         | 
| 63 | 
            -
                  base. | 
| 74 | 
            +
                  base.inherit_module!(self)
         | 
| 64 75 | 
             
                end
         | 
| 65 76 |  | 
| 66 77 | 
             
                def inherited(base) # DISCUSS: this could be in Decorator? but then we couldn't do B < A(include X) for non-decorators, right?
         | 
| 67 78 | 
             
                  super
         | 
| 68 | 
            -
                  base.representable_attrs.inherit(representable_attrs)
         | 
| 79 | 
            +
                  base.representable_attrs.inherit!(representable_attrs) # this should be inherit_class!
         | 
| 69 80 | 
             
                end
         | 
| 70 81 | 
             
              end
         | 
| 71 82 |  | 
| 72 83 | 
             
              module ModuleExtensions
         | 
| 73 | 
            -
                # Copies the representable_attrs to the extended object.
         | 
| 84 | 
            +
                # Copies the representable_attrs reference to the extended object.
         | 
| 85 | 
            +
                # Note that changing attrs in the instance will affect the class configuration.
         | 
| 74 86 | 
             
                def extended(object)
         | 
| 75 87 | 
             
                  super
         | 
| 76 88 | 
             
                  object.representable_attrs=(representable_attrs) # yes, we want a hard overwrite here and no inheritance.
         | 
| @@ -79,119 +91,30 @@ private | |
| 79 91 |  | 
| 80 92 |  | 
| 81 93 | 
             
              module ClassMethods
         | 
| 82 | 
            -
                #  | 
| 83 | 
            -
                def  | 
| 84 | 
            -
                   | 
| 85 | 
            -
                    yield represented, *args if block_given?
         | 
| 86 | 
            -
                  end
         | 
| 94 | 
            +
                # Gets overridden by Decorator as inheriting representers via include in Decorator means a bit more work (manifesting).
         | 
| 95 | 
            +
                def inherit_module!(parent)
         | 
| 96 | 
            +
                  representable_attrs.inherit!(parent.representable_attrs) # Module just inherits.
         | 
| 87 97 | 
             
                end
         | 
| 88 98 |  | 
| 89 99 | 
             
                def prepare(represented)
         | 
| 90 | 
            -
                  represented.extend(self) | 
| 100 | 
            +
                  represented.extend(self)
         | 
| 91 101 | 
             
                end
         | 
| 92 | 
            -
             | 
| 93 | 
            -
             | 
| 94 | 
            -
                module Declarations
         | 
| 95 | 
            -
                  def representable_attrs
         | 
| 96 | 
            -
                    @representable_attrs ||= build_config
         | 
| 97 | 
            -
                  end
         | 
| 98 | 
            -
             | 
| 99 | 
            -
                  def representation_wrap=(name)
         | 
| 100 | 
            -
                    representable_attrs.wrap = name
         | 
| 101 | 
            -
                  end
         | 
| 102 | 
            -
             | 
| 103 | 
            -
                  def property(name, options={}, &block)
         | 
| 104 | 
            -
                    representable_attrs << definition_class.new(name, options)
         | 
| 105 | 
            -
                  end
         | 
| 106 | 
            -
             | 
| 107 | 
            -
                  def collection(name, options={}, &block)
         | 
| 108 | 
            -
                    options[:collection] = true # FIXME: don't override original.
         | 
| 109 | 
            -
                    property(name, options, &block)
         | 
| 110 | 
            -
                  end
         | 
| 111 | 
            -
             | 
| 112 | 
            -
                  def hash(name=nil, options={}, &block)
         | 
| 113 | 
            -
                    return super() unless name  # allow Object.hash.
         | 
| 114 | 
            -
             | 
| 115 | 
            -
                    options[:hash] = true
         | 
| 116 | 
            -
                    property(name, options, &block)
         | 
| 117 | 
            -
                  end
         | 
| 118 | 
            -
             | 
| 119 | 
            -
                private
         | 
| 120 | 
            -
                  def definition_class
         | 
| 121 | 
            -
                    Definition
         | 
| 122 | 
            -
                  end
         | 
| 123 | 
            -
             | 
| 124 | 
            -
                  def build_config
         | 
| 125 | 
            -
                    Config.new
         | 
| 126 | 
            -
                  end
         | 
| 127 | 
            -
                end # Declarations
         | 
| 128 102 | 
             
              end
         | 
| 129 103 |  | 
| 130 | 
            -
              # Internal module for DSL sugar that should not go into the core library.
         | 
| 131 | 
            -
              module DSLAdditions
         | 
| 132 | 
            -
                # Allows you to nest a block of properties in a separate section while still mapping them to the outer object.
         | 
| 133 | 
            -
                def nested(name, options={}, &block)
         | 
| 134 | 
            -
                  options = options.merge(
         | 
| 135 | 
            -
                    :use_decorator => true,
         | 
| 136 | 
            -
                    :getter        => lambda { |*| self },
         | 
| 137 | 
            -
                    :setter        => lambda { |*| },
         | 
| 138 | 
            -
                    :instance      => lambda { |*| self }
         | 
| 139 | 
            -
                  ) # DISCUSS: should this be a macro just as :parse_strategy?
         | 
| 140 | 
            -
             | 
| 141 | 
            -
                  property(name, options, &block)
         | 
| 142 | 
            -
                end
         | 
| 143 | 
            -
             | 
| 144 | 
            -
                def property(name, options={}, &block)
         | 
| 145 | 
            -
                  modules = []
         | 
| 146 | 
            -
             | 
| 147 | 
            -
                  if options[:inherit] # TODO: move this to Definition.
         | 
| 148 | 
            -
                    parent  = representable_attrs[name]
         | 
| 149 | 
            -
                    modules << parent[:extend].evaluate(nil) if parent[:extend]# we can savely assume this is _not_ a lambda. # DISCUSS: leave that in #representer_module?
         | 
| 150 | 
            -
                  end # FIXME: can we handle this in super/Definition.new ?
         | 
| 151 104 |  | 
| 152 | 
            -
             | 
| 153 | 
            -
             | 
| 154 | 
            -
             | 
| 155 | 
            -
                     | 
| 156 | 
            -
             | 
| 157 | 
            -
             | 
| 158 | 
            -
                  return parent.merge!(options) if options.delete(:inherit)
         | 
| 159 | 
            -
             | 
| 160 | 
            -
                  super
         | 
| 161 | 
            -
                end
         | 
| 162 | 
            -
             | 
| 163 | 
            -
                def inline_representer(base_module, name, options, &block) # DISCUSS: separate module?
         | 
| 164 | 
            -
                  Module.new do
         | 
| 165 | 
            -
                    include *base_module # Representable::JSON or similar.
         | 
| 166 | 
            -
                    instance_exec &block
         | 
| 105 | 
            +
              module Feature
         | 
| 106 | 
            +
                def feature(*mods)
         | 
| 107 | 
            +
                  mods.each do |mod|
         | 
| 108 | 
            +
                    include mod
         | 
| 109 | 
            +
                    register_feature(mod)
         | 
| 167 110 | 
             
                  end
         | 
| 168 111 | 
             
                end
         | 
| 169 112 |  | 
| 170 113 | 
             
              private
         | 
| 171 | 
            -
                def  | 
| 172 | 
            -
                   | 
| 173 | 
            -
                  modules     = [representer_engine] + modules
         | 
| 174 | 
            -
             | 
| 175 | 
            -
                  representer.inline_representer(modules.compact.reverse, name, options, &block)
         | 
| 114 | 
            +
                def register_feature(mod)
         | 
| 115 | 
            +
                  representable_attrs[:features][mod] = true
         | 
| 176 116 | 
             
                end
         | 
| 177 | 
            -
             | 
| 178 | 
            -
                def handle_deprecated_inline_extend!(modules, options) # TODO: remove in 2.0.
         | 
| 179 | 
            -
                  return unless include_module = options.delete(:extend) and not options[:inherit]
         | 
| 180 | 
            -
             | 
| 181 | 
            -
                  warn "[Representable] Using :extend with an inline representer is deprecated. Include the module in the inline block."
         | 
| 182 | 
            -
                  modules << include_module
         | 
| 183 | 
            -
                end
         | 
| 184 | 
            -
              end # DSLAdditions
         | 
| 185 | 
            -
            end
         | 
| 186 | 
            -
             | 
| 187 | 
            -
             | 
| 188 | 
            -
            module Representable
         | 
| 189 | 
            -
              autoload :Hash, 'representable/hash'
         | 
| 190 | 
            -
             | 
| 191 | 
            -
              module Hash
         | 
| 192 | 
            -
                autoload :AllowSymbols, 'representable/hash/allow_symbols'
         | 
| 193 | 
            -
                autoload :Collection, 'representable/hash/collection'
         | 
| 194 117 | 
             
              end
         | 
| 195 | 
            -
             | 
| 196 | 
            -
              autoload :Decorator, 'representable/decorator'
         | 
| 197 118 | 
             
            end
         | 
| 119 | 
            +
             | 
| 120 | 
            +
            require 'representable/autoload'
         | 
| @@ -1,5 +1,11 @@ | |
| 1 | 
            +
            * Cleanup the manifest part in Decorator.
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            * all property objects should be extended/wrapped so we don't need the switch.
         | 
| 2 4 |  | 
| 3 5 | 
             
            # Deprecations
         | 
| 4 6 |  | 
| 5 | 
            -
            * deprecate instance: { nil } which is superseded by parse_strategy: :sync
         | 
| 7 | 
            +
            * deprecate instance: { nil } which is superseded by parse_strategy: :sync
         | 
| 8 | 
            +
             | 
| 9 | 
            +
             | 
| 10 | 
            +
             | 
| 11 | 
            +
            from_hash, property :band, class: vergessen
         | 
| @@ -14,7 +14,7 @@ module Representable | |
| 14 14 | 
             
                end
         | 
| 15 15 |  | 
| 16 16 | 
             
                def initialize(definition, represented, decorator, user_options={})  # TODO: remove default arg for user options.
         | 
| 17 | 
            -
                  @definition | 
| 17 | 
            +
                  @definition   = definition
         | 
| 18 18 | 
             
                  @represented  = represented
         | 
| 19 19 | 
             
                  @decorator    = decorator
         | 
| 20 20 | 
             
                  @user_options = user_options
         | 
| @@ -31,7 +31,8 @@ module Representable | |
| 31 31 | 
             
                # Retrieve value and write fragment to the doc.
         | 
| 32 32 | 
             
                def compile_fragment(doc)
         | 
| 33 33 | 
             
                  evaluate_option(:writer, doc) do
         | 
| 34 | 
            -
                     | 
| 34 | 
            +
                    value = render_filter(get, doc)
         | 
| 35 | 
            +
                    write_fragment(doc, value)
         | 
| 35 36 | 
             
                  end
         | 
| 36 37 | 
             
                end
         | 
| 37 38 |  | 
| @@ -39,6 +40,7 @@ module Representable | |
| 39 40 | 
             
                def uncompile_fragment(doc)
         | 
| 40 41 | 
             
                  evaluate_option(:reader, doc) do
         | 
| 41 42 | 
             
                    read_fragment(doc) do |value|
         | 
| 43 | 
            +
                      value = parse_filter(value, doc)
         | 
| 42 44 | 
             
                      set(value)
         | 
| 43 45 | 
             
                    end
         | 
| 44 46 | 
             
                  end
         | 
| @@ -70,6 +72,15 @@ module Representable | |
| 70 72 | 
             
                  read(doc)
         | 
| 71 73 | 
             
                end
         | 
| 72 74 |  | 
| 75 | 
            +
                def render_filter(value, doc)
         | 
| 76 | 
            +
                  evaluate_option(:render_filter, value, doc) { value }
         | 
| 77 | 
            +
                end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                def parse_filter(value, doc)
         | 
| 80 | 
            +
                  evaluate_option(:parse_filter, value, doc) { value }
         | 
| 81 | 
            +
                end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
             | 
| 73 84 | 
             
                def get
         | 
| 74 85 | 
             
                  evaluate_option(:getter) do
         | 
| 75 86 | 
             
                    exec_context.send(getter)
         | 
| @@ -142,7 +153,7 @@ module Representable | |
| 142 153 | 
             
                private
         | 
| 143 154 | 
             
                  # DISCUSS: deprecate :class in favour of :instance and simplicity?
         | 
| 144 155 | 
             
                  def class_for(fragment, *args)
         | 
| 145 | 
            -
                    item_class = class_from(fragment, *args) or return  | 
| 156 | 
            +
                    item_class = class_from(fragment, *args) or raise DeserializeError.new(":class did not return class constant.")
         | 
| 146 157 | 
             
                    item_class.new
         | 
| 147 158 | 
             
                  end
         | 
| 148 159 |  | 
| @@ -151,20 +162,13 @@ module Representable | |
| 151 162 | 
             
                  end
         | 
| 152 163 |  | 
| 153 164 | 
             
                  def instance_for(fragment, *args)
         | 
| 154 | 
            -
                     | 
| 155 | 
            -
             | 
| 156 | 
            -
                    if instance === true # TODO: remove in 2.0.
         | 
| 157 | 
            -
                      warn "[Representable] `instance: lambda { true }` is deprecated. Apparently, you know what you're doing, so use `parse_strategy: :sync` instead."
         | 
| 158 | 
            -
                      return get
         | 
| 159 | 
            -
                    end
         | 
| 160 | 
            -
             | 
| 161 | 
            -
                    instance
         | 
| 162 | 
            -
                  end
         | 
| 163 | 
            -
             | 
| 164 | 
            -
                  def handle_deprecated_class(fragment) # TODO: remove in 2.0.
         | 
| 165 | 
            -
                    warn "[Representable] `class: lambda { nil }` is deprecated. To return the fragment from parsing, use `instance: lambda { |fragment, *args| fragment }` instead."
         | 
| 166 | 
            -
                    fragment
         | 
| 165 | 
            +
                    # cool: if no :instance set, { return } will jump out of this method.
         | 
| 166 | 
            +
                    evaluate_option(:instance, fragment, *args) { return } or raise DeserializeError.new(":instance did not return object.")
         | 
| 167 167 | 
             
                  end
         | 
| 168 168 | 
             
                end
         | 
| 169 169 | 
             
              end
         | 
| 170 | 
            +
             | 
| 171 | 
            +
             | 
| 172 | 
            +
              class DeserializeError < RuntimeError
         | 
| 173 | 
            +
              end
         | 
| 170 174 | 
             
            end
         |