1require 'psych/helper'
2
3module 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
184end
185