psych 2.0.14-java

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