psych 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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