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/represent_test.rb
CHANGED
|
@@ -1,27 +1,26 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "test_helper"
|
|
2
2
|
|
|
3
|
-
class RepresentTest <
|
|
3
|
+
class RepresentTest < Minitest::Spec
|
|
4
4
|
let(:songs) { [song, Song.new("Can't Take Them All")] }
|
|
5
5
|
let(:song) { Song.new("Days Go By") }
|
|
6
6
|
|
|
7
7
|
for_formats(
|
|
8
|
-
:hash => [Representable::Hash, out=[{"name" => "Days Go By"}, {"name"=>"Can't Take Them All"}], out]
|
|
8
|
+
:hash => [Representable::Hash, out = [{"name" => "Days Go By"}, {"name"=>"Can't Take Them All"}], out]
|
|
9
9
|
# :json => [Representable::JSON, out="[{\"name\":\"Days Go By\"},{\"name\":\"Can't Take Them All\"}]", out],
|
|
10
10
|
# :xml => [Representable::XML, out="<a><song></song><song></song></a>", out]
|
|
11
11
|
) do |format, mod, output, input|
|
|
12
|
-
|
|
13
12
|
# Representer.represents detects collection.
|
|
14
13
|
describe "Module#to_/from_#{format}" do
|
|
15
14
|
let(:format) { format }
|
|
16
15
|
|
|
17
|
-
let(:representer)
|
|
16
|
+
let(:representer) do
|
|
18
17
|
Module.new do
|
|
19
18
|
include mod
|
|
20
19
|
property :name
|
|
21
20
|
|
|
22
21
|
collection_representer :class => Song # TODOOOOOOOOOOOO: test without Song and fix THIS FUCKINGNoMethodError: undefined method `name=' for {"name"=>"Days Go By"}:Hash ERROR!!!!!!!!!!!!!!!
|
|
23
22
|
end
|
|
24
|
-
|
|
23
|
+
end
|
|
25
24
|
|
|
26
25
|
it { render(representer.represent(songs)).must_equal_document output }
|
|
27
26
|
it { _(parse(representer.represent([]), input)).must_equal songs }
|
|
@@ -30,59 +29,56 @@ class RepresentTest < MiniTest::Spec
|
|
|
30
29
|
# Decorator.represents detects collection.
|
|
31
30
|
describe "Decorator#to_/from_#{format}" do
|
|
32
31
|
let(:format) { format }
|
|
33
|
-
let(:representer)
|
|
32
|
+
let(:representer) do
|
|
34
33
|
Class.new(Representable::Decorator) do
|
|
35
34
|
include mod
|
|
36
35
|
property :name
|
|
37
36
|
|
|
38
37
|
collection_representer :class => Song
|
|
39
38
|
end
|
|
40
|
-
|
|
39
|
+
end
|
|
41
40
|
|
|
42
41
|
it { render(representer.represent(songs)).must_equal_document output }
|
|
43
42
|
it("ficken") { _(parse(representer.represent([]), input)).must_equal songs }
|
|
44
43
|
end
|
|
45
44
|
end
|
|
46
45
|
|
|
47
|
-
|
|
48
46
|
for_formats(
|
|
49
|
-
:hash => [Representable::Hash, out={"name" => "Days Go By"}, out],
|
|
50
|
-
:json => [Representable::JSON, out="{\"name\":\"Days Go By\"}", out]
|
|
47
|
+
:hash => [Representable::Hash, out = {"name" => "Days Go By"}, out],
|
|
48
|
+
:json => [Representable::JSON, out = "{\"name\":\"Days Go By\"}", out]
|
|
51
49
|
# :xml => [Representable::XML, out="<a><song></song><song></song></a>", out]
|
|
52
50
|
) do |format, mod, output, input|
|
|
53
|
-
|
|
54
51
|
# Representer.represents detects singular.
|
|
55
52
|
describe "Module#to_/from_#{format}" do
|
|
56
53
|
let(:format) { format }
|
|
57
54
|
|
|
58
|
-
let(:representer)
|
|
55
|
+
let(:representer) do
|
|
59
56
|
Module.new do
|
|
60
57
|
include mod
|
|
61
58
|
property :name
|
|
62
59
|
|
|
63
60
|
collection_representer :class => Song
|
|
64
61
|
end
|
|
65
|
-
|
|
62
|
+
end
|
|
66
63
|
|
|
67
64
|
it { render(representer.represent(song)).must_equal_document output }
|
|
68
65
|
it { _(parse(representer.represent(Song.new), input)).must_equal song }
|
|
69
66
|
end
|
|
70
67
|
|
|
71
|
-
|
|
72
68
|
# Decorator.represents detects singular.
|
|
73
69
|
describe "Decorator#to_/from_#{format}" do
|
|
74
70
|
let(:format) { format }
|
|
75
|
-
let(:representer)
|
|
71
|
+
let(:representer) do
|
|
76
72
|
Class.new(Representable::Decorator) do
|
|
77
73
|
include mod
|
|
78
74
|
property :name
|
|
79
75
|
|
|
80
76
|
collection_representer :class => Song
|
|
81
77
|
end
|
|
82
|
-
|
|
78
|
+
end
|
|
83
79
|
|
|
84
80
|
it { render(representer.represent(song)).must_equal_document output }
|
|
85
81
|
it { _(parse(representer.represent(Song.new), input)).must_equal song }
|
|
86
82
|
end
|
|
87
83
|
end
|
|
88
|
-
end
|
|
84
|
+
end
|
data/test/representable_test.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "test_helper"
|
|
2
2
|
|
|
3
|
-
class RepresentableTest <
|
|
3
|
+
class RepresentableTest < Minitest::Spec
|
|
4
4
|
class Band
|
|
5
5
|
include Representable::Hash
|
|
6
6
|
property :name
|
|
@@ -25,21 +25,21 @@ class RepresentableTest < MiniTest::Spec
|
|
|
25
25
|
property :street_cred
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
|
|
29
28
|
describe "#representable_attrs" do
|
|
30
29
|
describe "in module" do
|
|
31
30
|
it "allows including the concrete representer module later" do
|
|
32
31
|
vd = class VD
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
attr_accessor :name, :street_cred
|
|
33
|
+
|
|
34
|
+
include Representable::JSON
|
|
35
|
+
include PunkBandRepresentation
|
|
36
|
+
end.new
|
|
37
37
|
vd.name = "Vention Dention"
|
|
38
38
|
vd.street_cred = 1
|
|
39
39
|
assert_json "{\"name\":\"Vention Dention\",\"street_cred\":1}", vd.to_json
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
-
#it "allows including the concrete representer module only" do
|
|
42
|
+
# it "allows including the concrete representer module only" do
|
|
43
43
|
# require 'representable/json'
|
|
44
44
|
# module RockBandRepresentation
|
|
45
45
|
# include Representable::JSON
|
|
@@ -50,11 +50,10 @@ class RepresentableTest < MiniTest::Spec
|
|
|
50
50
|
# end.new
|
|
51
51
|
# vd.name = "Van Halen"
|
|
52
52
|
# assert_equal "{\"name\":\"Van Halen\"}", vd.to_json
|
|
53
|
-
#end
|
|
53
|
+
# end
|
|
54
54
|
end
|
|
55
55
|
end
|
|
56
56
|
|
|
57
|
-
|
|
58
57
|
describe "inheritance" do
|
|
59
58
|
class CoverSong < OpenStruct
|
|
60
59
|
end
|
|
@@ -71,7 +70,7 @@ class RepresentableTest < MiniTest::Spec
|
|
|
71
70
|
end
|
|
72
71
|
|
|
73
72
|
it "merges properties from all ancestors" do
|
|
74
|
-
props = {"name"=>"The Brews", "by"=>"Nofx"}
|
|
73
|
+
props = {"name" => "The Brews", "by" => "Nofx"}
|
|
75
74
|
assert_equal(props, CoverSong.new(props).extend(CoverSongRepresenter).to_hash)
|
|
76
75
|
end
|
|
77
76
|
|
|
@@ -89,7 +88,7 @@ class RepresentableTest < MiniTest::Spec
|
|
|
89
88
|
band.name = "Bodyjar"
|
|
90
89
|
|
|
91
90
|
assert_json "{\"band\":{\"name\":\"Bodyjar\"}}", band.to_json
|
|
92
|
-
assert_xml_equal "<band><name>Bodyjar</name></band>"
|
|
91
|
+
assert_xml_equal(band.to_xml, "<band><name>Bodyjar</name></band>")
|
|
93
92
|
end
|
|
94
93
|
|
|
95
94
|
it "allows extending with different representers subsequentially" do
|
|
@@ -104,11 +103,10 @@ class RepresentableTest < MiniTest::Spec
|
|
|
104
103
|
end
|
|
105
104
|
|
|
106
105
|
@song = Song.new("Days Go By")
|
|
107
|
-
assert_xml_equal "<song name=\"Days Go By\"/>"
|
|
106
|
+
assert_xml_equal(@song.extend(SongXmlRepresenter).to_xml, "<song name=\"Days Go By\"/>")
|
|
108
107
|
assert_json "{\"name\":\"Days Go By\"}", @song.extend(SongJsonRepresenter).to_json
|
|
109
108
|
end
|
|
110
109
|
|
|
111
|
-
|
|
112
110
|
# test if we call super in
|
|
113
111
|
# ::inherited
|
|
114
112
|
# ::included
|
|
@@ -120,14 +118,18 @@ class RepresentableTest < MiniTest::Spec
|
|
|
120
118
|
class BaseClass
|
|
121
119
|
def self.inherited(subclass)
|
|
122
120
|
super
|
|
123
|
-
subclass.instance_eval
|
|
121
|
+
subclass.instance_eval do
|
|
122
|
+
def other
|
|
123
|
+
end
|
|
124
|
+
end
|
|
124
125
|
end
|
|
125
126
|
|
|
126
127
|
include Representable # overrides ::inherited.
|
|
127
128
|
include Representer
|
|
128
129
|
end
|
|
129
130
|
|
|
130
|
-
|
|
131
|
+
# triggers Representable::inherited, then OtherModule::inherited.
|
|
132
|
+
class SubClass < BaseClass
|
|
131
133
|
end
|
|
132
134
|
|
|
133
135
|
# test ::inherited.
|
|
@@ -138,7 +140,10 @@ class RepresentableTest < MiniTest::Spec
|
|
|
138
140
|
|
|
139
141
|
module DifferentIncluded
|
|
140
142
|
def included(includer)
|
|
141
|
-
includer.instance_eval
|
|
143
|
+
includer.instance_eval do
|
|
144
|
+
def different
|
|
145
|
+
end
|
|
146
|
+
end
|
|
142
147
|
end
|
|
143
148
|
end
|
|
144
149
|
|
|
@@ -159,7 +164,6 @@ class RepresentableTest < MiniTest::Spec
|
|
|
159
164
|
end
|
|
160
165
|
end
|
|
161
166
|
|
|
162
|
-
|
|
163
167
|
describe "#property" do
|
|
164
168
|
it "doesn't modify options hash" do
|
|
165
169
|
options = {}
|
|
@@ -215,7 +219,7 @@ class RepresentableTest < MiniTest::Spec
|
|
|
215
219
|
end
|
|
216
220
|
|
|
217
221
|
it "copies values from document to object" do
|
|
218
|
-
@band.from_hash({"name"=>"No One's Choice", "groupies"=>2})
|
|
222
|
+
@band.from_hash({"name" => "No One's Choice", "groupies" => 2})
|
|
219
223
|
assert_equal "No One's Choice", @band.name
|
|
220
224
|
assert_equal 2, @band.groupies
|
|
221
225
|
end
|
|
@@ -238,16 +242,16 @@ class RepresentableTest < MiniTest::Spec
|
|
|
238
242
|
|
|
239
243
|
it "ignores properties not present in the incoming document" do
|
|
240
244
|
@band.instance_eval do
|
|
241
|
-
def name=(*);
|
|
245
|
+
def name=(*); fail "I should never be called!"; end
|
|
242
246
|
end
|
|
243
247
|
@band.from_hash({})
|
|
244
248
|
end
|
|
245
249
|
|
|
246
|
-
|
|
247
250
|
# FIXME: do we need this test with XML _and_ JSON?
|
|
248
251
|
it "ignores (no-default) properties not present in the incoming document" do
|
|
249
|
-
{
|
|
250
|
-
Representable::
|
|
252
|
+
{
|
|
253
|
+
Representable::Hash => [:from_hash, {}],
|
|
254
|
+
Representable::XML => [:from_xml, xml(%{<band/>}).to_s]
|
|
251
255
|
}.each do |format, config|
|
|
252
256
|
nested_repr = Module.new do # this module is never applied. # FIXME: can we make that a simpler test?
|
|
253
257
|
include format
|
|
@@ -268,7 +272,6 @@ class RepresentableTest < MiniTest::Spec
|
|
|
268
272
|
describe "passing options" do
|
|
269
273
|
module TrackRepresenter
|
|
270
274
|
include Representable::Hash
|
|
271
|
-
|
|
272
275
|
end
|
|
273
276
|
|
|
274
277
|
representer! do
|
|
@@ -300,12 +303,21 @@ class RepresentableTest < MiniTest::Spec
|
|
|
300
303
|
end
|
|
301
304
|
|
|
302
305
|
it "#to_hash propagates to nested objects" do
|
|
303
|
-
_(
|
|
304
|
-
|
|
306
|
+
_(
|
|
307
|
+
OpenStruct.new(
|
|
308
|
+
track: OpenStruct.new(
|
|
309
|
+
nr: 1,
|
|
310
|
+
length: OpenStruct.new(seconds: nil)
|
|
311
|
+
)
|
|
312
|
+
).extend(representer).extend(Representable::Debug)
|
|
313
|
+
.to_hash(user_options: {nr: 9})
|
|
314
|
+
).must_equal({"track"=>{"nr" => 9, "length" => {seconds: 9}}})
|
|
305
315
|
end
|
|
306
316
|
|
|
307
317
|
it "#from_hash propagates to nested objects" do
|
|
308
|
-
song = OpenStruct.new.extend(representer).from_hash(
|
|
318
|
+
song = OpenStruct.new.extend(representer).from_hash(
|
|
319
|
+
{"track"=>{"nr" => "replace me", "length" => {"seconds"=>"replacing"}}}, user_options: {nr: 9}
|
|
320
|
+
)
|
|
309
321
|
_(song.track.nr).must_equal 9
|
|
310
322
|
_(song.track.length.seconds).must_equal 9
|
|
311
323
|
end
|
|
@@ -320,13 +332,13 @@ class RepresentableTest < MiniTest::Spec
|
|
|
320
332
|
end
|
|
321
333
|
|
|
322
334
|
it "compiles document from properties in object" do
|
|
323
|
-
assert_equal({"name"=>"No One's Choice", "groupies"=>2}, @band.to_hash)
|
|
335
|
+
assert_equal({"name" => "No One's Choice", "groupies" => 2}, @band.to_hash)
|
|
324
336
|
end
|
|
325
337
|
|
|
326
338
|
it "ignores non-readable properties" do
|
|
327
339
|
@band = Class.new(Band) { property :name; collection :founder_ids, :readable => false; attr_accessor :founder_ids }.new
|
|
328
340
|
@band.name = "Iron Maiden"
|
|
329
|
-
@band.founder_ids = [1,2,3]
|
|
341
|
+
@band.founder_ids = [1, 2, 3]
|
|
330
342
|
|
|
331
343
|
hash = @band.to_hash
|
|
332
344
|
assert_equal({"name" => "Iron Maiden"}, hash)
|
|
@@ -339,37 +351,40 @@ class RepresentableTest < MiniTest::Spec
|
|
|
339
351
|
|
|
340
352
|
it "writes false attributes" do
|
|
341
353
|
@band.groupies = false
|
|
342
|
-
assert_equal({"name"=>"No One's Choice","groupies"=>false}, @band.to_hash)
|
|
354
|
+
assert_equal({"name" => "No One's Choice", "groupies" => false}, @band.to_hash)
|
|
343
355
|
end
|
|
344
356
|
end
|
|
345
357
|
|
|
346
|
-
|
|
347
358
|
describe ":extend and :class" do
|
|
348
359
|
module UpcaseRepresenter
|
|
349
360
|
include Representable
|
|
350
361
|
def to_hash(*); upcase; end
|
|
351
|
-
|
|
362
|
+
# DISCUSS: from_hash must return self.
|
|
363
|
+
def from_hash(hsh, *_args); replace hsh.upcase; end
|
|
352
364
|
end
|
|
365
|
+
|
|
353
366
|
module DowncaseRepresenter
|
|
354
367
|
include Representable
|
|
355
368
|
def to_hash(*); downcase; end
|
|
356
|
-
def from_hash(hsh, *
|
|
369
|
+
def from_hash(hsh, *_args); replace hsh.downcase; end
|
|
357
370
|
end
|
|
358
|
-
class UpcaseString < String; end
|
|
359
371
|
|
|
372
|
+
class UpcaseString < String; end
|
|
360
373
|
|
|
361
374
|
describe "lambda blocks" do
|
|
362
375
|
representer! do
|
|
363
|
-
property :name, :extend =>
|
|
376
|
+
property :name, :extend => ->(name, *) { compute_representer(name) }
|
|
364
377
|
end
|
|
365
378
|
|
|
366
379
|
it "executes lambda in represented instance context" do
|
|
367
|
-
_(
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
380
|
+
_(
|
|
381
|
+
Song.new("Carnage").instance_eval {
|
|
382
|
+
def compute_representer(_name)
|
|
383
|
+
UpcaseRepresenter
|
|
384
|
+
end
|
|
385
|
+
self
|
|
386
|
+
}.extend(representer).to_hash
|
|
387
|
+
).must_equal({"name" => "CARNAGE"})
|
|
373
388
|
end
|
|
374
389
|
end
|
|
375
390
|
|
|
@@ -377,7 +392,7 @@ class RepresentableTest < MiniTest::Spec
|
|
|
377
392
|
obj = String.new("Fate")
|
|
378
393
|
mod = Module.new { include Representable; def from_hash(*); self; end }
|
|
379
394
|
representer! do
|
|
380
|
-
property :name, :extend => mod, :instance =>
|
|
395
|
+
property :name, :extend => mod, :instance => ->(*) { obj }
|
|
381
396
|
end
|
|
382
397
|
|
|
383
398
|
it "uses object from :instance but still extends it" do
|
|
@@ -389,12 +404,14 @@ class RepresentableTest < MiniTest::Spec
|
|
|
389
404
|
|
|
390
405
|
describe "property with :extend" do
|
|
391
406
|
representer! do
|
|
392
|
-
property :name, :extend =>
|
|
407
|
+
property :name, :extend => ->(options) {
|
|
408
|
+
options[:input].is_a?(UpcaseString) ? UpcaseRepresenter : DowncaseRepresenter
|
|
409
|
+
}, :class => String
|
|
393
410
|
end
|
|
394
411
|
|
|
395
412
|
it "uses lambda when rendering" do
|
|
396
|
-
assert_equal({"name" => "you make me thick"}, Song.new("You Make Me Thick").extend(representer).to_hash
|
|
397
|
-
assert_equal({"name" => "STEPSTRANGER"}, Song.new(UpcaseString.new
|
|
413
|
+
assert_equal({"name" => "you make me thick"}, Song.new("You Make Me Thick").extend(representer).to_hash)
|
|
414
|
+
assert_equal({"name" => "STEPSTRANGER"}, Song.new(UpcaseString.new("Stepstranger")).extend(representer).to_hash)
|
|
398
415
|
end
|
|
399
416
|
|
|
400
417
|
it "uses lambda when parsing" do
|
|
@@ -404,8 +421,10 @@ class RepresentableTest < MiniTest::Spec
|
|
|
404
421
|
|
|
405
422
|
describe "with :class lambda" do
|
|
406
423
|
representer! do
|
|
407
|
-
property :name, :extend =>
|
|
408
|
-
|
|
424
|
+
property :name, :extend => ->(options) {
|
|
425
|
+
options[:input].is_a?(UpcaseString) ? UpcaseRepresenter : DowncaseRepresenter
|
|
426
|
+
},
|
|
427
|
+
:class => ->(options) { options[:fragment] == "Still Failing?" ? String : UpcaseString }
|
|
409
428
|
end
|
|
410
429
|
|
|
411
430
|
it "creates instance from :class lambda when parsing" do
|
|
@@ -420,14 +439,25 @@ class RepresentableTest < MiniTest::Spec
|
|
|
420
439
|
end
|
|
421
440
|
end
|
|
422
441
|
|
|
423
|
-
|
|
424
442
|
describe "collection with :extend" do
|
|
425
443
|
representer! do
|
|
426
|
-
collection :songs, :extend =>
|
|
444
|
+
collection :songs, :extend => ->(options) {
|
|
445
|
+
options[:input].is_a?(UpcaseString) ? UpcaseRepresenter : DowncaseRepresenter
|
|
446
|
+
}, :class => String
|
|
427
447
|
end
|
|
428
448
|
|
|
429
449
|
it "uses lambda for each item when rendering" do
|
|
430
|
-
_(
|
|
450
|
+
_(
|
|
451
|
+
Album.new(
|
|
452
|
+
[
|
|
453
|
+
UpcaseString.new("Dean Martin"),
|
|
454
|
+
"Charlie Still Smirks"
|
|
455
|
+
]
|
|
456
|
+
).extend(representer).to_hash
|
|
457
|
+
).must_equal("songs" => [
|
|
458
|
+
"DEAN MARTIN",
|
|
459
|
+
"charlie still smirks"
|
|
460
|
+
])
|
|
431
461
|
end
|
|
432
462
|
|
|
433
463
|
it "uses lambda for each item when parsing" do
|
|
@@ -437,8 +467,10 @@ class RepresentableTest < MiniTest::Spec
|
|
|
437
467
|
|
|
438
468
|
describe "with :class lambda" do
|
|
439
469
|
representer! do
|
|
440
|
-
collection :songs,
|
|
441
|
-
|
|
470
|
+
collection :songs, :extend => ->(options) {
|
|
471
|
+
options[:input].is_a?(UpcaseString) ? UpcaseRepresenter : DowncaseRepresenter
|
|
472
|
+
},
|
|
473
|
+
:class => ->(options) { options[:input] == "Still Failing?" ? String : UpcaseString }
|
|
442
474
|
end
|
|
443
475
|
|
|
444
476
|
it "creates instance from :class lambda for each item when parsing" do
|
|
@@ -463,6 +495,7 @@ class RepresentableTest < MiniTest::Spec
|
|
|
463
495
|
include Representable::JSON
|
|
464
496
|
property :name
|
|
465
497
|
end
|
|
498
|
+
|
|
466
499
|
class AlbumRepresentation < Representable::Decorator
|
|
467
500
|
include Representable::JSON
|
|
468
501
|
|
|
@@ -475,7 +508,7 @@ class RepresentableTest < MiniTest::Spec
|
|
|
475
508
|
|
|
476
509
|
describe "module including Representable" do
|
|
477
510
|
it "uses :extend strategy" do
|
|
478
|
-
album_rpr = Module.new { include Representable::Hash; collection :songs, :class => Song, :extend => SongRepresenter}
|
|
511
|
+
album_rpr = Module.new { include Representable::Hash; collection :songs, :class => Song, :extend => SongRepresenter }
|
|
479
512
|
|
|
480
513
|
_(album_rpr.prepare(album).to_hash).must_equal({"songs"=>[{"name"=>"Still Friends In The End"}]})
|
|
481
514
|
_(album).must_respond_to :to_hash
|
data/test/schema_test.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "test_helper"
|
|
2
2
|
|
|
3
3
|
# Include Inherit Module And Decorator Test
|
|
4
|
-
class SchemaTest <
|
|
4
|
+
class SchemaTest < Minitest::Spec
|
|
5
5
|
module Genre
|
|
6
6
|
include Representable
|
|
7
7
|
property :genre
|
|
@@ -18,7 +18,6 @@ class SchemaTest < MiniTest::Spec
|
|
|
18
18
|
end
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
|
|
22
21
|
module Module
|
|
23
22
|
include Representable::Hash
|
|
24
23
|
feature LinkFeature
|
|
@@ -34,13 +33,11 @@ class SchemaTest < MiniTest::Spec
|
|
|
34
33
|
end
|
|
35
34
|
end
|
|
36
35
|
|
|
37
|
-
property :album, :extend =>
|
|
38
|
-
|
|
36
|
+
property :album, :extend => -> { fail "don't manifest me!" } # this is not an inline decorator, don't manifest it.
|
|
39
37
|
|
|
40
38
|
include Genre # Schema::Included::included is called!
|
|
41
39
|
end
|
|
42
40
|
|
|
43
|
-
|
|
44
41
|
class WithLocationStreetRepresenter < Representable::Decorator
|
|
45
42
|
include Representable::Hash
|
|
46
43
|
feature LinkFeature
|
|
@@ -61,14 +58,26 @@ class SchemaTest < MiniTest::Spec
|
|
|
61
58
|
let(:label) { OpenStruct.new(:name => "Epitaph", :location => OpenStruct.new(:city => "Sanfran", :name => "DON'T SHOW ME!")) }
|
|
62
59
|
|
|
63
60
|
# Module does correctly include features in inlines.
|
|
64
|
-
it {
|
|
61
|
+
it {
|
|
62
|
+
_(band.extend(Module).to_hash).must_equal(
|
|
63
|
+
{
|
|
64
|
+
"label" => {"name" => "Epitaph", "location" => {"city"=>"Sanfran"}},
|
|
65
|
+
"genre" => "Punkrock"
|
|
66
|
+
}
|
|
67
|
+
)
|
|
68
|
+
}
|
|
65
69
|
|
|
66
70
|
# Decorator does correctly include features in inlines.
|
|
67
|
-
it {
|
|
71
|
+
it {
|
|
72
|
+
_(Decorator.new(band).to_hash).must_equal(
|
|
73
|
+
{
|
|
74
|
+
"label" => {"name" => "Epitaph", "location" => {"city"=>"Sanfran"}},
|
|
75
|
+
"genre" => "Punkrock"
|
|
76
|
+
}
|
|
77
|
+
)
|
|
78
|
+
}
|
|
68
79
|
end
|
|
69
80
|
|
|
70
|
-
|
|
71
|
-
|
|
72
81
|
class Decorator < Representable::Decorator
|
|
73
82
|
feature Representable::Hash
|
|
74
83
|
|
|
@@ -77,17 +86,25 @@ class SchemaTest < MiniTest::Spec
|
|
|
77
86
|
|
|
78
87
|
# puts Decorator.representable_attrs[:definitions].inspect
|
|
79
88
|
|
|
80
|
-
let(:label)
|
|
89
|
+
let(:label) do
|
|
90
|
+
OpenStruct.new(
|
|
91
|
+
:name => "Fat Wreck", :city => "San Francisco", :employees => [OpenStruct.new(:name => "Mike")],
|
|
92
|
+
:location => OpenStruct.new(:city => "Sanfran")
|
|
93
|
+
)
|
|
94
|
+
end
|
|
81
95
|
let(:band) { OpenStruct.new(:genre => "Punkrock", :label => label) }
|
|
82
96
|
|
|
83
|
-
|
|
84
97
|
# it { FlatlinersDecorator.new( OpenStruct.new(label: OpenStruct.new) ).
|
|
85
98
|
# to_hash.must_equal({}) }
|
|
86
99
|
it do
|
|
87
|
-
_(Decorator.new(band).to_hash).must_equal(
|
|
100
|
+
_(Decorator.new(band).to_hash).must_equal(
|
|
101
|
+
{
|
|
102
|
+
"genre" => "Punkrock",
|
|
103
|
+
"label" => {"name" => "Fat Wreck", "location" => {"city"=>"Sanfran"}}
|
|
104
|
+
}
|
|
105
|
+
)
|
|
88
106
|
end
|
|
89
107
|
|
|
90
|
-
|
|
91
108
|
class InheritDecorator < Representable::Decorator
|
|
92
109
|
include Representable::Hash
|
|
93
110
|
|
|
@@ -103,11 +120,17 @@ class SchemaTest < MiniTest::Spec
|
|
|
103
120
|
end
|
|
104
121
|
|
|
105
122
|
it do
|
|
106
|
-
_(InheritDecorator.new(band).to_hash).must_equal(
|
|
123
|
+
_(InheritDecorator.new(band).to_hash).must_equal(
|
|
124
|
+
{
|
|
125
|
+
"genre" => "Punkrock",
|
|
126
|
+
"label" => {
|
|
127
|
+
"name" => "Fat Wreck", "city" => "San Francisco",
|
|
128
|
+
"location" => {"city"=>"Sanfran"}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
)
|
|
107
132
|
end
|
|
108
133
|
|
|
109
|
-
|
|
110
|
-
|
|
111
134
|
class InheritFromDecorator < InheritDecorator
|
|
112
135
|
property :label, inherit: true do
|
|
113
136
|
collection :employees do
|
|
@@ -117,12 +140,19 @@ class SchemaTest < MiniTest::Spec
|
|
|
117
140
|
end
|
|
118
141
|
|
|
119
142
|
it do
|
|
120
|
-
_(InheritFromDecorator.new(band).to_hash).must_equal(
|
|
143
|
+
_(InheritFromDecorator.new(band).to_hash).must_equal(
|
|
144
|
+
{
|
|
145
|
+
"genre" => "Punkrock",
|
|
146
|
+
"label" => {
|
|
147
|
+
"name" => "Fat Wreck", "city" => "San Francisco", "employees" => [{"name"=>"Mike"}],
|
|
148
|
+
"location" => {"city"=>"Sanfran"}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
)
|
|
121
152
|
end
|
|
122
153
|
end
|
|
123
154
|
|
|
124
|
-
|
|
125
|
-
class ApplyTest < MiniTest::Spec
|
|
155
|
+
class ApplyTest < Minitest::Spec
|
|
126
156
|
class AlbumDecorator < Representable::Decorator
|
|
127
157
|
include Representable::Hash
|
|
128
158
|
|
|
@@ -142,4 +172,4 @@ class ApplyTest < MiniTest::Spec
|
|
|
142
172
|
end
|
|
143
173
|
end
|
|
144
174
|
end
|
|
145
|
-
end
|
|
175
|
+
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "test_helper"
|
|
2
2
|
|
|
3
3
|
class SerializeDeserializeTest < BaseTest
|
|
4
4
|
subject { Struct.new(:song).new.extend(representer) }
|
|
@@ -6,28 +6,28 @@ class SerializeDeserializeTest < BaseTest
|
|
|
6
6
|
describe "deserialize" do
|
|
7
7
|
representer! do
|
|
8
8
|
property :song,
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
:instance => ->(options) { options[:input].to_s.upcase },
|
|
10
|
+
:prepare => ->(options) { options[:input] },
|
|
11
|
+
:deserialize => ->(options) {
|
|
12
|
+
"#{options[:input]} #{options[:fragment]} #{options[:user_options].inspect}"
|
|
13
|
+
}
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
it { _(subject.from_hash({"song" => Object}, user_options: {volume: 9}).song).must_equal "OBJECT Object {:
|
|
16
|
+
it { _(subject.from_hash({"song" => Object}, user_options: {volume: 9}).song).must_equal "OBJECT Object #{{volume: 9}.inspect}" }
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
describe "serialize" do
|
|
20
20
|
representer! do
|
|
21
21
|
property :song,
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
:representable => true,
|
|
23
|
+
:prepare => ->(options) { options[:fragment] },
|
|
24
|
+
:serialize => ->(options) {
|
|
25
|
+
"#{options[:input]} #{options[:user_options].inspect}"
|
|
26
|
+
}
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
before { subject.song = "Arrested In Shanghai" }
|
|
30
30
|
|
|
31
|
-
it { _(subject.to_hash(user_options: {volume: 9})).must_equal({"song"=>"Arrested In Shanghai {:
|
|
31
|
+
it { _(subject.to_hash(user_options: {volume: 9})).must_equal({"song" => "Arrested In Shanghai #{{volume: 9}.inspect}"}) }
|
|
32
32
|
end
|
|
33
|
-
end
|
|
33
|
+
end
|