representable 3.0.0 → 3.2.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.
Files changed (103) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ci.yml +23 -0
  3. data/CHANGES.md +33 -0
  4. data/Gemfile +4 -12
  5. data/LICENSE +1 -1
  6. data/README.md +12 -13
  7. data/Rakefile +1 -6
  8. data/TODO +1 -3
  9. data/TODO-4.0.md +72 -0
  10. data/lib/representable/binding.rb +32 -12
  11. data/lib/representable/cached.rb +1 -1
  12. data/lib/representable/coercion.rb +8 -6
  13. data/lib/representable/config.rb +13 -3
  14. data/lib/representable/debug.rb +23 -15
  15. data/lib/representable/declarative.rb +12 -7
  16. data/lib/representable/decorator.rb +1 -1
  17. data/lib/representable/definition.rb +7 -3
  18. data/lib/representable/deserializer.rb +5 -4
  19. data/lib/representable/for_collection.rb +1 -1
  20. data/lib/representable/hash/allow_symbols.rb +9 -11
  21. data/lib/representable/hash/binding.rb +1 -0
  22. data/lib/representable/hash/collection.rb +4 -2
  23. data/lib/representable/hash.rb +9 -2
  24. data/lib/representable/hash_methods.rb +3 -2
  25. data/lib/representable/insert.rb +1 -1
  26. data/lib/representable/json/collection.rb +3 -0
  27. data/lib/representable/json.rb +8 -7
  28. data/lib/representable/object/binding.rb +5 -1
  29. data/lib/representable/object.rb +1 -1
  30. data/lib/representable/option.rb +19 -0
  31. data/lib/representable/pipeline.rb +3 -2
  32. data/lib/representable/pipeline_factories.rb +4 -2
  33. data/lib/representable/populator.rb +1 -1
  34. data/lib/representable/represent.rb +1 -0
  35. data/lib/representable/serializer.rb +3 -2
  36. data/lib/representable/version.rb +1 -1
  37. data/lib/representable/xml/binding.rb +19 -13
  38. data/lib/representable/xml/namespace.rb +122 -0
  39. data/lib/representable/xml.rb +12 -10
  40. data/lib/representable/yaml/binding.rb +1 -0
  41. data/lib/representable/yaml.rb +6 -2
  42. data/lib/representable.rb +19 -25
  43. data/representable.gemspec +8 -9
  44. data/test/as_test.rb +7 -7
  45. data/test/binding_test.rb +14 -14
  46. data/test/cached_test.rb +59 -49
  47. data/test/class_test.rb +9 -9
  48. data/test/coercion_test.rb +33 -22
  49. data/test/config/inherit_test.rb +14 -14
  50. data/test/config_test.rb +20 -20
  51. data/test/decorator_scope_test.rb +4 -4
  52. data/test/decorator_test.rb +33 -20
  53. data/test/default_test.rb +8 -8
  54. data/test/defaults_options_test.rb +3 -3
  55. data/test/definition_test.rb +38 -40
  56. data/test/{example.rb → examples/example.rb} +0 -1
  57. data/test/examples/object.rb +1 -5
  58. data/test/exec_context_test.rb +8 -8
  59. data/test/features_test.rb +6 -6
  60. data/test/filter_test.rb +8 -8
  61. data/test/for_collection_test.rb +10 -10
  62. data/test/generic_test.rb +13 -13
  63. data/test/getter_setter_test.rb +5 -5
  64. data/test/hash_bindings_test.rb +1 -1
  65. data/test/hash_test.rb +45 -23
  66. data/test/heritage_test.rb +16 -13
  67. data/test/if_test.rb +9 -9
  68. data/test/include_exclude_test.rb +14 -14
  69. data/test/inherit_test.rb +18 -18
  70. data/test/inline_test.rb +24 -24
  71. data/test/instance_test.rb +31 -31
  72. data/test/is_representable_test.rb +10 -10
  73. data/test/json_test.rb +29 -7
  74. data/test/lonely_test.rb +31 -31
  75. data/test/nested_test.rb +13 -13
  76. data/test/object_test.rb +9 -9
  77. data/test/option_test.rb +36 -0
  78. data/test/parse_pipeline_test.rb +3 -5
  79. data/test/pipeline_test.rb +50 -50
  80. data/test/populator_test.rb +18 -18
  81. data/test/prepare_test.rb +4 -4
  82. data/test/private_options_test.rb +2 -2
  83. data/test/reader_writer_test.rb +2 -2
  84. data/test/render_nil_test.rb +2 -2
  85. data/test/represent_test.rb +14 -14
  86. data/test/representable_test.rb +34 -36
  87. data/test/schema_test.rb +8 -11
  88. data/test/serialize_deserialize_test.rb +2 -2
  89. data/test/skip_test.rb +14 -14
  90. data/test/stringify_hash_test.rb +3 -3
  91. data/test/test_helper.rb +26 -14
  92. data/test/uncategorized_test.rb +10 -10
  93. data/test/user_options_test.rb +4 -4
  94. data/test/wrap_test.rb +19 -19
  95. data/test/xml_bindings_test.rb +0 -4
  96. data/test/xml_namespace_test.rb +186 -0
  97. data/test/xml_test.rb +103 -43
  98. data/test/yaml_test.rb +51 -26
  99. metadata +42 -35
  100. data/.travis.yml +0 -7
  101. data/lib/representable/TODO.getting_serious +0 -11
  102. data/lib/representable/autoload.rb +0 -10
  103. data/test/mongoid_test.rb +0 -31
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 5caccf4a60cbe2ca6066a047755a13a741b488b1
4
- data.tar.gz: aa57e2ec29209f936b58642ac84cfdf223e6d09b
2
+ SHA256:
3
+ metadata.gz: f3a1388b7570e31d62c555a87d6165793e9d095cf1bed18c04cb8cbe86bc2ba2
4
+ data.tar.gz: 43e418db52478d3d4fc33f505ce86d840fcb666a8abc83e20269bbfab4c53a3a
5
5
  SHA512:
6
- metadata.gz: 9c5047e0c91d61a43677bd92cc64fbee0e34292b3b24ea59d10e2962075626c8c6dddd4b64c21092f65ed4d3abcfa1458f318bfd4d179085052c53565eb1d8ec
7
- data.tar.gz: be1d272ce967973dbac844beb02f7d1418adb9f1c59b02ca9472a912bde994ffa7543158c3f8543ae5a172dda49c1f838ce963e5413e5c83b204bddd8aa9366c
6
+ metadata.gz: 39e957975d24f76894ef9a7186fff69155525e5f777c120a77e2ecee8a7dcdccee62b2140ed8ab34ebc9de916a9098d9da846e0befda2c90fa32e4a9ff470ecc
7
+ data.tar.gz: cf309756f2470854283c09bbca25b3200b26ba1702b75e533573382dabd2f33a6f3eeaee963c2cc2bb0ddb9d3bdf026bf7dacba6da3f22f44dc805bc8d1ca505
@@ -0,0 +1,23 @@
1
+ name: CI
2
+ on:
3
+ push:
4
+ branches:
5
+ - master
6
+ pull_request:
7
+ branches:
8
+ - master
9
+
10
+ jobs:
11
+ test:
12
+ strategy:
13
+ fail-fast: false
14
+ matrix:
15
+ ruby: [2.5, 2.6, 2.7, '3.0', "3.1"]
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - uses: actions/checkout@v2
19
+ - uses: ruby/setup-ruby@v1
20
+ with:
21
+ ruby-version: ${{ matrix.ruby }}
22
+ bundler-cache: true
23
+ - run: bundle exec rake
data/CHANGES.md CHANGED
@@ -1,3 +1,36 @@
1
+ # 3.2.0
2
+ * Drop support for Virtus Coercion
3
+ * Fix deprecation warning with Nokogiri 1.13.0
4
+
5
+ # 3.1.1
6
+
7
+ * Upgrade `trailblazer-option` to `0.1.1` which supports passing an empty `keyword_arguments`.
8
+
9
+ # 3.1.0
10
+ * Remove circular require
11
+ * Use Dry-types 1.0.0+ as coercion library
12
+ * Renamed Coercion to VirtusCoercion to support old codebases
13
+ * Replace `declarative-option` with [`trailblazer-option`](https://github.com/trailblazer/trailblazer-option)
14
+
15
+ # 3.0.4
16
+
17
+ * Add proper XML namespace support.
18
+ * [internal] Replace `XML::Binding#node_for` with function `XML::Node`.
19
+
20
+ # 3.0.3
21
+
22
+ * Replace `Uber::Option` with the new [`Declarative::Option`](https://github.com/apotonick/declarative-option). This should result in a significant performance boost.
23
+
24
+ # 3.0.2
25
+
26
+ * Initialize `Config@wrap` to avoid Ruby's warning.
27
+ * Add `#render` and `#parse` alias methods to all format modules as a generic entry point.
28
+ * In `GetValue`, use `public_send` now.
29
+
30
+ # 3.0.1
31
+
32
+ * Loosen `uber` dependency.
33
+
1
34
  # 3.0.0
2
35
 
3
36
  * Removed deprecations from 2.4.
data/Gemfile CHANGED
@@ -1,19 +1,11 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
2
 
3
3
  gemspec
4
4
 
5
- platform :rbx do
6
- gem "psych"
7
- gem "rubysl-irb"
8
- gem "json_pure"
9
- end
10
-
11
5
  group :test do
12
- gem "nokogiri", require: false
13
- gem "multi_json", require: false
14
6
  gem "minitest-line"
15
- gem "pry"
7
+ gem "multi_json", require: false
8
+ gem "nokogiri", require: false
16
9
  end
10
+ gem 'pry-byebug'
17
11
 
18
- # gem "declarative", path: "../declarative"
19
- # gem "declarative", github: "apotonick/declarative"
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2011 - 2013 Nick Sutterer and the roar contributors
1
+ Copyright (c) 2011 - 2021 Nick Sutterer and the roar contributors
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -2,19 +2,19 @@
2
2
 
3
3
  Representable maps Ruby objects to documents and back.
4
4
 
5
- [![Gitter Chat](https://badges.gitter.im/trailblazer/chat.svg)](https://gitter.im/trailblazer/chat)
6
- [![Build
7
- Status](https://travis-ci.org/apotonick/representable.svg)](https://travis-ci.org/apotonick/representable)
5
+ ![Build
6
+ Status](https://github.com/trailblazer/representable/actions/workflows/ci.yml/badge.svg?branch=master)
8
7
  [![Gem Version](https://badge.fury.io/rb/representable.svg)](http://badge.fury.io/rb/representable)
9
8
 
9
+
10
10
  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.
11
11
 
12
- 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.
12
+ 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](https://github.com/trailblazer/roar) gem first, save work and time and make the world a better place instead.
13
13
 
14
14
 
15
15
  ## Full Documentation
16
16
 
17
- Representable comes with a rich set of options and semantics for parsing and rendering documents. Its [full documentation](http://trailblazer.to/gems/representable/3.0/api.html) can be found on the Trailblazer site.
17
+ Representable comes with a rich set of options and semantics for parsing and rendering documents. Its [full documentation](https://trailblazer.to/2.1/docs/representable.html) can be found on the Trailblazer site.
18
18
 
19
19
  ## Example
20
20
 
@@ -34,8 +34,6 @@ Representations are defined using representer classes, called _decorator, or mod
34
34
  In these examples, let's use decorators
35
35
 
36
36
  ```ruby
37
- require 'representable/json'
38
-
39
37
  class SongRepresenter < Representable::Decorator
40
38
  include Representable::JSON
41
39
 
@@ -65,7 +63,7 @@ song = SongRepresenter.new(song).from_json(%{ {"title":"Roxanne"} })
65
63
  #=> #<Song title="Roxanne", track=nil>
66
64
  ```
67
65
 
68
- Note that parsing hashes per default does [require string keys](http://trailblazer.to/gems/representable/3.0/api.html#symbol-keys) and does _not_ pick up symbol keys.
66
+ Note that parsing hashes per default does [require string keys](https://trailblazer.to/2.1/docs/representable.html#representable-api-symbol-keys) and does _not_ pick up symbol keys.
69
67
 
70
68
 
71
69
  ## Collections
@@ -131,19 +129,20 @@ class AlbumRepresenter < Representable::Decorator
131
129
  property :track
132
130
  collection :composers
133
131
  end
132
+ end
134
133
  ```
135
134
 
136
135
  ## More
137
136
 
138
137
  Representable has many more features and can literally parse and render any kind of document to an arbitrary Ruby object graph.
139
138
 
140
- Please check the [official documentation for more](http://trailblazer.to/gems/representable/).
139
+ Please check the [official documentation for more](https://trailblazer.to/2.1/docs/representable.html#representable-api).
141
140
 
142
141
 
143
142
  ## Installation
144
143
 
145
- The representable gem runs with all Ruby versions >= 1.9.3.
146
-
144
+ The representable gem runs with all Ruby versions >= 2.4.0.
145
+ t
147
146
  ```ruby
148
147
  gem 'representable'
149
148
  ```
@@ -169,7 +168,7 @@ gem 'nokogiri'
169
168
 
170
169
  Representable started as a heavily simplified fork of the ROXML gem. Big thanks to Ben Woosley for his extremely inspiring work.
171
170
 
172
- * Copyright (c) 2011-2016 Nick Sutterer <apotonick@gmail.com>
171
+ * Copyright (c) 2011-2020 Nick Sutterer <apotonick@gmail.com>
173
172
  * ROXML is Copyright (c) 2004-2009 Ben Woosley, Zak Mandhro and Anders Engstrom.
174
173
 
175
- Representable is released under the [MIT License](http://www.opensource.org/licenses/MIT).
174
+ Representable is released under the [MIT License](https://www.opensource.org/licenses/MIT).
data/Rakefile CHANGED
@@ -1,3 +1,4 @@
1
+ require "bundler/gem_tasks"
1
2
  require 'bundler/setup'
2
3
  require 'rake/testtask'
3
4
 
@@ -9,9 +10,3 @@ Rake::TestTask.new(:test) do |test|
9
10
  test.test_files = FileList['test/**/*_test.rb']
10
11
  test.verbose = true
11
12
  end
12
-
13
- Rake::TestTask.new(:dtest) do |test|
14
- test.libs << 'test-with-deprecations'
15
- test.test_files = FileList['test-with-deprecations/**/*_test.rb']
16
- test.verbose = true
17
- end
data/TODO CHANGED
@@ -1,8 +1,6 @@
1
1
  * Pass key/index as first block arg to :class and :extend
2
2
  class: |key, hsh|
3
3
 
4
- * Allow passing options to Binding#serialize.
5
- serialize(.., options{:exclude => ..})
6
4
 
7
5
  document `XML::AttributeHash` etc
8
6
 
@@ -37,4 +35,4 @@ module ReaderWriter
37
35
  * DISCUSS: should inline representers be created at runtime, so we don't need ::representer_engine?
38
36
  * deprecate `Decorator::Coercion`.
39
37
 
40
- * cleanup XML so it matches the current #serialize standard.
38
+ * cleanup XML so it matches the current #serialize standard.
data/TODO-4.0.md ADDED
@@ -0,0 +1,72 @@
1
+ # Decorator
2
+
3
+ XML::Binding::Collection.to_xml(represented)
4
+ bindings.each bin.to_xml
5
+
6
+
7
+ # hat vorteil: [].each{ Collection.to_xml(item) }
8
+
9
+ * make all properties "Object-like", even arrays of strings etc. This saves us from having `extend ObjectBinding if typed?` and we could just call to_hash/from_hash on all attributes. performance issues here? otherwise: implement!
10
+
11
+
12
+ # how to?
13
+
14
+ class CH
15
+ wrap :character
16
+ prpoerty :a
17
+
18
+
19
+ class
20
+ proerty :author, dec: CH
21
+
22
+ # how to?
23
+
24
+ * override specific bindings and their logic? e.g. `Namespace#read`
25
+ * Extend nested representers, e.g. the namespace prefix, when it gets plugged into composition
26
+ * Easier polymorphic representer
27
+
28
+ # XML
29
+
30
+ * ditch annoying nokogiri in favor of https://github.com/YorickPeterse/oga
31
+
32
+ # Parsing
33
+
34
+ * Let bindings have any "xpath"
35
+ * Allow to parse "wildcard" sections where you have no idea about the property names (and attribute names, eg. with links)
36
+
37
+ # Options
38
+
39
+ * There should be an easier way to pass a set of options to all nested #to_node decorators.
40
+
41
+ ```ruby
42
+ representable_attrs.keys.each do |property|
43
+ options[property.to_sym] = { show_definition: false, namespaces: options[:namespaces] }
44
+ end
45
+ ```
46
+
47
+ * Allow passing options to Binding#serialize.
48
+ serialize(.., options{:exclude => ..})
49
+
50
+
51
+ # wrap, as
52
+
53
+ AsWithNamespace( Binding )
54
+ BUT NOT FOR AsWithNamespace( Binding::Attribute )
55
+ => selectively wrap bindings at compile- and runtime
56
+
57
+
58
+
59
+
60
+
61
+
62
+ * Cleanup the manifest part in Decorator.
63
+
64
+ * all property objects should be extended/wrapped so we don't need the switch.
65
+
66
+ # Deprecations
67
+
68
+ * deprecate instance: { nil } which is superseded by parse_strategy: :sync
69
+
70
+
71
+
72
+ from_hash, property :band, class: vergessen
@@ -1,8 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'uber/delegates'
4
+
1
5
  module Representable
2
6
  # The Binding provides methods to read/write the fragment for one property.
3
7
  #
4
8
  # Actually parsing the fragment from the document happens in Binding#read, everything after that is generic.
5
9
  class Binding
10
+ class Map < Array
11
+ def call(method, options)
12
+ each do |bin|
13
+ options[:binding] = bin # this is so much faster than options.merge().
14
+ bin.send(method, options)
15
+ end
16
+ end
17
+
18
+ # TODO: Merge with Definitions.
19
+ def <<(binding) # can be slow. this is compile time code.
20
+ (existing = find { |bin| bin.name == binding.name }) ? self[index(existing)] = binding : super(binding)
21
+ end
22
+ end
23
+
6
24
  class FragmentNotFound
7
25
  end
8
26
 
@@ -29,12 +47,12 @@ module Representable
29
47
  module Deprecatable
30
48
  # Retrieve value and write fragment to the doc.
31
49
  def compile_fragment(options)
32
- render_pipeline(nil, options).(nil, options)
50
+ render_pipeline(nil, options).call(nil, options)
33
51
  end
34
52
 
35
53
  # Parse value from doc and update the model property.
36
54
  def uncompile_fragment(options)
37
- parse_pipeline(options[:doc], options).(options[:doc], options)
55
+ parse_pipeline(options[:doc], options).call(options[:doc], options)
38
56
  end
39
57
  end
40
58
  include Deprecatable
@@ -43,7 +61,7 @@ module Representable
43
61
  def evaluate_option(name, input, options)
44
62
  proc = self[name]
45
63
  # puts "@@@@@ #{self.inspect}, #{name}...... #{self[name]}"
46
- proc.(send(:exec_context, options), options.merge(user_options: options[:options][:user_options], input: input)) # from Uber::Options::Value. # NOTE: this can also be the Proc object if it's not wrapped by Uber:::Value.
64
+ proc.call(exec_context: send(:exec_context, options), keyword_arguments: options.merge(user_options: options[:options][:user_options], input: input)) # from Uber::Options::Value. # NOTE: this can also be the Proc object if it's not wrapped by Uber:::Value.
47
65
  end
48
66
  end
49
67
  include EvaluateOption
@@ -53,29 +71,30 @@ module Representable
53
71
  end
54
72
 
55
73
  def skipable_empty_value?(value)
56
- value.nil? and not self[:render_nil]
74
+ value.nil? and !(self[:render_nil])
57
75
  end
58
76
 
59
77
  def default_for(value)
60
78
  return self[:default] if skipable_empty_value?(value)
79
+
61
80
  value
62
81
  end
63
82
 
64
83
  attr_accessor :cached_representer
65
84
 
66
- require "representable/pipeline_factories"
85
+ require 'representable/pipeline_factories'
67
86
  include Factories
68
87
 
69
- private
88
+ private
70
89
 
71
90
  def setup_exec_context!
72
- @exec_context = ->(options) { options[:represented] } unless self[:exec_context]
73
- @exec_context = ->(options) { self } if self[:exec_context] == :binding
74
- @exec_context = ->(options) { options[:decorator] } if self[:exec_context] == :decorator
91
+ @exec_context = ->(options) { options[:represented] } unless self[:exec_context]
92
+ @exec_context = ->(_options) { self } if self[:exec_context] == :binding
93
+ @exec_context = ->(options) { options[:decorator] } if self[:exec_context] == :decorator
75
94
  end
76
95
 
77
96
  def exec_context(options)
78
- @exec_context.(options)
97
+ @exec_context.call(options)
79
98
  end
80
99
 
81
100
  def parse_pipeline(input, options)
@@ -90,8 +109,9 @@ module Representable
90
109
  module Collection
91
110
  def skipable_empty_value?(value)
92
111
  # TODO: this can be optimized, again.
93
- return true if value.nil? and not self[:render_nil] # FIXME: test this without the "and"
94
- return true if self[:render_empty] == false and value and value.size == 0 # TODO: change in 2.0, don't render emtpy.
112
+ return true if value.nil? && !(self[:render_nil]) # FIXME: test this without the "and"
113
+
114
+ true if (self[:render_empty] == false) && value && value.empty? # TODO: change in 2.0, don't render emtpy.
95
115
  end
96
116
  end
97
117
  end
@@ -19,4 +19,4 @@ module Representable
19
19
  self.class.map
20
20
  end
21
21
  end
22
- end
22
+ end
@@ -1,16 +1,18 @@
1
- require "virtus"
1
+ gem 'dry-types', '>= 1.0.0'
2
+ require "dry-types"
2
3
 
3
4
  module Representable
4
5
  module Coercion
6
+ module Types
7
+ include Dry::Types()
8
+ end
5
9
  class Coercer
6
10
  def initialize(type)
7
11
  @type = type
8
12
  end
9
13
 
10
- # This gets called when the :render_filter or :parse_filter option is evaluated.
11
- # Usually the Coercer instance is an element in a Pipeline to allow >1 filters per property.
12
- def call(input, options)
13
- Virtus::Attribute.build(@type).coerce(input)
14
+ def call(input, _options)
15
+ @type.call(input)
14
16
  end
15
17
  end
16
18
 
@@ -34,4 +36,4 @@ module Representable
34
36
  end
35
37
  end
36
38
  end
37
- end
39
+ end
@@ -1,10 +1,19 @@
1
+ require 'declarative/definitions'
2
+
1
3
  module Representable
4
+ autoload :Option, 'representable/option'
5
+
2
6
  # Stores Definitions from ::property. It preserves the adding order (1.9+).
3
7
  # Same-named properties get overridden, just like in a Hash.
4
8
  #
5
9
  # Overwrite definition_class if you need a custom Definition object (helpful when using
6
10
  # representable in other gems).
7
11
  class Config < ::Declarative::Definitions
12
+ def initialize(*)
13
+ super
14
+ @wrap = nil
15
+ end
16
+
8
17
  def remove(name)
9
18
  delete(name.to_s)
10
19
  end
@@ -15,16 +24,17 @@ module Representable
15
24
 
16
25
  def wrap=(value)
17
26
  value = value.to_s if value.is_a?(Symbol)
18
- @wrap = Uber::Options::Value.new(value)
27
+ @wrap = ::Representable::Option(value)
19
28
  end
20
29
 
21
30
  # Computes the wrap string or returns false.
22
- def wrap_for(represented, *args, &block)
31
+ def wrap_for(represented, options = {}, &block)
23
32
  return unless @wrap
24
33
 
25
- value = @wrap.evaluate(represented, *args)
34
+ value = @wrap.(exec_context: represented, keyword_arguments: options.to_hash)
26
35
 
27
36
  return value if value != true
37
+
28
38
  infer_name_for(represented.class.name)
29
39
  end
30
40
 
@@ -1,16 +1,24 @@
1
+ require 'logger'
2
+
1
3
  module Representable
2
4
  module Debug
5
+ module_function def _representable_logger
6
+ @logger ||= Logger.new(STDOUT)
7
+ end
8
+
9
+ module_function def representable_log(message)
10
+ _representable_logger.debug { message }
11
+ end
12
+
3
13
  def update_properties_from(doc, options, format)
4
- puts
5
- puts "[Deserialize]........."
6
- puts "[Deserialize] document #{doc.inspect}"
14
+ representable_log "[Deserialize]........."
15
+ representable_log "[Deserialize] document #{doc.inspect}"
7
16
  super
8
17
  end
9
18
 
10
19
  def create_representation_with(doc, options, format)
11
- puts
12
- puts "[Serialize]........."
13
- puts "[Serialize]"
20
+ representable_log "[Serialize]........."
21
+ representable_log "[Serialize]"
14
22
  super
15
23
  end
16
24
 
@@ -22,13 +30,13 @@ module Representable
22
30
 
23
31
  module Binding
24
32
  def evaluate_option(name, *args, &block)
25
- puts "=====#{self[name]}" if name ==:prepare
26
- puts (evaled = self[name]) ?
33
+ Debug.representable_log "=====#{self[name]}" if name ==:prepare
34
+ Debug.representable_log (evaled = self[name]) ?
27
35
  " #evaluate_option [#{name}]: eval!!!" :
28
36
  " #evaluate_option [#{name}]: skipping"
29
37
  value = super
30
- puts " #evaluate_option [#{name}]: --> #{value}" if evaled
31
- puts " #evaluate_option [#{name}]: -->= #{args.first}" if name == :setter
38
+ Debug.representable_log " #evaluate_option [#{name}]: --> #{value}" if evaled
39
+ Debug.representable_log " #evaluate_option [#{name}]: -->= #{args.first}" if name == :setter
32
40
  value
33
41
  end
34
42
 
@@ -45,17 +53,17 @@ module Representable
45
53
 
46
54
  module Pipeline::Debug
47
55
  def call(input, options)
48
- puts "Pipeline#call: #{inspect}"
49
- puts " input: #{input.inspect}"
56
+ Debug.representable_log "Pipeline#call: #{inspect}"
57
+ Debug.representable_log " input: #{input.inspect}"
50
58
  super
51
59
  end
52
60
 
53
61
  def evaluate(block, memo, options)
54
62
  block.extend(Pipeline::Debug) if block.is_a?(Collect)
55
63
 
56
- puts " Pipeline : -> #{_inspect_function(block)} "
64
+ Debug.representable_log " Pipeline : -> #{_inspect_function(block)} "
57
65
  super.tap do |res|
58
- puts " Pipeline : result: #{res.inspect}"
66
+ Debug.representable_log " Pipeline : result: #{res.inspect}"
59
67
  end
60
68
  end
61
69
 
@@ -70,8 +78,8 @@ module Representable
70
78
  def _inspect_function(func)
71
79
  return func.extend(Pipeline::Debug).inspect if func.is_a?(Collect)
72
80
  return func unless func.is_a?(Proc)
81
+
73
82
  File.readlines(func.source_location[0])[func.source_location[1]-1].match(/^\s+(\w+)/)[1]
74
83
  end
75
84
  end
76
85
  end
77
-
@@ -1,4 +1,9 @@
1
+ require "declarative/schema"
2
+
1
3
  module Representable
4
+ autoload :Decorator, "representation/decorator"
5
+ autoload :Definition, "representation/definition"
6
+
2
7
  module Declarative
3
8
  def representation_wrap=(name)
4
9
  heritage.record(:representation_wrap=, name)
@@ -21,9 +26,9 @@ module Representable
21
26
  # them to the original object.
22
27
  def nested(name, options={}, &block)
23
28
  options = options.merge(
24
- getter: ->(options) { self },
25
- setter: ->(options) { },
26
- instance: ->(options) { self },
29
+ getter: ->(_opts) { self },
30
+ setter: ->(opts) { },
31
+ instance: ->(_opts) { self },
27
32
  )
28
33
 
29
34
  if block
@@ -47,10 +52,10 @@ module Representable
47
52
  NestedBuilder = ->(options) do
48
53
  Module.new do
49
54
  include Representable # FIXME: do we really need this?
50
- feature *options[:_features]
51
- include *options[:_base] # base when :inherit, or in decorator.
55
+ feature(*options[:_features])
56
+ include(*options[:_base]) # base when :inherit, or in decorator.
52
57
 
53
- module_eval &options[:_block]
58
+ module_eval(&options[:_block])
54
59
  end
55
60
  end
56
61
 
@@ -64,4 +69,4 @@ module Representable
64
69
 
65
70
  alias_method :representable_attrs, :definitions
66
71
  end
67
- end
72
+ end
@@ -1,5 +1,5 @@
1
- require "representable"
2
1
  require "uber/inheritable_attr"
2
+ require "representable"
3
3
 
4
4
  module Representable
5
5
  class Decorator
@@ -1,7 +1,10 @@
1
- require "uber/options"
2
- require "representable/populator"
1
+ require 'declarative/definitions'
3
2
 
4
3
  module Representable
4
+ autoload :Pipeline, "representable/pipeline"
5
+ autoload :Populator, "representable/populator"
6
+ autoload :Option, "representable/option"
7
+
5
8
  # Created at class compile time. Keeps configuration options for one property.
6
9
  class Definition < ::Declarative::Definitions::Definition
7
10
 
@@ -54,6 +57,7 @@ module Representable
54
57
 
55
58
  def representable?
56
59
  return if self[:representable] == false
60
+
57
61
  self[:representable] or typed?
58
62
  end
59
63
 
@@ -102,7 +106,7 @@ module Representable
102
106
  @runtime_options = {}
103
107
 
104
108
  for name, value in options
105
- value = Uber::Options::Value.new(value) if dynamic_options.include?(name)
109
+ value = ::Representable::Option(value) if dynamic_options.include?(name)
106
110
  @runtime_options[name] = value
107
111
  end
108
112
  end
@@ -11,11 +11,11 @@ module Representable
11
11
  ReadFragment = ->(input, options) { options[:binding].read(input, options[:as]) }
12
12
  Reader = ->(input, options) { options[:binding].evaluate_option(:reader, input, options) }
13
13
 
14
- StopOnNotFound = ->(input, options) do
14
+ StopOnNotFound = ->(input, _options) do
15
15
  Binding::FragmentNotFound == input ? Pipeline::Stop : input
16
16
  end
17
17
 
18
- StopOnNil = ->(input, options) do # DISCUSS: Not tested/used, yet.
18
+ StopOnNil = ->(input, _options) do # DISCUSS: Not tested/used, yet.
19
19
  input.nil? ? Pipeline::Stop : input
20
20
  end
21
21
 
@@ -96,13 +96,14 @@ module Representable
96
96
  If = ->(input, options) { options[:binding].evaluate_option(:if, nil, options) ? input : Pipeline::Stop }
97
97
 
98
98
  StopOnExcluded = ->(input, options) do
99
- return input unless private = options[:options]
99
+ return input unless options[:options]
100
100
  return input unless props = (options[:options][:exclude] || options[:options][:include])
101
101
 
102
102
  res = props.include?(options[:binding].name.to_sym) # false with include: Stop. false with exclude: go!
103
103
 
104
104
  return input if options[:options][:include]&&res
105
105
  return input if options[:options][:exclude]&&!res
106
+
106
107
  Pipeline::Stop
107
108
  end
108
- end
109
+ end
@@ -24,4 +24,4 @@ module Representable
24
24
  @collection_representer = collection_representer!(options)
25
25
  end
26
26
  end
27
- end
27
+ end