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