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