km-psych 0.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.
- data/README.rdoc +129 -0
- data/ext/psych/emitter.c +488 -0
- data/ext/psych/emitter.h +8 -0
- data/ext/psych/extconf.rb +22 -0
- data/ext/psych/parser.c +349 -0
- data/ext/psych/parser.h +6 -0
- data/ext/psych/psych.c +34 -0
- data/ext/psych/psych.h +20 -0
- data/ext/psych/to_ruby.c +41 -0
- data/ext/psych/to_ruby.h +8 -0
- data/ext/psych/yaml_tree.c +24 -0
- data/ext/psych/yaml_tree.h +8 -0
- data/lib/km-psych.rb +244 -0
- data/lib/psych/coder.rb +86 -0
- data/lib/psych/core_ext.rb +38 -0
- data/lib/psych/deprecated.rb +82 -0
- data/lib/psych/handler.rb +221 -0
- data/lib/psych/json.rb +6 -0
- data/lib/psych/json/stream.rb +32 -0
- data/lib/psych/json/tree_builder.rb +32 -0
- data/lib/psych/nodes.rb +77 -0
- data/lib/psych/nodes/alias.rb +18 -0
- data/lib/psych/nodes/document.rb +60 -0
- data/lib/psych/nodes/mapping.rb +56 -0
- data/lib/psych/nodes/node.rb +42 -0
- data/lib/psych/nodes/scalar.rb +67 -0
- data/lib/psych/nodes/sequence.rb +81 -0
- data/lib/psych/nodes/stream.rb +37 -0
- data/lib/psych/omap.rb +4 -0
- data/lib/psych/parser.rb +44 -0
- data/lib/psych/scalar_scanner.rb +105 -0
- data/lib/psych/set.rb +4 -0
- data/lib/psych/stream.rb +53 -0
- data/lib/psych/tree_builder.rb +94 -0
- data/lib/psych/visitors.rb +5 -0
- data/lib/psych/visitors/emitter.rb +41 -0
- data/lib/psych/visitors/json_tree.rb +14 -0
- data/lib/psych/visitors/to_ruby.rb +263 -0
- data/lib/psych/visitors/visitor.rb +27 -0
- data/lib/psych/visitors/yaml_tree.rb +342 -0
- data/test/psych/helper.rb +63 -0
- data/test/psych/json/test_stream.rb +75 -0
- data/test/psych/test_alias_and_anchor.rb +26 -0
- data/test/psych/test_array.rb +19 -0
- data/test/psych/test_boolean.rb +36 -0
- data/test/psych/test_class.rb +17 -0
- data/test/psych/test_coder.rb +169 -0
- data/test/psych/test_date_time.rb +17 -0
- data/test/psych/test_deprecated.rb +210 -0
- data/test/psych/test_document.rb +46 -0
- data/test/psych/test_emitter.rb +88 -0
- data/test/psych/test_encoding.rb +179 -0
- data/test/psych/test_engine_manager.rb +57 -0
- data/test/psych/test_exception.rb +39 -0
- data/test/psych/test_hash.rb +30 -0
- data/test/psych/test_json_tree.rb +43 -0
- data/test/psych/test_null.rb +19 -0
- data/test/psych/test_object.rb +27 -0
- data/test/psych/test_omap.rb +68 -0
- data/test/psych/test_parser.rb +216 -0
- data/test/psych/test_psych.rb +133 -0
- data/test/psych/test_scalar.rb +11 -0
- data/test/psych/test_scalar_scanner.rb +70 -0
- data/test/psych/test_serialize_subclasses.rb +38 -0
- data/test/psych/test_set.rb +49 -0
- data/test/psych/test_stream.rb +49 -0
- data/test/psych/test_string.rb +49 -0
- data/test/psych/test_struct.rb +51 -0
- data/test/psych/test_symbol.rb +17 -0
- data/test/psych/test_to_yaml_properties.rb +63 -0
- data/test/psych/test_tree_builder.rb +79 -0
- data/test/psych/test_yaml.rb +1251 -0
- data/test/psych/visitors/test_emitter.rb +124 -0
- data/test/psych/visitors/test_to_ruby.rb +325 -0
- data/test/psych/visitors/test_yaml_tree.rb +149 -0
- metadata +187 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
module Psych
|
2
|
+
module Visitors
|
3
|
+
class Visitor
|
4
|
+
attr_reader :started, :finished
|
5
|
+
alias :finished? :finished
|
6
|
+
alias :started? :started
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@started = false
|
10
|
+
@finished = false
|
11
|
+
end
|
12
|
+
|
13
|
+
def accept target
|
14
|
+
case target
|
15
|
+
when Psych::Nodes::Scalar then visit_Psych_Nodes_Scalar target
|
16
|
+
when Psych::Nodes::Mapping then visit_Psych_Nodes_Mapping target
|
17
|
+
when Psych::Nodes::Sequence then visit_Psych_Nodes_Sequence target
|
18
|
+
when Psych::Nodes::Alias then visit_Psych_Nodes_Alias target
|
19
|
+
when Psych::Nodes::Document then visit_Psych_Nodes_Document target
|
20
|
+
when Psych::Nodes::Stream then visit_Psych_Nodes_Stream target
|
21
|
+
else
|
22
|
+
raise "Can't handle #{target}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,342 @@
|
|
1
|
+
module Psych
|
2
|
+
module Visitors
|
3
|
+
###
|
4
|
+
# YAMLTree builds a YAML ast given a ruby object. For example:
|
5
|
+
#
|
6
|
+
# builder = Psych::Visitors::YAMLTree.new
|
7
|
+
# builder << { :foo => 'bar' }
|
8
|
+
# builder.tree # => #<Psych::Nodes::Stream .. }
|
9
|
+
#
|
10
|
+
class YAMLTree < Psych::Visitors::Visitor
|
11
|
+
def initialize options = {}, emitter = Psych::TreeBuilder.new
|
12
|
+
super()
|
13
|
+
@emitter = emitter
|
14
|
+
@st = {}
|
15
|
+
@ss = ScalarScanner.new
|
16
|
+
|
17
|
+
@dispatch_cache = Hash.new do |h,klass|
|
18
|
+
method = "visit_#{(klass.name || '').split('::').join('_')}"
|
19
|
+
|
20
|
+
method = respond_to?(method) ? method : h[klass.superclass]
|
21
|
+
|
22
|
+
raise(TypeError, "Can't dump #{target.class}") unless method
|
23
|
+
|
24
|
+
h[klass] = method
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def start encoding = Nodes::Stream::UTF8
|
29
|
+
@emitter.start_stream(encoding).tap do
|
30
|
+
@started = true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def finish
|
35
|
+
@emitter.end_stream.tap do
|
36
|
+
@finished = true
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def tree
|
41
|
+
finish unless finished?
|
42
|
+
end
|
43
|
+
|
44
|
+
def push object
|
45
|
+
start unless started?
|
46
|
+
@emitter.start_document [], [], false
|
47
|
+
accept object
|
48
|
+
@emitter.end_document
|
49
|
+
end
|
50
|
+
alias :<< :push
|
51
|
+
|
52
|
+
def accept target
|
53
|
+
# return any aliases we find
|
54
|
+
if node = @st[target.object_id]
|
55
|
+
node.anchor = target.object_id.to_s
|
56
|
+
return @emitter.alias target.object_id.to_s
|
57
|
+
end
|
58
|
+
|
59
|
+
if target.respond_to?(:to_yaml)
|
60
|
+
loc = target.method(:to_yaml).source_location.first
|
61
|
+
if loc !~ /(syck\/rubytypes.rb|psych\/core_ext.rb)/
|
62
|
+
unless target.respond_to?(:encode_with)
|
63
|
+
if $VERBOSE
|
64
|
+
warn "implementing to_yaml is deprecated, please implement \"encode_with\""
|
65
|
+
end
|
66
|
+
|
67
|
+
target.to_yaml(:nodump => true)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
if target.respond_to?(:encode_with)
|
73
|
+
dump_coder target
|
74
|
+
else
|
75
|
+
send(@dispatch_cache[target.class], target)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def visit_Psych_Omap o
|
80
|
+
seq = @emitter.start_sequence(nil, '!omap', false, Nodes::Sequence::BLOCK)
|
81
|
+
register(o, seq)
|
82
|
+
|
83
|
+
o.each { |k,v| visit_Hash k => v }
|
84
|
+
@emitter.end_sequence
|
85
|
+
end
|
86
|
+
|
87
|
+
def visit_Object o
|
88
|
+
tag = Psych.dump_tags[o.class]
|
89
|
+
unless tag
|
90
|
+
klass = o.class == Object ? nil : o.class.name
|
91
|
+
tag = ['!ruby/object', klass].compact.join(':')
|
92
|
+
end
|
93
|
+
|
94
|
+
map = @emitter.start_mapping(nil, tag, false, Nodes::Mapping::BLOCK)
|
95
|
+
register(o, map)
|
96
|
+
|
97
|
+
dump_ivars o
|
98
|
+
@emitter.end_mapping
|
99
|
+
end
|
100
|
+
|
101
|
+
def visit_Struct o
|
102
|
+
tag = ['!ruby/struct', o.class.name].compact.join(':')
|
103
|
+
|
104
|
+
register o, @emitter.start_mapping(nil, tag, false, Nodes::Mapping::BLOCK)
|
105
|
+
o.members.each do |member|
|
106
|
+
@emitter.scalar member.to_s, nil, nil, true, false, Nodes::Scalar::ANY
|
107
|
+
accept o[member]
|
108
|
+
end
|
109
|
+
|
110
|
+
dump_ivars o
|
111
|
+
|
112
|
+
@emitter.end_mapping
|
113
|
+
end
|
114
|
+
|
115
|
+
def visit_Exception o
|
116
|
+
tag = ['!ruby/exception', o.class.name].join ':'
|
117
|
+
|
118
|
+
@emitter.start_mapping nil, tag, false, Nodes::Mapping::BLOCK
|
119
|
+
|
120
|
+
{
|
121
|
+
'message' => private_iv_get(o, 'mesg'),
|
122
|
+
'backtrace' => private_iv_get(o, 'backtrace'),
|
123
|
+
}.each do |k,v|
|
124
|
+
next unless v
|
125
|
+
@emitter.scalar k, nil, nil, true, false, Nodes::Scalar::ANY
|
126
|
+
accept v
|
127
|
+
end
|
128
|
+
|
129
|
+
dump_ivars o
|
130
|
+
|
131
|
+
@emitter.end_mapping
|
132
|
+
end
|
133
|
+
|
134
|
+
def visit_Regexp o
|
135
|
+
@emitter.scalar o.inspect, nil, '!ruby/regexp', false, false, Nodes::Scalar::ANY
|
136
|
+
end
|
137
|
+
|
138
|
+
def visit_DateTime o
|
139
|
+
formatted = format_time o.to_time
|
140
|
+
tag = '!ruby/object:DateTime'
|
141
|
+
@emitter.scalar formatted, nil, tag, false, false, Nodes::Scalar::ANY
|
142
|
+
end
|
143
|
+
|
144
|
+
def visit_Time o
|
145
|
+
formatted = format_time o
|
146
|
+
@emitter.scalar formatted, nil, nil, true, false, Nodes::Scalar::ANY
|
147
|
+
end
|
148
|
+
|
149
|
+
def visit_Rational o
|
150
|
+
@emitter.start_mapping(nil, '!ruby/object:Rational', false, Nodes::Mapping::BLOCK)
|
151
|
+
|
152
|
+
[
|
153
|
+
'denominator', o.denominator.to_s,
|
154
|
+
'numerator', o.numerator.to_s
|
155
|
+
].each do |m|
|
156
|
+
@emitter.scalar m, nil, nil, true, false, Nodes::Scalar::ANY
|
157
|
+
end
|
158
|
+
|
159
|
+
@emitter.end_mapping
|
160
|
+
end
|
161
|
+
|
162
|
+
def visit_Complex o
|
163
|
+
@emitter.start_mapping(nil, '!ruby/object:Complex', false, Nodes::Mapping::BLOCK)
|
164
|
+
|
165
|
+
['real', o.real.to_s, 'image', o.imag.to_s].each do |m|
|
166
|
+
@emitter.scalar m, nil, nil, true, false, Nodes::Scalar::ANY
|
167
|
+
end
|
168
|
+
|
169
|
+
@emitter.end_mapping
|
170
|
+
end
|
171
|
+
|
172
|
+
def visit_Integer o
|
173
|
+
@emitter.scalar o.to_s, nil, nil, true, false, Nodes::Scalar::ANY
|
174
|
+
end
|
175
|
+
alias :visit_TrueClass :visit_Integer
|
176
|
+
alias :visit_FalseClass :visit_Integer
|
177
|
+
alias :visit_Date :visit_Integer
|
178
|
+
|
179
|
+
def visit_Float o
|
180
|
+
if o.nan?
|
181
|
+
@emitter.scalar '.nan', nil, nil, true, false, Nodes::Scalar::ANY
|
182
|
+
elsif o.infinite?
|
183
|
+
@emitter.scalar((o.infinite? > 0 ? '.inf' : '-.inf'),
|
184
|
+
nil, nil, true, false, Nodes::Scalar::ANY)
|
185
|
+
else
|
186
|
+
@emitter.scalar o.to_s, nil, nil, true, false, Nodes::Scalar::ANY
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def visit_String o
|
191
|
+
plain = false
|
192
|
+
quote = false
|
193
|
+
style = Nodes::Scalar::ANY
|
194
|
+
|
195
|
+
if o.index("\x00") || o.count("^ -~\t\r\n").fdiv(o.length) > 0.3
|
196
|
+
str = [o].pack('m').chomp
|
197
|
+
tag = '!binary' # FIXME: change to below when syck is removed
|
198
|
+
#tag = 'tag:yaml.org,2002:binary'
|
199
|
+
style = Nodes::Scalar::LITERAL
|
200
|
+
else
|
201
|
+
str = o
|
202
|
+
tag = nil
|
203
|
+
quote = !(String === @ss.tokenize(o))
|
204
|
+
plain = !quote
|
205
|
+
end
|
206
|
+
|
207
|
+
ivars = find_ivars o
|
208
|
+
|
209
|
+
if ivars.empty?
|
210
|
+
@emitter.scalar str, nil, tag, plain, quote, style
|
211
|
+
else
|
212
|
+
@emitter.start_mapping nil, '!str', false, Nodes::Mapping::BLOCK
|
213
|
+
@emitter.scalar 'str', nil, nil, true, false, Nodes::Scalar::ANY
|
214
|
+
@emitter.scalar str, nil, tag, plain, quote, style
|
215
|
+
|
216
|
+
dump_ivars o
|
217
|
+
|
218
|
+
@emitter.end_mapping
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
def visit_Class o
|
223
|
+
raise TypeError, "can't dump anonymous class #{o.class}"
|
224
|
+
end
|
225
|
+
|
226
|
+
def visit_Range o
|
227
|
+
@emitter.start_mapping nil, '!ruby/range', false, Nodes::Mapping::BLOCK
|
228
|
+
['begin', o.begin, 'end', o.end, 'excl', o.exclude_end?].each do |m|
|
229
|
+
accept m
|
230
|
+
end
|
231
|
+
@emitter.end_mapping
|
232
|
+
end
|
233
|
+
|
234
|
+
def visit_Hash o
|
235
|
+
register(o, @emitter.start_mapping(nil, nil, true, Psych::Nodes::Mapping::BLOCK))
|
236
|
+
|
237
|
+
o.each do |k,v|
|
238
|
+
accept k
|
239
|
+
accept v
|
240
|
+
end
|
241
|
+
|
242
|
+
@emitter.end_mapping
|
243
|
+
end
|
244
|
+
|
245
|
+
def visit_Psych_Set o
|
246
|
+
register(o, @emitter.start_mapping(nil, '!set', false, Psych::Nodes::Mapping::BLOCK))
|
247
|
+
|
248
|
+
o.each do |k,v|
|
249
|
+
accept k
|
250
|
+
accept v
|
251
|
+
end
|
252
|
+
|
253
|
+
@emitter.end_mapping
|
254
|
+
end
|
255
|
+
|
256
|
+
def visit_Array o
|
257
|
+
register o, @emitter.start_sequence(nil, nil, true, Nodes::Sequence::BLOCK)
|
258
|
+
o.each { |c| accept c }
|
259
|
+
@emitter.end_sequence
|
260
|
+
end
|
261
|
+
|
262
|
+
def visit_NilClass o
|
263
|
+
@emitter.scalar('', nil, 'tag:yaml.org,2002:null', false, false, Nodes::Scalar::ANY)
|
264
|
+
end
|
265
|
+
|
266
|
+
def visit_Symbol o
|
267
|
+
@emitter.scalar ":#{o}", nil, nil, true, false, Nodes::Scalar::ANY
|
268
|
+
end
|
269
|
+
|
270
|
+
private
|
271
|
+
def format_time time
|
272
|
+
formatted = time.strftime("%Y-%m-%d %H:%M:%S.%9N")
|
273
|
+
if time.utc?
|
274
|
+
formatted += "Z"
|
275
|
+
else
|
276
|
+
zone = time.strftime('%z')
|
277
|
+
formatted += " #{zone[0,3]}:#{zone[3,5]}"
|
278
|
+
end
|
279
|
+
formatted
|
280
|
+
end
|
281
|
+
|
282
|
+
# FIXME: remove this method once "to_yaml_properties" is removed
|
283
|
+
def find_ivars target
|
284
|
+
loc = target.method(:to_yaml_properties).source_location.first
|
285
|
+
unless loc.start_with?(Psych::DEPRECATED) || loc.end_with?('rubytypes.rb')
|
286
|
+
if $VERBOSE
|
287
|
+
warn "#{loc}: to_yaml_properties is deprecated, please implement \"encode_with(coder)\""
|
288
|
+
end
|
289
|
+
return target.to_yaml_properties
|
290
|
+
end
|
291
|
+
|
292
|
+
target.instance_variables
|
293
|
+
end
|
294
|
+
|
295
|
+
def register target, yaml_obj
|
296
|
+
@st[target.object_id] = yaml_obj
|
297
|
+
yaml_obj
|
298
|
+
end
|
299
|
+
|
300
|
+
def dump_coder o
|
301
|
+
tag = Psych.dump_tags[o.class]
|
302
|
+
unless tag
|
303
|
+
klass = o.class == Object ? nil : o.class.name
|
304
|
+
tag = ['!ruby/object', klass].compact.join(':')
|
305
|
+
end
|
306
|
+
|
307
|
+
c = Psych::Coder.new(tag)
|
308
|
+
o.encode_with(c)
|
309
|
+
emit_coder c
|
310
|
+
end
|
311
|
+
|
312
|
+
def emit_coder c
|
313
|
+
case c.type
|
314
|
+
when :scalar
|
315
|
+
@emitter.scalar c.scalar, nil, c.tag, c.tag.nil?, false, Nodes::Scalar::ANY
|
316
|
+
when :seq
|
317
|
+
@emitter.start_sequence nil, c.tag, c.tag.nil?, Nodes::Sequence::BLOCK
|
318
|
+
c.seq.each do |thing|
|
319
|
+
accept thing
|
320
|
+
end
|
321
|
+
@emitter.end_sequence
|
322
|
+
when :map
|
323
|
+
@emitter.start_mapping nil, c.tag, c.implicit, c.style
|
324
|
+
c.map.each do |k,v|
|
325
|
+
@emitter.scalar k, nil, nil, true, false, Nodes::Scalar::ANY
|
326
|
+
accept v
|
327
|
+
end
|
328
|
+
@emitter.end_mapping
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
def dump_ivars target
|
333
|
+
ivars = find_ivars target
|
334
|
+
|
335
|
+
ivars.each do |iv|
|
336
|
+
@emitter.scalar("#{iv.to_s.sub(/^@/, '')}", nil, nil, true, false, Nodes::Scalar::ANY)
|
337
|
+
accept target.instance_variable_get(iv)
|
338
|
+
end
|
339
|
+
end
|
340
|
+
end
|
341
|
+
end
|
342
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'stringio'
|
3
|
+
require 'tempfile'
|
4
|
+
require 'date'
|
5
|
+
|
6
|
+
module Psych
|
7
|
+
class TestCase < MiniTest::Unit::TestCase
|
8
|
+
#
|
9
|
+
# Convert between Psych and the object to verify correct parsing and
|
10
|
+
# emitting
|
11
|
+
#
|
12
|
+
def assert_to_yaml( obj, yaml )
|
13
|
+
assert_equal( obj, Psych::load( yaml ) )
|
14
|
+
assert_equal( obj, Psych::parse( yaml ).transform )
|
15
|
+
assert_equal( obj, Psych::load( obj.psych_to_yaml ) )
|
16
|
+
assert_equal( obj, Psych::parse( obj.psych_to_yaml ).transform )
|
17
|
+
assert_equal( obj, Psych::load(
|
18
|
+
obj.psych_to_yaml(
|
19
|
+
:UseVersion => true, :UseHeader => true, :SortKeys => true
|
20
|
+
)
|
21
|
+
))
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
# Test parser only
|
26
|
+
#
|
27
|
+
def assert_parse_only( obj, yaml )
|
28
|
+
assert_equal( obj, Psych::load( yaml ) )
|
29
|
+
assert_equal( obj, Psych::parse( yaml ).transform )
|
30
|
+
end
|
31
|
+
|
32
|
+
def assert_cycle( obj )
|
33
|
+
v = Visitors::YAMLTree.new
|
34
|
+
v << obj
|
35
|
+
assert_equal(obj, Psych.load(v.tree.to_yaml))
|
36
|
+
assert_equal( obj, Psych::load(Psych.dump(obj)))
|
37
|
+
assert_equal( obj, Psych::load( obj.psych_to_yaml ) )
|
38
|
+
end
|
39
|
+
|
40
|
+
#
|
41
|
+
# Make a time with the time zone
|
42
|
+
#
|
43
|
+
def mktime( year, mon, day, hour, min, sec, usec, zone = "Z" )
|
44
|
+
usec = Rational(usec.to_s) * 1000000
|
45
|
+
val = Time::utc( year.to_i, mon.to_i, day.to_i, hour.to_i, min.to_i, sec.to_i, usec )
|
46
|
+
if zone != "Z"
|
47
|
+
hour = zone[0,3].to_i * 3600
|
48
|
+
min = zone[3,2].to_i * 60
|
49
|
+
ofs = (hour + min)
|
50
|
+
val = Time.at( val.tv_sec - ofs, val.tv_nsec / 1000.0 )
|
51
|
+
end
|
52
|
+
return val
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
require 'psych'
|
58
|
+
|
59
|
+
# FIXME: remove this when syck is removed
|
60
|
+
o = Object.new
|
61
|
+
a = o.method(:psych_to_yaml)
|
62
|
+
b = o.method(:to_yaml)
|
63
|
+
raise "psych should define to_yaml" unless a == b
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require_relative '../helper'
|
2
|
+
|
3
|
+
module Psych
|
4
|
+
module JSON
|
5
|
+
class TestStream < TestCase
|
6
|
+
def setup
|
7
|
+
@io = StringIO.new
|
8
|
+
@stream = Psych::JSON::Stream.new(@io)
|
9
|
+
@stream.start
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_explicit_documents
|
13
|
+
@io = StringIO.new
|
14
|
+
@stream = Psych::JSON::Stream.new(@io)
|
15
|
+
@stream.start
|
16
|
+
|
17
|
+
@stream.push({ 'foo' => 'bar' })
|
18
|
+
|
19
|
+
assert !@stream.finished?, 'stream not finished'
|
20
|
+
@stream.finish
|
21
|
+
assert @stream.finished?, 'stream finished'
|
22
|
+
|
23
|
+
assert_match(/^---/, @io.string)
|
24
|
+
assert_match(/\.\.\.$/, @io.string)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_null
|
28
|
+
@stream.push(nil)
|
29
|
+
assert_match(/^--- null/, @io.string)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_string
|
33
|
+
@stream.push "foo"
|
34
|
+
assert_match(/(['"])foo\1/, @io.string)
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_symbol
|
38
|
+
@stream.push :foo
|
39
|
+
assert_match(/(['"])foo\1/, @io.string)
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_int
|
43
|
+
@stream.push 10
|
44
|
+
assert_match(/^--- 10/, @io.string)
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_float
|
48
|
+
@stream.push 1.2
|
49
|
+
assert_match(/^--- 1.2/, @io.string)
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_hash
|
53
|
+
hash = { 'one' => 'two' }
|
54
|
+
@stream.push hash
|
55
|
+
|
56
|
+
json = @io.string
|
57
|
+
assert_match(/}$/, json)
|
58
|
+
assert_match(/^--- \{/, json)
|
59
|
+
assert_match(/['"]one['"]/, json)
|
60
|
+
assert_match(/['"]two['"]/, json)
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_list_to_json
|
64
|
+
list = %w{ one two }
|
65
|
+
@stream.push list
|
66
|
+
|
67
|
+
json = @io.string
|
68
|
+
assert_match(/]$/, json)
|
69
|
+
assert_match(/^--- \[/, json)
|
70
|
+
assert_match(/['"]one['"]/, json)
|
71
|
+
assert_match(/['"]two['"]/, json)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|