representable 2.4.0.rc3 → 2.4.0.rc4
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/CHANGES.md +7 -2
- data/Rakefile +6 -0
- data/lib/representable.rb +21 -17
- data/lib/representable/binding.rb +3 -2
- data/lib/representable/definition.rb +1 -1
- data/lib/representable/deprecations.rb +31 -5
- data/lib/representable/deserializer.rb +24 -34
- data/lib/representable/hash/collection.rb +9 -2
- data/lib/representable/hash_methods.rb +2 -2
- data/lib/representable/parse_strategies.rb +6 -7
- data/lib/representable/pipeline.rb +12 -1
- data/lib/representable/pipeline_factories.rb +9 -2
- data/lib/representable/serializer.rb +3 -3
- data/lib/representable/version.rb +1 -1
- data/test-with-deprecations/as_test.rb +65 -0
- data/test-with-deprecations/benchmarking.rb +83 -0
- data/test-with-deprecations/binding_test.rb +46 -0
- data/test-with-deprecations/blaaaaaaaa_test.rb +69 -0
- data/test-with-deprecations/cached_test.rb +147 -0
- data/test-with-deprecations/class_test.rb +119 -0
- data/test-with-deprecations/coercion_test.rb +52 -0
- data/test-with-deprecations/config/inherit_test.rb +135 -0
- data/test-with-deprecations/config_test.rb +122 -0
- data/test-with-deprecations/decorator_scope_test.rb +28 -0
- data/test-with-deprecations/decorator_test.rb +96 -0
- data/test-with-deprecations/default_test.rb +34 -0
- data/test-with-deprecations/defaults_options_test.rb +93 -0
- data/test-with-deprecations/definition_test.rb +264 -0
- data/test-with-deprecations/example.rb +310 -0
- data/test-with-deprecations/examples/object.rb +31 -0
- data/test-with-deprecations/exec_context_test.rb +93 -0
- data/test-with-deprecations/features_test.rb +70 -0
- data/test-with-deprecations/filter_test.rb +57 -0
- data/test-with-deprecations/for_collection_test.rb +74 -0
- data/test-with-deprecations/generic_test.rb +116 -0
- data/test-with-deprecations/getter_setter_test.rb +21 -0
- data/test-with-deprecations/hash_bindings_test.rb +87 -0
- data/test-with-deprecations/hash_test.rb +160 -0
- data/test-with-deprecations/heritage_test.rb +62 -0
- data/test-with-deprecations/if_test.rb +79 -0
- data/test-with-deprecations/include_exclude_test.rb +88 -0
- data/test-with-deprecations/inherit_test.rb +159 -0
- data/test-with-deprecations/inline_test.rb +272 -0
- data/test-with-deprecations/instance_test.rb +266 -0
- data/test-with-deprecations/is_representable_test.rb +77 -0
- data/test-with-deprecations/json_test.rb +355 -0
- data/test-with-deprecations/lonely_test.rb +239 -0
- data/test-with-deprecations/mongoid_test.rb +31 -0
- data/test-with-deprecations/nested_test.rb +115 -0
- data/test-with-deprecations/object_test.rb +60 -0
- data/{test/---deserialize-pipeline_test.rb → test-with-deprecations/parse_pipeline_test.rb} +29 -2
- data/test-with-deprecations/parse_strategy_test.rb +279 -0
- data/{test → test-with-deprecations}/pass_options_test.rb +0 -0
- data/test-with-deprecations/pipeline_test.rb +277 -0
- data/test-with-deprecations/populator_test.rb +105 -0
- data/test-with-deprecations/prepare_test.rb +67 -0
- data/test-with-deprecations/private_options_test.rb +18 -0
- data/test-with-deprecations/reader_writer_test.rb +19 -0
- data/test-with-deprecations/realistic_benchmark.rb +115 -0
- data/test-with-deprecations/render_nil_test.rb +21 -0
- data/test-with-deprecations/represent_test.rb +88 -0
- data/test-with-deprecations/representable_test.rb +511 -0
- data/test-with-deprecations/schema_test.rb +148 -0
- data/test-with-deprecations/serialize_deserialize_test.rb +33 -0
- data/test-with-deprecations/skip_test.rb +81 -0
- data/test-with-deprecations/stringify_hash_test.rb +41 -0
- data/test-with-deprecations/test_helper.rb +135 -0
- data/test-with-deprecations/test_helper_test.rb +25 -0
- data/test-with-deprecations/uncategorized_test.rb +67 -0
- data/test-with-deprecations/user_options_test.rb +15 -0
- data/test-with-deprecations/wrap_test.rb +152 -0
- data/test-with-deprecations/xml_bindings_test.rb +62 -0
- data/test-with-deprecations/xml_test.rb +503 -0
- data/test-with-deprecations/yaml_test.rb +162 -0
- data/test/as_test.rb +3 -3
- data/test/cached_test.rb +2 -2
- data/test/class_test.rb +5 -5
- data/test/exec_context_test.rb +2 -2
- data/test/filter_test.rb +1 -1
- data/test/getter_setter_test.rb +4 -4
- data/test/if_test.rb +2 -2
- data/test/include_exclude_test.rb +88 -0
- data/test/instance_test.rb +15 -15
- data/test/lonely_test.rb +18 -2
- data/test/object_test.rb +4 -4
- data/test/parse_pipeline_test.rb +64 -0
- data/test/parse_strategy_test.rb +3 -3
- data/test/pipeline_test.rb +8 -12
- data/test/prepare_test.rb +2 -3
- data/test/reader_writer_test.rb +3 -3
- data/test/representable_test.rb +12 -48
- data/test/serialize_deserialize_test.rb +9 -9
- data/test/skip_test.rb +11 -11
- data/test/test_helper.rb +2 -0
- data/test/uncategorized_test.rb +10 -10
- data/test/user_options_test.rb +15 -0
- data/test/wrap_test.rb +1 -1
- metadata +65 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 37e722a1246b50c21ee87fe22a3a712bc03c3ea0
|
4
|
+
data.tar.gz: 4c7cdfbdeb505aaff4f6295ef2b3c717cf4667e4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c64248b241a38e218d0078116f3fbd3ba79591ca6d9cbed24c80eaa0903c0b017aa5cd18dd1a7bc70f76ee26bf7a2b29b2b6b4c764579762be6a10181555f99a
|
7
|
+
data.tar.gz: a3a01d1dcd3ca21b5a2796eb4ad49f708b4d21d9710c160e176465710c45544b2894512322420e295c4dd6a70c8321d9d71814f8a8d448b977912fc99f17c895
|
data/CHANGES.md
CHANGED
@@ -44,13 +44,18 @@ and it suddenly is super simple to understand
|
|
44
44
|
* Removed `Binding@represented` (which was never public anyway). Use `Binding#represented`.
|
45
45
|
* Changed signature: `Binding#get(represented:)`. In now needs a hash `{represented: ..}`.
|
46
46
|
|
47
|
+
# 2.4.0.rc4
|
48
|
+
|
49
|
+
* The preferred way of passing user options is now `to_hash(user_options: {})`.
|
50
|
+
* Supports nested options for nested representers.
|
51
|
+
|
47
52
|
# 2.4.0.rc3
|
48
53
|
|
54
|
+
* `Set` is `SetValue`. `Get` is `GetValue`.
|
49
55
|
* `CreateObject` no longer invokes `AssignFragment`. This is now part of the official parse pipeline.
|
50
56
|
|
51
|
-
# 2.4.0.
|
57
|
+
# 2.4.0.rc2
|
52
58
|
|
53
|
-
* `Set` is `SetValue`. `Get` is `GetValue`.
|
54
59
|
* Use Declarative's `::build_definition` interface instead of overwriting `::property`.
|
55
60
|
|
56
61
|
# 2.3.0
|
data/Rakefile
CHANGED
@@ -9,3 +9,9 @@ Rake::TestTask.new(:test) do |test|
|
|
9
9
|
test.test_files = FileList['test/**/*_test.rb']
|
10
10
|
test.verbose = true
|
11
11
|
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/lib/representable.rb
CHANGED
@@ -39,7 +39,7 @@ private
|
|
39
39
|
|
40
40
|
# Compiles the document going through all properties.
|
41
41
|
def create_representation_with(doc, options, format)
|
42
|
-
propagated_options = normalize_options(options)
|
42
|
+
propagated_options = normalize_options(options)
|
43
43
|
|
44
44
|
representable_map!(doc, propagated_options, format, :compile_fragment)
|
45
45
|
doc
|
@@ -63,8 +63,8 @@ private
|
|
63
63
|
Binding::Map.new(representable_bindings_for(format, options))
|
64
64
|
end
|
65
65
|
|
66
|
-
def representable_map!(doc,
|
67
|
-
options = {doc: doc,
|
66
|
+
def representable_map!(doc, options, format, method)
|
67
|
+
options = {doc: doc, options: options, represented: represented, decorator: self}
|
68
68
|
|
69
69
|
representable_map(options, format).(method, options) # .(:uncompile_fragment, options)
|
70
70
|
end
|
@@ -73,23 +73,24 @@ private
|
|
73
73
|
representable_attrs.collect {|definition| format.build(definition) }
|
74
74
|
end
|
75
75
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
propagated_options = options.dup
|
83
|
-
propagated_options.delete(:wrap) # FIXME.
|
84
|
-
propagated_options.delete(:_private)
|
76
|
+
module NormalizeOptions
|
77
|
+
def normalize_options(options)
|
78
|
+
return options if options.any?
|
79
|
+
{user_options: {}}.merge(options) # TODO: use keyword args once we drop 2.0.
|
80
|
+
end
|
81
|
+
end
|
85
82
|
|
86
|
-
|
87
|
-
|
88
|
-
|
83
|
+
# Prepares options for a particular nested representer.
|
84
|
+
# This is used in Serializer and Deserializer.
|
85
|
+
OptionsForNested = ->(options, binding) do
|
86
|
+
child_options = {user_options: options[:user_options], }
|
89
87
|
|
90
|
-
|
88
|
+
# wrap:
|
89
|
+
child_options[:wrap] = binding[:wrap] unless binding[:wrap].nil?
|
91
90
|
|
92
|
-
|
91
|
+
# nested params:
|
92
|
+
child_options.merge!(options[binding.name.to_sym]) if options[binding.name.to_sym]
|
93
|
+
child_options
|
93
94
|
end
|
94
95
|
|
95
96
|
def representable_attrs
|
@@ -123,6 +124,9 @@ private
|
|
123
124
|
def self.deprecations=(value)
|
124
125
|
evaluator = value==false ? Binding::EvaluateOption : Binding::Deprecation::EvaluateOption
|
125
126
|
::Representable::Binding.send :include, evaluator
|
127
|
+
|
128
|
+
evaluator = value==false ? NormalizeOptions : Deprecation::NormalizeOptions
|
129
|
+
::Representable.send :include, evaluator
|
126
130
|
end
|
127
131
|
self.deprecations = true # TODO: change to false in 2.5 or remove entirely.
|
128
132
|
end
|
@@ -41,9 +41,10 @@ module Representable
|
|
41
41
|
include Deprecatable
|
42
42
|
|
43
43
|
module EvaluateOption
|
44
|
-
def evaluate_option(name, input
|
44
|
+
def evaluate_option(name, input, options)
|
45
45
|
proc = self[name]
|
46
|
-
|
46
|
+
# puts "@@@@@ #{self.inspect}, #{name}...... #{self[name]}"
|
47
|
+
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.
|
47
48
|
end
|
48
49
|
end
|
49
50
|
# include EvaluateOption
|
@@ -1,4 +1,29 @@
|
|
1
1
|
# WARNING: this will be removed in 3.0.
|
2
|
+
module Representable::Deprecation
|
3
|
+
module NormalizeOptions
|
4
|
+
def normalize_options(options)
|
5
|
+
|
6
|
+
unless options.any?
|
7
|
+
options[:user_options] = {}
|
8
|
+
return options
|
9
|
+
end
|
10
|
+
|
11
|
+
options = options.dup
|
12
|
+
|
13
|
+
user_option_keys = options.keys - [:exclude, :include, :wrap, :user_options, * representable_attrs.keys.map(&:to_sym)]
|
14
|
+
if user_option_keys.any?
|
15
|
+
user_options = {}
|
16
|
+
warn "[Representable] Mixing user and representable options is deprecated. Please provide your options via :user_options."
|
17
|
+
user_option_keys.each { |key| user_options[key] = options.delete(key) }
|
18
|
+
|
19
|
+
options[:user_options] = user_options
|
20
|
+
end
|
21
|
+
|
22
|
+
options # {user_options: {..}, include: [], wrap: "song", artist: {..}}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
2
27
|
module Representable::Binding::Deprecation
|
3
28
|
Options = Struct.new(:binding, :user_options, :represented, :decorator)
|
4
29
|
|
@@ -32,12 +57,14 @@ module Representable::Binding::Deprecation
|
|
32
57
|
__options = if self[:pass_options]
|
33
58
|
warn %{[Representable] The :pass_options option is deprecated. Please access environment objects via options[:binding].
|
34
59
|
Learn more here: http://trailblazerb.org/gems/representable/upgrading-guide.html#pass-options}
|
35
|
-
|
60
|
+
|
61
|
+
|
62
|
+
options[:options] ||= {}
|
63
|
+
Options.new(self, options[:options][:user_options], options[:represented], options[:decorator])
|
36
64
|
else
|
37
65
|
# user_options
|
38
|
-
options[:user_options]
|
66
|
+
options[:options][:user_options] || {}
|
39
67
|
end
|
40
|
-
# options[:user_options] = __options # TODO: always make this user_options in Representable 3.0.
|
41
68
|
|
42
69
|
if proc.send(:proc?) or proc.send(:method?)
|
43
70
|
arity = proc.instance_variable_get(:@value).arity if proc.send(:proc?)
|
@@ -54,12 +81,11 @@ module Representable::Binding::Deprecation
|
|
54
81
|
deprecated_args << __options and next if arg == :user_options# either hash or Options object.
|
55
82
|
deprecated_args << options[arg]
|
56
83
|
end
|
57
|
-
|
58
84
|
return proc.(send(:exec_context, options), *deprecated_args)
|
59
85
|
end
|
60
86
|
end
|
61
87
|
|
62
|
-
proc.(send(:exec_context, options), options)
|
88
|
+
proc.(send(:exec_context, options), options.merge(user_options: options[:options][:user_options]))
|
63
89
|
end
|
64
90
|
private :evaluate_option_with_deprecation
|
65
91
|
|
@@ -31,31 +31,7 @@ module Representable
|
|
31
31
|
options[:binding].evaluate_option(:skip_parse, input, options) ? Pipeline::Stop : input
|
32
32
|
end
|
33
33
|
|
34
|
-
Instance = ->(input, options) do
|
35
|
-
options[:binding].evaluate_option(:instance, input, options)
|
36
|
-
end
|
37
|
-
|
38
34
|
module Function
|
39
|
-
class CreateObject
|
40
|
-
def call(input, options)
|
41
|
-
instance_for(input, options) || class_for(input, options)
|
42
|
-
end
|
43
|
-
|
44
|
-
private
|
45
|
-
def class_for(input, options)
|
46
|
-
item_class = class_from(input, options) or raise DeserializeError.new(":class did not return class constant for `#{options[:binding].name}`.")
|
47
|
-
item_class.new
|
48
|
-
end
|
49
|
-
|
50
|
-
def class_from(input, options)
|
51
|
-
options[:binding].evaluate_option(:class, input, options) # FIXME: no additional args passed here, yet.
|
52
|
-
end
|
53
|
-
|
54
|
-
def instance_for(input, options)
|
55
|
-
Instance.(input, options)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
35
|
class Prepare
|
60
36
|
def call(input, options)
|
61
37
|
binding = options[:binding]
|
@@ -81,16 +57,30 @@ module Representable
|
|
81
57
|
end
|
82
58
|
end
|
83
59
|
|
84
|
-
|
60
|
+
module CreateObject
|
61
|
+
Instance = ->(input, options) { options[:binding].evaluate_option(:instance, input, options)||
|
62
|
+
raise( DeserializeError.new(":instance did not return class constant for `#{options[:binding].name}`.")) }
|
63
|
+
Class = ->(input, options) do
|
64
|
+
object_class = options[:binding].evaluate_option(:class, input, options) ||
|
65
|
+
raise( DeserializeError.new(":class did not return class constant for `#{options[:binding].name}`."))
|
66
|
+
object_class.new
|
67
|
+
end # FIXME: no additional args passed here, yet.
|
68
|
+
|
69
|
+
Populator = ->(*) { raise "Populator: implement me!" }
|
70
|
+
end
|
71
|
+
|
72
|
+
# CreateObject = Function::CreateObject.new
|
85
73
|
Prepare = Function::Prepare.new
|
86
74
|
Decorate = Function::Decorate.new
|
87
|
-
Deserializer =
|
75
|
+
Deserializer = ->(input, options) { options[:binding].evaluate_option(:deserialize, input, options) }
|
76
|
+
|
77
|
+
Deserialize = ->(input, args) do
|
78
|
+
binding, fragment, options = args[:binding], args[:fragment], args[:options]
|
88
79
|
|
89
|
-
|
90
|
-
|
80
|
+
# user_options:
|
81
|
+
child_options = OptionsForNested.(options, args[:binding])
|
91
82
|
|
92
|
-
|
93
|
-
input.send(binding.deserialize_method, fragment, user_options)
|
83
|
+
input.send(binding.deserialize_method, fragment, child_options)
|
94
84
|
end
|
95
85
|
|
96
86
|
ParseFilter = ->(input, options) do
|
@@ -106,13 +96,13 @@ module Representable
|
|
106
96
|
If = ->(input, options) { options[:binding].evaluate_option(:if, nil, options) ? input : Pipeline::Stop }
|
107
97
|
|
108
98
|
StopOnExcluded = ->(input, options) do
|
109
|
-
return input unless private = options[:
|
110
|
-
return input unless props = (
|
99
|
+
return input unless private = options[:options]
|
100
|
+
return input unless props = (options[:options][:exclude] || options[:options][:include])
|
111
101
|
|
112
102
|
res = props.include?(options[:binding].name.to_sym) # false with include: Stop. false with exclude: go!
|
113
103
|
|
114
|
-
return input if
|
115
|
-
return input if
|
104
|
+
return input if options[:options][:include]&&res
|
105
|
+
return input if options[:options][:exclude]&&!res
|
116
106
|
Pipeline::Stop
|
117
107
|
end
|
118
108
|
end
|
@@ -17,19 +17,26 @@ module Representable::Hash
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
+
# TODO: revise lonely collection and build separate pipeline where we just use Serialize, etc.
|
20
21
|
|
21
22
|
def create_representation_with(doc, options, format)
|
23
|
+
options = normalize_options(options)
|
24
|
+
options[:_self] = options
|
25
|
+
|
22
26
|
bin = representable_bindings_for(format, options).first
|
23
27
|
|
24
28
|
Collect[*bin.default_render_fragment_functions].
|
25
|
-
(represented, {doc: doc, fragment: represented,
|
29
|
+
(represented, {doc: doc, fragment: represented, options: options, binding: bin, represented: represented})
|
26
30
|
end
|
27
31
|
|
28
32
|
def update_properties_from(doc, options, format)
|
33
|
+
options = normalize_options(options)
|
34
|
+
options[:_self] = options
|
35
|
+
|
29
36
|
bin = representable_bindings_for(format, options).first
|
30
37
|
|
31
38
|
value = Collect[*bin.default_parse_fragment_functions].
|
32
|
-
(doc, fragment: doc, document: doc,
|
39
|
+
(doc, fragment: doc, document: doc, options: options, binding: bin, represented: represented)
|
33
40
|
|
34
41
|
represented.replace(value)
|
35
42
|
end
|
@@ -4,14 +4,14 @@ module Representable
|
|
4
4
|
hash = filter_keys_for!(represented, options) # FIXME: this modifies options and replicates logic from Representable.
|
5
5
|
bin = representable_map(options, format).first
|
6
6
|
|
7
|
-
Collect::Hash[*bin.default_render_fragment_functions].(hash, {doc: doc,
|
7
|
+
Collect::Hash[*bin.default_render_fragment_functions].(hash, {doc: doc, options: options, binding: bin, represented: represented, decorator: self})
|
8
8
|
end
|
9
9
|
|
10
10
|
def update_properties_from(doc, options, format)
|
11
11
|
hash = filter_keys_for!(doc, options)
|
12
12
|
bin = representable_map(options, format).first
|
13
13
|
|
14
|
-
value = Collect::Hash[*bin.default_parse_fragment_functions].(hash, fragment: hash, document: doc, binding: bin, represented: represented,
|
14
|
+
value = Collect::Hash[*bin.default_parse_fragment_functions].(hash, fragment: hash, document: doc, binding: bin, represented: represented, options: options, decorator: self)
|
15
15
|
|
16
16
|
represented.replace(value)
|
17
17
|
end
|
@@ -24,7 +24,7 @@ module Representable
|
|
24
24
|
options[:parse_pipeline] = ->(input, options) do
|
25
25
|
pipeline = Pipeline[*parse_functions] # TODO: AssignFragment
|
26
26
|
pipeline = Pipeline::Insert.(pipeline, SetValue, delete: true) # remove the setter function.
|
27
|
-
pipeline = Pipeline::Insert.(pipeline, populator, replace: CreateObject) # let the populator do
|
27
|
+
pipeline = Pipeline::Insert.(pipeline, populator, replace: CreateObject::Populator) # let the actual populator do the job.
|
28
28
|
# puts pipeline.extend(Representable::Pipeline::Debug).inspect
|
29
29
|
pipeline
|
30
30
|
end
|
@@ -72,8 +72,8 @@ module Representable
|
|
72
72
|
options[:setter] = lambda { |*args| }
|
73
73
|
options[:pass_options] = true
|
74
74
|
options[:instance] = options[:collection] ?
|
75
|
-
lambda { |
|
76
|
-
lambda { |
|
75
|
+
lambda { |options| options[:binding].get(options)[options[:index]] } :
|
76
|
+
lambda { |options| options[:binding].get(options) }
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
@@ -82,11 +82,10 @@ module Representable
|
|
82
82
|
class FindOrInstantiate
|
83
83
|
def self.apply!(name, options)
|
84
84
|
options[:pass_options] = true
|
85
|
-
options[:instance] = lambda { |
|
86
|
-
|
87
|
-
object_class = args.binding[:class].evaluate(self, fragment, args)
|
85
|
+
options[:instance] = lambda { |options|
|
86
|
+
object_class = options[:binding][:class].evaluate(self, options)
|
88
87
|
|
89
|
-
object_class.find_by({id: fragment["id"]}) or object_class.new
|
88
|
+
object_class.find_by({id: options[:fragment]["id"]}) or object_class.new
|
90
89
|
}
|
91
90
|
end
|
92
91
|
end
|
@@ -19,7 +19,18 @@ module Representable
|
|
19
19
|
def evaluate(block, input, options)
|
20
20
|
block.call(input, options)
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
|
+
|
24
|
+
module Insert # TODO: explicit test.
|
25
|
+
# Macro to quickly modify an array of functions via Pipeline::Insert and return a
|
26
|
+
# Pipeline instance.
|
27
|
+
def insert(functions, new_function, options)
|
28
|
+
Pipeline.new(Insert.(functions, new_function, options))
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
extend Insert
|
33
|
+
end # Pipeline
|
23
34
|
|
24
35
|
|
25
36
|
# Collect applies a pipeline to each element of input.
|
@@ -67,8 +67,15 @@ module Representable
|
|
67
67
|
functions = [AssignFragment]
|
68
68
|
functions << SkipParse if self[:skip_parse]
|
69
69
|
|
70
|
-
if
|
71
|
-
|
70
|
+
if self[:class] or self[:extend] or self[:instance] or self[:populator]
|
71
|
+
if self[:populator]
|
72
|
+
functions << CreateObject::Populator
|
73
|
+
elsif self[:parse_strategy]
|
74
|
+
functions << CreateObject::Instance # TODO: remove in 2.5.
|
75
|
+
else
|
76
|
+
functions << (self[:class] ? CreateObject::Class : CreateObject::Instance)
|
77
|
+
end
|
78
|
+
|
72
79
|
functions << Prepare if self[:prepare]
|
73
80
|
functions << Decorate if self[:extend]
|
74
81
|
if representable?
|
@@ -37,11 +37,11 @@ module Representable
|
|
37
37
|
|
38
38
|
Serialize = ->(input, options) do
|
39
39
|
return if input.nil? # DISCUSS: how can we prevent that?
|
40
|
-
binding,
|
40
|
+
binding, options = options[:binding], options[:options] # FIXME: rename to :local_options.
|
41
41
|
|
42
|
-
|
42
|
+
options_for_nested = OptionsForNested.(options, binding)
|
43
43
|
|
44
|
-
input.send(binding.serialize_method,
|
44
|
+
input.send(binding.serialize_method, options_for_nested)
|
45
45
|
end
|
46
46
|
|
47
47
|
WriteFragment = ->(input, options) { options[:binding].write(options[:doc], input, options[:as]) }
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class AsTest < MiniTest::Spec
|
4
|
+
for_formats(
|
5
|
+
:hash => [Representable::Hash, {"title" => "Wie Es Geht"}, {"title" => "Revolution"}],
|
6
|
+
# :xml => [Representable::XML, "<open_struct>\n <song>\n <name>Alive</name>\n </song>\n</open_struct>", "<open_struct><song><name>You've Taken Everything</name></song>/open_struct>"],
|
7
|
+
# :yaml => [Representable::YAML, "---\nsong:\n name: Alive\n", "---\nsong:\n name: You've Taken Everything\n"],
|
8
|
+
) do |format, mod, input, output|
|
9
|
+
|
10
|
+
let (:song) { representer.prepare(Song.new("Revolution")) }
|
11
|
+
let (:format) { format }
|
12
|
+
|
13
|
+
|
14
|
+
describe "as: with :symbol" do
|
15
|
+
representer!(:module => mod) do
|
16
|
+
property :name, :as => :title
|
17
|
+
end
|
18
|
+
|
19
|
+
it { render(song).must_equal_document output }
|
20
|
+
it { parse(song, input).name.must_equal "Wie Es Geht" }
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
describe "as: with lambda" do
|
25
|
+
representer!(:module => mod) do
|
26
|
+
property :name, :as => lambda { |*| "#{self.class}" }
|
27
|
+
end
|
28
|
+
|
29
|
+
it { render(song).must_equal_document({"Song" => "Revolution"}) }
|
30
|
+
it { parse(song, {"Song" => "Wie Es Geht"}).name.must_equal "Wie Es Geht" }
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
describe "lambda arguments" do
|
35
|
+
representer! do
|
36
|
+
property :name, :as => lambda { |*args| args.inspect }
|
37
|
+
end
|
38
|
+
|
39
|
+
it { render(song, :volume => 1).must_equal_document({"[{:volume=>1}]" => "Revolution"}) }
|
40
|
+
it { parse(song, {"[{:volume=>1}]" => "Wie Es Geht"}, :volume => 1).name.must_equal "Wie Es Geht" }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
# hash: to_hash(wrap: ) is representation_wrap
|
47
|
+
|
48
|
+
class AsXmlTest < MiniTest::Spec
|
49
|
+
Band = Struct.new(:name, :label)
|
50
|
+
Album = Struct.new(:band)
|
51
|
+
Label = Struct.new(:name)
|
52
|
+
|
53
|
+
representer!(module: Representable::XML, decorator: true) do
|
54
|
+
self.representation_wrap = :album
|
55
|
+
property :band, as: :combo do
|
56
|
+
self.representation_wrap = :band
|
57
|
+
property :name
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
it do
|
62
|
+
skip
|
63
|
+
representer.new(Album.new(Band.new("Offspring"))).to_xml.must_equal ""
|
64
|
+
end
|
65
|
+
end
|