jvyaml 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,98 @@
1
+ require 'test/unit'
2
+ require 'jvyaml'
3
+
4
+ class JvYAMLMoreUnitTests < Test::Unit::TestCase
5
+ def test_one
6
+ bad_text = %{
7
+ A
8
+ R}
9
+ dump = ::JvYAML.dump({'text' => bad_text})
10
+ loaded = ::JvYAML.load(dump)
11
+ assert_equal bad_text, loaded['text']
12
+ end
13
+
14
+ def test_two
15
+ # JRUBY-1903
16
+ assert_equal(<<YAML_OUT, ::JvYAML::JvYAMLi::Scalar.new("tag:yaml.org,2002:str","foobar",'').to_str)
17
+ --- foobar
18
+ YAML_OUT
19
+
20
+ assert_equal(<<YAML_OUT, ::JvYAML::JvYAMLi::Scalar.new("tag:yaml.org,2002:str","foobar",'').to_s)
21
+ --- foobar
22
+ YAML_OUT
23
+
24
+ assert_equal(<<YAML_OUT, ::JvYAML::JvYAMLi::Seq.new("tag:yaml.org,2002:seq",[::JvYAML::JvYAMLi::Scalar.new("tag:yaml.org,2002:str","foobar",'')],'').to_str)
25
+ --- [foobar]
26
+
27
+ YAML_OUT
28
+
29
+ assert_equal(<<YAML_OUT, ::JvYAML::JvYAMLi::Seq.new("tag:yaml.org,2002:seq",[::JvYAML::JvYAMLi::Scalar.new("tag:yaml.org,2002:str","foobar",'')],'').to_s)
30
+ --- [foobar]
31
+
32
+ YAML_OUT
33
+
34
+ assert_equal(<<YAML_OUT, ::JvYAML::JvYAMLi::Map.new("tag:yaml.org,2002:map",{::JvYAML::JvYAMLi::Scalar.new("tag:yaml.org,2002:str","a",'') => ::JvYAML::JvYAMLi::Scalar.new("tag:yaml.org,2002:str","b",'')},'').to_str)
35
+ --- {a: b}
36
+
37
+ YAML_OUT
38
+
39
+ assert_equal(<<YAML_OUT, ::JvYAML::JvYAMLi::Map.new("tag:yaml.org,2002:map",{::JvYAML::JvYAMLi::Scalar.new("tag:yaml.org,2002:str","a",'') => ::JvYAML::JvYAMLi::Scalar.new("tag:yaml.org,2002:str","b",'')},'').to_s)
40
+ --- {a: b}
41
+
42
+ YAML_OUT
43
+ end
44
+
45
+ def test_four
46
+ # Test Scanner exception
47
+ old_debug, $DEBUG = $DEBUG, true
48
+ begin
49
+ JvYAML.load("!<abc")
50
+ assert false
51
+ rescue Exception => e
52
+ assert e.to_s =~ /0:5\(5\)/
53
+ ensure
54
+ $DEBUG = old_debug
55
+ end
56
+
57
+ # Test Parser exception
58
+ old_debug, $DEBUG = $DEBUG, true
59
+ begin
60
+ JvYAML.load("%YAML 2.0")
61
+ assert false
62
+ rescue Exception => e
63
+ assert e.to_s =~ /0:0\(0\)/ && e.to_s =~ /0:9\(9\)/
64
+ ensure
65
+ $DEBUG = old_debug
66
+ end
67
+
68
+ # Test Composer exception
69
+ old_debug, $DEBUG = $DEBUG, true
70
+ begin
71
+ JvYAML.load("*foobar")
72
+ assert false
73
+ rescue Exception => e
74
+ assert e.to_s =~ /0:0\(0\)/ && e.to_s =~ /0:7\(7\)/
75
+ ensure
76
+ $DEBUG = old_debug
77
+ end
78
+ end
79
+
80
+ def test_five
81
+ hash = { "element" => "value", "array" => [ { "nested_element" => "nested_value" } ] }
82
+ ex1 = <<EXPECTED
83
+ ---
84
+ array:
85
+ - nested_element: nested_value
86
+ element: value
87
+ EXPECTED
88
+
89
+ ex2 = <<EXPECTED
90
+ ---
91
+ element: value
92
+ array:
93
+ - nested_element: nested_value
94
+ EXPECTED
95
+
96
+ assert [ex1, ex2].include?(hash.to_jvyaml), "was: #{hash.to_jvyaml.inspect}"
97
+ end
98
+ end
@@ -0,0 +1,1277 @@
1
+ require 'test/unit'
2
+ require 'jvyaml'
3
+
4
+ # [ruby-core:01946]
5
+ module YAML_Tests
6
+ StructTest = Struct::new( :c )
7
+ end
8
+
9
+ class YAML_Unit_Tests < Test::Unit::TestCase
10
+ #
11
+ # Convert between YAML and the object to verify correct parsing and
12
+ # emitting
13
+ #
14
+ def assert_to_jvyaml( obj, yaml )
15
+ assert_equal( obj, JvYAML::load( yaml ) )
16
+ assert_equal( obj, JvYAML::parse( yaml ).transform )
17
+ assert_equal( obj, JvYAML::load( obj.to_jvyaml ) )
18
+ assert_equal( obj, JvYAML::parse( obj.to_jvyaml ).transform )
19
+ assert_equal( obj, JvYAML::load(
20
+ obj.to_jvyaml( :UseVersion => true, :UseHeader => true, :SortKeys => true )
21
+ ) )
22
+ end
23
+
24
+ #
25
+ # Test parser only
26
+ #
27
+ def assert_parse_only( obj, yaml )
28
+ assert_equal( obj, JvYAML::load( yaml ) )
29
+ assert_equal( obj, JvYAML::parse( yaml ).transform )
30
+ end
31
+
32
+ def assert_cycle( obj )
33
+ assert_equal( obj, JvYAML::load( obj.to_jvyaml ) )
34
+ end
35
+
36
+ def assert_path_segments( path, segments )
37
+ JvYAML::YPath.each_path( path ) { |choice|
38
+ assert_equal( choice.segments, segments.shift )
39
+ }
40
+ assert_equal( segments.length, 0, "Some segments leftover: #{ segments.inspect }" )
41
+ end
42
+
43
+ #
44
+ # Make a time with the time zone
45
+ #
46
+ def mktime( year, mon, day, hour, min, sec, usec, zone = "Z" )
47
+ usec = usec.to_s.to_f * 1000000
48
+ val = Time::utc( year.to_i, mon.to_i, day.to_i, hour.to_i, min.to_i, sec.to_i, usec )
49
+ if zone != "Z"
50
+ hour = zone[0,3].to_i * 3600
51
+ min = zone[3,2].to_i * 60
52
+ ofs = (hour + min)
53
+ val = Time.at( val.to_f - ofs )
54
+ end
55
+ return val
56
+ end
57
+
58
+ #
59
+ # Tests modified from 00basic.t in YAML.pm
60
+ #
61
+ def test_basic_map
62
+ # Simple map
63
+ assert_parse_only(
64
+ { 'one' => 'foo', 'three' => 'baz', 'two' => 'bar' }, <<EOY
65
+ one: foo
66
+ two: bar
67
+ three: baz
68
+ EOY
69
+ )
70
+ end
71
+
72
+ def test_basic_strings
73
+ # Common string types
74
+ assert_cycle("x")
75
+ assert_cycle(":x")
76
+ assert_cycle(":")
77
+ assert_parse_only(
78
+ { 1 => 'simple string', 2 => 42, 3 => '1 Single Quoted String',
79
+ 4 => 'YAML\'s Double "Quoted" String', 5 => "A block\n with several\n lines.\n",
80
+ 6 => "A \"chomped\" block", 7 => "A folded\n string\n", 8 => ": started string" },
81
+ <<EOY
82
+ 1: simple string
83
+ 2: 42
84
+ 3: '1 Single Quoted String'
85
+ 4: "YAML's Double \\\"Quoted\\\" String"
86
+ 5: |
87
+ A block
88
+ with several
89
+ lines.
90
+ 6: |-
91
+ A "chomped" block
92
+ 7: >
93
+ A
94
+ folded
95
+ string
96
+ 8: ": started string"
97
+ EOY
98
+ )
99
+ end
100
+
101
+ #
102
+ # Test the specification examples
103
+ # - Many examples have been changes because of whitespace problems that
104
+ # caused the two to be inequivalent, or keys to be sorted wrong
105
+ #
106
+
107
+ def test_spec_simple_implicit_sequence
108
+ # Simple implicit sequence
109
+ assert_to_jvyaml(
110
+ [ 'Mark McGwire', 'Sammy Sosa', 'Ken Griffey' ], <<EOY
111
+ - Mark McGwire
112
+ - Sammy Sosa
113
+ - Ken Griffey
114
+ EOY
115
+ )
116
+ end
117
+
118
+ def test_spec_simple_implicit_map
119
+ # Simple implicit map
120
+ assert_to_jvyaml(
121
+ { 'hr' => 65, 'avg' => 0.278, 'rbi' => 147 }, <<EOY
122
+ avg: 0.278
123
+ hr: 65
124
+ rbi: 147
125
+ EOY
126
+ )
127
+ end
128
+
129
+ def test_spec_simple_map_with_nested_sequences
130
+ # Simple mapping with nested sequences
131
+ assert_to_jvyaml(
132
+ { 'american' =>
133
+ [ 'Boston Red Sox', 'Detroit Tigers', 'New York Yankees' ],
134
+ 'national' =>
135
+ [ 'New York Mets', 'Chicago Cubs', 'Atlanta Braves' ] }, <<EOY
136
+ american:
137
+ - Boston Red Sox
138
+ - Detroit Tigers
139
+ - New York Yankees
140
+ national:
141
+ - New York Mets
142
+ - Chicago Cubs
143
+ - Atlanta Braves
144
+ EOY
145
+ )
146
+ end
147
+
148
+ def test_spec_simple_sequence_with_nested_map
149
+ # Simple sequence with nested map
150
+ assert_to_jvyaml(
151
+ [
152
+ {'name' => 'Mark McGwire', 'hr' => 65, 'avg' => 0.278},
153
+ {'name' => 'Sammy Sosa', 'hr' => 63, 'avg' => 0.288}
154
+ ], <<EOY
155
+ -
156
+ avg: 0.278
157
+ hr: 65
158
+ name: Mark McGwire
159
+ -
160
+ avg: 0.288
161
+ hr: 63
162
+ name: Sammy Sosa
163
+ EOY
164
+ )
165
+ end
166
+
167
+ def test_spec_sequence_of_sequences
168
+ # Simple sequence with inline sequences
169
+ assert_parse_only(
170
+ [
171
+ [ 'name', 'hr', 'avg' ],
172
+ [ 'Mark McGwire', 65, 0.278 ],
173
+ [ 'Sammy Sosa', 63, 0.288 ]
174
+ ], <<EOY
175
+ - [ name , hr , avg ]
176
+ - [ Mark McGwire , 65 , 0.278 ]
177
+ - [ Sammy Sosa , 63 , 0.288 ]
178
+ EOY
179
+ )
180
+ end
181
+
182
+ def test_spec_mapping_of_mappings
183
+ # Simple map with inline maps
184
+ assert_parse_only(
185
+ { 'Mark McGwire' =>
186
+ { 'hr' => 65, 'avg' => 0.278 },
187
+ 'Sammy Sosa' =>
188
+ { 'hr' => 63, 'avg' => 0.288 }
189
+ }, <<EOY
190
+ Mark McGwire: {hr: 65, avg: 0.278}
191
+ Sammy Sosa: {hr: 63,
192
+ avg: 0.288}
193
+ EOY
194
+ )
195
+ end
196
+
197
+ def test_ambiguous_comments
198
+ # [ruby-talk:88012]
199
+ assert_to_jvyaml( "Call the method #dave", <<EOY )
200
+ --- "Call the method #dave"
201
+ EOY
202
+ end
203
+
204
+ def test_spec_nested_comments
205
+ # Map and sequences with comments
206
+ assert_parse_only(
207
+ { 'hr' => [ 'Mark McGwire', 'Sammy Sosa' ],
208
+ 'rbi' => [ 'Sammy Sosa', 'Ken Griffey' ] }, <<EOY
209
+ hr: # 1998 hr ranking
210
+ - Mark McGwire
211
+ - Sammy Sosa
212
+ rbi:
213
+ # 1998 rbi ranking
214
+ - Sammy Sosa
215
+ - Ken Griffey
216
+ EOY
217
+ )
218
+ end
219
+
220
+ def test_spec_anchors_and_aliases
221
+ # Anchors and aliases
222
+ assert_parse_only(
223
+ { 'hr' =>
224
+ [ 'Mark McGwire', 'Sammy Sosa' ],
225
+ 'rbi' =>
226
+ [ 'Sammy Sosa', 'Ken Griffey' ] }, <<EOY
227
+ hr:
228
+ - Mark McGwire
229
+ # Name "Sammy Sosa" scalar SS
230
+ - &SS Sammy Sosa
231
+ rbi:
232
+ # So it can be referenced later.
233
+ - *SS
234
+ - Ken Griffey
235
+ EOY
236
+ )
237
+
238
+ assert_to_jvyaml(
239
+ [{"arrival"=>"EDI", "departure"=>"LAX", "fareref"=>"DOGMA", "currency"=>"GBP"}, {"arrival"=>"MEL", "departure"=>"SYD", "fareref"=>"MADF", "currency"=>"AUD"}, {"arrival"=>"MCO", "departure"=>"JFK", "fareref"=>"DFSF", "currency"=>"USD"}], <<EOY
240
+ -
241
+ &F fareref: DOGMA
242
+ &C currency: GBP
243
+ &D departure: LAX
244
+ &A arrival: EDI
245
+ - { *F: MADF, *C: AUD, *D: SYD, *A: MEL }
246
+ - { *F: DFSF, *C: USD, *D: JFK, *A: MCO }
247
+ EOY
248
+ )
249
+
250
+ assert_to_jvyaml(
251
+ {"ALIASES"=>["fareref", "currency", "departure", "arrival"], "FARES"=>[{"arrival"=>"EDI", "departure"=>"LAX", "fareref"=>"DOGMA", "currency"=>"GBP"}, {"arrival"=>"MEL", "departure"=>"SYD", "fareref"=>"MADF", "currency"=>"AUD"}, {"arrival"=>"MCO", "departure"=>"JFK", "fareref"=>"DFSF", "currency"=>"USD"}]}, <<EOY
252
+ ---
253
+ ALIASES: [&f fareref, &c currency, &d departure, &a arrival]
254
+ FARES:
255
+ - *f: DOGMA
256
+ *c: GBP
257
+ *d: LAX
258
+ *a: EDI
259
+
260
+ - *f: MADF
261
+ *c: AUD
262
+ *d: SYD
263
+ *a: MEL
264
+
265
+ - *f: DFSF
266
+ *c: USD
267
+ *d: JFK
268
+ *a: MCO
269
+
270
+ EOY
271
+ )
272
+
273
+ end
274
+
275
+ def test_spec_mapping_between_sequences
276
+ # Complex key #1
277
+ dj = Date.new( 2001, 7, 23 )
278
+ assert_parse_only(
279
+ { [ 'Detroit Tigers', 'Chicago Cubs' ] => [ Date.new( 2001, 7, 23 ) ],
280
+ [ 'New York Yankees', 'Atlanta Braves' ] => [ Date.new( 2001, 7, 2 ), Date.new( 2001, 8, 12 ), Date.new( 2001, 8, 14 ) ] }, <<EOY
281
+ ? # PLAY SCHEDULE
282
+ - Detroit Tigers
283
+ - Chicago Cubs
284
+ :
285
+ - 2001-07-23
286
+
287
+ ? [ New York Yankees,
288
+ Atlanta Braves ]
289
+ : [ 2001-07-02, 2001-08-12,
290
+ 2001-08-14 ]
291
+ EOY
292
+ )
293
+
294
+ # Complex key #2
295
+ assert_parse_only(
296
+ { [ 'New York Yankees', 'Atlanta Braves' ] =>
297
+ [ Date.new( 2001, 7, 2 ), Date.new( 2001, 8, 12 ),
298
+ Date.new( 2001, 8, 14 ) ],
299
+ [ 'Detroit Tigers', 'Chicago Cubs' ] =>
300
+ [ Date.new( 2001, 7, 23 ) ]
301
+ }, <<EOY
302
+ ?
303
+ - New York Yankees
304
+ - Atlanta Braves
305
+ :
306
+ - 2001-07-02
307
+ - 2001-08-12
308
+ - 2001-08-14
309
+ ?
310
+ - Detroit Tigers
311
+ - Chicago Cubs
312
+ :
313
+ - 2001-07-23
314
+ EOY
315
+ )
316
+ end
317
+
318
+ def test_spec_sequence_key_shortcut
319
+ # Shortcut sequence map
320
+ assert_parse_only(
321
+ { 'invoice' => 34843, 'date' => Date.new( 2001, 1, 23 ),
322
+ 'bill-to' => 'Chris Dumars', 'product' =>
323
+ [ { 'item' => 'Super Hoop', 'quantity' => 1 },
324
+ { 'item' => 'Basketball', 'quantity' => 4 },
325
+ { 'item' => 'Big Shoes', 'quantity' => 1 } ] }, <<EOY
326
+ invoice: 34843
327
+ date : 2001-01-23
328
+ bill-to: Chris Dumars
329
+ product:
330
+ - item : Super Hoop
331
+ quantity: 1
332
+ - item : Basketball
333
+ quantity: 4
334
+ - item : Big Shoes
335
+ quantity: 1
336
+ EOY
337
+ )
338
+ end
339
+
340
+ def test_spec_sequence_in_sequence_shortcut
341
+ # Seq-in-seq
342
+ assert_parse_only( [ [ [ 'one', 'two', 'three' ] ] ], <<EOY )
343
+ - - - one
344
+ - two
345
+ - three
346
+ EOY
347
+ end
348
+
349
+ def test_spec_sequence_shortcuts
350
+ # Sequence shortcuts combined
351
+ assert_parse_only(
352
+ [
353
+ [
354
+ [ [ 'one' ] ],
355
+ [ 'two', 'three' ],
356
+ { 'four' => nil },
357
+ [ { 'five' => [ 'six' ] } ],
358
+ [ 'seven' ]
359
+ ],
360
+ [ 'eight', 'nine' ]
361
+ ], <<EOY )
362
+ - - - - one
363
+ - - two
364
+ - three
365
+ - four:
366
+ - - five:
367
+ - six
368
+ - - seven
369
+ - - eight
370
+ - nine
371
+ EOY
372
+ end
373
+
374
+ def test_spec_single_literal
375
+ # Literal scalar block
376
+ assert_parse_only( [ "\\/|\\/|\n/ | |_\n" ], <<EOY )
377
+ - |
378
+ \\/|\\/|
379
+ / | |_
380
+ EOY
381
+ end
382
+
383
+ def test_spec_single_folded
384
+ # Folded scalar block
385
+ assert_parse_only(
386
+ [ "Mark McGwire's year was crippled by a knee injury.\n" ], <<EOY
387
+ - >
388
+ Mark McGwire\'s
389
+ year was crippled
390
+ by a knee injury.
391
+ EOY
392
+ )
393
+ end
394
+
395
+ def test_spec_preserve_indent
396
+ # Preserve indented spaces
397
+ assert_parse_only(
398
+ "Sammy Sosa completed another fine season with great stats.\n\n 63 Home Runs\n 0.288 Batting Average\n\nWhat a year!\n", <<EOY
399
+ --- >
400
+ Sammy Sosa completed another
401
+ fine season with great stats.
402
+
403
+ 63 Home Runs
404
+ 0.288 Batting Average
405
+
406
+ What a year!
407
+ EOY
408
+ )
409
+ end
410
+
411
+ def test_spec_indentation_determines_scope
412
+ assert_parse_only(
413
+ { 'name' => 'Mark McGwire', 'accomplishment' => "Mark set a major league home run record in 1998.\n",
414
+ 'stats' => "65 Home Runs\n0.278 Batting Average\n" }, <<EOY
415
+ name: Mark McGwire
416
+ accomplishment: >
417
+ Mark set a major league
418
+ home run record in 1998.
419
+ stats: |
420
+ 65 Home Runs
421
+ 0.278 Batting Average
422
+ EOY
423
+ )
424
+ end
425
+
426
+ def test_spec_multiline_scalars
427
+ # Multiline flow scalars
428
+ assert_parse_only(
429
+ { 'plain' => 'This unquoted scalar spans many lines.',
430
+ 'quoted' => "So does this quoted scalar.\n" }, <<EOY
431
+ plain: This unquoted
432
+ scalar spans
433
+ many lines.
434
+ quoted: "\\
435
+ So does this quoted
436
+ scalar.\\n"
437
+ EOY
438
+ )
439
+ end
440
+
441
+ def test_spec_type_int
442
+ assert_parse_only(
443
+ { 'canonical' => 12345, 'decimal' => 12345, 'octal' => '014'.oct, 'hexadecimal' => '0xC'.hex }, <<EOY
444
+ canonical: 12345
445
+ decimal: +12,345
446
+ octal: 014
447
+ hexadecimal: 0xC
448
+ EOY
449
+ )
450
+ assert_parse_only(
451
+ { 'canonical' => 685230, 'decimal' => 685230, 'octal' => 02472256, 'hexadecimal' => 0x0A74AE, 'sexagesimal' => 685230 }, <<EOY)
452
+ canonical: 685230
453
+ decimal: +685,230
454
+ octal: 02472256
455
+ hexadecimal: 0x0A,74,AE
456
+ sexagesimal: 190:20:30
457
+ EOY
458
+ end
459
+
460
+ def test_spec_type_float
461
+ assert_parse_only(
462
+ { 'canonical' => 1230.15, 'exponential' => 1230.15, 'fixed' => 1230.15,
463
+ 'negative infinity' => -1.0/0.0 }, <<EOY)
464
+ canonical: 1.23015e+3
465
+ exponential: 12.3015e+02
466
+ fixed: 1,230.15
467
+ negative infinity: -.inf
468
+ EOY
469
+ nan = JvYAML::load( <<EOY )
470
+ not a number: .NaN
471
+ EOY
472
+ assert( nan['not a number'].nan? )
473
+ end
474
+
475
+ def test_spec_type_misc
476
+ assert_parse_only(
477
+ { nil => nil, true => true, false => false, 'string' => '12345' }, <<EOY
478
+ null: ~
479
+ true: yes
480
+ false: no
481
+ string: '12345'
482
+ EOY
483
+ )
484
+ end
485
+
486
+ def test_spec_complex_invoice
487
+ # Complex invoice type
488
+ id001 = { 'given' => 'Chris', 'family' => 'Dumars', 'address' =>
489
+ { 'lines' => "458 Walkman Dr.\nSuite #292\n", 'city' => 'Royal Oak',
490
+ 'state' => 'MI', 'postal' => 48046 } }
491
+ assert_parse_only(
492
+ { 'invoice' => 34843, 'date' => Date.new( 2001, 1, 23 ),
493
+ 'bill-to' => id001, 'ship-to' => id001, 'product' =>
494
+ [ { 'sku' => 'BL394D', 'quantity' => 4,
495
+ 'description' => 'Basketball', 'price' => 450.00 },
496
+ { 'sku' => 'BL4438H', 'quantity' => 1,
497
+ 'description' => 'Super Hoop', 'price' => 2392.00 } ],
498
+ 'tax' => 251.42, 'total' => 4443.52,
499
+ 'comments' => "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338.\n" }, <<EOY
500
+ invoice: 34843
501
+ date : 2001-01-23
502
+ bill-to: &id001
503
+ given : Chris
504
+ family : !str Dumars
505
+ address:
506
+ lines: |
507
+ 458 Walkman Dr.
508
+ Suite #292
509
+ city : Royal Oak
510
+ state : MI
511
+ postal : 48046
512
+ ship-to: *id001
513
+ product:
514
+ - !map
515
+ sku : BL394D
516
+ quantity : 4
517
+ description : Basketball
518
+ price : 450.00
519
+ - sku : BL4438H
520
+ quantity : 1
521
+ description : Super Hoop
522
+ price : 2392.00
523
+ tax : 251.42
524
+ total: 4443.52
525
+ comments: >
526
+ Late afternoon is best.
527
+ Backup contact is Nancy
528
+ Billsmer @ 338-4338.
529
+ EOY
530
+ )
531
+ end
532
+
533
+ def test_spec_log_file
534
+ doc_ct = 0
535
+ JvYAML::load_documents( <<EOY
536
+ ---
537
+ Time: 2001-11-23 15:01:42 -05:00
538
+ User: ed
539
+ Warning: >
540
+ This is an error message
541
+ for the log file
542
+ ---
543
+ Time: 2001-11-23 15:02:31 -05:00
544
+ User: ed
545
+ Warning: >
546
+ A slightly different error
547
+ message.
548
+ ---
549
+ Date: 2001-11-23 15:03:17 -05:00
550
+ User: ed
551
+ Fatal: >
552
+ Unknown variable "bar"
553
+ Stack:
554
+ - file: TopClass.py
555
+ line: 23
556
+ code: |
557
+ x = MoreObject("345\\n")
558
+ - file: MoreClass.py
559
+ line: 58
560
+ code: |-
561
+ foo = bar
562
+ EOY
563
+ ) { |doc|
564
+ case doc_ct
565
+ when 0
566
+ assert_equal( doc, { 'Time' => mktime( 2001, 11, 23, 15, 01, 42, 00, "-05:00" ),
567
+ 'User' => 'ed', 'Warning' => "This is an error message for the log file\n" } )
568
+ when 1
569
+ assert_equal( doc, { 'Time' => mktime( 2001, 11, 23, 15, 02, 31, 00, "-05:00" ),
570
+ 'User' => 'ed', 'Warning' => "A slightly different error message.\n" } )
571
+ when 2
572
+ assert_equal( doc, { 'Date' => mktime( 2001, 11, 23, 15, 03, 17, 00, "-05:00" ),
573
+ 'User' => 'ed', 'Fatal' => "Unknown variable \"bar\"\n",
574
+ 'Stack' => [
575
+ { 'file' => 'TopClass.py', 'line' => 23, 'code' => "x = MoreObject(\"345\\n\")\n" },
576
+ { 'file' => 'MoreClass.py', 'line' => 58, 'code' => "foo = bar" } ] } )
577
+ end
578
+ doc_ct += 1
579
+ }
580
+ assert_equal( doc_ct, 3 )
581
+ end
582
+
583
+ def test_spec_root_fold
584
+ y = JvYAML::load( <<EOY
585
+ --- >
586
+ This YAML stream contains a single text value.
587
+ The next stream is a log file - a sequence of
588
+ log entries. Adding an entry to the log is a
589
+ simple matter of appending it at the end.
590
+ EOY
591
+ )
592
+ assert_equal( y, "This YAML stream contains a single text value. The next stream is a log file - a sequence of log entries. Adding an entry to the log is a simple matter of appending it at the end.\n" )
593
+ end
594
+
595
+ def test_spec_root_mapping
596
+ y = JvYAML::load( <<EOY
597
+ # This stream is an example of a top-level mapping.
598
+ invoice : 34843
599
+ date : 2001-01-23
600
+ total : 4443.52
601
+ EOY
602
+ )
603
+ assert_equal( y, { 'invoice' => 34843, 'date' => Date.new( 2001, 1, 23 ), 'total' => 4443.52 } )
604
+ end
605
+
606
+ def test_spec_oneline_docs
607
+ doc_ct = 0
608
+ JvYAML::load_documents( <<EOY
609
+ # The following is a sequence of three documents.
610
+ # The first contains an empty mapping, the second
611
+ # an empty sequence, and the last an empty string.
612
+ --- {}
613
+ --- [ ]
614
+ --- ''
615
+ EOY
616
+ ) { |doc|
617
+ case doc_ct
618
+ when 0
619
+ assert_equal( doc, {} )
620
+ when 1
621
+ assert_equal( doc, [] )
622
+ when 2
623
+ assert_equal( doc, '' )
624
+ end
625
+ doc_ct += 1
626
+ }
627
+ assert_equal( doc_ct, 3 )
628
+ end
629
+
630
+ def _test_spec_domain_prefix
631
+ customer_proc = proc { |type, val|
632
+ if Hash === val
633
+ scheme, domain, type = type.split( ':', 3 )
634
+ val['type'] = "domain #{type}"
635
+ val
636
+ else
637
+ raise ArgumentError, "Not a Hash in domain.tld,2002/invoice: " + val.inspect
638
+ end
639
+ }
640
+ JvYAML.add_domain_type( "domain.tld,2002", 'invoice', &customer_proc )
641
+ JvYAML.add_domain_type( "domain.tld,2002", 'customer', &customer_proc )
642
+ assert_parse_only( { "invoice"=> { "customers"=> [ { "given"=>"Chris", "type"=>"domain customer", "family"=>"Dumars" } ], "type"=>"domain invoice" } }, <<EOY
643
+ # 'http://domain.tld,2002/invoice' is some type family.
644
+ invoice: !domain.tld,2002/^invoice
645
+ # 'seq' is shorthand for 'http://yaml.org/seq'.
646
+ # This does not effect '^customer' below
647
+ # because it is does not specify a prefix.
648
+ customers: !seq
649
+ # '^customer' is shorthand for the full
650
+ # notation 'http://domain.tld,2002/customer'.
651
+ - !^customer
652
+ given : Chris
653
+ family : Dumars
654
+ EOY
655
+ )
656
+ end
657
+
658
+ def test_spec_throwaway
659
+ assert_parse_only(
660
+ {"this"=>"contains three lines of text.\nThe third one starts with a\n# character. This isn't a comment.\n"}, <<EOY
661
+ ### These are four throwaway comment ###
662
+
663
+ ### lines (the second line is empty). ###
664
+ this: | # Comments may trail lines.
665
+ contains three lines of text.
666
+ The third one starts with a
667
+ # character. This isn't a comment.
668
+
669
+ # These are three throwaway comment
670
+ # lines (the first line is empty).
671
+ EOY
672
+ )
673
+ end
674
+
675
+ def test_spec_force_implicit
676
+ # Force implicit
677
+ assert_parse_only(
678
+ { 'integer' => 12, 'also int' => 12, 'string' => '12' }, <<EOY
679
+ integer: 12
680
+ also int: ! "12"
681
+ string: !str 12
682
+ EOY
683
+ )
684
+ end
685
+
686
+ def _test_spec_private_types
687
+ doc_ct = 0
688
+ JvYAML::parse_documents( <<EOY
689
+ # Private types are per-document.
690
+ ---
691
+ pool: !!ball
692
+ number: 8
693
+ color: black
694
+ ---
695
+ bearing: !!ball
696
+ material: steel
697
+ EOY
698
+ ) { |doc|
699
+ case doc_ct
700
+ when 0
701
+ assert_equal( doc['pool'].type_id, 'x-private:ball' )
702
+ assert_equal( doc['pool'].transform.value, { 'number' => 8, 'color' => 'black' } )
703
+ when 1
704
+ assert_equal( doc['bearing'].type_id, 'x-private:ball' )
705
+ assert_equal( doc['bearing'].transform.value, { 'material' => 'steel' } )
706
+ end
707
+ doc_ct += 1
708
+ }
709
+ assert_equal( doc_ct, 2 )
710
+ end
711
+
712
+ def _test_spec_url_escaping
713
+ JvYAML.add_domain_type( "domain.tld,2002", "type0" ) { |type, val|
714
+ "ONE: #{val}"
715
+ }
716
+ JvYAML.add_domain_type( "domain.tld,2002", "type%30" ) { |type, val|
717
+ "TWO: #{val}"
718
+ }
719
+ assert_parse_only(
720
+ { 'same' => [ 'ONE: value', 'ONE: value' ], 'different' => [ 'TWO: value' ] }, <<EOY
721
+ same:
722
+ - !domain.tld,2002/type\\x30 value
723
+ - !domain.tld,2002/type0 value
724
+ different: # As far as the YAML parser is concerned
725
+ - !domain.tld,2002/type%30 value
726
+ EOY
727
+ )
728
+ end
729
+
730
+ def test_spec_override_anchor
731
+ # Override anchor
732
+ a001 = "The alias node below is a repeated use of this value.\n"
733
+ assert_parse_only(
734
+ { 'anchor' => 'This scalar has an anchor.', 'override' => a001, 'alias' => a001 }, <<EOY
735
+ anchor : &A001 This scalar has an anchor.
736
+ override : &A001 >
737
+ The alias node below is a
738
+ repeated use of this value.
739
+ alias : *A001
740
+ EOY
741
+ )
742
+ end
743
+
744
+ def _test_spec_explicit_families
745
+ JvYAML.add_domain_type( "somewhere.com,2002", 'type' ) { |type, val|
746
+ "SOMEWHERE: #{val}"
747
+ }
748
+ assert_parse_only(
749
+ { 'not-date' => '2002-04-28', 'picture' => "GIF89a\f\000\f\000\204\000\000\377\377\367\365\365\356\351\351\345fff\000\000\000\347\347\347^^^\363\363\355\216\216\216\340\340\340\237\237\237\223\223\223\247\247\247\236\236\236i^\020' \202\n\001\000;", 'hmm' => "SOMEWHERE: family above is short for\nhttp://somewhere.com/type\n" }, <<EOY
750
+ not-date: !str 2002-04-28
751
+ picture: !binary |
752
+ R0lGODlhDAAMAIQAAP//9/X
753
+ 17unp5WZmZgAAAOfn515eXv
754
+ Pz7Y6OjuDg4J+fn5OTk6enp
755
+ 56enmleECcgggoBADs=
756
+
757
+ hmm: !somewhere.com,2002/type |
758
+ family above is short for
759
+ http://somewhere.com/type
760
+ EOY
761
+ )
762
+ end
763
+
764
+ def _test_spec_application_family
765
+ # Testing the clarkevans.com graphs
766
+ JvYAML.add_domain_type( "clarkevans.com,2002", 'graph/shape' ) { |type, val|
767
+ if Array === val
768
+ val << "Shape Container"
769
+ val
770
+ else
771
+ raise ArgumentError, "Invalid graph of type #{val.class}: " + val.inspect
772
+ end
773
+ }
774
+ one_shape_proc = Proc.new { |type, val|
775
+ if Hash === val
776
+ type = type.split( /:/ )
777
+ val['TYPE'] = "Shape: #{type[2]}"
778
+ val
779
+ else
780
+ raise ArgumentError, "Invalid graph of type #{val.class}: " + val.inspect
781
+ end
782
+ }
783
+ JvYAML.add_domain_type( "clarkevans.com,2002", 'graph/circle', &one_shape_proc )
784
+ JvYAML.add_domain_type( "clarkevans.com,2002", 'graph/line', &one_shape_proc )
785
+ JvYAML.add_domain_type( "clarkevans.com,2002", 'graph/text', &one_shape_proc )
786
+ assert_parse_only(
787
+ [[{"radius"=>7, "center"=>{"x"=>73, "y"=>129}, "TYPE"=>"Shape: graph/circle"}, {"finish"=>{"x"=>89, "y"=>102}, "TYPE"=>"Shape: graph/line", "start"=>{"x"=>73, "y"=>129}}, {"TYPE"=>"Shape: graph/text", "value"=>"Pretty vector drawing.", "start"=>{"x"=>73, "y"=>129}, "color"=>16772795}, "Shape Container"]], <<EOY
788
+ - !clarkevans.com,2002/graph/^shape
789
+ - !^circle
790
+ center: &ORIGIN {x: 73, y: 129}
791
+ radius: 7
792
+ - !^line # !clarkevans.com,2002/graph/line
793
+ start: *ORIGIN
794
+ finish: { x: 89, y: 102 }
795
+ - !^text
796
+ start: *ORIGIN
797
+ color: 0xFFEEBB
798
+ value: Pretty vector drawing.
799
+ EOY
800
+ )
801
+ end
802
+
803
+ def test_spec_float_explicit
804
+ assert_parse_only(
805
+ [ 10.0, 10.0, 10.0, 10.0 ], <<EOY
806
+ # All entries in the sequence
807
+ # have the same type and value.
808
+ - 10.0
809
+ - !float 10
810
+ - !yaml.org,2002/^float '10'
811
+ - !yaml.org,2002/float "\\
812
+ 1\\
813
+ 0"
814
+ EOY
815
+ )
816
+ end
817
+
818
+ def test_spec_builtin_seq
819
+ # Assortment of sequences
820
+ assert_parse_only(
821
+ { 'empty' => [], 'in-line' => [ 'one', 'two', 'three', 'four', 'five' ],
822
+ 'nested' => [ 'First item in top sequence', [ 'Subordinate sequence entry' ],
823
+ "A multi-line sequence entry\n", 'Sixth item in top sequence' ] }, <<EOY
824
+ empty: []
825
+ in-line: [ one, two, three # May span lines,
826
+ , four, # indentation is
827
+ five ] # mostly ignored.
828
+ nested:
829
+ - First item in top sequence
830
+ -
831
+ - Subordinate sequence entry
832
+ - >
833
+ A multi-line
834
+ sequence entry
835
+ - Sixth item in top sequence
836
+ EOY
837
+ )
838
+ end
839
+
840
+ def test_spec_builtin_map
841
+ # Assortment of mappings
842
+ assert_parse_only(
843
+ { 'empty' => {}, 'in-line' => { 'one' => 1, 'two' => 2 },
844
+ 'spanning' => { 'one' => 1, 'two' => 2 },
845
+ 'nested' => { 'first' => 'First entry', 'second' =>
846
+ { 'key' => 'Subordinate mapping' }, 'third' =>
847
+ [ 'Subordinate sequence', {}, 'Previous mapping is empty.',
848
+ { 'A key' => 'value pair in a sequence.', 'A second' => 'key:value pair.' },
849
+ 'The previous entry is equal to the following one.',
850
+ { 'A key' => 'value pair in a sequence.', 'A second' => 'key:value pair.' } ],
851
+ 12.0 => 'This key is a float.', "?\n" => 'This key had to be protected.',
852
+ "\a" => 'This key had to be escaped.',
853
+ "This is a multi-line folded key\n" => "Whose value is also multi-line.\n",
854
+ [ 'This key', 'is a sequence' ] => [ 'With a sequence value.' ] } }, <<EOY
855
+
856
+ empty: {}
857
+ in-line: { one: 1, two: 2 }
858
+ spanning: { one: 1,
859
+ two: 2 }
860
+ nested:
861
+ first : First entry
862
+ second:
863
+ key: Subordinate mapping
864
+ third:
865
+ - Subordinate sequence
866
+ - { }
867
+ - Previous mapping is empty.
868
+ - A key: value pair in a sequence.
869
+ A second: key:value pair.
870
+ - The previous entry is equal to the following one.
871
+ -
872
+ A key: value pair in a sequence.
873
+ A second: key:value pair.
874
+ !float 12 : This key is a float.
875
+ ? >
876
+ ?
877
+ : This key had to be protected.
878
+ "\\a" : This key had to be escaped.
879
+ ? >
880
+ This is a
881
+ multi-line
882
+ folded key
883
+ : >
884
+ Whose value is
885
+ also multi-line.
886
+ ?
887
+ - This key
888
+ - is a sequence
889
+ :
890
+ - With a sequence value.
891
+ # The following parses correctly,
892
+ # but Ruby 1.6.* fails the comparison!
893
+ # ?
894
+ # This: key
895
+ # is a: mapping
896
+ # :
897
+ # with a: mapping value.
898
+ EOY
899
+ )
900
+ end
901
+
902
+ def test_spec_builtin_literal_blocks
903
+ # Assortment of literal scalar blocks
904
+ assert_parse_only(
905
+ {"both are equal to"=>" This has no newline.", "is equal to"=>"The \\ ' \" characters may be\nfreely used. Leading white\n space is significant.\n\nLine breaks are significant.\nThus this value contains one\nempty line and ends with a\nsingle line break, but does\nnot start with one.\n", "also written as"=>" This has no newline.", "indented and chomped"=>" This has no newline.", "empty"=>"", "literal"=>"The \\ ' \" characters may be\nfreely used. Leading white\n space is significant.\n\nLine breaks are significant.\nThus this value contains one\nempty line and ends with a\nsingle line break, but does\nnot start with one.\n"}, <<EOY
906
+ empty: |
907
+
908
+ literal: |
909
+ The \\ ' " characters may be
910
+ freely used. Leading white
911
+ space is significant.
912
+
913
+ Line breaks are significant.
914
+ Thus this value contains one
915
+ empty line and ends with a
916
+ single line break, but does
917
+ not start with one.
918
+
919
+ is equal to: "The \\ ' \\" characters may \\
920
+ be\\nfreely used. Leading white\\n space \\
921
+ is significant.\\n\\nLine breaks are \\
922
+ significant.\\nThus this value contains \\
923
+ one\\nempty line and ends with a\\nsingle \\
924
+ line break, but does\\nnot start with one.\\n"
925
+
926
+ # Comments may follow a nested
927
+ # scalar value. They must be
928
+ # less indented.
929
+
930
+ # Modifiers may be combined in any order.
931
+ indented and chomped: |2-
932
+ This has no newline.
933
+
934
+ also written as: |-2
935
+ This has no newline.
936
+
937
+ both are equal to: " This has no newline."
938
+ EOY
939
+ )
940
+
941
+ str1 = "This has one newline.\n"
942
+ str2 = "This has no newline."
943
+ str3 = "This has two newlines.\n\n"
944
+ assert_parse_only(
945
+ { 'clipped' => str1, 'same as "clipped" above' => str1,
946
+ 'stripped' => str2, 'same as "stripped" above' => str2,
947
+ 'kept' => str3, 'same as "kept" above' => str3 }, <<EOY
948
+ clipped: |
949
+ This has one newline.
950
+
951
+ same as "clipped" above: "This has one newline.\\n"
952
+
953
+ stripped: |-
954
+ This has no newline.
955
+
956
+ same as "stripped" above: "This has no newline."
957
+
958
+ kept: |+
959
+ This has two newlines.
960
+
961
+ same as "kept" above: "This has two newlines.\\n\\n"
962
+
963
+ EOY
964
+ )
965
+ end
966
+
967
+ def test_spec_span_single_quote
968
+ assert_parse_only( {"third"=>"a single quote ' must be escaped.", "second"=>"! : \\ etc. can be used freely.", "is same as"=>"this contains six spaces\nand one line break", "empty"=>"", "span"=>"this contains six spaces\nand one line break"}, <<EOY
969
+ empty: ''
970
+ second: '! : \\ etc. can be used freely.'
971
+ third: 'a single quote '' must be escaped.'
972
+ span: 'this contains
973
+ six spaces
974
+
975
+ and one
976
+ line break'
977
+ is same as: "this contains six spaces\\nand one line break"
978
+ EOY
979
+ )
980
+ end
981
+
982
+ def test_spec_span_double_quote
983
+ assert_parse_only( {"is equal to"=>"this contains four spaces", "third"=>"a \" or a \\ must be escaped.", "second"=>"! : etc. can be used freely.", "empty"=>"", "fourth"=>"this value ends with an LF.\n", "span"=>"this contains four spaces"}, <<EOY
984
+ empty: ""
985
+ second: "! : etc. can be used freely."
986
+ third: "a \\\" or a \\\\ must be escaped."
987
+ fourth: "this value ends with an LF.\\n"
988
+ span: "this contains
989
+ four \\
990
+ spaces"
991
+ is equal to: "this contains four spaces"
992
+ EOY
993
+ )
994
+ end
995
+
996
+ def test_spec_builtin_time
997
+ # Time
998
+ assert_parse_only(
999
+ { "space separated" => mktime( 2001, 12, 14, 21, 59, 43, ".00", "-05:00" ),
1000
+ "canonical" => mktime( 2001, 12, 15, 2, 59, 43, ".00" ),
1001
+ "date (noon UTC)" => Date.new( 2002, 12, 14),
1002
+ "valid iso8601" => mktime( 2001, 12, 14, 21, 59, 43, ".00", "-05:00" ) }, <<EOY
1003
+ canonical: 2001-12-15T02:59:43.0Z
1004
+ valid iso8601: 2001-12-14t21:59:43.00-05:00
1005
+ space separated: 2001-12-14 21:59:43.00 -05:00
1006
+ date (noon UTC): 2002-12-14
1007
+ EOY
1008
+ )
1009
+ end
1010
+
1011
+ def test_spec_builtin_binary
1012
+ arrow_gif = "GIF89a\f\000\f\000\204\000\000\377\377\367\365\365\356\351\351\345fff\000\000\000\347\347\347^^^\363\363\355\216\216\216\340\340\340\237\237\237\223\223\223\247\247\247\236\236\236iiiccc\243\243\243\204\204\204\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371!\376\016Made with GIMP\000,\000\000\000\000\f\000\f\000\000\005, \216\2010\236\343@\024\350i\020\304\321\212\010\034\317\200M$z\357\3770\205p\270\2601f\r\e\316\001\303\001\036\020' \202\n\001\000;"
1013
+ assert_parse_only(
1014
+ { 'canonical' => arrow_gif, 'base64' => arrow_gif,
1015
+ 'description' => "The binary value above is a tiny arrow encoded as a gif image.\n" }, <<EOY
1016
+ canonical: !binary "\\
1017
+ R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOf\\
1018
+ n515eXvPz7Y6OjuDg4J+fn5OTk6enp56enmlpaW\\
1019
+ NjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++\\
1020
+ f/++f/++f/++f/++f/++f/++f/++SH+Dk1hZGUg\\
1021
+ d2l0aCBHSU1QACwAAAAADAAMAAAFLCAgjoEwnuN\\
1022
+ AFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84Bww\\
1023
+ EeECcgggoBADs="
1024
+ base64: !binary |
1025
+ R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOf
1026
+ n515eXvPz7Y6OjuDg4J+fn5OTk6enp56enmlpaW
1027
+ NjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++
1028
+ f/++f/++f/++f/++f/++f/++f/++SH+Dk1hZGUg
1029
+ d2l0aCBHSU1QACwAAAAADAAMAAAFLCAgjoEwnuN
1030
+ AFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84Bww
1031
+ EeECcgggoBADs=
1032
+ description: >
1033
+ The binary value above is a tiny arrow
1034
+ encoded as a gif image.
1035
+ EOY
1036
+ )
1037
+ end
1038
+
1039
+ def test_ruby_regexp
1040
+ # Test Ruby regular expressions
1041
+ assert_to_jvyaml({'simple' => /a.b/, 'complex' => %r'\A"((?:[^"]|\")+)"',
1042
+ 'case-insensitive' => /George McFly/i }, <<EOY
1043
+ case-insensitive: !ruby/regexp "/George McFly/i"
1044
+ complex: !ruby/regexp "/\\\\A\\"((?:[^\\"]|\\\\\\")+)\\"/"
1045
+ simple: !ruby/regexp "/a.b/"
1046
+ EOY
1047
+ )
1048
+ end
1049
+
1050
+ #
1051
+ # Test of Ranges
1052
+ #
1053
+ def test_ranges
1054
+ # Simple numeric
1055
+ assert_to_jvyaml( 1..3, <<EOY )
1056
+ --- !ruby/range 1..3
1057
+ EOY
1058
+
1059
+ # Simple alphabetic
1060
+ assert_to_jvyaml( 'a'..'z', <<EOY )
1061
+ --- !ruby/range a..z
1062
+ EOY
1063
+
1064
+ # Float
1065
+ assert_to_jvyaml( 10.5...30.3, <<EOY )
1066
+ --- !ruby/range 10.5...30.3
1067
+ EOY
1068
+
1069
+ end
1070
+
1071
+ def test_ruby_struct
1072
+ # Ruby structures
1073
+ book_struct = Struct::new( "BookStruct", :author, :title, :year, :isbn )
1074
+ assert_to_jvyaml(
1075
+ [ book_struct.new( "Yukihiro Matsumoto", "Ruby in a Nutshell", 2002, "0-596-00214-9" ),
1076
+ book_struct.new( [ 'Dave Thomas', 'Andy Hunt' ], "The Pickaxe", 2002,
1077
+ book_struct.new( "This should be the ISBN", "but I have another struct here", 2002, "None" )
1078
+ ) ], <<EOY
1079
+ - !ruby/struct:BookStruct
1080
+ author: Yukihiro Matsumoto
1081
+ title: Ruby in a Nutshell
1082
+ year: 2002
1083
+ isbn: 0-596-00214-9
1084
+ - !ruby/struct:BookStruct
1085
+ author:
1086
+ - Dave Thomas
1087
+ - Andy Hunt
1088
+ title: The Pickaxe
1089
+ year: 2002
1090
+ isbn: !ruby/struct:BookStruct
1091
+ author: This should be the ISBN
1092
+ title: but I have another struct here
1093
+ year: 2002
1094
+ isbn: None
1095
+ EOY
1096
+ )
1097
+
1098
+ assert_to_jvyaml( YAML_Tests::StructTest.new( 123 ), <<EOY )
1099
+ --- !ruby/struct:YAML_Tests::StructTest
1100
+ c: 123
1101
+ EOY
1102
+
1103
+ end
1104
+
1105
+ def test_emitting_indicators
1106
+ assert_to_jvyaml( "Hi, from Object 1. You passed: please, pretty please", <<EOY
1107
+ --- "Hi, from Object 1. You passed: please, pretty please"
1108
+ EOY
1109
+ )
1110
+ end
1111
+
1112
+ #
1113
+ # Test the JvYAML::Stream class -- INACTIVE at the moment
1114
+ #
1115
+ def test_document
1116
+ y = JvYAML::Stream.new( :Indent => 2, :UseVersion => 0 )
1117
+ y.add(
1118
+ { 'hi' => 'hello', 'map' =>
1119
+ { 'good' => 'two' },
1120
+ 'time' => Time.now,
1121
+ 'try' => /^po(.*)$/,
1122
+ 'bye' => 'goodbye'
1123
+ }
1124
+ )
1125
+ y.add( { 'po' => 'nil', 'oper' => 90 } )
1126
+ y.add( { 'hi' => 'wow!', 'bye' => 'wow!' } )
1127
+ y.add( { [ 'Red Socks', 'Boston' ] => [ 'One', 'Two', 'Three' ] } )
1128
+ y.add( [ true, false, false ] )
1129
+ end
1130
+
1131
+ #
1132
+ # Test YPath choices parsing
1133
+ #
1134
+ def _test_ypath_parsing
1135
+ assert_path_segments( "/*/((one|three)/name|place)|//place",
1136
+ [ ["*", "one", "name"],
1137
+ ["*", "three", "name"],
1138
+ ["*", "place"],
1139
+ ["/", "place"] ]
1140
+ )
1141
+ end
1142
+
1143
+ #
1144
+ # Tests from Tanaka Akira on [ruby-core]
1145
+ #
1146
+ def test_akira
1147
+ # Commas in plain scalars [ruby-core:1066]
1148
+ assert_to_jvyaml(
1149
+ {"A"=>"A,","B"=>"B"}, <<EOY
1150
+ A: "A,"
1151
+ B: B
1152
+ EOY
1153
+ )
1154
+
1155
+ # Double-quoted keys [ruby-core:1069]
1156
+ assert_to_jvyaml(
1157
+ {"1"=>2, "2"=>3}, <<EOY
1158
+ '1': 2
1159
+ "2": 3
1160
+ EOY
1161
+ )
1162
+
1163
+ # Anchored mapping [ruby-core:1071]
1164
+ assert_to_jvyaml(
1165
+ [{"a"=>"b"}] * 2, <<EOY
1166
+ - &id001
1167
+ a: b
1168
+ - *id001
1169
+ EOY
1170
+ )
1171
+
1172
+ # Stress test [ruby-core:1071]
1173
+ # a = []; 1000.times { a << {"a"=>"b", "c"=>"d"} }
1174
+ # JvYAML::load( a.to_jvyaml )
1175
+
1176
+ end
1177
+
1178
+ #
1179
+ # Test Time.now cycle
1180
+ #
1181
+ def test_time_now_cycle
1182
+ #
1183
+ # From Minero Aoki [ruby-core:2305]
1184
+ #
1185
+ require 'yaml'
1186
+ t = Time.now
1187
+ 5.times do
1188
+ assert_cycle(t)
1189
+ end
1190
+ end
1191
+
1192
+ #
1193
+ # Test Range cycle
1194
+ #
1195
+ def test_range_cycle
1196
+ #
1197
+ # From Minero Aoki [ruby-core:02306]
1198
+ #
1199
+ assert_cycle("a".."z")
1200
+
1201
+ #
1202
+ # From Nobu Nakada [ruby-core:02311]
1203
+ #
1204
+ assert_cycle(0..1)
1205
+ assert_cycle(1.0e20 .. 2.0e20)
1206
+ assert_cycle("0".."1")
1207
+ assert_cycle(".."..."...")
1208
+ assert_cycle(".rb"..".pl")
1209
+ assert_cycle(".rb"...".pl")
1210
+ assert_cycle('"'...".")
1211
+ assert_cycle("'"...".")
1212
+ end
1213
+
1214
+ #
1215
+ # Circular references
1216
+ #
1217
+ def test_circular_references
1218
+ a = []; a[0] = a; a[1] = a
1219
+ inspect_str = "[[...], [...]]"
1220
+ assert_equal( inspect_str, JvYAML::load( a.to_jvyaml ).inspect )
1221
+ end
1222
+
1223
+ #
1224
+ # Test Symbol cycle
1225
+ #
1226
+ def test_symbol_cycle
1227
+ #
1228
+ # From Aaron Schrab [ruby-Bugs:2535]
1229
+ #
1230
+ assert_cycle(:"^foo")
1231
+ end
1232
+
1233
+ #
1234
+ # Test Numeric cycle
1235
+ #
1236
+ class NumericTest < Numeric
1237
+ def initialize(value)
1238
+ @value = value
1239
+ end
1240
+ def ==(other)
1241
+ @value == other.instance_eval{ @value }
1242
+ end
1243
+ end
1244
+ def test_numeric_cycle
1245
+ assert_cycle(1) # Fixnum
1246
+ assert_cycle(111111111111111111111111111111111) # Bignum
1247
+ assert_cycle(NumericTest.new(3)) # Subclass of Numeric
1248
+ end
1249
+
1250
+ #
1251
+ # Test empty map/seq in map cycle
1252
+ #
1253
+ def test_empty_map_key
1254
+ #
1255
+ # empty seq as key
1256
+ #
1257
+ o = JvYAML.load({[]=>""}.to_jvyaml)
1258
+ assert_equal(Hash, o.class)
1259
+ assert_equal([[]], o.keys)
1260
+
1261
+ #
1262
+ # empty map as key
1263
+ #
1264
+ o = JvYAML.load({{}=>""}.to_jvyaml)
1265
+ assert_equal(Hash, o.class)
1266
+ assert_equal([{}], o.keys)
1267
+ end
1268
+
1269
+ #
1270
+ # contributed by riley lynch [ruby-Bugs-8548]
1271
+ #
1272
+ def test_object_id_collision
1273
+ omap = JvYAML::Omap.new
1274
+ 1000.times { |i| omap["key_#{i}"] = { "value" => i } }
1275
+ raise "id collision in ordered map" if omap.to_jvyaml =~ /id\d+/
1276
+ end
1277
+ end