psych 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. data/.autotest +18 -0
  2. data/.gemtest +0 -0
  3. data/CHANGELOG.rdoc +3 -0
  4. data/Manifest.txt +87 -0
  5. data/README.rdoc +50 -0
  6. data/Rakefile +66 -0
  7. data/ext/psych/emitter.c +517 -0
  8. data/ext/psych/emitter.h +8 -0
  9. data/ext/psych/extconf.rb +22 -0
  10. data/ext/psych/parser.c +384 -0
  11. data/ext/psych/parser.h +6 -0
  12. data/ext/psych/psych.c +34 -0
  13. data/ext/psych/psych.h +20 -0
  14. data/ext/psych/to_ruby.c +41 -0
  15. data/ext/psych/to_ruby.h +8 -0
  16. data/ext/psych/yaml_tree.c +24 -0
  17. data/ext/psych/yaml_tree.h +8 -0
  18. data/lib/psych.rb +263 -0
  19. data/lib/psych/coder.rb +94 -0
  20. data/lib/psych/core_ext.rb +39 -0
  21. data/lib/psych/deprecated.rb +82 -0
  22. data/lib/psych/handler.rb +221 -0
  23. data/lib/psych/json.rb +6 -0
  24. data/lib/psych/json/ruby_events.rb +19 -0
  25. data/lib/psych/json/stream.rb +15 -0
  26. data/lib/psych/json/tree_builder.rb +12 -0
  27. data/lib/psych/json/yaml_events.rb +29 -0
  28. data/lib/psych/nodes.rb +77 -0
  29. data/lib/psych/nodes/alias.rb +18 -0
  30. data/lib/psych/nodes/document.rb +60 -0
  31. data/lib/psych/nodes/mapping.rb +56 -0
  32. data/lib/psych/nodes/node.rb +52 -0
  33. data/lib/psych/nodes/scalar.rb +67 -0
  34. data/lib/psych/nodes/sequence.rb +81 -0
  35. data/lib/psych/nodes/stream.rb +37 -0
  36. data/lib/psych/omap.rb +4 -0
  37. data/lib/psych/parser.rb +47 -0
  38. data/lib/psych/scalar_scanner.rb +105 -0
  39. data/lib/psych/set.rb +4 -0
  40. data/lib/psych/stream.rb +36 -0
  41. data/lib/psych/streaming.rb +22 -0
  42. data/lib/psych/tree_builder.rb +94 -0
  43. data/lib/psych/visitors.rb +6 -0
  44. data/lib/psych/visitors/depth_first.rb +26 -0
  45. data/lib/psych/visitors/emitter.rb +44 -0
  46. data/lib/psych/visitors/json_tree.rb +21 -0
  47. data/lib/psych/visitors/to_ruby.rb +267 -0
  48. data/lib/psych/visitors/visitor.rb +19 -0
  49. data/lib/psych/visitors/yaml_tree.rb +373 -0
  50. data/test/psych/helper.rb +63 -0
  51. data/test/psych/json/test_stream.rb +109 -0
  52. data/test/psych/nodes/test_enumerable.rb +43 -0
  53. data/test/psych/test_alias_and_anchor.rb +26 -0
  54. data/test/psych/test_array.rb +19 -0
  55. data/test/psych/test_boolean.rb +36 -0
  56. data/test/psych/test_class.rb +17 -0
  57. data/test/psych/test_coder.rb +184 -0
  58. data/test/psych/test_date_time.rb +17 -0
  59. data/test/psych/test_deprecated.rb +210 -0
  60. data/test/psych/test_document.rb +46 -0
  61. data/test/psych/test_emitter.rb +94 -0
  62. data/test/psych/test_encoding.rb +179 -0
  63. data/test/psych/test_engine_manager.rb +57 -0
  64. data/test/psych/test_exception.rb +39 -0
  65. data/test/psych/test_hash.rb +30 -0
  66. data/test/psych/test_json_tree.rb +65 -0
  67. data/test/psych/test_merge_keys.rb +72 -0
  68. data/test/psych/test_nil.rb +18 -0
  69. data/test/psych/test_null.rb +19 -0
  70. data/test/psych/test_object.rb +27 -0
  71. data/test/psych/test_omap.rb +68 -0
  72. data/test/psych/test_parser.rb +297 -0
  73. data/test/psych/test_psych.rb +168 -0
  74. data/test/psych/test_scalar.rb +11 -0
  75. data/test/psych/test_scalar_scanner.rb +69 -0
  76. data/test/psych/test_serialize_subclasses.rb +38 -0
  77. data/test/psych/test_set.rb +49 -0
  78. data/test/psych/test_stream.rb +49 -0
  79. data/test/psych/test_string.rb +49 -0
  80. data/test/psych/test_struct.rb +51 -0
  81. data/test/psych/test_symbol.rb +17 -0
  82. data/test/psych/test_to_yaml_properties.rb +63 -0
  83. data/test/psych/test_tree_builder.rb +79 -0
  84. data/test/psych/test_yaml.rb +1256 -0
  85. data/test/psych/visitors/test_depth_first.rb +49 -0
  86. data/test/psych/visitors/test_emitter.rb +144 -0
  87. data/test/psych/visitors/test_to_ruby.rb +325 -0
  88. data/test/psych/visitors/test_yaml_tree.rb +155 -0
  89. metadata +232 -0
@@ -0,0 +1,210 @@
1
+ require 'psych/helper'
2
+
3
+ module Psych
4
+ class TestDeprecated < TestCase
5
+ def teardown
6
+ Psych.domain_types.clear
7
+ end
8
+
9
+ class QuickEmitter
10
+ attr_reader :name
11
+ attr_reader :value
12
+
13
+ def initialize
14
+ @name = 'hello!!'
15
+ @value = 'Friday!'
16
+ end
17
+
18
+ def to_yaml opts = {}
19
+ Psych.quick_emit object_id, opts do |out|
20
+ out.map taguri, to_yaml_style do |map|
21
+ map.add 'name', @name
22
+ map.add 'value', nil
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ def setup
29
+ @qe = QuickEmitter.new
30
+ end
31
+
32
+ def test_quick_emit
33
+ qe2 = Psych.load @qe.to_yaml
34
+ assert_equal @qe.name, qe2.name
35
+ assert_instance_of QuickEmitter, qe2
36
+ assert_nil qe2.value
37
+ end
38
+
39
+ def test_recursive_quick_emit
40
+ hash = { :qe => @qe }
41
+ hash2 = Psych.load Psych.dump hash
42
+ qe = hash2[:qe]
43
+
44
+ assert_equal @qe.name, qe.name
45
+ assert_instance_of QuickEmitter, qe
46
+ assert_nil qe.value
47
+ end
48
+
49
+ class QuickEmitterEncodeWith
50
+ attr_reader :name
51
+ attr_reader :value
52
+
53
+ def initialize
54
+ @name = 'hello!!'
55
+ @value = 'Friday!'
56
+ end
57
+
58
+ def encode_with coder
59
+ coder.map do |map|
60
+ map.add 'name', @name
61
+ map.add 'value', nil
62
+ end
63
+ end
64
+
65
+ def to_yaml opts = {}
66
+ raise
67
+ end
68
+ end
69
+
70
+ ###
71
+ # An object that defines both to_yaml and encode_with should only call
72
+ # encode_with.
73
+ def test_recursive_quick_emit_encode_with
74
+ qeew = QuickEmitterEncodeWith.new
75
+ hash = { :qe => qeew }
76
+ hash2 = Psych.load Psych.dump hash
77
+ qe = hash2[:qe]
78
+
79
+ assert_equal qeew.name, qe.name
80
+ assert_instance_of QuickEmitterEncodeWith, qe
81
+ assert_nil qe.value
82
+ end
83
+
84
+ class YamlInit
85
+ attr_reader :name
86
+ attr_reader :value
87
+
88
+ def initialize
89
+ @name = 'hello!!'
90
+ @value = 'Friday!'
91
+ end
92
+
93
+ def yaml_initialize tag, vals
94
+ vals.each { |ivar, val| instance_variable_set "@#{ivar}", 'TGIF!' }
95
+ end
96
+ end
97
+
98
+ def test_yaml_initialize
99
+ hash = { :yi => YamlInit.new }
100
+ hash2 = Psych.load Psych.dump hash
101
+ yi = hash2[:yi]
102
+
103
+ assert_equal 'TGIF!', yi.name
104
+ assert_equal 'TGIF!', yi.value
105
+ assert_instance_of YamlInit, yi
106
+ end
107
+
108
+ class YamlInitAndInitWith
109
+ attr_reader :name
110
+ attr_reader :value
111
+
112
+ def initialize
113
+ @name = 'shaners'
114
+ @value = 'Friday!'
115
+ end
116
+
117
+ def init_with coder
118
+ coder.map.each { |ivar, val| instance_variable_set "@#{ivar}", 'TGIF!' }
119
+ end
120
+
121
+ def yaml_initialize tag, vals
122
+ raise
123
+ end
124
+ end
125
+
126
+ ###
127
+ # An object that implements both yaml_initialize and init_with should not
128
+ # receive the yaml_initialize call.
129
+ def test_yaml_initialize_and_init_with
130
+ hash = { :yi => YamlInitAndInitWith.new }
131
+ hash2 = Psych.load Psych.dump hash
132
+ yi = hash2[:yi]
133
+
134
+ assert_equal 'TGIF!', yi.name
135
+ assert_equal 'TGIF!', yi.value
136
+ assert_instance_of YamlInitAndInitWith, yi
137
+ end
138
+
139
+ def test_coder_scalar
140
+ coder = Psych::Coder.new 'foo'
141
+ coder.scalar('tag', 'some string', :plain)
142
+ assert_equal 'tag', coder.tag
143
+ assert_equal 'some string', coder.scalar
144
+ assert_equal :scalar, coder.type
145
+ end
146
+
147
+ class YamlAs
148
+ yaml_as 'helloworld'
149
+ end
150
+
151
+ def test_yaml_as
152
+ assert_match(/helloworld/, Psych.dump(YamlAs.new))
153
+ end
154
+
155
+ def test_ruby_type
156
+ types = []
157
+ appender = lambda { |*args| types << args }
158
+
159
+ Psych.add_ruby_type('foo', &appender)
160
+ Psych.load <<-eoyml
161
+ - !ruby.yaml.org,2002/foo bar
162
+ eoyml
163
+
164
+ assert_equal [["tag:ruby.yaml.org,2002:foo", "bar"]], types
165
+ end
166
+
167
+ def test_detect_implicit
168
+ assert_equal '', Psych.detect_implicit(nil)
169
+ assert_equal '', Psych.detect_implicit(Object.new)
170
+ assert_equal '', Psych.detect_implicit(1.2)
171
+ assert_equal 'null', Psych.detect_implicit('')
172
+ assert_equal 'string', Psych.detect_implicit('foo')
173
+ end
174
+
175
+ def test_private_type
176
+ types = []
177
+ Psych.add_private_type('foo') { |*args| types << args }
178
+ Psych.load <<-eoyml
179
+ - !x-private:foo bar
180
+ eoyml
181
+
182
+ assert_equal [["x-private:foo", "bar"]], types
183
+ end
184
+
185
+ def test_tagurize
186
+ assert_nil Psych.tagurize nil
187
+ assert_equal Psych, Psych.tagurize(Psych)
188
+ assert_equal 'tag:yaml.org,2002:foo', Psych.tagurize('foo')
189
+ end
190
+
191
+ def test_read_type_class
192
+ things = Psych.read_type_class 'tag:yaml.org,2002:int:Psych::TestDeprecated::QuickEmitter', Object
193
+ assert_equal 'int', things.first
194
+ assert_equal Psych::TestDeprecated::QuickEmitter, things.last
195
+ end
196
+
197
+ def test_read_type_class_no_class
198
+ things = Psych.read_type_class 'tag:yaml.org,2002:int', Object
199
+ assert_equal 'int', things.first
200
+ assert_equal Object, things.last
201
+ end
202
+
203
+ def test_object_maker
204
+ thing = Psych.object_maker(Object, { 'a' => 'b', 'c' => 'd' })
205
+ assert_instance_of(Object, thing)
206
+ assert_equal 'b', thing.instance_variable_get(:@a)
207
+ assert_equal 'd', thing.instance_variable_get(:@c)
208
+ end
209
+ end
210
+ end
@@ -0,0 +1,46 @@
1
+ require 'psych/helper'
2
+
3
+ module Psych
4
+ class TestDocument < TestCase
5
+ def setup
6
+ super
7
+ @stream = Psych.parse_stream(<<-eoyml)
8
+ %YAML 1.1
9
+ %TAG ! tag:tenderlovemaking.com,2009:
10
+ --- !fun
11
+ eoyml
12
+ @doc = @stream.children.first
13
+ end
14
+
15
+ def test_parse_tag
16
+ assert_equal([['!', 'tag:tenderlovemaking.com,2009:']],
17
+ @doc.tag_directives)
18
+ end
19
+
20
+ def test_emit_tag
21
+ assert_match('%TAG ! tag:tenderlovemaking.com,2009:', @stream.to_yaml)
22
+ end
23
+
24
+ def test_emit_multitag
25
+ @doc.tag_directives << ['!!', 'foo.com,2009:']
26
+ yaml = @stream.to_yaml
27
+ assert_match('%TAG ! tag:tenderlovemaking.com,2009:', yaml)
28
+ assert_match('%TAG !! foo.com,2009:', yaml)
29
+ end
30
+
31
+ def test_emit_bad_tag
32
+ assert_raises(RuntimeError) do
33
+ @doc.tag_directives = [['!']]
34
+ @stream.to_yaml
35
+ end
36
+ end
37
+
38
+ def test_parse_version
39
+ assert_equal([1,1], @doc.version)
40
+ end
41
+
42
+ def test_emit_version
43
+ assert_match('%YAML 1.1', @stream.to_yaml)
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,94 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'psych/helper'
4
+
5
+ module Psych
6
+ class TestEmitter < TestCase
7
+ def setup
8
+ super
9
+ @out = StringIO.new('')
10
+ @emitter = Psych::Emitter.new @out
11
+ end
12
+
13
+ def test_line_width
14
+ assert_equal 0, @emitter.line_width
15
+ assert_equal 10, @emitter.line_width = 10
16
+ assert_equal 10, @emitter.line_width
17
+ end
18
+
19
+ def test_set_canonical
20
+ @emitter.canonical = true
21
+ assert_equal true, @emitter.canonical
22
+
23
+ @emitter.canonical = false
24
+ assert_equal false, @emitter.canonical
25
+ end
26
+
27
+ def test_indentation_set
28
+ assert_equal 2, @emitter.indentation
29
+ @emitter.indentation = 5
30
+ assert_equal 5, @emitter.indentation
31
+ end
32
+
33
+ def test_emit_utf_8
34
+ @emitter.start_stream Psych::Nodes::Stream::UTF8
35
+ @emitter.start_document [], [], false
36
+ @emitter.scalar '日本語', nil, nil, false, true, 1
37
+ @emitter.end_document true
38
+ @emitter.end_stream
39
+ assert_match('日本語', @out.string)
40
+ end
41
+
42
+ def test_start_stream_arg_error
43
+ assert_raises(TypeError) do
44
+ @emitter.start_stream 'asdfasdf'
45
+ end
46
+ end
47
+
48
+ def test_start_doc_arg_error
49
+ @emitter.start_stream Psych::Nodes::Stream::UTF8
50
+
51
+ [
52
+ [nil, [], false],
53
+ [[nil, nil], [], false],
54
+ [[], 'foo', false],
55
+ [[], ['foo'], false],
56
+ [[], [nil,nil], false],
57
+ ].each do |args|
58
+ assert_raises(TypeError) do
59
+ @emitter.start_document(*args)
60
+ end
61
+ end
62
+ end
63
+
64
+ def test_scalar_arg_error
65
+ @emitter.start_stream Psych::Nodes::Stream::UTF8
66
+ @emitter.start_document [], [], false
67
+
68
+ [
69
+ [:foo, nil, nil, false, true, 1],
70
+ ['foo', Object.new, nil, false, true, 1],
71
+ ['foo', nil, Object.new, false, true, 1],
72
+ ['foo', nil, nil, false, true, :foo],
73
+ [nil, nil, nil, false, true, 1],
74
+ ].each do |args|
75
+ assert_raises(TypeError) do
76
+ @emitter.scalar(*args)
77
+ end
78
+ end
79
+ end
80
+
81
+ def test_start_sequence_arg_error
82
+ @emitter.start_stream Psych::Nodes::Stream::UTF8
83
+ @emitter.start_document [], [], false
84
+
85
+ assert_raises(TypeError) do
86
+ @emitter.start_sequence(nil, Object.new, true, 1)
87
+ end
88
+
89
+ assert_raises(TypeError) do
90
+ @emitter.start_sequence(nil, nil, true, :foo)
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,179 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'psych/helper'
4
+
5
+ module Psych
6
+ class TestEncoding < TestCase
7
+ class EncodingCatcher < Handler
8
+ attr_reader :strings
9
+ def initialize
10
+ @strings = []
11
+ end
12
+
13
+ (Handler.instance_methods(true) -
14
+ Object.instance_methods).each do |m|
15
+ class_eval %{
16
+ def #{m} *args
17
+ @strings += args.flatten.find_all { |a|
18
+ String === a
19
+ }
20
+ end
21
+ }
22
+ end
23
+ end
24
+
25
+ def setup
26
+ super
27
+ @buffer = StringIO.new
28
+ @handler = EncodingCatcher.new
29
+ @parser = Psych::Parser.new @handler
30
+ @utf8 = Encoding.find('UTF-8')
31
+ @emitter = Psych::Emitter.new @buffer
32
+ end
33
+
34
+ def test_emit_alias
35
+ @emitter.start_stream Psych::Parser::UTF8
36
+ @emitter.start_document [], [], true
37
+ e = assert_raises(RuntimeError) do
38
+ @emitter.alias 'ドラえもん'.encode('EUC-JP')
39
+ end
40
+ assert_match(/alias value/, e.message)
41
+ end
42
+
43
+ def test_start_mapping
44
+ foo = 'foo'
45
+ bar = 'バー'
46
+
47
+ @emitter.start_stream Psych::Parser::UTF8
48
+ @emitter.start_document [], [], true
49
+ @emitter.start_mapping(
50
+ foo.encode('Shift_JIS'),
51
+ bar.encode('UTF-16LE'),
52
+ false, Nodes::Sequence::ANY)
53
+ @emitter.end_mapping
54
+ @emitter.end_document false
55
+ @emitter.end_stream
56
+
57
+ @parser.parse @buffer.string
58
+ assert_encodings @utf8, @handler.strings
59
+ assert_equal [foo, bar], @handler.strings
60
+ end
61
+
62
+ def test_start_sequence
63
+ foo = 'foo'
64
+ bar = 'バー'
65
+
66
+ @emitter.start_stream Psych::Parser::UTF8
67
+ @emitter.start_document [], [], true
68
+ @emitter.start_sequence(
69
+ foo.encode('Shift_JIS'),
70
+ bar.encode('UTF-16LE'),
71
+ false, Nodes::Sequence::ANY)
72
+ @emitter.end_sequence
73
+ @emitter.end_document false
74
+ @emitter.end_stream
75
+
76
+ @parser.parse @buffer.string
77
+ assert_encodings @utf8, @handler.strings
78
+ assert_equal [foo, bar], @handler.strings
79
+ end
80
+
81
+ def test_doc_tag_encoding
82
+ key = '鍵'
83
+ @emitter.start_stream Psych::Parser::UTF8
84
+ @emitter.start_document(
85
+ [1, 1],
86
+ [['!'.encode('EUC-JP'), key.encode('EUC-JP')]],
87
+ true
88
+ )
89
+ @emitter.scalar 'foo', nil, nil, true, false, Nodes::Scalar::ANY
90
+ @emitter.end_document false
91
+ @emitter.end_stream
92
+
93
+ @parser.parse @buffer.string
94
+ assert_encodings @utf8, @handler.strings
95
+ assert_equal key, @handler.strings[1]
96
+ end
97
+
98
+ def test_emitter_encoding
99
+ str = "壁に耳あり、障子に目あり"
100
+ thing = Psych.load Psych.dump str.encode('EUC-JP')
101
+ assert_equal str, thing
102
+ end
103
+
104
+ def test_default_internal
105
+ before = Encoding.default_internal
106
+
107
+ Encoding.default_internal = 'EUC-JP'
108
+
109
+ str = "壁に耳あり、障子に目あり"
110
+ yaml = "--- #{str}"
111
+ assert_equal @utf8, str.encoding
112
+
113
+ @parser.parse str
114
+ assert_encodings Encoding.find('EUC-JP'), @handler.strings
115
+ assert_equal str, @handler.strings.first.encode('UTF-8')
116
+ ensure
117
+ Encoding.default_internal = before
118
+ end
119
+
120
+ def test_scalar
121
+ @parser.parse("--- a")
122
+ assert_encodings @utf8, @handler.strings
123
+ end
124
+
125
+ def test_alias
126
+ @parser.parse(<<-eoyml)
127
+ %YAML 1.1
128
+ ---
129
+ !!seq [
130
+ !!str "Without properties",
131
+ &A !!str "Anchored",
132
+ !!str "Tagged",
133
+ *A,
134
+ !!str "",
135
+ ]
136
+ eoyml
137
+ assert_encodings @utf8, @handler.strings
138
+ end
139
+
140
+ def test_list_anchor
141
+ list = %w{ a b }
142
+ list << list
143
+ @parser.parse(Psych.dump(list))
144
+ assert_encodings @utf8, @handler.strings
145
+ end
146
+
147
+ def test_map_anchor
148
+ h = {}
149
+ h['a'] = h
150
+ @parser.parse(Psych.dump(h))
151
+ assert_encodings @utf8, @handler.strings
152
+ end
153
+
154
+ def test_map_tag
155
+ @parser.parse(<<-eoyml)
156
+ %YAML 1.1
157
+ ---
158
+ !!map { a : b }
159
+ eoyml
160
+ assert_encodings @utf8, @handler.strings
161
+ end
162
+
163
+ def test_doc_tag
164
+ @parser.parse(<<-eoyml)
165
+ %YAML 1.1
166
+ %TAG ! tag:tenderlovemaking.com,2009:
167
+ --- !fun
168
+ eoyml
169
+ assert_encodings @utf8, @handler.strings
170
+ end
171
+
172
+ private
173
+ def assert_encodings encoding, strings
174
+ strings.each do |str|
175
+ assert_equal encoding, str.encoding, str
176
+ end
177
+ end
178
+ end
179
+ end