representable 2.0.4 → 2.1.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/CHANGES.md +17 -0
- data/README.md +20 -1
- data/lib/representable.rb +2 -1
- data/lib/representable/binding.rb +115 -59
- data/lib/representable/config.rb +8 -0
- data/lib/representable/definition.rb +10 -14
- data/lib/representable/deserializer.rb +64 -25
- data/lib/representable/hash.rb +3 -3
- data/lib/representable/hash/binding.rb +40 -0
- data/lib/representable/hash/collection.rb +3 -2
- data/lib/representable/hash_methods.rb +4 -2
- data/lib/representable/mapper.rb +1 -1
- data/lib/representable/populator.rb +59 -0
- data/lib/representable/serializer.rb +24 -13
- data/lib/representable/version.rb +1 -1
- data/lib/representable/xml.rb +3 -3
- data/lib/representable/xml/binding.rb +171 -0
- data/lib/representable/yaml.rb +3 -3
- data/lib/representable/yaml/binding.rb +48 -0
- data/representable.gemspec +1 -1
- data/test/benchmarking.rb +83 -0
- data/test/binding_test.rb +46 -0
- data/test/definition_test.rb +5 -58
- data/test/exec_context_test.rb +4 -4
- data/test/hash_bindings_test.rb +4 -52
- data/test/hash_test.rb +6 -6
- data/test/json_test.rb +8 -8
- data/test/lonely_test.rb +1 -1
- data/test/realistic_benchmark.rb +83 -0
- data/test/skip_test.rb +28 -0
- data/test/xml_bindings_test.rb +2 -109
- data/test/xml_test.rb +61 -23
- data/test/yaml_test.rb +5 -8
- metadata +19 -11
- data/lib/representable/bindings/hash_bindings.rb +0 -64
- data/lib/representable/bindings/xml_bindings.rb +0 -172
- data/lib/representable/bindings/yaml_bindings.rb +0 -49
data/test/lonely_test.rb
CHANGED
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'benchmark'
|
3
|
+
|
4
|
+
SONG_PROPERTIES = 50.times.collect do |i|
|
5
|
+
"property_#{i}"
|
6
|
+
end
|
7
|
+
|
8
|
+
|
9
|
+
module SongRepresenter
|
10
|
+
include Representable::JSON
|
11
|
+
|
12
|
+
SONG_PROPERTIES.each { |p| property p }
|
13
|
+
end
|
14
|
+
|
15
|
+
class SongDecorator < Representable::Decorator
|
16
|
+
include Representable::JSON
|
17
|
+
|
18
|
+
SONG_PROPERTIES.each { |p| property p }
|
19
|
+
end
|
20
|
+
|
21
|
+
module AlbumRepresenter
|
22
|
+
include Representable::JSON
|
23
|
+
|
24
|
+
# collection :songs, extend: SongRepresenter
|
25
|
+
collection :songs, extend: SongDecorator
|
26
|
+
end
|
27
|
+
|
28
|
+
def random_song
|
29
|
+
attrs = Hash[SONG_PROPERTIES.collect { |n| [n,n] }]
|
30
|
+
OpenStruct.new(attrs)
|
31
|
+
end
|
32
|
+
|
33
|
+
times = []
|
34
|
+
|
35
|
+
3.times.each do
|
36
|
+
album = OpenStruct.new(songs: 50.times.collect { random_song })
|
37
|
+
|
38
|
+
times << Benchmark.measure do
|
39
|
+
puts "================ next!"
|
40
|
+
album.extend(AlbumRepresenter).to_json
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
puts times.join("")
|
45
|
+
|
46
|
+
# 100 songs, 100 attrs
|
47
|
+
# 0.050000 0.000000 0.050000 ( 0.093157)
|
48
|
+
|
49
|
+
## 100 songs, 1000 attrs
|
50
|
+
# 0.470000 0.010000 0.480000 ( 0.483708)
|
51
|
+
|
52
|
+
|
53
|
+
### without binding cache:
|
54
|
+
# 2.790000 0.030000 2.820000 ( 2.820190)
|
55
|
+
|
56
|
+
|
57
|
+
|
58
|
+
### with extend: on Song, with binding cache>
|
59
|
+
# 2.490000 0.030000 2.520000 ( 2.517433) 2.4-3.0
|
60
|
+
### without skip?
|
61
|
+
# 2.030000 0.020000 2.050000 ( 2.050796) 2.1-2.3
|
62
|
+
|
63
|
+
### without :writer
|
64
|
+
# 2.270000 0.010000 2.280000 ( 2.284530 1.9-2.2
|
65
|
+
### without :render_filter
|
66
|
+
# 2.020000 0.000000 2.020000 ( 2.030234) 1.5-2.0
|
67
|
+
###without default_for and skipable?
|
68
|
+
# 1.730000 0.010000 1.740000 ( 1.735597 1.4-1.7
|
69
|
+
### without :serialize
|
70
|
+
# 1.780000 0.010000 1.790000 ( 1.786791) 1.4-1.7
|
71
|
+
### using decorator
|
72
|
+
# 1.400000 0.030000 1.430000 ( 1.434206) 1.4-1.6
|
73
|
+
### with prepare AFTER representable?
|
74
|
+
# 1.330000 0.010000 1.340000 ( 1.335900) 1.1-1.3
|
75
|
+
|
76
|
+
|
77
|
+
# representable 2.0
|
78
|
+
# 3.000000 0.020000 3.020000 ( 3.013031) 2.7-3.0
|
79
|
+
|
80
|
+
# no method missing
|
81
|
+
# 2.280000 0.030000 2.310000 ( 2.313522) 2.2-2.5
|
82
|
+
# no def_delegator in Definition
|
83
|
+
# 2.130000 0.010000 2.140000 ( 2.136115) 1.7-2.1
|
data/test/skip_test.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class SkipTest < MiniTest::Spec
|
4
|
+
representer! do
|
5
|
+
property :title
|
6
|
+
property :band,
|
7
|
+
skip_parse: lambda { |fragment, opts| opts[:skip?] and fragment["name"].nil? }, class: OpenStruct do
|
8
|
+
property :name
|
9
|
+
end
|
10
|
+
|
11
|
+
collection :airplays,
|
12
|
+
skip_parse: lambda { |fragment, opts| puts fragment.inspect; opts[:skip?] and fragment["station"].nil? }, class: OpenStruct do
|
13
|
+
property :station
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
let (:song) { OpenStruct.new.extend(representer) }
|
18
|
+
|
19
|
+
# do parse.
|
20
|
+
it { song.from_hash({"band" => {"name" => "Mute 98"}}, skip?: true).band.name.must_equal "Mute 98" }
|
21
|
+
it { song.from_hash({"airplays" => [{"station" => "JJJ"}]}, skip?: true).airplays[0].station.must_equal "JJJ" }
|
22
|
+
|
23
|
+
# skip parsing.
|
24
|
+
it { song.from_hash({"band" => {}}, skip?: true).band.must_equal nil }
|
25
|
+
# skip_parse is _per item_.
|
26
|
+
let (:airplay) { OpenStruct.new(station: "JJJ") }
|
27
|
+
it { song.from_hash({"airplays" => [{"station" => "JJJ"}, {}]}, skip?: true).airplays.must_equal [airplay] }
|
28
|
+
end
|
data/test/xml_bindings_test.rb
CHANGED
@@ -23,120 +23,13 @@ class XMLBindingTest < MiniTest::Spec
|
|
23
23
|
@song = SongWithRepresenter.new("Thinning the Herd")
|
24
24
|
end
|
25
25
|
|
26
|
-
describe "PropertyBinding" do
|
27
|
-
describe "with plain text" do
|
28
|
-
before do
|
29
|
-
@property = Representable::XML::PropertyBinding.new(Representable::Definition.new(:song), nil, nil, {:doc => @doc})
|
30
|
-
end
|
31
|
-
|
32
|
-
it "extracts with #read" do
|
33
|
-
assert_equal "Thinning the Herd", @property.read(Nokogiri::XML("<song>Thinning the Herd</song>"))
|
34
|
-
end
|
35
|
-
|
36
|
-
it "inserts with #write" do
|
37
|
-
@property.write(@doc, "Thinning the Herd")
|
38
|
-
assert_xml_equal "<song>Thinning the Herd</song>", @doc.to_s
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
describe "with an object" do
|
43
|
-
before do
|
44
|
-
@property = Representable::XML::PropertyBinding.new(Representable::Definition.new(:song, :class => SongWithRepresenter), nil, nil, {:doc => @doc})
|
45
|
-
end
|
46
|
-
|
47
|
-
it "extracts with #read" do
|
48
|
-
assert_equal @song, @property.read(Nokogiri::XML("<song><name>Thinning the Herd</name></song>"))
|
49
|
-
end
|
50
|
-
|
51
|
-
it "inserts with #write" do
|
52
|
-
@property.write(@doc, @song)
|
53
|
-
assert_xml_equal("<song><name>Thinning the Herd</name></song>", @doc.to_s)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
describe "with an object and :extend" do
|
58
|
-
before do
|
59
|
-
@property = Representable::XML::PropertyBinding.new(Representable::Definition.new(:song, :class => Song, :extend => SongRepresenter), nil, nil, {:doc => @doc})
|
60
|
-
end
|
61
|
-
|
62
|
-
it "extracts with #read" do
|
63
|
-
assert_equal @song, @property.read(Nokogiri::XML("<song><name>Thinning the Herd</name></song>"))
|
64
|
-
end
|
65
|
-
|
66
|
-
it "inserts with #write" do
|
67
|
-
@property.write(@doc, @song)
|
68
|
-
assert_xml_equal("<song><name>Thinning the Herd</name></song>", @doc.to_s)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
|
74
|
-
describe "CollectionBinding" do
|
75
|
-
describe "with plain text items" do
|
76
|
-
before do
|
77
|
-
@property = Representable::XML::CollectionBinding.new(Representable::Definition.new(:song, :collection => true), Struct.new(:song).new, nil)
|
78
|
-
end
|
79
26
|
|
80
|
-
it "extracts with #read" do
|
81
|
-
assert_equal ["The Gargoyle", "Bronx"], @property.read(Nokogiri::XML("<doc><song>The Gargoyle</song><song>Bronx</song></doc>").root)
|
82
|
-
end
|
83
|
-
|
84
|
-
it "inserts with #write" do
|
85
|
-
parent = Nokogiri::XML::Node.new("parent", @doc)
|
86
|
-
@property.write(parent, ["The Gargoyle", "Bronx"])
|
87
|
-
assert_xml_equal("<songs><song>The Gargoyle</song><song>Bronx</song></songs>", parent.to_s)
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
describe "with objects" do
|
92
|
-
before do
|
93
|
-
@property = Representable::XML::PropertyBinding.new(Representable::Definition.new(:song, :collection => true, :class => SongWithRepresenter), nil, nil, {:doc => @doc})
|
94
|
-
end
|
95
|
-
|
96
|
-
it "extracts with #read" do
|
97
|
-
assert_equal @song, @property.read(Nokogiri::XML("<song><name>Thinning the Herd</name></song>"))
|
98
|
-
end
|
99
|
-
|
100
|
-
it "inserts with #write" do
|
101
|
-
@property.write(@doc, @song)
|
102
|
-
assert_xml_equal("<song><name>Thinning the Herd</name></song>", @doc.to_s)
|
103
|
-
assert_kind_of Nokogiri::XML::Node, @doc.children.first
|
104
|
-
assert_equal "song", @doc.children.first.name
|
105
|
-
assert_equal "name", @doc.children.first.children.first.name
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
|
111
|
-
describe "HashBinding" do
|
112
|
-
describe "with plain text items" do
|
113
|
-
before do
|
114
|
-
@property = Representable::XML::HashBinding.new(Representable::Definition.new(:songs, :hash => true), nil, nil)
|
115
|
-
end
|
116
|
-
|
117
|
-
it "extracts with #read" do
|
118
|
-
assert_equal({"first" => "The Gargoyle", "second" => "Bronx"} , @property.read(Nokogiri::XML("<songs><first>The Gargoyle</first><second>Bronx</second></songs>")))
|
119
|
-
end
|
120
|
-
|
121
|
-
it "inserts with #write" do
|
122
|
-
parent = Nokogiri::XML::Node.new("parent", @doc)
|
123
|
-
@property.write(parent, {"first" => "The Gargoyle", "second" => "Bronx"})
|
124
|
-
assert_xml_equal("<songs><first>The Gargoyle</first><second>Bronx</second></songs>", parent.to_s)
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
describe "with objects" do
|
129
|
-
before do
|
130
|
-
@property = Representable::XML::HashBinding.new(Representable::Definition.new(:songs, :hash => true, :class => Song, :extend => SongRepresenter), nil)
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|
134
27
|
|
135
28
|
|
136
29
|
describe "AttributeBinding" do
|
137
30
|
describe "with plain text items" do
|
138
31
|
before do
|
139
|
-
@property = Representable::XML::
|
32
|
+
@property = Representable::XML::Binding::Attribute.new(Representable::Definition.new(:name, :attribute => true), nil, nil)
|
140
33
|
end
|
141
34
|
|
142
35
|
it "extracts with #read" do
|
@@ -153,7 +46,7 @@ class XMLBindingTest < MiniTest::Spec
|
|
153
46
|
|
154
47
|
describe "ContentBinding" do
|
155
48
|
before do
|
156
|
-
@property = Representable::XML::
|
49
|
+
@property = Representable::XML::Binding::Content.new(Representable::Definition.new(:name, :content => true), nil, nil)
|
157
50
|
end
|
158
51
|
|
159
52
|
it "extracts with #read" do
|
data/test/xml_test.rb
CHANGED
@@ -104,20 +104,20 @@ class XmlTest < MiniTest::Spec
|
|
104
104
|
|
105
105
|
describe "XML::Binding#build_for" do
|
106
106
|
it "returns AttributeBinding" do
|
107
|
-
assert_kind_of XML::
|
107
|
+
assert_kind_of XML::Binding::Attribute, XML::Binding.build_for(Def.new(:band, :as => "band", :attribute => true), nil, nil)
|
108
108
|
end
|
109
109
|
|
110
|
-
it "returns
|
111
|
-
assert_kind_of XML::
|
112
|
-
assert_kind_of XML::
|
110
|
+
it "returns Binding" do
|
111
|
+
assert_kind_of XML::Binding, XML::Binding.build_for(Def.new(:band, :class => Hash), nil, nil)
|
112
|
+
assert_kind_of XML::Binding, XML::Binding.build_for(Def.new(:band, :as => :content), nil, nil)
|
113
113
|
end
|
114
114
|
|
115
115
|
it "returns CollectionBinding" do
|
116
|
-
assert_kind_of XML::
|
116
|
+
assert_kind_of XML::Binding::Collection, XML::Binding.build_for(Def.new(:band, :collection => :true), nil, nil)
|
117
117
|
end
|
118
118
|
|
119
119
|
it "returns HashBinding" do
|
120
|
-
assert_kind_of XML::
|
120
|
+
assert_kind_of XML::Binding::Hash, XML::Binding.build_for(Def.new(:band, :hash => :true), nil, nil)
|
121
121
|
end
|
122
122
|
end
|
123
123
|
|
@@ -206,7 +206,7 @@ end
|
|
206
206
|
|
207
207
|
|
208
208
|
class CDataBand
|
209
|
-
class CData < Representable::XML::
|
209
|
+
class CData < Representable::XML::Binding
|
210
210
|
def serialize_node(parent, value)
|
211
211
|
parent << Nokogiri::XML::CDATA.new(parent, represented.name)
|
212
212
|
end
|
@@ -320,14 +320,14 @@ class CollectionTest < MiniTest::Spec
|
|
320
320
|
|
321
321
|
|
322
322
|
describe ":as" do
|
323
|
-
let(:
|
323
|
+
let(:xml_doc) {
|
324
324
|
Module.new do
|
325
325
|
include Representable::XML
|
326
326
|
collection :songs, :as => :song
|
327
327
|
end }
|
328
328
|
|
329
329
|
it "collects untyped items" do
|
330
|
-
album = Album.new.extend(
|
330
|
+
album = Album.new.extend(xml_doc).from_xml(%{
|
331
331
|
<album>
|
332
332
|
<song>Two Kevins</song>
|
333
333
|
<song>Wright and Rong</song>
|
@@ -340,8 +340,8 @@ class CollectionTest < MiniTest::Spec
|
|
340
340
|
|
341
341
|
|
342
342
|
describe ":wrap" do
|
343
|
-
let (:album) { Album.new.extend(
|
344
|
-
let (:
|
343
|
+
let (:album) { Album.new.extend(xml_doc) }
|
344
|
+
let (:xml_doc) {
|
345
345
|
Module.new do
|
346
346
|
include Representable::XML
|
347
347
|
collection :songs, :as => :song, :wrap => :songs
|
@@ -397,22 +397,22 @@ class CollectionTest < MiniTest::Spec
|
|
397
397
|
end
|
398
398
|
|
399
399
|
let (:songs) { [Song.new("Days Go By"), Song.new("Can't Take Them All")] }
|
400
|
-
let (:
|
400
|
+
let (:xml_doc) { "<songs><song><name>Days Go By</name></song><song><name>Can't Take Them All</name></song></songs>" }
|
401
401
|
|
402
402
|
it "renders array" do
|
403
|
-
songs.extend(representer).to_xml.must_equal_xml
|
403
|
+
songs.extend(representer).to_xml.must_equal_xml xml_doc
|
404
404
|
end
|
405
405
|
|
406
406
|
it "renders array with decorator" do
|
407
|
-
decorator.new(songs).to_xml.must_equal_xml
|
407
|
+
decorator.new(songs).to_xml.must_equal_xml xml_doc
|
408
408
|
end
|
409
409
|
|
410
410
|
it "parses array" do
|
411
|
-
[].extend(representer).from_xml(
|
411
|
+
[].extend(representer).from_xml(xml_doc).must_equal songs
|
412
412
|
end
|
413
413
|
|
414
414
|
it "parses array with decorator" do
|
415
|
-
decorator.new([]).from_xml(
|
415
|
+
decorator.new([]).from_xml(xml_doc).must_equal songs
|
416
416
|
end
|
417
417
|
end
|
418
418
|
end
|
@@ -423,11 +423,11 @@ class CollectionTest < MiniTest::Spec
|
|
423
423
|
end
|
424
424
|
|
425
425
|
let (:songs) { {"one" => "Graveyards", "two" => "Can't Take Them All"} }
|
426
|
-
let (:
|
426
|
+
let (:xml_doc) { "<favs one=\"Graveyards\" two=\"Can't Take Them All\" />" }
|
427
427
|
|
428
428
|
describe "#to_xml" do
|
429
429
|
it "renders hash" do
|
430
|
-
songs.extend(representer).to_xml.must_equal_xml
|
430
|
+
songs.extend(representer).to_xml.must_equal_xml xml_doc
|
431
431
|
end
|
432
432
|
|
433
433
|
it "respects :exclude" do
|
@@ -439,27 +439,65 @@ class CollectionTest < MiniTest::Spec
|
|
439
439
|
end
|
440
440
|
|
441
441
|
it "renders hash with decorator" do
|
442
|
-
decorator.new(songs).to_xml.must_equal_xml
|
442
|
+
decorator.new(songs).to_xml.must_equal_xml xml_doc
|
443
443
|
end
|
444
444
|
end
|
445
445
|
|
446
446
|
describe "#from_json" do
|
447
447
|
it "returns hash" do
|
448
|
-
{}.extend(representer).from_xml(
|
448
|
+
{}.extend(representer).from_xml(xml_doc).must_equal songs
|
449
449
|
end
|
450
450
|
|
451
451
|
it "respects :exclude" do
|
452
|
-
assert_equal({"two" => "Can't Take Them All"}, {}.extend(representer).from_xml(
|
452
|
+
assert_equal({"two" => "Can't Take Them All"}, {}.extend(representer).from_xml(xml_doc, :exclude => [:one]))
|
453
453
|
end
|
454
454
|
|
455
455
|
it "respects :include" do
|
456
|
-
assert_equal({"one" => "Graveyards"}, {}.extend(representer).from_xml(
|
456
|
+
assert_equal({"one" => "Graveyards"}, {}.extend(representer).from_xml(xml_doc, :include => [:one]))
|
457
457
|
end
|
458
458
|
|
459
459
|
it "parses hash with decorator" do
|
460
|
-
decorator.new({}).from_xml(
|
460
|
+
decorator.new({}).from_xml(xml_doc).must_equal songs
|
461
461
|
end
|
462
462
|
end
|
463
463
|
end
|
464
464
|
end
|
465
465
|
end
|
466
|
+
|
467
|
+
class XmlHashTest < MiniTest::Spec
|
468
|
+
# scalar, no object
|
469
|
+
describe "plain text" do
|
470
|
+
representer!(module: Representable::XML) do
|
471
|
+
hash :songs
|
472
|
+
end
|
473
|
+
|
474
|
+
let (:doc) { "<open_struct><first>The Gargoyle</first><second>Bronx</second></open_struct>" }
|
475
|
+
|
476
|
+
# to_xml
|
477
|
+
it { OpenStruct.new(songs: {"first" => "The Gargoyle", "second" => "Bronx"}).extend(representer).to_xml.must_equal_xml(doc) }
|
478
|
+
# FIXME: this NEVER worked!
|
479
|
+
# it { OpenStruct.new.extend(representer).from_xml(doc).songs.must_equal({"first" => "The Gargoyle", "second" => "Bronx"}) }
|
480
|
+
end
|
481
|
+
|
482
|
+
describe "with objects" do
|
483
|
+
representer!(module: Representable::XML) do
|
484
|
+
hash :songs, class: OpenStruct do
|
485
|
+
property :title
|
486
|
+
end
|
487
|
+
end
|
488
|
+
|
489
|
+
let (:doc) { "<open_struct>
|
490
|
+
<open_struct>
|
491
|
+
<title>The Gargoyle</title>
|
492
|
+
</open_struct>
|
493
|
+
<open_struct>
|
494
|
+
<title>Bronx</title>
|
495
|
+
</open_struct>
|
496
|
+
</open_struct>" }
|
497
|
+
|
498
|
+
# to_xml
|
499
|
+
it { OpenStruct.new(songs: {"first" => OpenStruct.new(title: "The Gargoyle"), "second" => OpenStruct.new(title: "Bronx")}).extend(representer).to_xml.must_equal_xml(doc) }
|
500
|
+
# FIXME: this NEVER worked!
|
501
|
+
# it { OpenStruct.new.extend(representer).from_xml(doc).songs.must_equal({"first" => "The Gargoyle", "second" => "Bronx"}) }
|
502
|
+
end
|
503
|
+
end
|
data/test/yaml_test.rb
CHANGED
@@ -124,18 +124,15 @@ songs: [Off Key Melody, Sinking]").must_equal Album.new(["Off Key Melody", "Sink
|
|
124
124
|
|
125
125
|
|
126
126
|
describe "with :class and :extend" do
|
127
|
-
yaml_song = yaml_representer do
|
128
|
-
property :name
|
129
|
-
property :track
|
130
|
-
end
|
131
127
|
let (:yaml_album) { Module.new do
|
132
128
|
include Representable::YAML
|
133
|
-
collection :songs, :
|
129
|
+
collection :songs, :class => Song do
|
130
|
+
property :name
|
131
|
+
property :track
|
132
|
+
end
|
134
133
|
end }
|
135
134
|
|
136
|
-
let (:album) { Album.new.
|
137
|
-
album.songs = [Song.new("Liar", 1), Song.new("What I Know", 2)]
|
138
|
-
end }
|
135
|
+
let (:album) { Album.new([Song.new("Liar", 1), Song.new("What I Know", 2)]) }
|
139
136
|
|
140
137
|
|
141
138
|
describe "#to_yaml" do
|