psych 1.2.2 → 1.3.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/.travis.yml +6 -0
- data/CHANGELOG.rdoc +126 -0
- data/Manifest.txt +3 -2
- data/README.rdoc +1 -1
- data/Rakefile +1 -1
- data/ext/psych/emitter.c +1 -1
- data/ext/psych/parser.c +241 -62
- data/lib/psych.rb +86 -21
- data/lib/psych/core_ext.rb +2 -0
- data/lib/psych/handlers/document_stream.rb +22 -0
- data/lib/psych/parser.rb +4 -0
- data/lib/psych/scalar_scanner.rb +15 -5
- data/lib/psych/syntax_error.rb +19 -0
- data/lib/psych/tree_builder.rb +3 -1
- data/lib/psych/visitors/to_ruby.rb +51 -15
- data/lib/psych/visitors/yaml_tree.rb +58 -11
- data/test/psych/test_array.rb +28 -0
- data/test/psych/test_encoding.rb +73 -0
- data/test/psych/test_exception.rb +91 -0
- data/test/psych/test_numeric.rb +11 -0
- data/test/psych/test_object_references.rb +67 -0
- data/test/psych/test_parser.rb +44 -9
- data/test/psych/test_scalar_scanner.rb +22 -0
- data/test/psych/test_stream.rb +44 -0
- data/test/psych/test_string.rb +31 -0
- data/test/psych/test_struct.rb +1 -3
- data/test/psych/test_tainted.rb +3 -1
- data/test/psych/test_yamldbm.rb +16 -9
- data/test/psych/test_yamlstore.rb +6 -6
- metadata +57 -68
- data/Gemfile +0 -11
- data/lib/psych/json.rb +0 -6
data/test/psych/test_array.rb
CHANGED
@@ -2,11 +2,39 @@ require 'psych/helper'
|
|
2
2
|
|
3
3
|
module Psych
|
4
4
|
class TestArray < TestCase
|
5
|
+
class X < Array
|
6
|
+
end
|
7
|
+
|
8
|
+
class Y < Array
|
9
|
+
attr_accessor :val
|
10
|
+
end
|
11
|
+
|
5
12
|
def setup
|
6
13
|
super
|
7
14
|
@list = [{ :a => 'b' }, 'foo']
|
8
15
|
end
|
9
16
|
|
17
|
+
def test_subclass
|
18
|
+
yaml = Psych.dump X.new
|
19
|
+
assert_match X.name, yaml
|
20
|
+
|
21
|
+
list = X.new
|
22
|
+
list << 1
|
23
|
+
assert_equal X, list.class
|
24
|
+
assert_equal 1, list.first
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_subclass_with_attributes
|
28
|
+
y = Psych.load Psych.dump Y.new.tap {|y| y.val = 1}
|
29
|
+
assert_equal Y, y.class
|
30
|
+
assert_equal 1, y.val
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_backwards_with_syck
|
34
|
+
x = Psych.load "--- !seq:#{X.name} []\n\n"
|
35
|
+
assert_equal X, x.class
|
36
|
+
end
|
37
|
+
|
10
38
|
def test_self_referential
|
11
39
|
@list << @list
|
12
40
|
assert_cycle(@list)
|
data/test/psych/test_encoding.rb
CHANGED
@@ -31,6 +31,79 @@ module Psych
|
|
31
31
|
@emitter = Psych::Emitter.new @buffer
|
32
32
|
end
|
33
33
|
|
34
|
+
def test_transcode_shiftjis
|
35
|
+
str = "こんにちは!"
|
36
|
+
loaded = Psych.load("--- こんにちは!".encode('SHIFT_JIS'))
|
37
|
+
assert_equal str, loaded
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_transcode_utf16le
|
41
|
+
str = "こんにちは!"
|
42
|
+
loaded = Psych.load("--- こんにちは!".encode('UTF-16LE'))
|
43
|
+
assert_equal str, loaded
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_transcode_utf16be
|
47
|
+
str = "こんにちは!"
|
48
|
+
loaded = Psych.load("--- こんにちは!".encode('UTF-16BE'))
|
49
|
+
assert_equal str, loaded
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_io_shiftjis
|
53
|
+
t = Tempfile.new(['shiftjis', 'yml'], :encoding => 'SHIFT_JIS')
|
54
|
+
t.write '--- こんにちは!'
|
55
|
+
t.close
|
56
|
+
|
57
|
+
# If the external encoding isn't utf8, utf16le, or utf16be, we cannot
|
58
|
+
# process the file.
|
59
|
+
File.open(t.path, 'r', :encoding => 'SHIFT_JIS') do |f|
|
60
|
+
assert_raises ArgumentError do
|
61
|
+
Psych.load(f)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
t.close(true)
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_io_utf16le
|
69
|
+
t = Tempfile.new(['utf16le', 'yml'])
|
70
|
+
t.binmode
|
71
|
+
t.write '--- こんにちは!'.encode('UTF-16LE')
|
72
|
+
t.close
|
73
|
+
|
74
|
+
File.open(t.path, 'rb', :encoding => 'UTF-16LE') do |f|
|
75
|
+
assert_equal "こんにちは!", Psych.load(f)
|
76
|
+
end
|
77
|
+
|
78
|
+
t.close(true)
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_io_utf16be
|
82
|
+
t = Tempfile.new(['utf16be', 'yml'])
|
83
|
+
t.binmode
|
84
|
+
t.write '--- こんにちは!'.encode('UTF-16BE')
|
85
|
+
t.close
|
86
|
+
|
87
|
+
File.open(t.path, 'rb', :encoding => 'UTF-16BE') do |f|
|
88
|
+
assert_equal "こんにちは!", Psych.load(f)
|
89
|
+
end
|
90
|
+
|
91
|
+
t.close(true)
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_io_utf8
|
95
|
+
t = Tempfile.new(['utf8', 'yml'])
|
96
|
+
t.binmode
|
97
|
+
t.write '--- こんにちは!'.encode('UTF-8')
|
98
|
+
t.close
|
99
|
+
|
100
|
+
File.open(t.path, 'rb', :encoding => 'UTF-8') do |f|
|
101
|
+
assert_equal "こんにちは!", Psych.load(f)
|
102
|
+
end
|
103
|
+
|
104
|
+
t.close(true)
|
105
|
+
end
|
106
|
+
|
34
107
|
def test_emit_alias
|
35
108
|
@emitter.start_stream Psych::Parser::UTF8
|
36
109
|
@emitter.start_document [], [], true
|
@@ -16,6 +16,97 @@ module Psych
|
|
16
16
|
@wups = Wups.new
|
17
17
|
end
|
18
18
|
|
19
|
+
def test_load_takes_file
|
20
|
+
ex = assert_raises(Psych::SyntaxError) do
|
21
|
+
Psych.load '--- `'
|
22
|
+
end
|
23
|
+
assert_nil ex.file
|
24
|
+
|
25
|
+
ex = assert_raises(Psych::SyntaxError) do
|
26
|
+
Psych.load '--- `', 'meow'
|
27
|
+
end
|
28
|
+
assert_equal 'meow', ex.file
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_psych_parse_stream_takes_file
|
32
|
+
ex = assert_raises(Psych::SyntaxError) do
|
33
|
+
Psych.parse_stream '--- `'
|
34
|
+
end
|
35
|
+
assert_nil ex.file
|
36
|
+
assert_match '(<unknown>)', ex.message
|
37
|
+
|
38
|
+
ex = assert_raises(Psych::SyntaxError) do
|
39
|
+
Psych.parse_stream '--- `', 'omg!'
|
40
|
+
end
|
41
|
+
assert_equal 'omg!', ex.file
|
42
|
+
assert_match 'omg!', ex.message
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_load_stream_takes_file
|
46
|
+
ex = assert_raises(Psych::SyntaxError) do
|
47
|
+
Psych.load_stream '--- `'
|
48
|
+
end
|
49
|
+
assert_nil ex.file
|
50
|
+
assert_match '(<unknown>)', ex.message
|
51
|
+
|
52
|
+
ex = assert_raises(Psych::SyntaxError) do
|
53
|
+
Psych.load_stream '--- `', 'omg!'
|
54
|
+
end
|
55
|
+
assert_equal 'omg!', ex.file
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_parse_file_exception
|
59
|
+
t = Tempfile.new(['parsefile', 'yml'])
|
60
|
+
t.binmode
|
61
|
+
t.write '--- `'
|
62
|
+
t.close
|
63
|
+
ex = assert_raises(Psych::SyntaxError) do
|
64
|
+
Psych.parse_file t.path
|
65
|
+
end
|
66
|
+
assert_equal t.path, ex.file
|
67
|
+
t.close(true)
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_load_file_exception
|
71
|
+
t = Tempfile.new(['loadfile', 'yml'])
|
72
|
+
t.binmode
|
73
|
+
t.write '--- `'
|
74
|
+
t.close
|
75
|
+
ex = assert_raises(Psych::SyntaxError) do
|
76
|
+
Psych.load_file t.path
|
77
|
+
end
|
78
|
+
assert_equal t.path, ex.file
|
79
|
+
t.close(true)
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_psych_parse_takes_file
|
83
|
+
ex = assert_raises(Psych::SyntaxError) do
|
84
|
+
Psych.parse '--- `'
|
85
|
+
end
|
86
|
+
assert_match '(<unknown>)', ex.message
|
87
|
+
assert_nil ex.file
|
88
|
+
|
89
|
+
ex = assert_raises(Psych::SyntaxError) do
|
90
|
+
Psych.parse '--- `', 'omg!'
|
91
|
+
end
|
92
|
+
assert_match 'omg!', ex.message
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_attributes
|
96
|
+
e = assert_raises(Psych::SyntaxError) {
|
97
|
+
Psych.load '--- `foo'
|
98
|
+
}
|
99
|
+
|
100
|
+
assert_nil e.file
|
101
|
+
assert_equal 1, e.line
|
102
|
+
assert_equal 5, e.column
|
103
|
+
# FIXME: offset isn't being set correctly by libyaml
|
104
|
+
# assert_equal 5, e.offset
|
105
|
+
|
106
|
+
assert e.problem
|
107
|
+
assert e.context
|
108
|
+
end
|
109
|
+
|
19
110
|
def test_convert
|
20
111
|
w = Psych.load(Psych.dump(@wups))
|
21
112
|
assert_equal @wups, w
|
data/test/psych/test_numeric.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'psych/helper'
|
2
|
+
require 'bigdecimal'
|
2
3
|
|
3
4
|
module Psych
|
4
5
|
###
|
@@ -10,5 +11,15 @@ module Psych
|
|
10
11
|
str = Psych.load('--- 090')
|
11
12
|
assert_equal '090', str
|
12
13
|
end
|
14
|
+
|
15
|
+
def test_big_decimal_tag
|
16
|
+
decimal = BigDecimal("12.34")
|
17
|
+
assert_match "!ruby/object:BigDecimal", Psych.dump(decimal)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_big_decimal_round_trip
|
21
|
+
decimal = BigDecimal("12.34")
|
22
|
+
assert_cycle decimal
|
23
|
+
end
|
13
24
|
end
|
14
25
|
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'psych/helper'
|
2
|
+
|
3
|
+
module Psych
|
4
|
+
class TestObjectReferences < TestCase
|
5
|
+
def test_range_has_references
|
6
|
+
assert_reference_trip 1..2
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_module_has_references
|
10
|
+
assert_reference_trip Psych
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_class_has_references
|
14
|
+
assert_reference_trip TestObjectReferences
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_rational_has_references
|
18
|
+
assert_reference_trip Rational('1.2')
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_complex_has_references
|
22
|
+
assert_reference_trip Complex(1, 2)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_datetime_has_references
|
26
|
+
assert_reference_trip DateTime.now
|
27
|
+
end
|
28
|
+
|
29
|
+
def assert_reference_trip obj
|
30
|
+
yml = Psych.dump([obj, obj])
|
31
|
+
assert_match(/\*-?\d+/, yml)
|
32
|
+
data = Psych.load yml
|
33
|
+
assert_equal data.first.object_id, data.last.object_id
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_float_references
|
37
|
+
data = Psych.load <<-eoyml
|
38
|
+
---
|
39
|
+
- &name 1.2
|
40
|
+
- *name
|
41
|
+
eoyml
|
42
|
+
assert_equal data.first, data.last
|
43
|
+
assert_equal data.first.object_id, data.last.object_id
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_binary_references
|
47
|
+
data = Psych.load <<-eoyml
|
48
|
+
---
|
49
|
+
- &name !binary |-
|
50
|
+
aGVsbG8gd29ybGQh
|
51
|
+
- *name
|
52
|
+
eoyml
|
53
|
+
assert_equal data.first, data.last
|
54
|
+
assert_equal data.first.object_id, data.last.object_id
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_regexp_references
|
58
|
+
data = Psych.load <<-eoyml
|
59
|
+
---
|
60
|
+
- &name !ruby/regexp /pattern/i
|
61
|
+
- *name
|
62
|
+
eoyml
|
63
|
+
assert_equal data.first, data.last
|
64
|
+
assert_equal data.first.object_id, data.last.object_id
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/test/psych/test_parser.rb
CHANGED
@@ -32,6 +32,49 @@ module Psych
|
|
32
32
|
@handler.parser = @parser
|
33
33
|
end
|
34
34
|
|
35
|
+
def test_exception_memory_leak
|
36
|
+
yaml = <<-eoyaml
|
37
|
+
%YAML 1.1
|
38
|
+
%TAG ! tag:tenderlovemaking.com,2009:
|
39
|
+
--- &ponies
|
40
|
+
- first element
|
41
|
+
- *ponies
|
42
|
+
- foo: bar
|
43
|
+
...
|
44
|
+
eoyaml
|
45
|
+
|
46
|
+
[:start_stream, :start_document, :end_document, :alias, :scalar,
|
47
|
+
:start_sequence, :end_sequence, :start_mapping, :end_mapping,
|
48
|
+
:end_stream].each do |method|
|
49
|
+
|
50
|
+
klass = Class.new(Psych::Handler) do
|
51
|
+
define_method(method) do |*args|
|
52
|
+
raise
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
parser = Psych::Parser.new klass.new
|
57
|
+
2.times {
|
58
|
+
assert_raises(RuntimeError, method.to_s) do
|
59
|
+
parser.parse yaml
|
60
|
+
end
|
61
|
+
}
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_multiparse
|
66
|
+
3.times do
|
67
|
+
@parser.parse '--- foo'
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_filename
|
72
|
+
ex = assert_raises(Psych::SyntaxError) do
|
73
|
+
@parser.parse '--- `', 'omg!'
|
74
|
+
end
|
75
|
+
assert_match 'omg!', ex.message
|
76
|
+
end
|
77
|
+
|
35
78
|
def test_line_numbers
|
36
79
|
assert_equal 0, @parser.mark.line
|
37
80
|
@parser.parse "---\n- hello\n- world"
|
@@ -80,15 +123,6 @@ module Psych
|
|
80
123
|
assert_equal 19, @parser.mark.index
|
81
124
|
end
|
82
125
|
|
83
|
-
def test_set_encoding_twice
|
84
|
-
@parser.external_encoding = Psych::Parser::UTF16LE
|
85
|
-
|
86
|
-
e = assert_raises(Psych::Exception) do
|
87
|
-
@parser.external_encoding = Psych::Parser::UTF16LE
|
88
|
-
end
|
89
|
-
assert_equal "don't set the encoding twice!", e.message
|
90
|
-
end
|
91
|
-
|
92
126
|
def test_bom
|
93
127
|
tadpole = 'おたまじゃくし'
|
94
128
|
|
@@ -108,6 +142,7 @@ module Psych
|
|
108
142
|
|
109
143
|
def test_bogus_io
|
110
144
|
o = Object.new
|
145
|
+
def o.external_encoding; nil end
|
111
146
|
def o.read len; self end
|
112
147
|
|
113
148
|
assert_raises(TypeError) do
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'psych/helper'
|
2
|
+
require 'date'
|
2
3
|
|
3
4
|
module Psych
|
4
5
|
class TestScalarScanner < TestCase
|
@@ -20,6 +21,27 @@ module Psych
|
|
20
21
|
end
|
21
22
|
end
|
22
23
|
|
24
|
+
def test_scan_bad_dates
|
25
|
+
x = '2000-15-01'
|
26
|
+
assert_equal x, @ss.tokenize(x)
|
27
|
+
|
28
|
+
x = '2000-10-51'
|
29
|
+
assert_equal x, @ss.tokenize(x)
|
30
|
+
|
31
|
+
x = '2000-10-32'
|
32
|
+
assert_equal x, @ss.tokenize(x)
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_scan_good_edge_date
|
36
|
+
x = '2000-1-31'
|
37
|
+
assert_equal Date.strptime(x, '%Y-%m-%d'), @ss.tokenize(x)
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_scan_bad_edge_date
|
41
|
+
x = '2000-11-31'
|
42
|
+
assert_equal x, @ss.tokenize(x)
|
43
|
+
end
|
44
|
+
|
23
45
|
def test_scan_date
|
24
46
|
date = '1980-12-16'
|
25
47
|
token = @ss.tokenize date
|
data/test/psych/test_stream.rb
CHANGED
@@ -2,6 +2,50 @@ require 'psych/helper'
|
|
2
2
|
|
3
3
|
module Psych
|
4
4
|
class TestStream < TestCase
|
5
|
+
def test_parse_partial
|
6
|
+
rb = Psych.parse("--- foo\n...\n--- `").to_ruby
|
7
|
+
assert_equal 'foo', rb
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_load_partial
|
11
|
+
rb = Psych.load("--- foo\n...\n--- `")
|
12
|
+
assert_equal 'foo', rb
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_parse_stream_yields_documents
|
16
|
+
list = []
|
17
|
+
Psych.parse_stream("--- foo\n...\n--- bar") do |doc|
|
18
|
+
list << doc.to_ruby
|
19
|
+
end
|
20
|
+
assert_equal %w{ foo bar }, list
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_parse_stream_break
|
24
|
+
list = []
|
25
|
+
Psych.parse_stream("--- foo\n...\n--- `") do |doc|
|
26
|
+
list << doc.to_ruby
|
27
|
+
break
|
28
|
+
end
|
29
|
+
assert_equal %w{ foo }, list
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_load_stream_yields_documents
|
33
|
+
list = []
|
34
|
+
Psych.load_stream("--- foo\n...\n--- bar") do |ruby|
|
35
|
+
list << ruby
|
36
|
+
end
|
37
|
+
assert_equal %w{ foo bar }, list
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_load_stream_break
|
41
|
+
list = []
|
42
|
+
Psych.load_stream("--- foo\n...\n--- `") do |ruby|
|
43
|
+
list << ruby
|
44
|
+
break
|
45
|
+
end
|
46
|
+
assert_equal %w{ foo }, list
|
47
|
+
end
|
48
|
+
|
5
49
|
def test_explicit_documents
|
6
50
|
io = StringIO.new
|
7
51
|
stream = Psych::Stream.new(io)
|