representable 3.2.0 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +17 -10
- data/.github/workflows/ci_jruby.yml +21 -0
- data/.github/workflows/ci_truffleruby.yml +19 -0
- data/CHANGES.md +5 -0
- data/Gemfile +1 -1
- data/README.md +0 -1
- data/lib/representable/hash/binding.rb +1 -0
- data/lib/representable/json.rb +14 -2
- data/lib/representable/version.rb +1 -1
- data/lib/representable/xml/binding.rb +0 -7
- data/lib/representable/xml.rb +7 -0
- data/representable.gemspec +1 -3
- data/test/as_test.rb +8 -13
- data/test/benchmarking.rb +20 -25
- data/test/binding_test.rb +13 -5
- data/test/cached_test.rb +55 -35
- data/test/class_test.rb +46 -33
- data/test/coercion_test.rb +29 -19
- data/test/config/inherit_test.rb +12 -17
- data/test/config_test.rb +5 -7
- data/test/decorator_scope_test.rb +13 -11
- data/test/decorator_test.rb +11 -11
- data/test/default_test.rb +2 -2
- data/test/defaults_options_test.rb +37 -9
- data/test/definition_test.rb +10 -12
- data/test/examples/example.rb +43 -38
- data/test/examples/object.rb +7 -6
- data/test/exec_context_test.rb +18 -23
- data/test/features_test.rb +29 -10
- data/test/filter_test.rb +29 -20
- data/test/for_collection_test.rb +12 -15
- data/test/generic_test.rb +15 -22
- data/test/getter_setter_test.rb +11 -6
- data/test/hash_bindings_test.rb +21 -12
- data/test/hash_test.rb +53 -38
- data/test/heritage_test.rb +0 -1
- data/test/if_test.rb +25 -21
- data/test/include_exclude_test.rb +24 -16
- data/test/inherit_test.rb +114 -27
- data/test/inline_test.rb +42 -33
- data/test/instance_test.rb +151 -109
- data/test/is_representable_test.rb +19 -17
- data/test/json_test.rb +48 -46
- data/test/lonely_test.rb +35 -33
- data/test/nested_test.rb +16 -19
- data/test/object_test.rb +6 -6
- data/test/option_test.rb +10 -8
- data/test/parse_pipeline_test.rb +21 -15
- data/test/pipeline_test.rb +144 -108
- data/test/populator_test.rb +18 -15
- data/test/prepare_test.rb +15 -17
- data/test/private_options_test.rb +3 -2
- data/test/reader_writer_test.rb +4 -4
- data/test/realistic_benchmark.rb +21 -27
- data/test/render_nil_test.rb +1 -1
- data/test/represent_test.rb +14 -18
- data/test/representable_test.rb +86 -53
- data/test/schema_test.rb +51 -21
- data/test/serialize_deserialize_test.rb +14 -14
- data/test/skip_test.rb +39 -28
- data/test/stringify_hash_test.rb +29 -31
- data/test/test_helper.rb +31 -25
- data/test/test_helper_test.rb +7 -7
- data/test/uncategorized_test.rb +20 -15
- data/test/user_options_test.rb +12 -3
- data/test/wrap_test.rb +27 -17
- data/test/xml_assertions.rb +29 -0
- data/test/xml_bindings_test.rb +5 -8
- data/test/xml_namespace_test.rb +46 -39
- data/test/xml_test.rb +109 -88
- data/test/yaml_test.rb +73 -51
- metadata +7 -32
data/test/inherit_test.rb
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "test_helper"
|
|
2
2
|
|
|
3
|
-
class InheritTest <
|
|
4
|
-
|
|
3
|
+
class InheritTest < Minitest::Spec
|
|
4
|
+
# it's important to have a global module so we can test if stuff gets overridden in the original module.
|
|
5
|
+
module SongRepresenter
|
|
5
6
|
include Representable::Hash
|
|
6
7
|
property :name, :as => :title do
|
|
7
8
|
property :string, :as => :str
|
|
@@ -16,11 +17,11 @@ class InheritTest < MiniTest::Spec
|
|
|
16
17
|
representer! do
|
|
17
18
|
include SongRepresenter
|
|
18
19
|
|
|
19
|
-
property :track, :inherit => true, :getter =>
|
|
20
|
+
property :track, :inherit => true, :getter => ->(*) { "n/a" }
|
|
20
21
|
end
|
|
21
22
|
|
|
22
|
-
it { _(SongRepresenter.prepare(song).to_hash).must_equal({"title"=>{"str"=>"Roxanne"}, "no"=>1}) }
|
|
23
|
-
it { _(representer.prepare(song).to_hash).must_equal({"title"=>{"str"=>"Roxanne"}, "no"=>"n/a"}) } # as: inherited.
|
|
23
|
+
it { _(SongRepresenter.prepare(song).to_hash).must_equal({"title" => {"str"=>"Roxanne"}, "no" => 1}) }
|
|
24
|
+
it { _(representer.prepare(song).to_hash).must_equal({"title" => {"str"=>"Roxanne"}, "no" => "n/a"}) } # as: inherited.
|
|
24
25
|
end
|
|
25
26
|
|
|
26
27
|
describe ":inherit with empty inline representer" do
|
|
@@ -32,9 +33,27 @@ class InheritTest < MiniTest::Spec
|
|
|
32
33
|
end
|
|
33
34
|
end
|
|
34
35
|
|
|
35
|
-
it {
|
|
36
|
+
it {
|
|
37
|
+
_(
|
|
38
|
+
SongRepresenter.prepare(
|
|
39
|
+
Song.new(
|
|
40
|
+
Struct.new(:string).new("Believe It"),
|
|
41
|
+
1
|
|
42
|
+
)
|
|
43
|
+
).to_hash
|
|
44
|
+
).must_equal({"title" => {"str"=>"Believe It"}, "no" => 1})
|
|
45
|
+
}
|
|
36
46
|
# the block doesn't override the inline representer.
|
|
37
|
-
it {
|
|
47
|
+
it {
|
|
48
|
+
_(
|
|
49
|
+
representer.prepare(
|
|
50
|
+
Song.new(
|
|
51
|
+
Struct.new(:string).new("Believe It"),
|
|
52
|
+
1
|
|
53
|
+
)
|
|
54
|
+
).to_hash
|
|
55
|
+
).must_equal({"title" => {"str"=>"Believe It"}, "no" => 1})
|
|
56
|
+
}
|
|
38
57
|
end
|
|
39
58
|
|
|
40
59
|
describe ":inherit with overriding inline representer" do
|
|
@@ -48,7 +67,16 @@ class InheritTest < MiniTest::Spec
|
|
|
48
67
|
end
|
|
49
68
|
end
|
|
50
69
|
|
|
51
|
-
it {
|
|
70
|
+
it {
|
|
71
|
+
_(
|
|
72
|
+
representer.prepare(
|
|
73
|
+
Song.new(
|
|
74
|
+
Struct.new(:string, :length).new("Believe It", 10),
|
|
75
|
+
1
|
|
76
|
+
)
|
|
77
|
+
).to_hash
|
|
78
|
+
).must_equal({"title" => {"s" => "Believe It", "length" => 10}, "no" => 1})
|
|
79
|
+
}
|
|
52
80
|
end
|
|
53
81
|
|
|
54
82
|
describe ":inherit with empty inline and options" do
|
|
@@ -60,8 +88,26 @@ class InheritTest < MiniTest::Spec
|
|
|
60
88
|
end
|
|
61
89
|
end
|
|
62
90
|
|
|
63
|
-
it {
|
|
64
|
-
|
|
91
|
+
it {
|
|
92
|
+
_(
|
|
93
|
+
SongRepresenter.prepare(
|
|
94
|
+
Song.new(
|
|
95
|
+
Struct.new(:string).new("Believe It"),
|
|
96
|
+
1
|
|
97
|
+
)
|
|
98
|
+
).to_hash
|
|
99
|
+
).must_equal({"title" => {"str"=>"Believe It"}, "no" => 1})
|
|
100
|
+
}
|
|
101
|
+
it {
|
|
102
|
+
_(
|
|
103
|
+
representer.prepare(
|
|
104
|
+
Song.new(
|
|
105
|
+
Struct.new(:string).new("Believe It"),
|
|
106
|
+
1
|
|
107
|
+
)
|
|
108
|
+
).to_hash
|
|
109
|
+
).must_equal({"name" => {"str"=>"Believe It"}, "no" => 1})
|
|
110
|
+
}
|
|
65
111
|
end
|
|
66
112
|
|
|
67
113
|
describe ":inherit with inline without block but options" do
|
|
@@ -71,12 +117,28 @@ class InheritTest < MiniTest::Spec
|
|
|
71
117
|
property :name, :inherit => true, :as => :name # FIXME: add :getter or something else dynamic since this is double-wrapped.
|
|
72
118
|
end
|
|
73
119
|
|
|
74
|
-
it {
|
|
75
|
-
|
|
120
|
+
it {
|
|
121
|
+
_(
|
|
122
|
+
SongRepresenter.prepare(
|
|
123
|
+
Song.new(
|
|
124
|
+
Struct.new(:string).new("Believe It"),
|
|
125
|
+
1
|
|
126
|
+
)
|
|
127
|
+
).to_hash
|
|
128
|
+
).must_equal({"title" => {"str"=>"Believe It"}, "no" => 1})
|
|
129
|
+
}
|
|
130
|
+
it {
|
|
131
|
+
_(
|
|
132
|
+
representer.prepare(
|
|
133
|
+
Song.new(
|
|
134
|
+
Struct.new(:string).new("Believe It"),
|
|
135
|
+
1
|
|
136
|
+
)
|
|
137
|
+
).to_hash
|
|
138
|
+
).must_equal({"name" => {"str"=>"Believe It"}, "no" => 1})
|
|
139
|
+
}
|
|
76
140
|
end
|
|
77
141
|
|
|
78
|
-
|
|
79
|
-
|
|
80
142
|
# no :inherit
|
|
81
143
|
describe "overwriting without :inherit" do
|
|
82
144
|
representer! do
|
|
@@ -90,12 +152,11 @@ class InheritTest < MiniTest::Spec
|
|
|
90
152
|
|
|
91
153
|
definition = representer.representable_attrs.get(:track) # TODO: find a better way to assert Definition identity.
|
|
92
154
|
# definition.keys.size.must_equal 2
|
|
93
|
-
_(definition[:representable]).
|
|
155
|
+
_(definition[:representable]).must_equal true
|
|
94
156
|
_(definition.name).must_equal "track" # was "no".
|
|
95
157
|
end
|
|
96
158
|
end
|
|
97
159
|
|
|
98
|
-
|
|
99
160
|
# decorator
|
|
100
161
|
describe ":inherit with decorator" do
|
|
101
162
|
representer!(:decorator => true) do
|
|
@@ -108,7 +169,7 @@ class InheritTest < MiniTest::Spec
|
|
|
108
169
|
end
|
|
109
170
|
end
|
|
110
171
|
|
|
111
|
-
let(:inheriting)
|
|
172
|
+
let(:inheriting) do
|
|
112
173
|
class InheritingDecorator < representer
|
|
113
174
|
include Representable::Debug
|
|
114
175
|
property :hit, :inherit => true do
|
|
@@ -117,30 +178,56 @@ class InheritTest < MiniTest::Spec
|
|
|
117
178
|
end
|
|
118
179
|
self
|
|
119
180
|
end
|
|
120
|
-
|
|
181
|
+
end
|
|
121
182
|
|
|
122
|
-
it {
|
|
123
|
-
|
|
183
|
+
it {
|
|
184
|
+
_(
|
|
185
|
+
representer.new(
|
|
186
|
+
OpenStruct.new(
|
|
187
|
+
hit: OpenStruct.new(
|
|
188
|
+
title: "I WILL BE OVERRIDDEN",
|
|
189
|
+
:length => "2:59"
|
|
190
|
+
)
|
|
191
|
+
)
|
|
192
|
+
).to_hash
|
|
193
|
+
).must_equal(
|
|
194
|
+
{"hit"=>{"title"=>"Cheap Transistor Radio"}}
|
|
195
|
+
)
|
|
196
|
+
}
|
|
124
197
|
|
|
125
198
|
# inheriting decorator inherits inline representer class (InlineRepresenter#title).
|
|
126
199
|
# inheriting decorator adds :length.
|
|
127
|
-
it {
|
|
128
|
-
|
|
200
|
+
it {
|
|
201
|
+
_(
|
|
202
|
+
inheriting.new(
|
|
203
|
+
OpenStruct.new(
|
|
204
|
+
:hit => OpenStruct.new(
|
|
205
|
+
:title => "Hole In Your Soul",
|
|
206
|
+
:length => "2:59"
|
|
207
|
+
)
|
|
208
|
+
)
|
|
209
|
+
).to_hash
|
|
210
|
+
).must_equal(
|
|
211
|
+
{
|
|
212
|
+
"hit" => {
|
|
213
|
+
"title" => "Cheap Transistor Radio", "length" => "2:59"
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
)
|
|
217
|
+
}
|
|
129
218
|
end
|
|
130
219
|
|
|
131
|
-
|
|
132
220
|
# :inherit when property doesn't exist, yet.
|
|
133
221
|
describe ":inherit without inheritable property" do
|
|
134
222
|
representer! do
|
|
135
223
|
property :name, :inherit => true
|
|
136
224
|
end
|
|
137
225
|
|
|
138
|
-
it { _(representer.prepare(Song.new("The Beginning")).to_hash).must_equal({"name"=>"The Beginning"})}
|
|
226
|
+
it { _(representer.prepare(Song.new("The Beginning")).to_hash).must_equal({"name"=>"The Beginning"}) }
|
|
139
227
|
end
|
|
140
228
|
end
|
|
141
229
|
|
|
142
|
-
|
|
143
|
-
# class InheritancingTest < MiniTest::Spec
|
|
230
|
+
# class InheritancingTest < Minitest::Spec
|
|
144
231
|
# class SongDecorator < Representable::Decorator
|
|
145
232
|
# include Representable::Hash
|
|
146
233
|
# property :album do
|
data/test/inline_test.rb
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "test_helper"
|
|
2
2
|
|
|
3
|
-
class InlineTest <
|
|
3
|
+
class InlineTest < Minitest::Spec
|
|
4
4
|
let(:song) { Song.new("Alive") }
|
|
5
5
|
let(:request) { representer.prepare(OpenStruct.new(:song => song)) }
|
|
6
6
|
|
|
7
7
|
{
|
|
8
8
|
:hash => [Representable::Hash, {"song"=>{"name"=>"Alive"}}, {"song"=>{"name"=>"You've Taken Everything"}}],
|
|
9
9
|
:json => [Representable::JSON, "{\"song\":{\"name\":\"Alive\"}}", "{\"song\":{\"name\":\"You've Taken Everything\"}}"],
|
|
10
|
-
:xml => [
|
|
11
|
-
|
|
10
|
+
:xml => [
|
|
11
|
+
Representable::XML, "<open_struct>\n <song>\n <name>Alive</name>\n </song>\n</open_struct>",
|
|
12
|
+
"<open_struct><song><name>You've Taken Everything</name></song>/open_struct>"
|
|
13
|
+
],
|
|
14
|
+
:yaml => [Representable::YAML, "---\nsong:\n name: Alive\n", "---\nsong:\n name: You've Taken Everything\n"]
|
|
12
15
|
}.each do |format, cfg|
|
|
13
16
|
mod, output, input = cfg
|
|
14
17
|
|
|
@@ -22,15 +25,18 @@ class InlineTest < MiniTest::Spec
|
|
|
22
25
|
let(:format) { format }
|
|
23
26
|
|
|
24
27
|
it { render(request).must_equal_document output }
|
|
25
|
-
it { _(parse(request, input).song.name).must_equal "You've Taken Everything"}
|
|
28
|
+
it { _(parse(request, input).song.name).must_equal "You've Taken Everything" }
|
|
26
29
|
end
|
|
27
30
|
end
|
|
28
31
|
|
|
29
32
|
{
|
|
30
33
|
:hash => [Representable::Hash, {"songs"=>[{"name"=>"Alive"}]}, {"songs"=>[{"name"=>"You've Taken Everything"}]}],
|
|
31
34
|
:json => [Representable::JSON, "{\"songs\":[{\"name\":\"Alive\"}]}", "{\"songs\":[{\"name\":\"You've Taken Everything\"}]}"],
|
|
32
|
-
:xml => [
|
|
33
|
-
|
|
35
|
+
:xml => [
|
|
36
|
+
Representable::XML, "<open_struct>\n <song>\n <name>Alive</name>\n </song>\n</open_struct>",
|
|
37
|
+
"<open_struct><song><name>You've Taken Everything</name></song></open_struct>", {:as => :song}
|
|
38
|
+
],
|
|
39
|
+
:yaml => [Representable::YAML, "---\nsongs:\n- name: Alive\n", "---\nsongs:\n- name: You've Taken Everything\n"]
|
|
34
40
|
}.each do |format, cfg|
|
|
35
41
|
mod, output, input, collection_options = cfg
|
|
36
42
|
collection_options ||= {}
|
|
@@ -47,7 +53,7 @@ class InlineTest < MiniTest::Spec
|
|
|
47
53
|
let(:format) { format } # FIXME: why do we have to define this?
|
|
48
54
|
|
|
49
55
|
it { render(request).must_equal_document output }
|
|
50
|
-
it { _(parse(request, input).songs.first.name).must_equal "You've Taken Everything"}
|
|
56
|
+
it { _(parse(request, input).songs.first.name).must_equal "You've Taken Everything" }
|
|
51
57
|
end
|
|
52
58
|
end
|
|
53
59
|
|
|
@@ -61,13 +67,11 @@ class InlineTest < MiniTest::Spec
|
|
|
61
67
|
it { _(request.to_hash).must_equal({"song"=>{"name"=>"Alive"}}) }
|
|
62
68
|
end
|
|
63
69
|
|
|
64
|
-
|
|
65
70
|
for_formats(
|
|
66
|
-
:hash => [Representable::Hash, {}]
|
|
71
|
+
:hash => [Representable::Hash, {}]
|
|
67
72
|
# :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>"],
|
|
68
73
|
# :yaml => [Representable::YAML, "---\nsong:\n name: Alive\n", "---\nsong:\n name: You've Taken Everything\n"],
|
|
69
74
|
) do |format, mod, input|
|
|
70
|
-
|
|
71
75
|
describe "parsing [#{format}] where nested property missing" do
|
|
72
76
|
representer!(:module => mod) do
|
|
73
77
|
property :song do
|
|
@@ -81,7 +85,6 @@ class InlineTest < MiniTest::Spec
|
|
|
81
85
|
end
|
|
82
86
|
end
|
|
83
87
|
|
|
84
|
-
|
|
85
88
|
describe "inheriting from outer representer" do
|
|
86
89
|
let(:request) { Struct.new(:song, :requester).new(song, "Josephine") }
|
|
87
90
|
|
|
@@ -96,8 +99,8 @@ class InlineTest < MiniTest::Spec
|
|
|
96
99
|
|
|
97
100
|
let(:decorator) { representer.prepare(request) }
|
|
98
101
|
|
|
99
|
-
it { _(decorator.to_hash).must_equal({"requester"=>"Josephine", "song"=>{"name"=>"Alive"}}) }
|
|
100
|
-
it { _(decorator.from_hash({"song"=>{"name"=>"You've Taken Everything"}}).song.name).must_equal "You've Taken Everything"}
|
|
102
|
+
it { _(decorator.to_hash).must_equal({"requester" => "Josephine", "song" => {"name"=>"Alive"}}) }
|
|
103
|
+
it { _(decorator.from_hash({"song"=>{"name"=>"You've Taken Everything"}}).song.name).must_equal "You've Taken Everything" }
|
|
101
104
|
end
|
|
102
105
|
end
|
|
103
106
|
|
|
@@ -144,13 +147,13 @@ class InlineTest < MiniTest::Spec
|
|
|
144
147
|
# end
|
|
145
148
|
# end
|
|
146
149
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
:hash => [Representable::Hash, {"album" => {"artist" => {"label"=>"Epitaph"}}}]
|
|
150
|
+
for_formats(
|
|
151
|
+
{
|
|
152
|
+
:hash => [Representable::Hash, {"album" => {"artist" => {"label"=>"Epitaph"}}}]
|
|
150
153
|
# :xml => [Representable::XML, "<open_struct></open_struct>"],
|
|
151
|
-
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
+
# :yaml => [Representable::YAML, "---\nlabel:\n label: Epitaph\n owner: Brett Gurewitz\n"]
|
|
155
|
+
}
|
|
156
|
+
) do |format, mod, output, _input|
|
|
154
157
|
class ArtistDecorator < Representable::Decorator
|
|
155
158
|
include Representable::JSON
|
|
156
159
|
property :label
|
|
@@ -162,7 +165,7 @@ class InlineTest < MiniTest::Spec
|
|
|
162
165
|
representer!(:module => mod) do
|
|
163
166
|
self.representation_wrap = "album"
|
|
164
167
|
|
|
165
|
-
property :artist, :getter =>
|
|
168
|
+
property :artist, :getter => ->(_args) { represented }, :decorator => ArtistDecorator
|
|
166
169
|
end
|
|
167
170
|
|
|
168
171
|
let(:album) { OpenStruct.new(:label => "Epitaph").extend(representer) }
|
|
@@ -173,14 +176,14 @@ class InlineTest < MiniTest::Spec
|
|
|
173
176
|
end
|
|
174
177
|
end
|
|
175
178
|
|
|
176
|
-
|
|
177
179
|
# test helper methods within inline representer
|
|
178
|
-
for_formats(
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
180
|
+
for_formats(
|
|
181
|
+
{
|
|
182
|
+
:hash => [Representable::Hash, {"song"=>{"name"=>"ALIVE"}}],
|
|
183
|
+
:xml => [Representable::XML, "<request>\n <song>\n <name>ALIVE</name>\n </song>\n</request>"],
|
|
184
|
+
:yaml => [Representable::YAML, "---\nsong:\n name: ALIVE\n"]
|
|
185
|
+
}
|
|
186
|
+
) do |format, mod, output|
|
|
184
187
|
describe "helper method within inline representer [#{format}]" do
|
|
185
188
|
let(:format) { format }
|
|
186
189
|
|
|
@@ -207,7 +210,6 @@ class InlineTest < MiniTest::Spec
|
|
|
207
210
|
end
|
|
208
211
|
end
|
|
209
212
|
|
|
210
|
-
|
|
211
213
|
describe "include module in inline representers" do
|
|
212
214
|
representer! do
|
|
213
215
|
extension = Module.new do
|
|
@@ -221,13 +223,20 @@ class InlineTest < MiniTest::Spec
|
|
|
221
223
|
end
|
|
222
224
|
end
|
|
223
225
|
|
|
224
|
-
it do
|
|
225
|
-
|
|
226
|
-
|
|
226
|
+
it do
|
|
227
|
+
_(
|
|
228
|
+
OpenStruct.new(
|
|
229
|
+
:song => OpenStruct.new(
|
|
230
|
+
:title => "The Fever And The Sound",
|
|
231
|
+
:artist => "Strung Out"
|
|
232
|
+
)
|
|
233
|
+
).extend(representer)
|
|
234
|
+
.to_hash
|
|
235
|
+
)
|
|
236
|
+
.must_equal({"song"=>{"artist" => "Strung Out", "title" => "The Fever And The Sound"}})
|
|
227
237
|
end
|
|
228
238
|
end
|
|
229
239
|
|
|
230
|
-
|
|
231
240
|
# define method in inline representer
|
|
232
241
|
describe "define method in inline representer" do
|
|
233
242
|
Mod = Module.new do
|