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.
- data/.autotest +18 -0
- data/.gemtest +0 -0
- data/CHANGELOG.rdoc +3 -0
- data/Manifest.txt +87 -0
- data/README.rdoc +50 -0
- data/Rakefile +66 -0
- data/ext/psych/emitter.c +517 -0
- data/ext/psych/emitter.h +8 -0
- data/ext/psych/extconf.rb +22 -0
- data/ext/psych/parser.c +384 -0
- data/ext/psych/parser.h +6 -0
- data/ext/psych/psych.c +34 -0
- data/ext/psych/psych.h +20 -0
- data/ext/psych/to_ruby.c +41 -0
- data/ext/psych/to_ruby.h +8 -0
- data/ext/psych/yaml_tree.c +24 -0
- data/ext/psych/yaml_tree.h +8 -0
- data/lib/psych.rb +263 -0
- data/lib/psych/coder.rb +94 -0
- data/lib/psych/core_ext.rb +39 -0
- data/lib/psych/deprecated.rb +82 -0
- data/lib/psych/handler.rb +221 -0
- data/lib/psych/json.rb +6 -0
- data/lib/psych/json/ruby_events.rb +19 -0
- data/lib/psych/json/stream.rb +15 -0
- data/lib/psych/json/tree_builder.rb +12 -0
- data/lib/psych/json/yaml_events.rb +29 -0
- data/lib/psych/nodes.rb +77 -0
- data/lib/psych/nodes/alias.rb +18 -0
- data/lib/psych/nodes/document.rb +60 -0
- data/lib/psych/nodes/mapping.rb +56 -0
- data/lib/psych/nodes/node.rb +52 -0
- data/lib/psych/nodes/scalar.rb +67 -0
- data/lib/psych/nodes/sequence.rb +81 -0
- data/lib/psych/nodes/stream.rb +37 -0
- data/lib/psych/omap.rb +4 -0
- data/lib/psych/parser.rb +47 -0
- data/lib/psych/scalar_scanner.rb +105 -0
- data/lib/psych/set.rb +4 -0
- data/lib/psych/stream.rb +36 -0
- data/lib/psych/streaming.rb +22 -0
- data/lib/psych/tree_builder.rb +94 -0
- data/lib/psych/visitors.rb +6 -0
- data/lib/psych/visitors/depth_first.rb +26 -0
- data/lib/psych/visitors/emitter.rb +44 -0
- data/lib/psych/visitors/json_tree.rb +21 -0
- data/lib/psych/visitors/to_ruby.rb +267 -0
- data/lib/psych/visitors/visitor.rb +19 -0
- data/lib/psych/visitors/yaml_tree.rb +373 -0
- data/test/psych/helper.rb +63 -0
- data/test/psych/json/test_stream.rb +109 -0
- data/test/psych/nodes/test_enumerable.rb +43 -0
- data/test/psych/test_alias_and_anchor.rb +26 -0
- data/test/psych/test_array.rb +19 -0
- data/test/psych/test_boolean.rb +36 -0
- data/test/psych/test_class.rb +17 -0
- data/test/psych/test_coder.rb +184 -0
- data/test/psych/test_date_time.rb +17 -0
- data/test/psych/test_deprecated.rb +210 -0
- data/test/psych/test_document.rb +46 -0
- data/test/psych/test_emitter.rb +94 -0
- data/test/psych/test_encoding.rb +179 -0
- data/test/psych/test_engine_manager.rb +57 -0
- data/test/psych/test_exception.rb +39 -0
- data/test/psych/test_hash.rb +30 -0
- data/test/psych/test_json_tree.rb +65 -0
- data/test/psych/test_merge_keys.rb +72 -0
- data/test/psych/test_nil.rb +18 -0
- data/test/psych/test_null.rb +19 -0
- data/test/psych/test_object.rb +27 -0
- data/test/psych/test_omap.rb +68 -0
- data/test/psych/test_parser.rb +297 -0
- data/test/psych/test_psych.rb +168 -0
- data/test/psych/test_scalar.rb +11 -0
- data/test/psych/test_scalar_scanner.rb +69 -0
- data/test/psych/test_serialize_subclasses.rb +38 -0
- data/test/psych/test_set.rb +49 -0
- data/test/psych/test_stream.rb +49 -0
- data/test/psych/test_string.rb +49 -0
- data/test/psych/test_struct.rb +51 -0
- data/test/psych/test_symbol.rb +17 -0
- data/test/psych/test_to_yaml_properties.rb +63 -0
- data/test/psych/test_tree_builder.rb +79 -0
- data/test/psych/test_yaml.rb +1256 -0
- data/test/psych/visitors/test_depth_first.rb +49 -0
- data/test/psych/visitors/test_emitter.rb +144 -0
- data/test/psych/visitors/test_to_ruby.rb +325 -0
- data/test/psych/visitors/test_yaml_tree.rb +155 -0
- metadata +232 -0
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'psych/helper'
|
2
|
+
|
3
|
+
module Psych
|
4
|
+
module JSON
|
5
|
+
class TestStream < TestCase
|
6
|
+
def setup
|
7
|
+
@io = StringIO.new
|
8
|
+
@stream = Psych::JSON::Stream.new(@io)
|
9
|
+
@stream.start
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_explicit_documents
|
13
|
+
@io = StringIO.new
|
14
|
+
@stream = Psych::JSON::Stream.new(@io)
|
15
|
+
@stream.start
|
16
|
+
|
17
|
+
@stream.push({ 'foo' => 'bar' })
|
18
|
+
|
19
|
+
assert !@stream.finished?, 'stream not finished'
|
20
|
+
@stream.finish
|
21
|
+
assert @stream.finished?, 'stream finished'
|
22
|
+
|
23
|
+
assert_match(/^---/, @io.string)
|
24
|
+
assert_match(/\.\.\.$/, @io.string)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_null
|
28
|
+
@stream.push(nil)
|
29
|
+
assert_match(/^--- null/, @io.string)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_string
|
33
|
+
@stream.push "foo"
|
34
|
+
assert_match(/(["])foo\1/, @io.string)
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_symbol
|
38
|
+
@stream.push :foo
|
39
|
+
assert_match(/(["])foo\1/, @io.string)
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_int
|
43
|
+
@stream.push 10
|
44
|
+
assert_match(/^--- 10/, @io.string)
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_float
|
48
|
+
@stream.push 1.2
|
49
|
+
assert_match(/^--- 1.2/, @io.string)
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_hash
|
53
|
+
hash = { 'one' => 'two' }
|
54
|
+
@stream.push hash
|
55
|
+
|
56
|
+
json = @io.string
|
57
|
+
assert_match(/}$/, json)
|
58
|
+
assert_match(/^--- \{/, json)
|
59
|
+
assert_match(/["]one['"]/, json)
|
60
|
+
assert_match(/["]two['"]/, json)
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_list_to_json
|
64
|
+
list = %w{ one two }
|
65
|
+
@stream.push list
|
66
|
+
|
67
|
+
json = @io.string
|
68
|
+
assert_match(/]$/, json)
|
69
|
+
assert_match(/^--- \[/, json)
|
70
|
+
assert_match(/["]one["]/, json)
|
71
|
+
assert_match(/["]two["]/, json)
|
72
|
+
end
|
73
|
+
|
74
|
+
class Foo; end
|
75
|
+
|
76
|
+
def test_json_dump_exclude_tag
|
77
|
+
@stream << Foo.new
|
78
|
+
json = @io.string
|
79
|
+
refute_match('Foo', json)
|
80
|
+
end
|
81
|
+
|
82
|
+
class Bar
|
83
|
+
def encode_with coder
|
84
|
+
coder.represent_seq 'omg', %w{ a b c }
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_json_list_dump_exclude_tag
|
89
|
+
@stream << Bar.new
|
90
|
+
json = @io.string
|
91
|
+
refute_match('omg', json)
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_time
|
95
|
+
time = Time.utc(2010, 10, 10)
|
96
|
+
@stream.push({'a' => time })
|
97
|
+
json = @io.string
|
98
|
+
assert_match "{\"a\": \"2010-10-10 00:00:00.000000000Z\"}\n", json
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_datetime
|
102
|
+
time = Time.new(2010, 10, 10).to_datetime
|
103
|
+
@stream.push({'a' => time })
|
104
|
+
json = @io.string
|
105
|
+
assert_match "{\"a\": \"#{time.strftime("%Y-%m-%d %H:%M:%S.%9N %:z")}\"}\n", json
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'psych/helper'
|
2
|
+
|
3
|
+
module Psych
|
4
|
+
module Nodes
|
5
|
+
class TestEnumerable < TestCase
|
6
|
+
def test_includes_enumerable
|
7
|
+
yaml = '--- hello'
|
8
|
+
assert_equal 3, Psych.parse_stream(yaml).to_a.length
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_returns_enumerator
|
12
|
+
yaml = '--- hello'
|
13
|
+
assert_equal 3, Psych.parse_stream(yaml).each.map { |x| x }.length
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_scalar
|
17
|
+
assert_equal 3, calls('--- hello').length
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_sequence
|
21
|
+
assert_equal 4, calls("---\n- hello").length
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_mapping
|
25
|
+
assert_equal 5, calls("---\nhello: world").length
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_alias
|
29
|
+
assert_equal 5, calls("--- &yay\n- foo\n- *yay\n").length
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def calls yaml
|
35
|
+
calls = []
|
36
|
+
Psych.parse_stream(yaml).each do |node|
|
37
|
+
calls << node
|
38
|
+
end
|
39
|
+
calls
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'psych/helper'
|
2
|
+
|
3
|
+
module Psych
|
4
|
+
class TestAliasAndAnchor < TestCase
|
5
|
+
def test_mri_compatibility
|
6
|
+
yaml = <<EOYAML
|
7
|
+
---
|
8
|
+
- &id001 !ruby/object {}
|
9
|
+
|
10
|
+
- *id001
|
11
|
+
- *id001
|
12
|
+
EOYAML
|
13
|
+
result = Psych.load yaml
|
14
|
+
result.each {|el| assert_same(result[0], el) }
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_anchor_alias_round_trip
|
18
|
+
o = Object.new
|
19
|
+
original = [o,o,o]
|
20
|
+
|
21
|
+
yaml = Psych.dump original
|
22
|
+
result = Psych.load yaml
|
23
|
+
result.each {|el| assert_same(result[0], el) }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'psych/helper'
|
2
|
+
|
3
|
+
module Psych
|
4
|
+
class TestArray < TestCase
|
5
|
+
def setup
|
6
|
+
super
|
7
|
+
@list = [{ :a => 'b' }, 'foo']
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_self_referential
|
11
|
+
@list << @list
|
12
|
+
assert_cycle(@list)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_cycle
|
16
|
+
assert_cycle(@list)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'psych/helper'
|
2
|
+
|
3
|
+
module Psych
|
4
|
+
###
|
5
|
+
# Test booleans from YAML spec:
|
6
|
+
# http://yaml.org/type/bool.html
|
7
|
+
class TestBoolean < TestCase
|
8
|
+
%w{ yes Yes YES true True TRUE on On ON }.each do |truth|
|
9
|
+
define_method(:"test_#{truth}") do
|
10
|
+
assert_equal true, Psych.load("--- #{truth}")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
%w{ no No NO false False FALSE off Off OFF }.each do |truth|
|
15
|
+
define_method(:"test_#{truth}") do
|
16
|
+
assert_equal false, Psych.load("--- #{truth}")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
###
|
21
|
+
# YAML spec says "y" and "Y" may be used as true, but Syck treats them
|
22
|
+
# as literal strings
|
23
|
+
def test_y
|
24
|
+
assert_equal "y", Psych.load("--- y")
|
25
|
+
assert_equal "Y", Psych.load("--- Y")
|
26
|
+
end
|
27
|
+
|
28
|
+
###
|
29
|
+
# YAML spec says "n" and "N" may be used as false, but Syck treats them
|
30
|
+
# as literal strings
|
31
|
+
def test_n
|
32
|
+
assert_equal "n", Psych.load("--- n")
|
33
|
+
assert_equal "N", Psych.load("--- N")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'psych/helper'
|
2
|
+
|
3
|
+
module Psych
|
4
|
+
class TestClass < TestCase
|
5
|
+
def test_cycle
|
6
|
+
assert_raises(::TypeError) do
|
7
|
+
assert_cycle(TestClass)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_dump
|
12
|
+
assert_raises(::TypeError) do
|
13
|
+
Psych.dump TestClass
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,184 @@
|
|
1
|
+
require 'psych/helper'
|
2
|
+
|
3
|
+
module Psych
|
4
|
+
class TestCoder < TestCase
|
5
|
+
class InitApi
|
6
|
+
attr_accessor :implicit
|
7
|
+
attr_accessor :style
|
8
|
+
attr_accessor :tag
|
9
|
+
attr_accessor :a, :b, :c
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@a = 1
|
13
|
+
@b = 2
|
14
|
+
@c = 3
|
15
|
+
end
|
16
|
+
|
17
|
+
def init_with coder
|
18
|
+
@a = coder['aa']
|
19
|
+
@b = coder['bb']
|
20
|
+
@implicit = coder.implicit
|
21
|
+
@tag = coder.tag
|
22
|
+
@style = coder.style
|
23
|
+
end
|
24
|
+
|
25
|
+
def encode_with coder
|
26
|
+
coder['aa'] = @a
|
27
|
+
coder['bb'] = @b
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class TaggingCoder < InitApi
|
32
|
+
def encode_with coder
|
33
|
+
super
|
34
|
+
coder.tag = coder.tag.sub(/!/, '!hello')
|
35
|
+
coder.implicit = false
|
36
|
+
coder.style = Psych::Nodes::Mapping::FLOW
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class ScalarCoder
|
41
|
+
def encode_with coder
|
42
|
+
coder.scalar = "foo"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class Represent
|
47
|
+
yaml_tag 'foo'
|
48
|
+
def encode_with coder
|
49
|
+
coder.represent_scalar 'foo', 'bar'
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class RepresentWithInit
|
54
|
+
yaml_tag name
|
55
|
+
attr_accessor :str
|
56
|
+
|
57
|
+
def init_with coder
|
58
|
+
@str = coder.scalar
|
59
|
+
end
|
60
|
+
|
61
|
+
def encode_with coder
|
62
|
+
coder.represent_scalar self.class.name, 'bar'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class RepresentWithSeq
|
67
|
+
yaml_tag name
|
68
|
+
attr_accessor :seq
|
69
|
+
|
70
|
+
def init_with coder
|
71
|
+
@seq = coder.seq
|
72
|
+
end
|
73
|
+
|
74
|
+
def encode_with coder
|
75
|
+
coder.represent_seq self.class.name, %w{ foo bar }
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
class RepresentWithMap
|
80
|
+
yaml_tag name
|
81
|
+
attr_accessor :map
|
82
|
+
|
83
|
+
def init_with coder
|
84
|
+
@map = coder.map
|
85
|
+
end
|
86
|
+
|
87
|
+
def encode_with coder
|
88
|
+
coder.represent_map self.class.name, { 'a' => 'b' }
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
class RepresentWithObject
|
93
|
+
def encode_with coder
|
94
|
+
coder.represent_object self.class.name, 20
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_represent_with_object
|
99
|
+
thing = Psych.load(Psych.dump(RepresentWithObject.new))
|
100
|
+
assert_equal 20, thing
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_json_dump_exclude_tag
|
104
|
+
refute_match('TestCoder::InitApi', Psych.to_json(InitApi.new))
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_map_takes_block
|
108
|
+
coder = Psych::Coder.new 'foo'
|
109
|
+
tag = coder.tag
|
110
|
+
style = coder.style
|
111
|
+
coder.map { |map| map.add 'foo', 'bar' }
|
112
|
+
assert_equal 'bar', coder['foo']
|
113
|
+
assert_equal tag, coder.tag
|
114
|
+
assert_equal style, coder.style
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_map_with_tag
|
118
|
+
coder = Psych::Coder.new 'foo'
|
119
|
+
coder.map('hello') { |map| map.add 'foo', 'bar' }
|
120
|
+
assert_equal 'bar', coder['foo']
|
121
|
+
assert_equal 'hello', coder.tag
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_map_with_tag_and_style
|
125
|
+
coder = Psych::Coder.new 'foo'
|
126
|
+
coder.map('hello', 'world') { |map| map.add 'foo', 'bar' }
|
127
|
+
assert_equal 'bar', coder['foo']
|
128
|
+
assert_equal 'hello', coder.tag
|
129
|
+
assert_equal 'world', coder.style
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_represent_map
|
133
|
+
thing = Psych.load(Psych.dump(RepresentWithMap.new))
|
134
|
+
assert_equal({ 'a' => 'b' }, thing.map)
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_represent_sequence
|
138
|
+
thing = Psych.load(Psych.dump(RepresentWithSeq.new))
|
139
|
+
assert_equal %w{ foo bar }, thing.seq
|
140
|
+
end
|
141
|
+
|
142
|
+
def test_represent_with_init
|
143
|
+
thing = Psych.load(Psych.dump(RepresentWithInit.new))
|
144
|
+
assert_equal 'bar', thing.str
|
145
|
+
end
|
146
|
+
|
147
|
+
def test_represent!
|
148
|
+
assert_match(/foo/, Psych.dump(Represent.new))
|
149
|
+
assert_instance_of(Represent, Psych.load(Psych.dump(Represent.new)))
|
150
|
+
end
|
151
|
+
|
152
|
+
def test_scalar_coder
|
153
|
+
foo = Psych.load(Psych.dump(ScalarCoder.new))
|
154
|
+
assert_equal 'foo', foo
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_load_dumped_tagging
|
158
|
+
foo = InitApi.new
|
159
|
+
bar = Psych.load(Psych.dump(foo))
|
160
|
+
assert_equal false, bar.implicit
|
161
|
+
assert_equal "!ruby/object:Psych::TestCoder::InitApi", bar.tag
|
162
|
+
assert_equal Psych::Nodes::Mapping::BLOCK, bar.style
|
163
|
+
end
|
164
|
+
|
165
|
+
def test_dump_with_tag
|
166
|
+
foo = TaggingCoder.new
|
167
|
+
assert_match(/hello/, Psych.dump(foo))
|
168
|
+
assert_match(/\{aa/, Psych.dump(foo))
|
169
|
+
end
|
170
|
+
|
171
|
+
def test_dump_encode_with
|
172
|
+
foo = InitApi.new
|
173
|
+
assert_match(/aa/, Psych.dump(foo))
|
174
|
+
end
|
175
|
+
|
176
|
+
def test_dump_init_with
|
177
|
+
foo = InitApi.new
|
178
|
+
bar = Psych.load(Psych.dump(foo))
|
179
|
+
assert_equal foo.a, bar.a
|
180
|
+
assert_equal foo.b, bar.b
|
181
|
+
assert_nil bar.c
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'psych/helper'
|
2
|
+
require 'date'
|
3
|
+
|
4
|
+
module Psych
|
5
|
+
class TestDateTime < TestCase
|
6
|
+
def test_string_tag
|
7
|
+
dt = DateTime.now
|
8
|
+
yaml = Psych.dump dt
|
9
|
+
assert_match(/DateTime/, yaml)
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_round_trip
|
13
|
+
dt = DateTime.now
|
14
|
+
assert_cycle dt
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|