source: trunk/yaml/tests/TestDumper.py @ 87

Revision 87, 12.5 KB checked in by tim, 9 years ago (diff)

moved tests into a module under yaml and added a testrunner script courtesy of matt goodall

  • Property svn:executable set to *
Line 
1import YamlTest
2from yaml.dump import *
3import yaml
4from here import flushLeft
5from test import assertEquals
6
7class SampleClass:
8    def expected(self, modname, classname):
9        """
10        Tough to test, because this class may be in __main__
11        namespace, may be in TestDumper, depending where you
12        run it
13        """
14        return """
15        --- !!%s.%s
16        bar: 4
17        foo: 3
18        items:
19            - apple
20            - banana
21        """ % (modname, classname)
22
23    def __init__(self):
24        self.foo = 3
25        self.bar = 4
26        self.items = ['apple', 'banana']
27
28
29class SampleException(Exception):
30    def __init__(self, args):
31        self.args = args
32
33class Test(YamlTest.YamlTest):
34    def dumpTest(self, obj, expect):
35        assertEquals(yaml.dump(obj), flushLeft(expect))
36    def dumpTestSort(self,sort):
37        obj = {'a':'aaaa','d':'dddd','b':'bbbb','c':'cccc'}
38        exp = flushLeft(\
39            """
40            ---
41            b: bbbb
42            d: dddd
43            a: aaaa
44            c: cccc
45            """)
46        dumper = yaml.Dumper().setSort(sort)
47        self.assertEquals(dumper.dump(obj),exp)
48    def testsort_map(self):
49        self.dumpTestSort({'a':4,'b':2,'d':3})
50    def testsort_tuple(self):
51        self.dumpTestSort(('b','d','a'))
52    def testsort_list(self):
53        self.dumpTestSort(['b','d','a'])
54    def testsort_func(self):
55        self.dumpTestSort({'a':4,'b':2,'d':3}.get)
56    def test1(self):
57        self.dumpTest(
58            { 'foo': 'bar', 'yo': 'mama' },
59            """
60            ---
61            foo: bar
62            yo: mama
63            """,
64        )
65
66    def test2(self):
67        self.dumpTest(
68            { 'foo': {'bar': 3} },
69            """
70            ---
71            foo:
72                bar: 3
73            """,
74        )
75
76    def test3(self):
77        self.dumpTest(
78            { 
79                'foo': 3,
80                'fruits': {
81                    'apple': 'red',
82                    'banana': 'yellow',
83                }
84            },
85            """
86            ---
87            foo: 3
88            fruits:
89                apple: red
90                banana: yellow
91            """
92            )
93               
94    def test4(self):
95        self.dumpTest(
96            { 
97                'foo': 3,
98                'fruits': ['apple', 'orange']
99            },
100            """
101            ---
102            foo: 3
103            fruits:
104                - apple
105                - orange
106            """
107            )
108               
109    def testTuple(self):
110        self.dumpTest(
111            { 
112                'foo': 3,
113                'fruits': ('apple', 'orange')
114            },
115            """
116            ---
117            foo: 3
118            fruits:
119                - apple
120                - orange
121            """
122            )
123               
124    def testMultiLineBlock(self):
125        self.dumpTest(
126             { 
127                 'foo': "a\nb\nc\n",
128             },
129             """
130             ---
131             foo: |
132                 a
133                 b
134                 c
135             """
136             )
137
138    def testDoubleQuote(self):
139        assertEquals(doubleUpQuotes("foo'bar"), "foo''bar")
140        assertEquals(doubleUpQuotes("''x'"), "''''x''")
141
142    def testQuotingRules(self):
143        # Raw:
144        self.assertEquals(dump(None), "--- ~\n")
145        self.assertEquals(dump('simple'), "--- simple\n")
146        self.assertEquals(dump(''), "--- ''\n")
147        self.assertEquals(dump('two words'), "--- two words\n")
148        self.assertEquals(dump('single\'quote'), "--- single'quote\n")
149        self.assertEquals(dump('5.2'), "--- '5.2'\n")
150        self.assertEquals(dump(5.2), "--- 5.2\n")
151        self.assertEquals(dump(1234), "--- 1234\n")
152        self.assertEquals(dump('harmless-dash'), "--- harmless-dash\n")
153        self.assertEquals(dump('* harmless bullet'), "--- * harmless bullet\n")
154        self.dumpTest(
155            [ "a - b", "another-harmless-dash" ],
156            """
157            ---
158            - a - b
159            - another-harmless-dash
160            """)
161        # Single Quoted:
162        self.assertEquals(dump(''), "--- ''\n")
163        self.assertEquals(dump('4.3.1.5.2'), "--- '4.3.1.5.2'\n")
164        self.assertEquals(dump("'leading quote"), '--- "\'leading quote"\n')
165        self.assertEquals(dump('4.3.'), "--- '4.3.'\n")
166        self.assertEquals(dump('12345'), "--- '12345'\n")
167        self.assertEquals(dump('-12345'), "--- '-12345'\n")
168        self.assertEquals(dump('key: value'), "--- 'key: value'\n")
169        self.assertEquals(dump('ending colon:'), "--- 'ending colon:'\n")
170        self.assertEquals(dump('&foo'), "--- '&foo'\n")
171        self.assertEquals(dump(' xx'), "--- ' xx'\n")
172        self.assertEquals(dump('*bar'), "--- '*bar'\n")
173        assertEquals(dump('"middle \'quote'), '--- \'"middle \'\'quote\'\n')
174        # Double quoted:
175        self.assertEquals(dump("\thas a tab"), "--- \"\\thas a tab\"\n")
176        self.dumpTest(
177            { "key: quote": 'normal value' },
178            """
179            ---
180            'key: quote': normal value
181            """)
182
183    def testArrayWithSingleQuoted(self):
184        self.dumpTest(
185            [ 'foo:', {'bar': 'colon:'}],
186            """
187            ---
188            - 'foo:'
189            -
190                bar: 'colon:'
191            """
192            )
193
194    def testDumpObject(self):
195        sample = SampleClass()
196        self.dumpTest(sample, 
197            sample.expected(sample.__module__, 'SampleClass'))
198
199    def testWithSpuriousToYaml(self):
200        class ClassWithSpuriousToYaml(SampleClass):
201            to_yaml = 1 # Shouldn't get invoked
202        x = ClassWithSpuriousToYaml()
203        self.dumpTest(x, 
204            x.expected(x.__module__,'ClassWithSpuriousToYaml'))
205
206    def testNormalToYamlUse(self):
207        class NormalYamlUse(SampleClass):
208            def to_yaml(self):
209                dict = {}
210                dict['bar'] = self.foo * 2
211                return (dict, None)
212        self.dumpTest(NormalYamlUse(),
213            """
214            ---
215            bar: 6
216            """)
217
218    def testDumpingPrivateTypes(self):
219        class Foobar(SampleClass):
220            def to_yaml(self):
221                dict = {'foo': 'bar'}
222                return (dict, '!!foobar')
223        self.dumpTest(Foobar(),
224            """
225            --- !!foobar
226            foo: bar
227            """)
228        class OddList(SampleClass):
229            def to_yaml(self):
230                return ([1, 3, 5], '!!oddlist')
231        self.dumpTest(OddList(),
232            """
233            --- !!oddlist
234            - 1
235            - 3
236            - 5
237            """)
238
239
240    def testToYamlShouldBeAllowedToThrowIfItWants(self):
241        class ThrowsInsideToYaml:
242            def to_yaml(self):
243                raise SampleException('bla')
244        caught_exception = 'undef'
245        try:
246            dump(ThrowsInsideToYaml())
247        except Exception, e:
248            caught_exception = e
249        self.assertEquals('bla', caught_exception.args)
250
251    def testObjectWithListOfClasses(self):
252        class Foo:
253            def __init__(self, items):
254                self.items = items
255             
256        class Bar:
257            def __init__(self, data):
258                self.data = data
259
260        foo = Foo([Bar('apple'), Bar('banana')])
261        mod = foo.__module__ # depends where called
262        self.dumpTest(foo,
263            """
264            --- !!%s.Foo
265            items:
266                - !!%s.Bar
267                    data: apple
268                - !!%s.Bar
269                    data: banana
270            """ % (mod, mod, mod))
271
272    def testHasMethod(self):
273        class ClassWithMethodA:
274            b = 1
275            def a(): pass
276
277        sc = ClassWithMethodA()
278        self.assertEquals(1, hasMethod(sc, 'a'))
279        self.assertEquals(0, hasMethod(sc, 'b'))
280
281    def testComplexKey(self):
282        self.dumpTest( {(3,4): 4},
283            """
284            ---
285            ?
286                - 3
287                - 4
288            : 4
289            """)           
290   
291    def testApostrophe(self):
292        self.dumpTest( "Joe's hot dogs.\n",
293            """
294            --- |
295            Joe's hot dogs.
296            """)
297
298    def testCustomIndent(self):
299        self.assertEquals(
300            yaml.Dumper().setIndent('xx').dump(
301                { 
302                    'foo': 3,
303                    'fruits': ('apple', 'orange')
304                }, 
305            ),
306            flushLeft(
307                """
308                ---
309                foo: 3
310                fruits:
311                xx- apple
312                xx- orange
313                """
314            )
315            )
316
317    def testUnicode(self):
318        if YamlTest.hasUnicode:
319            self.dumpTest({'foo': u"Foo\u263A"},
320                r"""
321                ---
322                foo: "Foo\u263a"
323                """)
324
325    def testTab(self):
326        self.dumpTest({'tab': "foo\tbar"},
327            r"""
328            ---
329            tab: "foo\tbar"
330            """)
331
332    def testIsMulti(self):
333        self.failUnless(isMulti("foo\nbar"))
334        self.failIf(isMulti("foobar"))
335        self.failIf(isMulti("line\twith tab\nsecond line"))
336        self.failUnless(isMulti("foo\\slash\nbar"))
337
338    def testHasSpecialChar(self):
339        self.failUnless(hasSpecialChar("foo\tbar"))
340        self.failIf(hasSpecialChar("foobar"))
341
342    def testTabs(self):
343        self.dumpTest({'control': "\b1998\t1999\t2000\n"},
344            r"""
345            ---
346            control: "\b1998\t1999\t2000\n"
347            """)
348
349    def test12345(self):
350        self.dumpTest({'foo': 12345, 'bar': '12345'},
351            r"""
352            ---
353            bar: '12345'
354            foo: 12345
355            """)
356
357    def testDataThatsCoincidentallyTheSame(self):
358        self.dumpTest([ {'foo': 'bar'}, {'foo': 'bar'} ],
359            """
360            ---
361            -
362                foo: bar
363            -
364                foo: bar
365            """)
366
367    def testAliasClass(self):
368        dup = {'foo': 'bar'}
369        dupList = [dup, dup]
370        myAnchors = YamlAnchors(dupList)
371        self.assertEquals(id(dup), myAnchors._anchorVisits.keys()[0])
372        self.assertEquals(0,myAnchors.isAlias(dup))
373        self.assertEquals(1,myAnchors.shouldAnchor(dup) )
374        self.assertEquals(0,myAnchors.shouldAnchor('bar'))
375        self.assertEquals(0,myAnchors.shouldAnchor(dup['foo']))
376        self.assertEquals(0,myAnchors.shouldAnchor(dup))
377        self.assertEquals(1,myAnchors.isAlias(dup))
378
379    def testAliases(self):
380        dup = {'foo': 'bar'}
381        self.dumpTest([dup, dup],
382            """
383            ---
384            - &1
385                foo: bar
386            - *1
387            """)
388
389    def testHashAlias(self):
390        dup = {}
391        dup['foo'] = dup
392        self.dumpTest(dup, 
393            """
394            --- &1
395            foo: *1
396            """)
397
398    def testEmptyArray(self):
399        self.dumpTest([],
400            """
401            --- []
402            """)
403
404    def testEmptyHash(self):
405        self.dumpTest({},
406            """
407            --- {}
408            """)
409
410    def testEmptyHashAsHashKey(self):
411        self.dumpTest({'foo': {} },
412            """
413            ---
414            foo: {}
415            """)
416
417    def testEmptyArrrayAsHashKey(self):
418        self.dumpTest({'foo': [] },
419            """
420            ---
421            foo: []
422            """)
423
424    def testAliasNone(self):
425        foo = None
426        self.dumpTest([foo, foo, foo],
427            """
428            ---
429            - ~
430            - ~
431            - ~
432            """)
433
434    def testDumpMany(self):
435        assertEquals(
436            yaml.dump({'foo': 1}, ['a', 'b', 'c']),
437            flushLeft(
438                """
439                ---
440                foo: 1
441                ---
442                - a
443                - b
444                - c
445                """))
446
447    def testDumpExtraNewLines(self):
448        self.dumpTest( "Joe's hot dogs.\n\n",
449            """
450            --- |+
451            Joe's hot dogs.
452
453            """)
454
455
456    def testDumpExtraNewLinesInDict(self):
457        data = {'preserving': "extra new lines are kept\n\n\n"}
458        self.dumpTest(data,
459            """
460            ---
461            preserving: |+
462                extra new lines are kept
463               
464               
465            """)
466
467if __name__ == '__main__':
468    import unittest
469    unittest.main()
Note: See TracBrowser for help on using the repository browser.