1from io import BytesIO 2import os 3import unittest 4from fontTools.misc.textTools import bytesjoin, tobytes 5from fontTools.misc.xmlWriter import XMLWriter 6 7HEADER = b'<?xml version="1.0" encoding="UTF-8"?>\n' 8 9 10class TestXMLWriter(unittest.TestCase): 11 def test_comment_escaped(self): 12 writer = XMLWriter(BytesIO()) 13 writer.comment("This&that are <comments>") 14 self.assertEqual( 15 HEADER + b"<!-- This&that are <comments> -->", 16 writer.file.getvalue(), 17 ) 18 19 def test_comment_multiline(self): 20 writer = XMLWriter(BytesIO()) 21 writer.comment("Hello world\nHow are you?") 22 self.assertEqual( 23 HEADER + b"<!-- Hello world\n How are you? -->", writer.file.getvalue() 24 ) 25 26 def test_encoding_default(self): 27 writer = XMLWriter(BytesIO()) 28 self.assertEqual( 29 b'<?xml version="1.0" encoding="UTF-8"?>\n', writer.file.getvalue() 30 ) 31 32 def test_encoding_utf8(self): 33 # https://github.com/fonttools/fonttools/issues/246 34 writer = XMLWriter(BytesIO(), encoding="utf8") 35 self.assertEqual( 36 b'<?xml version="1.0" encoding="UTF-8"?>\n', writer.file.getvalue() 37 ) 38 39 def test_encoding_UTF_8(self): 40 # https://github.com/fonttools/fonttools/issues/246 41 writer = XMLWriter(BytesIO(), encoding="UTF-8") 42 self.assertEqual( 43 b'<?xml version="1.0" encoding="UTF-8"?>\n', writer.file.getvalue() 44 ) 45 46 def test_encoding_UTF8(self): 47 # https://github.com/fonttools/fonttools/issues/246 48 writer = XMLWriter(BytesIO(), encoding="UTF8") 49 self.assertEqual( 50 b'<?xml version="1.0" encoding="UTF-8"?>\n', writer.file.getvalue() 51 ) 52 53 def test_encoding_other(self): 54 self.assertRaises(Exception, XMLWriter, BytesIO(), encoding="iso-8859-1") 55 56 def test_write(self): 57 writer = XMLWriter(BytesIO()) 58 writer.write("foo&bar") 59 self.assertEqual(HEADER + b"foo&bar", writer.file.getvalue()) 60 61 def test_indent_dedent(self): 62 writer = XMLWriter(BytesIO()) 63 writer.write("foo") 64 writer.newline() 65 writer.indent() 66 writer.write("bar") 67 writer.newline() 68 writer.dedent() 69 writer.write("baz") 70 self.assertEqual( 71 HEADER + bytesjoin(["foo", " bar", "baz"], "\n"), writer.file.getvalue() 72 ) 73 74 def test_writecdata(self): 75 writer = XMLWriter(BytesIO()) 76 writer.writecdata("foo&bar") 77 self.assertEqual(HEADER + b"<![CDATA[foo&bar]]>", writer.file.getvalue()) 78 79 def test_simpletag(self): 80 writer = XMLWriter(BytesIO()) 81 writer.simpletag("tag", a="1", b="2") 82 self.assertEqual(HEADER + b'<tag a="1" b="2"/>', writer.file.getvalue()) 83 84 def test_begintag_endtag(self): 85 writer = XMLWriter(BytesIO()) 86 writer.begintag("tag", attr="value") 87 writer.write("content") 88 writer.endtag("tag") 89 self.assertEqual( 90 HEADER + b'<tag attr="value">content</tag>', writer.file.getvalue() 91 ) 92 93 def test_dumphex(self): 94 writer = XMLWriter(BytesIO()) 95 writer.dumphex( 96 "Type is a beautiful group of letters, not a group of beautiful letters." 97 ) 98 self.assertEqual( 99 HEADER 100 + bytesjoin( 101 [ 102 "54797065 20697320 61206265 61757469", 103 "66756c20 67726f75 70206f66 206c6574", 104 "74657273 2c206e6f 74206120 67726f75", 105 "70206f66 20626561 75746966 756c206c", 106 "65747465 72732e ", 107 "", 108 ], 109 joiner="\n", 110 ), 111 writer.file.getvalue(), 112 ) 113 114 def test_stringifyattrs(self): 115 writer = XMLWriter(BytesIO()) 116 expected = ' attr="0"' 117 self.assertEqual(expected, writer.stringifyattrs(attr=0)) 118 self.assertEqual(expected, writer.stringifyattrs(attr=b"0")) 119 self.assertEqual(expected, writer.stringifyattrs(attr="0")) 120 self.assertEqual(expected, writer.stringifyattrs(attr="0")) 121 122 def test_carriage_return_escaped(self): 123 writer = XMLWriter(BytesIO()) 124 writer.write("two lines\r\nseparated by Windows line endings") 125 self.assertEqual( 126 HEADER + b"two lines \nseparated by Windows line endings", 127 writer.file.getvalue(), 128 ) 129 130 def test_newlinestr(self): 131 header = b'<?xml version="1.0" encoding="UTF-8"?>' 132 133 for nls in (None, "\n", "\r\n", "\r", ""): 134 writer = XMLWriter(BytesIO(), newlinestr=nls) 135 writer.write("hello") 136 writer.newline() 137 writer.write("world") 138 writer.newline() 139 140 linesep = tobytes(os.linesep) if nls is None else tobytes(nls) 141 142 self.assertEqual( 143 header + linesep + b"hello" + linesep + b"world" + linesep, 144 writer.file.getvalue(), 145 ) 146 147 148if __name__ == "__main__": 149 import sys 150 151 sys.exit(unittest.main()) 152