representable 2.4.0.rc3 → 2.4.0.rc4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|