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,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