~ubuntu-branches/ubuntu/quantal/ruby1.9.1/quantal

« back to all changes in this revision

Viewing changes to test/yaml/test_yaml.rb

  • Committer: Bazaar Package Importer
  • Author(s): Lucas Nussbaum
  • Date: 2010-07-31 17:08:39 UTC
  • mfrom: (1.1.4 upstream) (8.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20100731170839-j034dmpdqt1cc4p6
Tags: 1.9.2~svn28788-1
* New release based on upstream snapshot from the 1.9.2 branch,
  after 1.9.2 RC2. That branch is (supposed to be) binary-compatible
  with the 1.9.1 branch.
  + Builds fine on i386. Closes: #580852.
* Upgrade to Standards-Version: 3.9.1. No changes needed.
* Updated generated incs.
* Patches that still need work:
  + Unclear status, need more investigation:
   090729_fix_Makefile_deps.dpatch
   090803_exclude_rdoc.dpatch
   203_adjust_base_of_search_path.dpatch
   902_define_YAML_in_yaml_stringio.rb.dpatch
   919_common.mk_tweaks.dpatch
   931_libruby_suffix.dpatch
   940_test_thread_mutex_sync_shorter.dpatch
  + Maybe not needed anymore, keeping but not applying.
   102_skip_test_copy_stream.dpatch (test doesn't block anymore?)
   104_skip_btest_io.dpatch (test doesn't block anymore?)
   201_gem_prelude.dpatch (we don't use that rubygems anyway?)
   202_gem_default_dir.dpatch (we don't use that rubygems anyway?)
   940_test_file_exhaustive_fails_as_root.dpatch
   940_test_priority_fails.dpatch
   100518_load_libc_libm.dpatch
* Add disable-tests.diff: disable some tests that cause failures on FreeBSD.
  Closes: #590002, #543805, #542927.
* However, many new failures on FreeBSD. Since that version is still an
  improvement, add the check that makes test suite failures non-fatal on
  FreeBSD again. That still needs to be investigated.
* Re-add 903_skip_base_ruby_check.dpatch
* Add build-dependency on ruby1.8 and drop all pre-generated files.

Show diffs side-by-side

added added

removed removed

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