1# -*- coding: utf-8 -*-
2from __future__ import absolute_import, unicode_literals
3import unittest
4from fontTools.ufoLib.glifLib import GlifLibError, readGlyphFromString, writeGlyphToString
5from .testSupport import Glyph, stripText
6from itertools import islice
7
8try:
9	basestring
10except NameError:
11	basestring = str
12# ----------
13# Test Cases
14# ----------
15
16class TestGLIF2(unittest.TestCase):
17
18	def assertEqual(self, first, second, msg=None):
19		if isinstance(first, basestring):
20			first = stripText(first)
21		if isinstance(second, basestring):
22			second = stripText(second)
23		return super(TestGLIF2, self).assertEqual(first, second, msg=msg)
24
25	def pyToGLIF(self, py):
26		py = stripText(py)
27		glyph = Glyph()
28		exec(py, {"glyph" : glyph, "pointPen" : glyph})
29		glif = writeGlyphToString(glyph.name, glyphObject=glyph, drawPointsFunc=glyph.drawPoints, formatVersion=2, validate=True)
30		# discard the first line containing the xml declaration
31		return "\n".join(islice(glif.splitlines(), 1, None))
32
33	def glifToPy(self, glif):
34		glif = stripText(glif)
35		glif = "<?xml version=\"1.0\"?>\n" + glif
36		glyph = Glyph()
37		readGlyphFromString(glif, glyphObject=glyph, pointPen=glyph, validate=True)
38		return glyph.py()
39
40	def testTopElement(self):
41		# not glyph
42		glif = """
43		<notglyph name="a" format="2">
44			<outline>
45			</outline>
46		</notglyph>
47		"""
48		self.assertRaises(GlifLibError, self.glifToPy, glif)
49
50	def testName_legal(self):
51		# legal
52		glif = """
53		<glyph name="a" format="2">
54			<outline>
55			</outline>
56		</glyph>
57		"""
58		py = """
59		glyph.name = "a"
60		"""
61		resultGlif = self.pyToGLIF(py)
62		resultPy = self.glifToPy(glif)
63		self.assertEqual(glif, resultGlif)
64		self.assertEqual(py, resultPy)
65
66	def testName_empty(self):
67		# empty
68		glif = """
69		<glyph name="" format="2">
70			<outline>
71			</outline>
72		</glyph>
73		"""
74		py = """
75		glyph.name = ""
76		"""
77		self.assertRaises(GlifLibError, self.pyToGLIF, py)
78		self.assertRaises(GlifLibError, self.glifToPy, glif)
79
80	def testName_not_a_string(self):
81		# not a string
82		py = """
83		glyph.name = 1
84		"""
85		self.assertRaises(GlifLibError, self.pyToGLIF, py)
86
87	def testFormat_legal(self):
88		# legal
89		glif = """
90		<glyph name="a" format="2">
91			<outline>
92			</outline>
93		</glyph>
94		"""
95		py = """
96		glyph.name = "a"
97		"""
98		resultGlif = self.pyToGLIF(py)
99		resultPy = self.glifToPy(glif)
100		self.assertEqual(glif, resultGlif)
101		self.assertEqual(py, resultPy)
102
103	def testFormat_illegal_wrong_number(self):
104		# wrong number
105		glif = """
106		<glyph name="a" format="-1">
107			<outline>
108			</outline>
109		</glyph>
110		"""
111		self.assertRaises(GlifLibError, self.glifToPy, glif)
112
113	def testFormat_illegal_not_int(self):
114		# not an int
115		glif = """
116		<glyph name="a" format="A">
117			<outline>
118			</outline>
119		</glyph>
120		"""
121		self.assertRaises(GlifLibError, self.glifToPy, glif)
122
123	def testBogusGlyphStructure_unknown_element(self):
124		# unknown element
125		glif = """
126		<glyph name="a" format="2">
127			<unknown />
128		</glyph>
129		"""
130		self.assertRaises(GlifLibError, self.glifToPy, glif)
131
132	def testBogusGlyphStructure_content(self):
133		# content
134		glif = """
135		<glyph name="a" format="2">
136			Hello World.
137		</glyph>
138		"""
139		self.assertRaises(GlifLibError, self.glifToPy, glif)
140
141	def testAdvance_legal_widht_and_height(self):
142		# legal: width and height
143		glif = """
144		<glyph name="a" format="2">
145			<advance height="200" width="100"/>
146			<outline>
147			</outline>
148		</glyph>
149		"""
150		py = """
151		glyph.name = "a"
152		glyph.width = 100
153		glyph.height = 200
154		"""
155		resultGlif = self.pyToGLIF(py)
156		resultPy = self.glifToPy(glif)
157		self.assertEqual(glif, resultGlif)
158		self.assertEqual(py, resultPy)
159
160	def testAdvance_legal_width_and_height_floats(self):
161		# legal: width and height floats
162		glif = """
163		<glyph name="a" format="2">
164			<advance height="200.1" width="100.1"/>
165			<outline>
166			</outline>
167		</glyph>
168		"""
169		py = """
170		glyph.name = "a"
171		glyph.width = 100.1
172		glyph.height = 200.1
173		"""
174		resultGlif = self.pyToGLIF(py)
175		resultPy = self.glifToPy(glif)
176		self.assertEqual(glif, resultGlif)
177		self.assertEqual(py, resultPy)
178
179	def testAdvance_legal_width(self):
180		# legal: width
181		glif = """
182		<glyph name="a" format="2">
183			<advance width="100"/>
184			<outline>
185			</outline>
186		</glyph>
187		"""
188		py = """
189		glyph.name = "a"
190		glyph.width = 100
191		"""
192		resultGlif = self.pyToGLIF(py)
193		resultPy = self.glifToPy(glif)
194		self.assertEqual(glif, resultGlif)
195		self.assertEqual(py, resultPy)
196
197	def testAdvance_legal_height(self):
198		# legal: height
199		glif = """
200		<glyph name="a" format="2">
201			<advance height="200"/>
202			<outline>
203			</outline>
204		</glyph>
205		"""
206		py = """
207		glyph.name = "a"
208		glyph.height = 200
209		"""
210		resultGlif = self.pyToGLIF(py)
211		resultPy = self.glifToPy(glif)
212		self.assertEqual(glif, resultGlif)
213		self.assertEqual(py, resultPy)
214
215	def testAdvance_illegal_width(self):
216		# illegal: not a number
217		glif = """
218		<glyph name="a" format="2">
219			<advance width="a"/>
220			<outline>
221			</outline>
222		</glyph>
223		"""
224		py = """
225		glyph.name = "a"
226		glyph.width = "a"
227		"""
228		self.assertRaises(GlifLibError, self.pyToGLIF, py)
229		self.assertRaises(GlifLibError, self.glifToPy, glif)
230
231	def testAdvance_illegal_height(self):
232		glif = """
233		<glyph name="a" format="2">
234			<advance height="a"/>
235			<outline>
236			</outline>
237		</glyph>
238		"""
239		py = """
240		glyph.name = "a"
241		glyph.height = "a"
242		"""
243		self.assertRaises(GlifLibError, self.pyToGLIF, py)
244		self.assertRaises(GlifLibError, self.glifToPy, glif)
245
246	def testUnicodes_legal(self):
247		# legal
248		glif = """
249		<glyph name="a" format="2">
250			<unicode hex="0061"/>
251			<outline>
252			</outline>
253		</glyph>
254		"""
255		py = """
256		glyph.name = "a"
257		glyph.unicodes = [97]
258		"""
259		resultGlif = self.pyToGLIF(py)
260		resultPy = self.glifToPy(glif)
261		self.assertEqual(glif, resultGlif)
262		self.assertEqual(py, resultPy)
263
264	def testUnicodes_legal_multiple(self):
265		glif = """
266		<glyph name="a" format="2">
267			<unicode hex="0062"/>
268			<unicode hex="0063"/>
269			<unicode hex="0061"/>
270			<outline>
271			</outline>
272		</glyph>
273		"""
274		py = """
275		glyph.name = "a"
276		glyph.unicodes = [98, 99, 97]
277		"""
278		resultGlif = self.pyToGLIF(py)
279		resultPy = self.glifToPy(glif)
280		self.assertEqual(glif, resultGlif)
281		self.assertEqual(py, resultPy)
282
283	def testUnicodes_illegal(self):
284		# illegal
285		glif = """
286		<glyph name="a" format="2">
287			<unicode hex="1.1"/>
288			<outline>
289			</outline>
290		</glyph>
291		"""
292		py = """
293		glyph.name = "zzzzzz"
294		glyph.unicodes = ["1.1"]
295		"""
296		self.assertRaises(GlifLibError, self.pyToGLIF, py)
297		self.assertRaises(GlifLibError, self.glifToPy, glif)
298
299	def testNote(self):
300		glif = """
301		<glyph name="a" format="2">
302			<note>
303				hëllö
304			</note>
305			<outline>
306			</outline>
307		</glyph>
308		"""
309		py = """
310		glyph.name = "a"
311		glyph.note = "hëllö"
312		"""
313		resultGlif = self.pyToGLIF(py)
314		resultPy = self.glifToPy(glif)
315		self.assertEqual(glif, resultGlif)
316		self.assertEqual(py, resultPy)
317
318	def testLib(self):
319		glif = """
320		<glyph name="a" format="2">
321			<outline>
322			</outline>
323			<lib>
324				<dict>
325					<key>dict</key>
326					<dict>
327						<key>hello</key>
328						<string>world</string>
329					</dict>
330					<key>float</key>
331					<real>2.5</real>
332					<key>int</key>
333					<integer>1</integer>
334					<key>list</key>
335					<array>
336						<string>a</string>
337						<string>b</string>
338						<integer>1</integer>
339						<real>2.5</real>
340					</array>
341					<key>string</key>
342					<string>a</string>
343				</dict>
344			</lib>
345		</glyph>
346		"""
347		py = """
348		glyph.name = "a"
349		glyph.lib = {"dict" : {"hello" : "world"}, "float" : 2.5, "int" : 1, "list" : ["a", "b", 1, 2.5], "string" : "a"}
350		"""
351		resultGlif = self.pyToGLIF(py)
352		resultPy = self.glifToPy(glif)
353		self.assertEqual(glif, resultGlif)
354		self.assertEqual(py, resultPy)
355
356	def testGuidelines_legal(self):
357		# legal
358		glif = """
359		<glyph name="a" format="2">
360			<guideline x="1"/>
361			<guideline y="1"/>
362			<guideline x="1" y="1" angle="0"/>
363			<guideline x="1" y="1" angle="360"/>
364			<guideline x="1.1" y="1.1" angle="45.5"/>
365			<guideline x="1" name="a"/>
366			<guideline x="1" color="1,1,1,1"/>
367			<outline>
368			</outline>
369		</glyph>
370		"""
371		py = """
372		glyph.name = "a"
373		glyph.guidelines = [{"x" : 1}, {"y" : 1}, {"angle" : 0, "x" : 1, "y" : 1}, {"angle" : 360, "x" : 1, "y" : 1}, {"angle" : 45.5, "x" : 1.1, "y" : 1.1}, {"name" : "a", "x" : 1}, {"color" : "1,1,1,1", "x" : 1}]
374		"""
375		resultGlif = self.pyToGLIF(py)
376		resultPy = self.glifToPy(glif)
377		self.assertEqual(glif, resultGlif)
378		self.assertEqual(py, resultPy)
379
380	def testGuidelines_illegal_x(self):
381		# x not an int or float
382		glif = """
383		<glyph name="a" format="2">
384			<guideline x="a" y="1" angle="45"/>
385			<outline>
386			</outline>
387		</glyph>
388		"""
389		py = """
390		glyph.name = "a"
391		glyph.guidelines = [{"angle" : 45, "x" : "a", "y" : 1}]
392		"""
393		self.assertRaises(GlifLibError, self.pyToGLIF, py)
394		self.assertRaises(GlifLibError, self.glifToPy, glif)
395
396	def testGuidelines_illegal_y(self):
397		# y not an int or float
398		glif = """
399		<glyph name="a" format="2">
400			<guideline x="1" y="y" angle="45"/>
401			<outline>
402			</outline>
403		</glyph>
404		"""
405		py = """
406		glyph.name = "a"
407		glyph.guidelines = [{"angle" : 45, "x" : 1, "y" : "a"}]
408		"""
409		self.assertRaises(GlifLibError, self.pyToGLIF, py)
410		self.assertRaises(GlifLibError, self.glifToPy, glif)
411
412	def testGuidelines_illegal_angle(self):
413		# angle not an int or float
414		glif = """
415		<glyph name="a" format="2">
416			<guideline x="1" y="1" angle="a"/>
417			<outline>
418			</outline>
419		</glyph>
420		"""
421		py = """
422		glyph.name = "a"
423		glyph.guidelines = [{"angle" : "a", "x" : 1, "y" : 1}]
424		"""
425		self.assertRaises(GlifLibError, self.pyToGLIF, py)
426		self.assertRaises(GlifLibError, self.glifToPy, glif)
427
428	def testGuidelines_illegal_x_missing(self):
429		# x missing
430		glif = """
431		<glyph name="a" format="2">
432			<guideline y="1" angle="45"/>
433			<outline>
434			</outline>
435		</glyph>
436		"""
437		py = """
438		glyph.name = "a"
439		glyph.guidelines = [{"angle" : 45, "y" : 1}]
440		"""
441		self.assertRaises(GlifLibError, self.pyToGLIF, py)
442		self.assertRaises(GlifLibError, self.glifToPy, glif)
443
444	def testGuidelines_illegal_y_missing(self):
445		# y missing
446		glif = """
447		<glyph name="a" format="2">
448			<guideline x="1" angle="45"/>
449			<outline>
450			</outline>
451		</glyph>
452		"""
453		py = """
454		glyph.name = "a"
455		glyph.guidelines = [{"angle" : 45, "x" : 1}]
456		"""
457		self.assertRaises(GlifLibError, self.pyToGLIF, py)
458		self.assertRaises(GlifLibError, self.glifToPy, glif)
459
460	def testGuidelines_illegal_angle_missing(self):
461		# angle missing
462		glif = """
463		<glyph name="a" format="2">
464			<guideline x="1" y="1"/>
465			<outline>
466			</outline>
467		</glyph>
468		"""
469		py = """
470		glyph.name = "a"
471		glyph.guidelines = [{"x" : 1, "y" : 1}]
472		"""
473		self.assertRaises(GlifLibError, self.pyToGLIF, py)
474		self.assertRaises(GlifLibError, self.glifToPy, glif)
475
476	def testGuidelines_illegal_angle_out_of_range(self):
477		# angle out of range
478		glif = """
479		<glyph name="a" format="2">
480			<guideline x="1" y="1" angle="-1"/>
481			<outline>
482			</outline>
483		</glyph>
484		"""
485		py = """
486		glyph.name = "a"
487		glyph.guidelines = [{"angle" : -1, "x" : "1", "y" : 1}]
488		"""
489		self.assertRaises(GlifLibError, self.pyToGLIF, py)
490		self.assertRaises(GlifLibError, self.glifToPy, glif)
491		glif = """
492		<glyph name="a" format="2">
493			<guideline x="1" y="1" angle="361"/>
494			<outline>
495			</outline>
496		</glyph>
497		"""
498		py = """
499		glyph.name = "a"
500		glyph.guidelines = [{"angle" : 361, "x" : "1", "y" : 1}]
501		"""
502		self.assertRaises(GlifLibError, self.pyToGLIF, py)
503		self.assertRaises(GlifLibError, self.glifToPy, glif)
504
505	def testAnchors_legal(self):
506		# legal
507		glif = """
508		<glyph name="a" format="2">
509			<anchor x="1" y="2" name="test" color="1,0,0,1"/>
510			<anchor x="1" y="2"/>
511			<outline>
512			</outline>
513		</glyph>
514		"""
515		py = """
516		glyph.name = "a"
517		glyph.anchors = [{"color" : "1,0,0,1", "name" : "test", "x" : 1, "y" : 2}, {"x" : 1, "y" : 2}]
518		"""
519		resultGlif = self.pyToGLIF(py)
520		resultPy = self.glifToPy(glif)
521		self.assertEqual(glif, resultGlif)
522		self.assertEqual(py, resultPy)
523
524	def testAnchors_illegal_x(self):
525		# x not an int or float
526		glif = """
527		<glyph name="a" format="2">
528			<anchor x="a" y="1"/>
529			<outline>
530			</outline>
531		</glyph>
532		"""
533		py = """
534		glyph.name = "a"
535		glyph.anchors = [{"x" : "a", "y" : 1}]
536		"""
537		self.assertRaises(GlifLibError, self.pyToGLIF, py)
538		self.assertRaises(GlifLibError, self.glifToPy, glif)
539
540	def testAnchors_illegal_y(self):
541		# y not an int or float
542		glif = """
543		<glyph name="a" format="2">
544			<anchor x="1" y="a"/>
545			<outline>
546			</outline>
547		</glyph>
548		"""
549		py = """
550		glyph.name = "a"
551		glyph.anchors = [{"x" : 1, "y" : "a"}]
552		"""
553		self.assertRaises(GlifLibError, self.pyToGLIF, py)
554		self.assertRaises(GlifLibError, self.glifToPy, glif)
555
556	def testAnchors_illegal_x_missing(self):
557		# x missing
558		glif = """
559		<glyph name="a" format="2">
560			<anchor y="1"/>
561			<outline>
562			</outline>
563		</glyph>
564		"""
565		py = """
566		glyph.name = "a"
567		glyph.anchors = [{"y" : 1}]
568		"""
569		self.assertRaises(GlifLibError, self.pyToGLIF, py)
570		self.assertRaises(GlifLibError, self.glifToPy, glif)
571
572	def testAnchors_illegal_y_missing(self):
573		# y missing
574		glif = """
575		<glyph name="a" format="2">
576			<anchor x="1"/>
577			<outline>
578			</outline>
579		</glyph>
580		"""
581		py = """
582		glyph.name = "a"
583		glyph.anchors = [{"x" : 1}]
584		"""
585		self.assertRaises(GlifLibError, self.pyToGLIF, py)
586		self.assertRaises(GlifLibError, self.glifToPy, glif)
587
588	def testImage_legal(self):
589		# legal
590		glif = """
591		<glyph name="a" format="2">
592			<image fileName="test.png" xScale="2" xyScale="3" yxScale="6" yScale="5" xOffset="1" yOffset="4" color="1,1,1,1"/>
593			<outline>
594			</outline>
595		</glyph>
596		"""
597		py = """
598		glyph.name = "a"
599		glyph.image = {"color" : "1,1,1,1", "fileName" : "test.png", "xOffset" : 1, "xScale" : 2, "xyScale" : 3, "yOffset" : 4, "yScale" : 5, "yxScale" : 6}
600		"""
601		resultGlif = self.pyToGLIF(py)
602		resultPy = self.glifToPy(glif)
603		self.assertEqual(glif, resultGlif)
604		self.assertEqual(py, resultPy)
605
606	def testImage_legal_no_color_or_transformation(self):
607		# legal: no color or transformation
608		glif = """
609		<glyph name="a" format="2">
610			<image fileName="test.png"/>
611			<outline>
612			</outline>
613		</glyph>
614		"""
615		py = """
616		glyph.name = "a"
617		glyph.image = {"fileName" : "test.png", "xOffset" : 0, "xScale" : 1, "xyScale" : 0, "yOffset" : 0, "yScale" : 1, "yxScale" : 0}
618		"""
619		resultGlif = self.pyToGLIF(py)
620		resultPy = self.glifToPy(glif)
621		self.assertEqual(glif, resultGlif)
622		self.assertEqual(py, resultPy)
623
624	def testImage_illegal_no_file_name(self):
625		# no file name
626		glif = """
627		<glyph name="a" format="2">
628			<image xScale="2" xyScale="3" yxScale="6" yScale="5" xOffset="1" yOffset="4" color="1,1,1,1"/>
629			<outline>
630			</outline>
631		</glyph>
632		"""
633		py = """
634		glyph.name = "a"
635		glyph.image = {"color" : "1,1,1,1", "xOffset" : 1, "xScale" : 2, "xyScale" : 3, "yOffset" : 4, "yScale" : 5, "yxScale" : 6}
636		"""
637		self.assertRaises(GlifLibError, self.pyToGLIF, py)
638		self.assertRaises(GlifLibError, self.glifToPy, glif)
639
640	def testImage_bogus_transformation(self):
641		# bogus transformation
642		glif = """
643		<glyph name="a" format="2">
644			<image fileName="test.png" xScale="a" xyScale="3" yxScale="6" yScale="5" xOffset="1" yOffset="4"/>
645			<outline>
646			</outline>
647		</glyph>
648		"""
649		py = """
650		glyph.name = "a"
651		glyph.image = {"fileName" : "test.png", "xOffset" : 1, "xScale" : "a", "xyScale" : 3, "yOffset" : 4, "yScale" : 5, "yxScale" : 6}
652		"""
653		self.assertRaises(GlifLibError, self.pyToGLIF, py)
654		self.assertRaises(GlifLibError, self.glifToPy, glif)
655		glif = """
656		<glyph name="a" format="2">
657			<image fileName="test.png" xScale="2" xyScale="a" yxScale="6" yScale="5" xOffset="1" yOffset="4"/>
658			<outline>
659			</outline>
660		</glyph>
661		"""
662		py = """
663		glyph.name = "a"
664		glyph.image = {"fileName" : "test.png", "xOffset" : 1, "xScale" : 2, "xyScale" : "a", "yOffset" : 4, "yScale" : 5, "yxScale" : 6}
665		"""
666		self.assertRaises(GlifLibError, self.pyToGLIF, py)
667		self.assertRaises(GlifLibError, self.glifToPy, glif)
668		glif = """
669		<glyph name="a" format="2">
670			<image fileName="test.png" xScale="2" xyScale="3" yxScale="a" yScale="5" xOffset="1" yOffset="4"/>
671			<outline>
672			</outline>
673		</glyph>
674		"""
675		py = """
676		glyph.name = "a"
677		glyph.image = {"fileName" : "test.png", "xOffset" : 1, "xScale" : 2, "xyScale" : 3, "yOffset" : 4, "yScale" : 5, "yxScale" : "a"}
678		"""
679		self.assertRaises(GlifLibError, self.pyToGLIF, py)
680		self.assertRaises(GlifLibError, self.glifToPy, glif)
681		glif = """
682		<glyph name="a" format="2">
683			<image fileName="test.png" xScale="2" xyScale="3" yxScale="6" yScale="a" xOffset="1" yOffset="4"/>
684			<outline>
685			</outline>
686		</glyph>
687		"""
688		py = """
689		glyph.name = "a"
690		glyph.image = {"fileName" : "test.png", "xOffset" : 1, "xScale" : 2, "xyScale" : 3, "yOffset" : 4, "yScale" : "a", "yxScale" : 6}
691		"""
692		self.assertRaises(GlifLibError, self.pyToGLIF, py)
693		self.assertRaises(GlifLibError, self.glifToPy, glif)
694		glif = """
695		<glyph name="a" format="2">
696			<image fileName="test.png" xScale="2" xyScale="3" yxScale="6" yScale="5" xOffset="a" yOffset="4"/>
697			<outline>
698			</outline>
699		</glyph>
700		"""
701		py = """
702		glyph.name = "a"
703		glyph.image = {"fileName" : "test.png", "xOffset" : "a", "xScale" : 2, "xyScale" : 3, "yOffset" : 4, "yScale" : 5, "yxScale" : 6}
704		"""
705		self.assertRaises(GlifLibError, self.pyToGLIF, py)
706		self.assertRaises(GlifLibError, self.glifToPy, glif)
707		glif = """
708		<glyph name="a" format="2">
709			<image fileName="test.png" xScale="2" xyScale="3" yxScale="6" yScale="5" xOffset="1" yOffset="a"/>
710			<outline>
711			</outline>
712		</glyph>
713		"""
714		py = """
715		glyph.name = "a"
716		glyph.image = {"fileName" : "test.png", "xOffset" : 1, "xScale" : 2, "xyScale" : 3, "yOffset" : "a", "yScale" : 5, "yxScale" : 6}
717		"""
718		self.assertRaises(GlifLibError, self.pyToGLIF, py)
719		self.assertRaises(GlifLibError, self.glifToPy, glif)
720
721	def testImage_bogus_color(self):
722		# bogus color
723		glif = """
724		<glyph name="a" format="2">
725			<image fileName="test.png" color="1,1,1,x"/>
726			<outline>
727			</outline>
728		</glyph>
729		"""
730		py = """
731		glyph.name = "a"
732		glyph.image = {"color" : "1,1,1,x"}
733		"""
734		self.assertRaises(GlifLibError, self.pyToGLIF, py)
735		self.assertRaises(GlifLibError, self.glifToPy, glif)
736
737	def testOutline_unknown_element(self):
738		# unknown element
739		glif = """
740		<glyph name="a" format="2">
741			<outline>
742				<unknown/>
743			</outline>
744		</glyph>
745		"""
746		self.assertRaises(GlifLibError, self.glifToPy, glif)
747
748	def testOutline_content(self):
749		# content
750		glif = """
751		<glyph name="a" format="2">
752			<outline>
753				hello
754			</outline>
755		</glyph>
756		"""
757		self.assertRaises(GlifLibError, self.glifToPy, glif)
758
759	def testComponent_legal(self):
760		# legal
761		glif = """
762		<glyph name="a" format="2">
763			<outline>
764				<component base="x" xScale="2" xyScale="3" yxScale="6" yScale="5" xOffset="1" yOffset="4"/>
765			</outline>
766		</glyph>
767		"""
768		py = """
769		glyph.name = "a"
770		pointPen.addComponent(*["x", (2, 3, 6, 5, 1, 4)])
771		"""
772		resultGlif = self.pyToGLIF(py)
773		resultPy = self.glifToPy(glif)
774		self.assertEqual(glif, resultGlif)
775		self.assertEqual(py, resultPy)
776
777	def testComponent_illegal_no_base(self):
778		# no base
779		glif = """
780		<glyph name="a" format="2">
781			<outline>
782				<component xScale="2" xyScale="3" yxScale="6" yScale="5" xOffset="1" yOffset="4"/>
783			</outline>
784		</glyph>
785		"""
786		self.assertRaises(GlifLibError, self.glifToPy, glif)
787
788	def testComponent_illegal_bogus_transformation(self):
789		# bogus values in transformation
790		glif = """
791		<glyph name="a" format="2">
792			<outline>
793				<component base="x" xScale="a" xyScale="3" yxScale="6" yScale="5" xOffset="1" yOffset="4"/>
794			</outline>
795		</glyph>
796		"""
797		py = """
798		glyph.name = "a"
799		pointPen.addComponent(*["x", ("a", 3, 6, 5, 1, 4)])
800		"""
801		self.assertRaises(GlifLibError, self.pyToGLIF, py)
802		self.assertRaises(GlifLibError, self.glifToPy, glif)
803		glif = """
804		<glyph name="a" format="2">
805			<outline>
806				<component base="x" xScale="a" xyScale="3" yxScale="6" yScale="5" xOffset="1" yOffset="4"/>
807			</outline>
808		</glyph>
809		"""
810		py = """
811		glyph.name = "a"
812		pointPen.addComponent(*["x", (2, "a", 6, 5, 1, 4)])
813		"""
814		self.assertRaises(GlifLibError, self.pyToGLIF, py)
815		self.assertRaises(GlifLibError, self.glifToPy, glif)
816		glif = """
817		<glyph name="a" format="2">
818			<outline>
819				<component base="x" xScale="2" xyScale="3" yxScale="a" yScale="5" xOffset="1" yOffset="4"/>
820			</outline>
821		</glyph>
822		"""
823		py = """
824		glyph.name = "a"
825		pointPen.addComponent(*["x", (2, 3, "a", 5, 1, 4)])
826		"""
827		self.assertRaises(GlifLibError, self.pyToGLIF, py)
828		self.assertRaises(GlifLibError, self.glifToPy, glif)
829		glif = """
830		<glyph name="a" format="2">
831			<outline>
832				<component base="x" xScale="2" xyScale="3" yxScale="6" yScale="a" xOffset="1" yOffset="4"/>
833			</outline>
834		</glyph>
835		"""
836		py = """
837		glyph.name = "a"
838		pointPen.addComponent(*["x", (2, 3, 6, "a", 1, 4)])
839		"""
840		self.assertRaises(GlifLibError, self.pyToGLIF, py)
841		self.assertRaises(GlifLibError, self.glifToPy, glif)
842		glif = """
843		<glyph name="a" format="2">
844			<outline>
845				<component base="x" xScale="2" xyScale="3" yxScale="6" yScale="5" xOffset="a" yOffset="4"/>
846			</outline>
847		</glyph>
848		"""
849		py = """
850		glyph.name = "a"
851		pointPen.addComponent(*["x", (2, 3, 6, 5, "a", 4)])
852		"""
853		self.assertRaises(GlifLibError, self.pyToGLIF, py)
854		self.assertRaises(GlifLibError, self.glifToPy, glif)
855		glif = """
856		<glyph name="a" format="2">
857			<outline>
858				<component base="x" xScale="2" xyScale="3" yxScale="6" yScale="5" xOffset="1" yOffset="a"/>
859			</outline>
860		</glyph>
861		"""
862		py = """
863		glyph.name = "a"
864		pointPen.addComponent(*["x", (2, 3, 6, 5, 1, "a")])
865		"""
866		self.assertRaises(GlifLibError, self.pyToGLIF, py)
867		self.assertRaises(GlifLibError, self.glifToPy, glif)
868
869	def testContour_legal_one_contour(self):
870		# legal: one contour
871		glif = """
872		<glyph name="a" format="2">
873			<outline>
874				<contour>
875				</contour>
876			</outline>
877		</glyph>
878		"""
879		py = """
880		glyph.name = "a"
881		pointPen.beginPath()
882		pointPen.endPath()
883		"""
884		resultGlif = self.pyToGLIF(py)
885		resultPy = self.glifToPy(glif)
886		self.assertEqual(glif, resultGlif)
887		self.assertEqual(py, resultPy)
888
889	def testContour_legal_two_contours(self):
890		# legal: two contours
891		glif = """
892		<glyph name="a" format="2">
893			<outline>
894				<contour>
895					<point x="1" y="2" type="move"/>
896				</contour>
897				<contour>
898					<point x="1" y="2" type="move"/>
899					<point x="10" y="20" type="line"/>
900				</contour>
901			</outline>
902		</glyph>
903		"""
904		py = """
905		glyph.name = "a"
906		pointPen.beginPath()
907		pointPen.addPoint(*[(1, 2)], **{"segmentType" : "move", "smooth" : False})
908		pointPen.endPath()
909		pointPen.beginPath()
910		pointPen.addPoint(*[(1, 2)], **{"segmentType" : "move", "smooth" : False})
911		pointPen.addPoint(*[(10, 20)], **{"segmentType" : "line", "smooth" : False})
912		pointPen.endPath()
913		"""
914		resultGlif = self.pyToGLIF(py)
915		resultPy = self.glifToPy(glif)
916		self.assertEqual(glif, resultGlif)
917		self.assertEqual(py, resultPy)
918
919	def testContour_illegal_unkonwn_element(self):
920		# unknown element
921		glif = """
922		<glyph name="a" format="2">
923			<outline>
924				<contour>
925					<unknown/>
926				</contour>
927			</outline>
928		</glyph>
929		"""
930		self.assertRaises(GlifLibError, self.glifToPy, glif)
931
932	def testContourIdentifier(self):
933		glif = """
934		<glyph name="a" format="2">
935			<outline>
936				<contour identifier="foo">
937				</contour>
938			</outline>
939		</glyph>
940		"""
941		py = """
942		glyph.name = "a"
943		pointPen.beginPath(**{"identifier" : "foo"})
944		pointPen.endPath()
945		"""
946		resultGlif = self.pyToGLIF(py)
947		resultPy = self.glifToPy(glif)
948		self.assertEqual(glif, resultGlif)
949		self.assertEqual(py, resultPy)
950
951	def testPointCoordinates_legal_int(self):
952		# legal: int
953		glif = """
954		<glyph name="a" format="2">
955			<outline>
956				<contour>
957					<point x="1" y="-2" type="move"/>
958				</contour>
959			</outline>
960		</glyph>
961		"""
962		py = """
963		glyph.name = "a"
964		pointPen.beginPath()
965		pointPen.addPoint(*[(1, -2)], **{"segmentType" : "move", "smooth" : False})
966		pointPen.endPath()
967		"""
968		resultGlif = self.pyToGLIF(py)
969		resultPy = self.glifToPy(glif)
970		self.assertEqual(glif, resultGlif)
971		self.assertEqual(py, resultPy)
972
973	def testPointCoordinates_legal_float(self):
974		# legal: float
975		glif = """
976		<glyph name="a" format="2">
977			<outline>
978				<contour>
979					<point x="1.1" y="-2.2" type="move"/>
980				</contour>
981			</outline>
982		</glyph>
983		"""
984		py = """
985		glyph.name = "a"
986		pointPen.beginPath()
987		pointPen.addPoint(*[(1.1, -2.2)], **{"segmentType" : "move", "smooth" : False})
988		pointPen.endPath()
989		"""
990		resultGlif = self.pyToGLIF(py)
991		resultPy = self.glifToPy(glif)
992		self.assertEqual(glif, resultGlif)
993		self.assertEqual(py, resultPy)
994
995	def testPointCoordinates_illegal_x(self):
996		# illegal: x as string
997		glif = """
998		<glyph name="a" format="2">
999			<outline>
1000				<contour>
1001					<point x="a" y="2" type="move"/>
1002				</contour>
1003			</outline>
1004		</glyph>
1005		"""
1006		py = """
1007		glyph.name = "a"
1008		pointPen.beginPath()
1009		pointPen.addPoint(*[("a", 2)], **{"segmentType" : "move", "smooth" : False})
1010		pointPen.endPath()
1011		"""
1012		self.assertRaises(GlifLibError, self.pyToGLIF, py)
1013		self.assertRaises(GlifLibError, self.glifToPy, glif)
1014
1015	def testPointCoordinates_illegal_y(self):
1016		# illegal: y as string
1017		glif = """
1018		<glyph name="a" format="2">
1019			<outline>
1020				<contour>
1021					<point x="1" y="a" type="move"/>
1022				</contour>
1023			</outline>
1024		</glyph>
1025		"""
1026		py = """
1027		glyph.name = "a"
1028		pointPen.beginPath()
1029		pointPen.addPoint(*[(1, "a")], **{"segmentType" : "move", "smooth" : False})
1030		pointPen.endPath()
1031		"""
1032		self.assertRaises(GlifLibError, self.pyToGLIF, py)
1033		self.assertRaises(GlifLibError, self.glifToPy, glif)
1034
1035	def testPointTypeMove_legal(self):
1036		# legal
1037		glif = """
1038		<glyph name="a" format="2">
1039			<outline>
1040				<contour>
1041					<point x="1" y="-2" type="move"/>
1042					<point x="3" y="-4" type="line"/>
1043				</contour>
1044			</outline>
1045		</glyph>
1046		"""
1047		py = """
1048		glyph.name = "a"
1049		pointPen.beginPath()
1050		pointPen.addPoint(*[(1, -2)], **{"segmentType" : "move", "smooth" : False})
1051		pointPen.addPoint(*[(3, -4)], **{"segmentType" : "line", "smooth" : False})
1052		pointPen.endPath()
1053		"""
1054		resultGlif = self.pyToGLIF(py)
1055		resultPy = self.glifToPy(glif)
1056		self.assertEqual(glif, resultGlif)
1057		self.assertEqual(py, resultPy)
1058
1059	def testPointTypeMove_legal_smooth(self):
1060		# legal: smooth=True
1061		glif = """
1062		<glyph name="a" format="2">
1063			<outline>
1064				<contour>
1065					<point x="1" y="-2" type="move" smooth="yes"/>
1066					<point x="3" y="-4" type="line"/>
1067				</contour>
1068			</outline>
1069		</glyph>
1070		"""
1071		py = """
1072		glyph.name = "a"
1073		pointPen.beginPath()
1074		pointPen.addPoint(*[(1, -2)], **{"segmentType" : "move", "smooth" : True})
1075		pointPen.addPoint(*[(3, -4)], **{"segmentType" : "line", "smooth" : False})
1076		pointPen.endPath()
1077		"""
1078		resultGlif = self.pyToGLIF(py)
1079		resultPy = self.glifToPy(glif)
1080		self.assertEqual(glif, resultGlif)
1081		self.assertEqual(py, resultPy)
1082
1083	def testPointTypeMove_illegal_not_at_start(self):
1084		# illegal: not at start
1085		glif = """
1086		<glyph name="a" format="2">
1087			<outline>
1088				<contour>
1089					<point x="3" y="-4" type="line"/>
1090					<point x="1" y="-2" type="move"/>
1091				</contour>
1092			</outline>
1093		</glyph>
1094		"""
1095		py = """
1096		glyph.name = "a"
1097		pointPen.beginPath()
1098		pointPen.addPoint(*[(3, -4)], **{"segmentType" : "line", "smooth" : False})
1099		pointPen.addPoint(*[(1, -2)], **{"segmentType" : "move", "smooth" : False})
1100		pointPen.endPath()
1101		"""
1102		self.assertRaises(GlifLibError, self.pyToGLIF, py)
1103		self.assertRaises(GlifLibError, self.glifToPy, glif)
1104
1105	def testPointTypeLine_legal(self):
1106		# legal
1107		glif = """
1108		<glyph name="a" format="2">
1109			<outline>
1110				<contour>
1111					<point x="1" y="-2" type="move"/>
1112					<point x="3" y="-4" type="line"/>
1113				</contour>
1114			</outline>
1115		</glyph>
1116		"""
1117		py = """
1118		glyph.name = "a"
1119		pointPen.beginPath()
1120		pointPen.addPoint(*[(1, -2)], **{"segmentType" : "move", "smooth" : False})
1121		pointPen.addPoint(*[(3, -4)], **{"segmentType" : "line", "smooth" : False})
1122		pointPen.endPath()
1123		"""
1124		resultGlif = self.pyToGLIF(py)
1125		resultPy = self.glifToPy(glif)
1126		self.assertEqual(glif, resultGlif)
1127		self.assertEqual(py, resultPy)
1128
1129	def testPointTypeLine_legal_start_of_contour(self):
1130		# legal: start of contour
1131		glif = """
1132		<glyph name="a" format="2">
1133			<outline>
1134				<contour>
1135					<point x="1" y="-2" type="line"/>
1136					<point x="3" y="-4" type="line"/>
1137				</contour>
1138			</outline>
1139		</glyph>
1140		"""
1141		py = """
1142		glyph.name = "a"
1143		pointPen.beginPath()
1144		pointPen.addPoint(*[(1, -2)], **{"segmentType" : "line", "smooth" : False})
1145		pointPen.addPoint(*[(3, -4)], **{"segmentType" : "line", "smooth" : False})
1146		pointPen.endPath()
1147		"""
1148		resultGlif = self.pyToGLIF(py)
1149		resultPy = self.glifToPy(glif)
1150		self.assertEqual(glif, resultGlif)
1151		self.assertEqual(py, resultPy)
1152
1153	def testPointTypeLine_legal_smooth(self):
1154		# legal: smooth=True
1155		glif = """
1156		<glyph name="a" format="2">
1157			<outline>
1158				<contour>
1159					<point x="1" y="-2" type="move"/>
1160					<point x="3" y="-4" type="line" smooth="yes"/>
1161				</contour>
1162			</outline>
1163		</glyph>
1164		"""
1165		py = """
1166		glyph.name = "a"
1167		pointPen.beginPath()
1168		pointPen.addPoint(*[(1, -2)], **{"segmentType" : "move", "smooth" : False})
1169		pointPen.addPoint(*[(3, -4)], **{"segmentType" : "line", "smooth" : True})
1170		pointPen.endPath()
1171		"""
1172		resultGlif = self.pyToGLIF(py)
1173		resultPy = self.glifToPy(glif)
1174		self.assertEqual(glif, resultGlif)
1175		self.assertEqual(py, resultPy)
1176
1177	def testPointTypeCurve_legal(self):
1178		# legal
1179		glif = """
1180		<glyph name="a" format="2">
1181			<outline>
1182				<contour>
1183					<point x="0" y="0" type="move"/>
1184					<point x="0" y="65"/>
1185					<point x="65" y="200"/>
1186					<point x="100" y="200" type="curve"/>
1187				</contour>
1188			</outline>
1189		</glyph>
1190		"""
1191		py = """
1192		glyph.name = "a"
1193		pointPen.beginPath()
1194		pointPen.addPoint(*[(0, 0)], **{"segmentType" : "move", "smooth" : False})
1195		pointPen.addPoint(*[(0, 65)], **{"smooth" : False})
1196		pointPen.addPoint(*[(65, 200)], **{"smooth" : False})
1197		pointPen.addPoint(*[(100, 200)], **{"segmentType" : "curve", "smooth" : False})
1198		pointPen.endPath()
1199		"""
1200		resultGlif = self.pyToGLIF(py)
1201		resultPy = self.glifToPy(glif)
1202		self.assertEqual(glif, resultGlif)
1203		self.assertEqual(py, resultPy)
1204
1205	def testPointTypeCurve_legal_start_of_contour(self):
1206		# legal: start of contour
1207		glif = """
1208		<glyph name="a" format="2">
1209			<outline>
1210				<contour>
1211					<point x="100" y="200" type="curve"/>
1212					<point x="0" y="65"/>
1213					<point x="65" y="200"/>
1214				</contour>
1215			</outline>
1216		</glyph>
1217		"""
1218		py = """
1219		glyph.name = "a"
1220		pointPen.beginPath()
1221		pointPen.addPoint(*[(100, 200)], **{"segmentType" : "curve", "smooth" : False})
1222		pointPen.addPoint(*[(0, 65)], **{"smooth" : False})
1223		pointPen.addPoint(*[(65, 200)], **{"smooth" : False})
1224		pointPen.endPath()
1225		"""
1226		resultGlif = self.pyToGLIF(py)
1227		resultPy = self.glifToPy(glif)
1228		self.assertEqual(glif, resultGlif)
1229		self.assertEqual(py, resultPy)
1230
1231	def testPointTypeCurve_legal_smooth(self):
1232		# legal: smooth=True
1233		glif = """
1234		<glyph name="a" format="2">
1235			<outline>
1236				<contour>
1237					<point x="0" y="0" type="move"/>
1238					<point x="0" y="65"/>
1239					<point x="65" y="200"/>
1240					<point x="100" y="200" type="curve" smooth="yes"/>
1241				</contour>
1242			</outline>
1243		</glyph>
1244		"""
1245		py = """
1246		glyph.name = "a"
1247		pointPen.beginPath()
1248		pointPen.addPoint(*[(0, 0)], **{"segmentType" : "move", "smooth" : False})
1249		pointPen.addPoint(*[(0, 65)], **{"smooth" : False})
1250		pointPen.addPoint(*[(65, 200)], **{"smooth" : False})
1251		pointPen.addPoint(*[(100, 200)], **{"segmentType" : "curve", "smooth" : True})
1252		pointPen.endPath()
1253		"""
1254		resultGlif = self.pyToGLIF(py)
1255		resultPy = self.glifToPy(glif)
1256		self.assertEqual(glif, resultGlif)
1257		self.assertEqual(py, resultPy)
1258
1259	def testPointTypeCurve_legal_no_off_curves(self):
1260		# legal: no off-curves
1261		glif = """
1262		<glyph name="a" format="2">
1263			<outline>
1264				<contour>
1265					<point x="0" y="0" type="move"/>
1266					<point x="100" y="200" type="curve"/>
1267				</contour>
1268			</outline>
1269		</glyph>
1270		"""
1271		py = """
1272		glyph.name = "a"
1273		pointPen.beginPath()
1274		pointPen.addPoint(*[(0, 0)], **{"segmentType" : "move", "smooth" : False})
1275		pointPen.addPoint(*[(100, 200)], **{"segmentType" : "curve", "smooth" : False})
1276		pointPen.endPath()
1277		"""
1278		resultGlif = self.pyToGLIF(py)
1279		resultPy = self.glifToPy(glif)
1280		self.assertEqual(glif, resultGlif)
1281		self.assertEqual(py, resultPy)
1282
1283	def testPointTypeCurve_legal_1_off_curve(self):
1284		# legal: 1 off-curve
1285		glif = """
1286		<glyph name="a" format="2">
1287			<outline>
1288				<contour>
1289					<point x="0" y="0" type="move"/>
1290					<point x="50" y="100"/>
1291					<point x="100" y="200" type="curve"/>
1292				</contour>
1293			</outline>
1294		</glyph>
1295		"""
1296		py = """
1297		glyph.name = "a"
1298		pointPen.beginPath()
1299		pointPen.addPoint(*[(0, 0)], **{"segmentType" : "move", "smooth" : False})
1300		pointPen.addPoint(*[(50, 100)], **{"smooth" : False})
1301		pointPen.addPoint(*[(100, 200)], **{"segmentType" : "curve", "smooth" : False})
1302		pointPen.endPath()
1303		"""
1304		resultGlif = self.pyToGLIF(py)
1305		resultPy = self.glifToPy(glif)
1306		self.assertEqual(glif, resultGlif)
1307		self.assertEqual(py, resultPy)
1308
1309	def testPointTypeCurve_illegal_3_off_curves(self):
1310		# illegal: 3 off-curves
1311		glif = """
1312		<glyph name="a" format="2">
1313			<outline>
1314				<contour>
1315					<point x="0" y="0" type="move"/>
1316					<point x="0" y="100"/>
1317					<point x="35" y="125"/>
1318					<point x="65" y="200"/>
1319					<point x="100" y="200" type="curve"/>
1320				</contour>
1321			</outline>
1322		</glyph>
1323		"""
1324		py = """
1325		glyph.name = "a"
1326		pointPen.beginPath()
1327		pointPen.addPoint(*[(0, 0)], **{"segmentType" : "move", "smooth" : False})
1328		pointPen.addPoint(*[(0, 100)], **{"smooth" : False})
1329		pointPen.addPoint(*[(35, 125)], **{"smooth" : False})
1330		pointPen.addPoint(*[(65, 200)], **{"smooth" : False})
1331		pointPen.addPoint(*[(100, 200)], **{"segmentType" : "curve", "smooth" : False})
1332		pointPen.endPath()
1333		"""
1334		self.assertRaises(GlifLibError, self.pyToGLIF, py)
1335		self.assertRaises(GlifLibError, self.glifToPy, glif)
1336
1337	def testPointQCurve_legal(self):
1338		# legal
1339		glif = """
1340		<glyph name="a" format="2">
1341			<outline>
1342				<contour>
1343					<point x="0" y="0" type="move"/>
1344					<point x="0" y="65"/>
1345					<point x="65" y="200"/>
1346					<point x="100" y="200" type="qcurve"/>
1347				</contour>
1348			</outline>
1349		</glyph>
1350		"""
1351		py = """
1352		glyph.name = "a"
1353		pointPen.beginPath()
1354		pointPen.addPoint(*[(0, 0)], **{"segmentType" : "move", "smooth" : False})
1355		pointPen.addPoint(*[(0, 65)], **{"smooth" : False})
1356		pointPen.addPoint(*[(65, 200)], **{"smooth" : False})
1357		pointPen.addPoint(*[(100, 200)], **{"segmentType" : "qcurve", "smooth" : False})
1358		pointPen.endPath()
1359		"""
1360		resultGlif = self.pyToGLIF(py)
1361		resultPy = self.glifToPy(glif)
1362		self.assertEqual(glif, resultGlif)
1363		self.assertEqual(py, resultPy)
1364
1365	def testPointQCurve_legal_start_of_contour(self):
1366		# legal: start of contour
1367		glif = """
1368		<glyph name="a" format="2">
1369			<outline>
1370				<contour>
1371					<point x="100" y="200" type="qcurve"/>
1372					<point x="0" y="65"/>
1373					<point x="65" y="200"/>
1374				</contour>
1375			</outline>
1376		</glyph>
1377		"""
1378		py = """
1379		glyph.name = "a"
1380		pointPen.beginPath()
1381		pointPen.addPoint(*[(100, 200)], **{"segmentType" : "qcurve", "smooth" : False})
1382		pointPen.addPoint(*[(0, 65)], **{"smooth" : False})
1383		pointPen.addPoint(*[(65, 200)], **{"smooth" : False})
1384		pointPen.endPath()
1385		"""
1386		resultGlif = self.pyToGLIF(py)
1387		resultPy = self.glifToPy(glif)
1388		self.assertEqual(glif, resultGlif)
1389		self.assertEqual(py, resultPy)
1390
1391	def testPointQCurve_legal_smooth(self):
1392		# legal: smooth=True
1393		glif = """
1394		<glyph name="a" format="2">
1395			<outline>
1396				<contour>
1397					<point x="0" y="0" type="move"/>
1398					<point x="0" y="65"/>
1399					<point x="65" y="200"/>
1400					<point x="100" y="200" type="qcurve" smooth="yes"/>
1401				</contour>
1402			</outline>
1403		</glyph>
1404		"""
1405		py = """
1406		glyph.name = "a"
1407		pointPen.beginPath()
1408		pointPen.addPoint(*[(0, 0)], **{"segmentType" : "move", "smooth" : False})
1409		pointPen.addPoint(*[(0, 65)], **{"smooth" : False})
1410		pointPen.addPoint(*[(65, 200)], **{"smooth" : False})
1411		pointPen.addPoint(*[(100, 200)], **{"segmentType" : "qcurve", "smooth" : True})
1412		pointPen.endPath()
1413		"""
1414		resultGlif = self.pyToGLIF(py)
1415		resultPy = self.glifToPy(glif)
1416		self.assertEqual(glif, resultGlif)
1417		self.assertEqual(py, resultPy)
1418
1419	def testPointQCurve_legal_no_off_curves(self):
1420		# legal: no off-curves
1421		glif = """
1422		<glyph name="a" format="2">
1423			<outline>
1424				<contour>
1425					<point x="0" y="0" type="move"/>
1426					<point x="100" y="200" type="qcurve"/>
1427				</contour>
1428			</outline>
1429		</glyph>
1430		"""
1431		py = """
1432		glyph.name = "a"
1433		pointPen.beginPath()
1434		pointPen.addPoint(*[(0, 0)], **{"segmentType" : "move", "smooth" : False})
1435		pointPen.addPoint(*[(100, 200)], **{"segmentType" : "qcurve", "smooth" : False})
1436		pointPen.endPath()
1437		"""
1438		resultGlif = self.pyToGLIF(py)
1439		resultPy = self.glifToPy(glif)
1440		self.assertEqual(glif, resultGlif)
1441		self.assertEqual(py, resultPy)
1442
1443	def testPointQCurve_legal_one_off_curve(self):
1444		# legal: 1 off-curve
1445		glif = """
1446		<glyph name="a" format="2">
1447			<outline>
1448				<contour>
1449					<point x="0" y="0" type="move"/>
1450					<point x="50" y="100"/>
1451					<point x="100" y="200" type="qcurve"/>
1452				</contour>
1453			</outline>
1454		</glyph>
1455		"""
1456		py = """
1457		glyph.name = "a"
1458		pointPen.beginPath()
1459		pointPen.addPoint(*[(0, 0)], **{"segmentType" : "move", "smooth" : False})
1460		pointPen.addPoint(*[(50, 100)], **{"smooth" : False})
1461		pointPen.addPoint(*[(100, 200)], **{"segmentType" : "qcurve", "smooth" : False})
1462		pointPen.endPath()
1463		"""
1464		resultGlif = self.pyToGLIF(py)
1465		resultPy = self.glifToPy(glif)
1466		self.assertEqual(glif, resultGlif)
1467		self.assertEqual(py, resultPy)
1468
1469	def testPointQCurve_legal_3_off_curves(self):
1470		# legal: 3 off-curves
1471		glif = """
1472		<glyph name="a" format="2">
1473			<outline>
1474				<contour>
1475					<point x="0" y="0" type="move"/>
1476					<point x="0" y="100"/>
1477					<point x="35" y="125"/>
1478					<point x="65" y="200"/>
1479					<point x="100" y="200" type="qcurve"/>
1480				</contour>
1481			</outline>
1482		</glyph>
1483		"""
1484		py = """
1485		glyph.name = "a"
1486		pointPen.beginPath()
1487		pointPen.addPoint(*[(0, 0)], **{"segmentType" : "move", "smooth" : False})
1488		pointPen.addPoint(*[(0, 100)], **{"smooth" : False})
1489		pointPen.addPoint(*[(35, 125)], **{"smooth" : False})
1490		pointPen.addPoint(*[(65, 200)], **{"smooth" : False})
1491		pointPen.addPoint(*[(100, 200)], **{"segmentType" : "qcurve", "smooth" : False})
1492		pointPen.endPath()
1493		"""
1494		resultGlif = self.pyToGLIF(py)
1495		resultPy = self.glifToPy(glif)
1496		self.assertEqual(glif, resultGlif)
1497		self.assertEqual(py, resultPy)
1498
1499	def testSpecialCaseQCurve_legal_no_on_curve(self):
1500		# contour with no on curve
1501		glif = """
1502		<glyph name="a" format="2">
1503			<outline>
1504				<contour>
1505					<point x="0" y="0"/>
1506					<point x="0" y="100"/>
1507					<point x="100" y="100"/>
1508					<point x="100" y="0"/>
1509				</contour>
1510			</outline>
1511		</glyph>
1512		"""
1513		py = """
1514		glyph.name = "a"
1515		pointPen.beginPath()
1516		pointPen.addPoint(*[(0, 0)], **{"smooth" : False})
1517		pointPen.addPoint(*[(0, 100)], **{"smooth" : False})
1518		pointPen.addPoint(*[(100, 100)], **{"smooth" : False})
1519		pointPen.addPoint(*[(100, 0)], **{"smooth" : False})
1520		pointPen.endPath()
1521		"""
1522		resultGlif = self.pyToGLIF(py)
1523		resultPy = self.glifToPy(glif)
1524		self.assertEqual(glif, resultGlif)
1525		self.assertEqual(py, resultPy)
1526
1527	def testPointTypeOffCurve_legal(self):
1528		# legal
1529		glif = """
1530		<glyph name="a" format="2">
1531			<outline>
1532				<contour>
1533					<point x="0" y="0" type="move"/>
1534					<point x="0" y="65"/>
1535					<point x="65" y="200"/>
1536					<point x="100" y="200" type="curve"/>
1537				</contour>
1538			</outline>
1539		</glyph>
1540		"""
1541		py = """
1542		glyph.name = "a"
1543		pointPen.beginPath()
1544		pointPen.addPoint(*[(0, 0)], **{"segmentType" : "move", "smooth" : False})
1545		pointPen.addPoint(*[(0, 65)], **{"smooth" : False})
1546		pointPen.addPoint(*[(65, 200)], **{"smooth" : False})
1547		pointPen.addPoint(*[(100, 200)], **{"segmentType" : "curve", "smooth" : False})
1548		pointPen.endPath()
1549		"""
1550		resultGlif = self.pyToGLIF(py)
1551		resultPy = self.glifToPy(glif)
1552		self.assertEqual(glif, resultGlif)
1553		self.assertEqual(py, resultPy)
1554
1555	def testPointTypeOffCurve_legal_start_of_contour(self):
1556		# legal: start of contour
1557		glif = """
1558		<glyph name="a" format="2">
1559			<outline>
1560				<contour>
1561					<point x="0" y="65"/>
1562					<point x="65" y="200"/>
1563					<point x="100" y="200" type="curve"/>
1564				</contour>
1565			</outline>
1566		</glyph>
1567		"""
1568		py = """
1569		glyph.name = "a"
1570		pointPen.beginPath()
1571		pointPen.addPoint(*[(0, 65)], **{"smooth" : False})
1572		pointPen.addPoint(*[(65, 200)], **{"smooth" : False})
1573		pointPen.addPoint(*[(100, 200)], **{"segmentType" : "curve", "smooth" : False})
1574		pointPen.endPath()
1575		"""
1576		resultGlif = self.pyToGLIF(py)
1577		resultPy = self.glifToPy(glif)
1578		self.assertEqual(glif, resultGlif)
1579		self.assertEqual(py, resultPy)
1580
1581	def testPointTypeOffCurve_illegal_before_move(self):
1582		# before move
1583		glif = """
1584		<glyph name="a" format="2">
1585			<outline>
1586				<contour>
1587					<point x="0" y="65"/>
1588					<point x="0" y="0" type="move"/>
1589				</contour>
1590			</outline>
1591		</glyph>
1592		"""
1593		py = """
1594		glyph.name = "a"
1595		pointPen.beginPath()
1596		pointPen.addPoint(*[(0, 65)], **{"smooth" : False})
1597		pointPen.addPoint(*[(0, 0)], **{"segmentType" : "move", "smooth" : False})
1598		pointPen.endPath()
1599		"""
1600		self.assertRaises(GlifLibError, self.pyToGLIF, py)
1601		self.assertRaises(GlifLibError, self.glifToPy, glif)
1602
1603	def testPointTypeOffCurve_illegal_before_line(self):
1604		# before line
1605		glif = """
1606		<glyph name="a" format="2">
1607			<outline>
1608				<contour>
1609					<point x="0" y="65"/>
1610					<point x="0" y="0" type="line"/>
1611				</contour>
1612			</outline>
1613		</glyph>
1614		"""
1615		py = """
1616		glyph.name = "a"
1617		pointPen.beginPath()
1618		pointPen.addPoint(*[(0, 65)], **{"smooth" : False})
1619		pointPen.addPoint(*[(0, 0)], **{"segmentType" : "line", "smooth" : False})
1620		pointPen.endPath()
1621		"""
1622		self.assertRaises(GlifLibError, self.pyToGLIF, py)
1623		self.assertRaises(GlifLibError, self.glifToPy, glif)
1624
1625	def testPointTypeOffCurve_illegal_smooth(self):
1626		# smooth=True
1627		glif = """
1628		<glyph name="a" format="2">
1629			<outline>
1630				<contour>
1631					<point x="0" y="65" smooth="yess"/>
1632					<point x="0" y="0" type="curve"/>
1633				</contour>
1634			</outline>
1635		</glyph>
1636		"""
1637		py = """
1638		glyph.name = "a"
1639		pointPen.beginPath()
1640		pointPen.addPoint(*[(0, 65)], **{"smooth" : True})
1641		pointPen.addPoint(*[(0, 0)], **{"segmentType" : "curve", "smooth" : False})
1642		pointPen.endPath()
1643		"""
1644		self.assertRaises(GlifLibError, self.pyToGLIF, py)
1645		self.assertRaises(GlifLibError, self.glifToPy, glif)
1646
1647	def testOpenContourLooseOffCurves(self):
1648		glif = """
1649		<glyph name="a" format="2">
1650			<outline>
1651				<contour>
1652					<point x="1" y="2" type="move"/>
1653					<point x="1" y="2"/>
1654					<point x="1" y="2"/>
1655					<point x="1" y="2" type="curve"/>
1656					<point x="1" y="2"/>
1657				</contour>
1658			</outline>
1659		</glyph>
1660		"""
1661		self.assertRaises(GlifLibError, self.glifToPy, glif)
1662		py = """
1663		glyph.name = "a"
1664		pointPen.beginPath()
1665		pointPen.addPoint(*[(1, 2)], **{"segmentType" : "move", "smooth" : False})
1666		pointPen.addPoint(*[(1, 2)], **{"smooth" : False})
1667		pointPen.addPoint(*[(1, 2)], **{"smooth" : False})
1668		pointPen.addPoint(*[(1, 2)], **{"segmentType" : "curve", "smooth" : False})
1669		pointPen.addPoint(*[(1, 2)], **{"smooth" : False})
1670		pointPen.endPath()
1671		"""
1672		self.assertRaises(GlifLibError, self.pyToGLIF, py)
1673
1674	def testPointIdentifier(self):
1675		glif = """
1676		<glyph name="a" format="2">
1677			<outline>
1678				<contour>
1679					<point x="1" y="-2" type="move" identifier="1"/>
1680					<point x="1" y="-2" type="line" identifier="2"/>
1681					<point x="1" y="-2" type="curve" identifier="3"/>
1682					<point x="1" y="-2" type="qcurve" identifier="4"/>
1683				</contour>
1684			</outline>
1685		</glyph>
1686		"""
1687		py = """
1688		glyph.name = "a"
1689		pointPen.beginPath()
1690		pointPen.addPoint(*[(1, -2)], **{"identifier" : "1", "segmentType" : "move", "smooth" : False})
1691		pointPen.addPoint(*[(1, -2)], **{"identifier" : "2", "segmentType" : "line", "smooth" : False})
1692		pointPen.addPoint(*[(1, -2)], **{"identifier" : "3", "segmentType" : "curve", "smooth" : False})
1693		pointPen.addPoint(*[(1, -2)], **{"identifier" : "4", "segmentType" : "qcurve", "smooth" : False})
1694		pointPen.endPath()
1695		"""
1696		resultGlif = self.pyToGLIF(py)
1697		resultPy = self.glifToPy(glif)
1698		self.assertEqual(glif, resultGlif)
1699		self.assertEqual(py, resultPy)
1700
1701	def testIdentifierConflict_legal_no_conflict(self):
1702		glif = """
1703		<glyph name="a" format="2">
1704			<guideline x="0" identifier="guideline1"/>
1705			<guideline x="0" identifier="guideline2"/>
1706			<anchor x="0" y="0" identifier="anchor1"/>
1707			<anchor x="0" y="0" identifier="anchor2"/>
1708			<outline>
1709				<contour identifier="contour1">
1710					<point x="1" y="-2" type="move" identifier="point1"/>
1711					<point x="1" y="-2" type="line" identifier="point2"/>
1712					<point x="1" y="-2" type="curve" identifier="point3"/>
1713					<point x="1" y="-2" type="qcurve" identifier="point4"/>
1714				</contour>
1715				<contour identifier="contour2">
1716					<point x="1" y="-2" type="move" identifier="point5"/>
1717				</contour>
1718				<component base="x" xyScale="1" yxScale="1" xOffset="1" yOffset="1" identifier="component1"/>
1719				<component base="x" xyScale="1" yxScale="1" xOffset="1" yOffset="1" identifier="component2"/>
1720			</outline>
1721		</glyph>
1722		"""
1723		py = """
1724		glyph.name = "a"
1725		glyph.guidelines = [{"identifier" : "guideline1", "x" : 0}, {"identifier" : "guideline2", "x" : 0}]
1726		glyph.anchors = [{"identifier" : "anchor1", "x" : 0, "y" : 0}, {"identifier" : "anchor2", "x" : 0, "y" : 0}]
1727		pointPen.beginPath(**{"identifier" : "contour1"})
1728		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point1", "segmentType" : "move", "smooth" : False})
1729		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point2", "segmentType" : "line", "smooth" : False})
1730		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point3", "segmentType" : "curve", "smooth" : False})
1731		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point4", "segmentType" : "qcurve", "smooth" : False})
1732		pointPen.endPath()
1733		pointPen.beginPath(**{"identifier" : "contour2"})
1734		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point5", "segmentType" : "move", "smooth" : False})
1735		pointPen.endPath()
1736		pointPen.addComponent(*["x", (1, 1, 1, 1, 1, 1)], **{"identifier" : "component1"})
1737		pointPen.addComponent(*["x", (1, 1, 1, 1, 1, 1)], **{"identifier" : "component2"})
1738		"""
1739		resultGlif = self.pyToGLIF(py)
1740		resultPy = self.glifToPy(glif)
1741		self.assertEqual(glif, resultGlif)
1742		self.assertEqual(py, resultPy)
1743
1744	def testIdentifierConflict_point_point(self):
1745		# point - point
1746		glif = """
1747		<glyph name="a" format="2">
1748			<guideline x="0" identifier="guideline1"/>
1749			<guideline x="0" identifier="guideline2"/>
1750			<anchor x="0" y="0" identifier="anchor1"/>
1751			<anchor x="0" y="0" identifier="anchor2"/>
1752			<outline>
1753				<contour identifier="contour1">
1754					<point x="1" y="-2" type="move" identifier="point1"/>
1755					<point x="1" y="-2" type="line" identifier="point1"/>
1756					<point x="1" y="-2" type="curve" identifier="point3"/>
1757					<point x="1" y="-2" type="qcurve" identifier="point4"/>
1758				</contour>
1759				<contour identifier="contour2">
1760					<point x="1" y="-2" type="move" identifier="point5"/>
1761				</contour>
1762				<component base="x" xyScale="1" yxScale="1" xOffset="1" yOffset="1" identifier="component1"/>
1763				<component base="x" xyScale="1" yxScale="1" xOffset="1" yOffset="1" identifier="component2"/>
1764			</outline>
1765		</glyph>
1766		"""
1767		py = """
1768		glyph.name = "a"
1769		glyph.guidelines = [{"identifier" : "guideline1", "x" : 0}, {"identifier" : "guideline2", "x" : 0}]
1770		glyph.anchors = [{"identifier" : "anchor1", "x" : 0, "y" : 0}, {"identifier" : "anchor2", "x" : 0, "y" : 0}]
1771		pointPen.beginPath(**{"identifier" : "contour1"})
1772		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point1", "segmentType" : "move", "smooth" : False})
1773		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point1", "segmentType" : "line", "smooth" : False})
1774		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point3", "segmentType" : "curve", "smooth" : False})
1775		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point4", "segmentType" : "qcurve", "smooth" : False})
1776		pointPen.endPath()
1777		pointPen.beginPath(**{"identifier" : "contour2"})
1778		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point5", "segmentType" : "move", "smooth" : False})
1779		pointPen.endPath()
1780		pointPen.addComponent(*["x", (1, 1, 1, 1, 1, 1)], **{"identifier" : "component1"})
1781		pointPen.addComponent(*["x", (1, 1, 1, 1, 1, 1)], **{"identifier" : "component2"})
1782		"""
1783		self.assertRaises(GlifLibError, self.pyToGLIF, py)
1784		self.assertRaises(GlifLibError, self.glifToPy, glif)
1785
1786	def testIdentifierConflict_point_contour(self):
1787		# point - contour
1788		glif = """
1789		<glyph name="a" format="2">
1790			<guideline x="0" identifier="guideline1"/>
1791			<guideline x="0" identifier="guideline2"/>
1792			<anchor x="0" y="0" identifier="anchor1"/>
1793			<anchor x="0" y="0" identifier="anchor2"/>
1794			<outline>
1795				<contour identifier="contour1">
1796					<point x="1" y="-2" type="move" identifier="contour1"/>
1797					<point x="1" y="-2" type="line" identifier="point2"/>
1798					<point x="1" y="-2" type="curve" identifier="point3"/>
1799					<point x="1" y="-2" type="qcurve" identifier="point4"/>
1800				</contour>
1801				<contour identifier="contour2">
1802					<point x="1" y="-2" type="move" identifier="point5"/>
1803				</contour>
1804				<component base="x" xyScale="1" yxScale="1" xOffset="1" yOffset="1" identifier="component1"/>
1805				<component base="x" xyScale="1" yxScale="1" xOffset="1" yOffset="1" identifier="component2"/>
1806			</outline>
1807		</glyph>
1808		"""
1809		py = """
1810		glyph.name = "a"
1811		glyph.guidelines = [{"identifier" : "guideline1", "x" : 0}, {"identifier" : "guideline2", "x" : 0}]
1812		glyph.anchors = [{"identifier" : "anchor1", "x" : 0, "y" : 0}, {"identifier" : "anchor2", "x" : 0, "y" : 0}]
1813		pointPen.beginPath(**{"identifier" : "contour1"})
1814		pointPen.addPoint(*[(1, -2)], **{"identifier" : "contour1", "segmentType" : "move", "smooth" : False})
1815		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point2", "segmentType" : "line", "smooth" : False})
1816		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point3", "segmentType" : "curve", "smooth" : False})
1817		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point4", "segmentType" : "qcurve", "smooth" : False})
1818		pointPen.endPath()
1819		pointPen.beginPath(**{"identifier" : "contour2"})
1820		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point5", "segmentType" : "move", "smooth" : False})
1821		pointPen.endPath()
1822		pointPen.addComponent(*["x", (1, 1, 1, 1, 1, 1)], **{"identifier" : "component1"})
1823		pointPen.addComponent(*["x", (1, 1, 1, 1, 1, 1)], **{"identifier" : "component2"})
1824		"""
1825		self.assertRaises(GlifLibError, self.pyToGLIF, py)
1826		self.assertRaises(GlifLibError, self.glifToPy, glif)
1827
1828	def testIdentifierConflict_point_component(self):
1829		# point - component
1830		glif = """
1831		<glyph name="a" format="2">
1832			<guideline x="0" identifier="guideline1"/>
1833			<guideline x="0" identifier="guideline2"/>
1834			<anchor x="0" y="0" identifier="anchor1"/>
1835			<anchor x="0" y="0" identifier="anchor2"/>
1836			<outline>
1837				<contour identifier="contour1">
1838					<point x="1" y="-2" type="move" identifier="component1"/>
1839					<point x="1" y="-2" type="line" identifier="point2"/>
1840					<point x="1" y="-2" type="curve" identifier="point3"/>
1841					<point x="1" y="-2" type="qcurve" identifier="point4"/>
1842				</contour>
1843				<contour identifier="contour2">
1844					<point x="1" y="-2" type="move" identifier="point5"/>
1845				</contour>
1846				<component base="x" xyScale="1" yxScale="1" xOffset="1" yOffset="1" identifier="component1"/>
1847				<component base="x" xyScale="1" yxScale="1" xOffset="1" yOffset="1" identifier="component2"/>
1848			</outline>
1849		</glyph>
1850		"""
1851		py = """
1852		glyph.name = "a"
1853		glyph.guidelines = [{"identifier" : "guideline1", "x" : 0}, {"identifier" : "guideline2", "x" : 0}]
1854		glyph.anchors = [{"identifier" : "anchor1", "x" : 0, "y" : 0}, {"identifier" : "anchor2", "x" : 0, "y" : 0}]
1855		pointPen.beginPath(**{"identifier" : "contour1"})
1856		pointPen.addPoint(*[(1, -2)], **{"identifier" : "component1", "segmentType" : "move", "smooth" : False})
1857		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point2", "segmentType" : "line", "smooth" : False})
1858		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point3", "segmentType" : "curve", "smooth" : False})
1859		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point4", "segmentType" : "qcurve", "smooth" : False})
1860		pointPen.endPath()
1861		pointPen.beginPath(**{"identifier" : "contour2"})
1862		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point5", "segmentType" : "move", "smooth" : False})
1863		pointPen.endPath()
1864		pointPen.addComponent(*["x", (1, 1, 1, 1, 1, 1)], **{"identifier" : "component1"})
1865		pointPen.addComponent(*["x", (1, 1, 1, 1, 1, 1)], **{"identifier" : "component2"})
1866		"""
1867		self.assertRaises(GlifLibError, self.pyToGLIF, py)
1868		self.assertRaises(GlifLibError, self.glifToPy, glif)
1869
1870	def testIdentifierConflict_point_guideline(self):
1871		# point - guideline
1872		glif = """
1873		<glyph name="a" format="2">
1874			<guideline x="0" identifier="guideline1"/>
1875			<guideline x="0" identifier="guideline2"/>
1876			<anchor x="0" y="0" identifier="anchor1"/>
1877			<anchor x="0" y="0" identifier="anchor2"/>
1878			<outline>
1879				<contour identifier="contour1">
1880					<point x="1" y="-2" type="move" identifier="guideline1"/>
1881					<point x="1" y="-2" type="line" identifier="point2"/>
1882					<point x="1" y="-2" type="curve" identifier="point3"/>
1883					<point x="1" y="-2" type="qcurve" identifier="point4"/>
1884				</contour>
1885				<contour identifier="contour2">
1886					<point x="1" y="-2" type="move" identifier="point5"/>
1887				</contour>
1888				<component base="x" xyScale="1" yxScale="1" xOffset="1" yOffset="1" identifier="component1"/>
1889				<component base="x" xyScale="1" yxScale="1" xOffset="1" yOffset="1" identifier="component2"/>
1890			</outline>
1891		</glyph>
1892		"""
1893		py = """
1894		glyph.name = "a"
1895		glyph.guidelines = [{"identifier" : "guideline1", "x" : 0}, {"identifier" : "guideline2", "x" : 0}]
1896		glyph.anchors = [{"identifier" : "anchor1", "x" : 0, "y" : 0}, {"identifier" : "anchor2", "x" : 0, "y" : 0}]
1897		pointPen.beginPath(**{"identifier" : "contour1"})
1898		pointPen.addPoint(*[(1, -2)], **{"identifier" : "guideline1", "segmentType" : "move", "smooth" : False})
1899		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point2", "segmentType" : "line", "smooth" : False})
1900		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point3", "segmentType" : "curve", "smooth" : False})
1901		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point4", "segmentType" : "qcurve", "smooth" : False})
1902		pointPen.endPath()
1903		pointPen.beginPath(**{"identifier" : "contour2"})
1904		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point5", "segmentType" : "move", "smooth" : False})
1905		pointPen.endPath()
1906		pointPen.addComponent(*["x", (1, 1, 1, 1, 1, 1)], **{"identifier" : "component1"})
1907		pointPen.addComponent(*["x", (1, 1, 1, 1, 1, 1)], **{"identifier" : "component2"})
1908		"""
1909		self.assertRaises(GlifLibError, self.pyToGLIF, py)
1910		self.assertRaises(GlifLibError, self.glifToPy, glif)
1911
1912	def testIdentifierConflict_point_anchor(self):
1913		# point - anchor
1914		glif = """
1915		<glyph name="a" format="2">
1916			<guideline x="0" identifier="guideline1"/>
1917			<guideline x="0" identifier="guideline2"/>
1918			<anchor x="0" y="0" identifier="anchor1"/>
1919			<anchor x="0" y="0" identifier="anchor2"/>
1920			<outline>
1921				<contour identifier="contour1">
1922					<point x="1" y="-2" type="move" identifier="anchor1"/>
1923					<point x="1" y="-2" type="line" identifier="point2"/>
1924					<point x="1" y="-2" type="curve" identifier="point3"/>
1925					<point x="1" y="-2" type="qcurve" identifier="point4"/>
1926				</contour>
1927				<contour identifier="contour2">
1928					<point x="1" y="-2" type="move" identifier="point5"/>
1929				</contour>
1930				<component base="x" xyScale="1" yxScale="1" xOffset="1" yOffset="1" identifier="component1"/>
1931				<component base="x" xyScale="1" yxScale="1" xOffset="1" yOffset="1" identifier="component2"/>
1932			</outline>
1933		</glyph>
1934		"""
1935		py = """
1936		glyph.name = "a"
1937		glyph.guidelines = [{"identifier" : "guideline1", "x" : 0}, {"identifier" : "guideline2", "x" : 0}]
1938		glyph.anchors = [{"identifier" : "anchor1", "x" : 0, "y" : 0}, {"identifier" : "anchor2", "x" : 0, "y" : 0}]
1939		pointPen.beginPath(**{"identifier" : "contour1"})
1940		pointPen.addPoint(*[(1, -2)], **{"identifier" : "anchor1", "segmentType" : "move", "smooth" : False})
1941		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point2", "segmentType" : "line", "smooth" : False})
1942		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point3", "segmentType" : "curve", "smooth" : False})
1943		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point4", "segmentType" : "qcurve", "smooth" : False})
1944		pointPen.endPath()
1945		pointPen.beginPath(**{"identifier" : "contour2"})
1946		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point5", "segmentType" : "move", "smooth" : False})
1947		pointPen.endPath()
1948		pointPen.addComponent(*["x", (1, 1, 1, 1, 1, 1)], **{"identifier" : "component1"})
1949		pointPen.addComponent(*["x", (1, 1, 1, 1, 1, 1)], **{"identifier" : "component2"})
1950		"""
1951		self.assertRaises(GlifLibError, self.pyToGLIF, py)
1952		self.assertRaises(GlifLibError, self.glifToPy, glif)
1953
1954	def testIdentifierConflict_contour_contour(self):
1955		# contour - contour
1956		glif = """
1957		<glyph name="a" format="2">
1958			<guideline x="0" identifier="guideline1"/>
1959			<guideline x="0" identifier="guideline2"/>
1960			<anchor x="0" y="0" identifier="anchor1"/>
1961			<anchor x="0" y="0" identifier="anchor2"/>
1962			<outline>
1963				<contour identifier="contour1">
1964					<point x="1" y="-2" type="move" identifier="point1"/>
1965					<point x="1" y="-2" type="line" identifier="point2"/>
1966					<point x="1" y="-2" type="curve" identifier="point3"/>
1967					<point x="1" y="-2" type="qcurve" identifier="point4"/>
1968				</contour>
1969				<contour identifier="contour1">
1970					<point x="1" y="-2" type="move" identifier="point5"/>
1971				</contour>
1972				<component base="x" xyScale="1" yxScale="1" xOffset="1" yOffset="1" identifier="component1"/>
1973				<component base="x" xyScale="1" yxScale="1" xOffset="1" yOffset="1" identifier="component2"/>
1974			</outline>
1975		</glyph>
1976		"""
1977		py = """
1978		glyph.name = "a"
1979		glyph.guidelines = [{"identifier" : "guideline1", "x" : 0}, {"identifier" : "guideline2", "x" : 0}]
1980		glyph.anchors = [{"identifier" : "anchor1", "x" : 0, "y" : 0}, {"identifier" : "anchor2", "x" : 0, "y" : 0}]
1981		pointPen.beginPath(**{"identifier" : "contour1"})
1982		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point1", "segmentType" : "move", "smooth" : False})
1983		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point2", "segmentType" : "line", "smooth" : False})
1984		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point3", "segmentType" : "curve", "smooth" : False})
1985		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point4", "segmentType" : "qcurve", "smooth" : False})
1986		pointPen.endPath()
1987		pointPen.beginPath(**{"identifier" : "contour1"})
1988		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point5", "segmentType" : "move", "smooth" : False})
1989		pointPen.endPath()
1990		pointPen.addComponent(*["x", (1, 1, 1, 1, 1, 1)], **{"identifier" : "component1"})
1991		pointPen.addComponent(*["x", (1, 1, 1, 1, 1, 1)], **{"identifier" : "component2"})
1992		"""
1993		self.assertRaises(GlifLibError, self.pyToGLIF, py)
1994		self.assertRaises(GlifLibError, self.glifToPy, glif)
1995
1996	def testIdentifierConflict_contour_component(self):
1997		# contour - component
1998		glif = """
1999		<glyph name="a" format="2">
2000			<guideline x="0" identifier="guideline1"/>
2001			<guideline x="0" identifier="guideline2"/>
2002			<anchor x="0" y="0" identifier="anchor1"/>
2003			<anchor x="0" y="0" identifier="anchor2"/>
2004			<outline>
2005				<contour identifier="contour1">
2006					<point x="1" y="-2" type="move" identifier="point1"/>
2007					<point x="1" y="-2" type="line" identifier="point2"/>
2008					<point x="1" y="-2" type="curve" identifier="point3"/>
2009					<point x="1" y="-2" type="qcurve" identifier="point4"/>
2010				</contour>
2011				<contour identifier="contour2">
2012					<point x="1" y="-2" type="move" identifier="point5"/>
2013				</contour>
2014				<component base="x" xyScale="1" yxScale="1" xOffset="1" yOffset="1" identifier="contour1"/>
2015				<component base="x" xyScale="1" yxScale="1" xOffset="1" yOffset="1" identifier="component2"/>
2016			</outline>
2017		</glyph>
2018		"""
2019		py = """
2020		glyph.name = "a"
2021		glyph.guidelines = [{"identifier" : "guideline1", "x" : 0}, {"identifier" : "guideline2", "x" : 0}]
2022		glyph.anchors = [{"identifier" : "anchor1", "x" : 0, "y" : 0}, {"identifier" : "anchor2", "x" : 0, "y" : 0}]
2023		pointPen.beginPath(**{"identifier" : "contour1"})
2024		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point1", "segmentType" : "move", "smooth" : False})
2025		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point2", "segmentType" : "line", "smooth" : False})
2026		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point3", "segmentType" : "curve", "smooth" : False})
2027		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point4", "segmentType" : "qcurve", "smooth" : False})
2028		pointPen.endPath()
2029		pointPen.beginPath(**{"identifier" : "contour2"})
2030		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point5", "segmentType" : "move", "smooth" : False})
2031		pointPen.endPath()
2032		pointPen.addComponent(*["x", (1, 1, 1, 1, 1, 1)], **{"identifier" : "contour1"})
2033		pointPen.addComponent(*["x", (1, 1, 1, 1, 1, 1)], **{"identifier" : "component2"})
2034		"""
2035		self.assertRaises(GlifLibError, self.pyToGLIF, py)
2036		self.assertRaises(GlifLibError, self.glifToPy, glif)
2037
2038	def testIdentifierConflict_contour_guideline(self):
2039		# contour - guideline
2040		glif = """
2041		<glyph name="a" format="2">
2042			<guideline x="0" identifier="contour1"/>
2043			<guideline x="0" identifier="guideline2"/>
2044			<anchor x="0" y="0" identifier="anchor1"/>
2045			<anchor x="0" y="0" identifier="anchor2"/>
2046			<outline>
2047				<contour identifier="contour1">
2048					<point x="1" y="-2" type="move" identifier="point1"/>
2049					<point x="1" y="-2" type="line" identifier="point2"/>
2050					<point x="1" y="-2" type="curve" identifier="point3"/>
2051					<point x="1" y="-2" type="qcurve" identifier="point4"/>
2052				</contour>
2053				<contour identifier="contour2">
2054					<point x="1" y="-2" type="move" identifier="point5"/>
2055				</contour>
2056				<component base="x" xyScale="1" yxScale="1" xOffset="1" yOffset="1" identifier="component1"/>
2057				<component base="x" xyScale="1" yxScale="1" xOffset="1" yOffset="1" identifier="component2"/>
2058			</outline>
2059		</glyph>
2060		"""
2061		py = """
2062		glyph.name = "a"
2063		glyph.guidelines = [{"identifier" : "contour1", "x" : 0}, {"identifier" : "guideline2", "x" : 0}]
2064		glyph.anchors = [{"identifier" : "anchor1", "x" : 0, "y" : 0}, {"identifier" : "anchor2", "x" : 0, "y" : 0}]
2065		pointPen.beginPath(**{"identifier" : "contour1"})
2066		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point1", "segmentType" : "move", "smooth" : False})
2067		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point2", "segmentType" : "line", "smooth" : False})
2068		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point3", "segmentType" : "curve", "smooth" : False})
2069		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point4", "segmentType" : "qcurve", "smooth" : False})
2070		pointPen.endPath()
2071		pointPen.beginPath(**{"identifier" : "contour2"})
2072		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point5", "segmentType" : "move", "smooth" : False})
2073		pointPen.endPath()
2074		pointPen.addComponent(*["x", (1, 1, 1, 1, 1, 1)], **{"identifier" : "component1"})
2075		pointPen.addComponent(*["x", (1, 1, 1, 1, 1, 1)], **{"identifier" : "component2"})
2076		"""
2077		self.assertRaises(GlifLibError, self.pyToGLIF, py)
2078		self.assertRaises(GlifLibError, self.glifToPy, glif)
2079
2080	def testIdentifierConflict_contour_anchor(self):
2081		# contour - anchor
2082		glif = """
2083		<glyph name="a" format="2">
2084			<guideline x="0" identifier="guideline1"/>
2085			<guideline x="0" identifier="guideline2"/>
2086			<anchor x="0" y="0" identifier="anchor1"/>
2087			<anchor x="0" y="0" identifier="anchor2"/>
2088			<outline>
2089				<contour identifier="anchor1">
2090					<point x="1" y="-2" type="move" identifier="point1"/>
2091					<point x="1" y="-2" type="line" identifier="point2"/>
2092					<point x="1" y="-2" type="curve" identifier="point3"/>
2093					<point x="1" y="-2" type="qcurve" identifier="point4"/>
2094				</contour>
2095				<contour identifier="contour2">
2096					<point x="1" y="-2" type="move" identifier="point5"/>
2097				</contour>
2098				<component base="x" xyScale="1" yxScale="1" xOffset="1" yOffset="1" identifier="component1"/>
2099				<component base="x" xyScale="1" yxScale="1" xOffset="1" yOffset="1" identifier="component2"/>
2100			</outline>
2101		</glyph>
2102		"""
2103		py = """
2104		glyph.name = "a"
2105		glyph.guidelines = [{"identifier" : "guideline1", "x" : 0}, {"identifier" : "guideline2", "x" : 0}]
2106		glyph.anchors = [{"identifier" : "anchor1", "x" : 0, "y" : 0}, {"identifier" : "anchor2", "x" : 0, "y" : 0}]
2107		pointPen.beginPath(**{"identifier" : "anchor1"})
2108		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point1", "segmentType" : "move", "smooth" : False})
2109		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point2", "segmentType" : "line", "smooth" : False})
2110		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point3", "segmentType" : "curve", "smooth" : False})
2111		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point4", "segmentType" : "qcurve", "smooth" : False})
2112		pointPen.endPath()
2113		pointPen.beginPath(**{"identifier" : "contour2"})
2114		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point5", "segmentType" : "move", "smooth" : False})
2115		pointPen.endPath()
2116		pointPen.addComponent(*["x", (1, 1, 1, 1, 1, 1)], **{"identifier" : "component1"})
2117		pointPen.addComponent(*["x", (1, 1, 1, 1, 1, 1)], **{"identifier" : "component2"})
2118		"""
2119		self.assertRaises(GlifLibError, self.pyToGLIF, py)
2120		self.assertRaises(GlifLibError, self.glifToPy, glif)
2121
2122	def testIdentifierConflict_component_component(self):
2123		# component - component
2124		glif = """
2125		<glyph name="a" format="2">
2126			<guideline x="0" identifier="guideline1"/>
2127			<guideline x="0" identifier="guideline2"/>
2128			<anchor x="0" y="0" identifier="anchor1"/>
2129			<anchor x="0" y="0" identifier="anchor2"/>
2130			<outline>
2131				<contour identifier="contour1">
2132					<point x="1" y="-2" type="move" identifier="point1"/>
2133					<point x="1" y="-2" type="line" identifier="point2"/>
2134					<point x="1" y="-2" type="curve" identifier="point3"/>
2135					<point x="1" y="-2" type="qcurve" identifier="point4"/>
2136				</contour>
2137				<contour identifier="contour2">
2138					<point x="1" y="-2" type="move" identifier="point5"/>
2139				</contour>
2140				<component base="x" xyScale="1" yxScale="1" xOffset="1" yOffset="1" identifier="component1"/>
2141				<component base="x" xyScale="1" yxScale="1" xOffset="1" yOffset="1" identifier="component1"/>
2142			</outline>
2143		</glyph>
2144		"""
2145		py = """
2146		glyph.name = "a"
2147		glyph.guidelines = [{"identifier" : "guideline1", "x" : 0}, {"identifier" : "guideline2", "x" : 0}]
2148		glyph.anchors = [{"identifier" : "anchor1", "x" : 0, "y" : 0}, {"identifier" : "anchor2", "x" : 0, "y" : 0}]
2149		pointPen.beginPath(**{"identifier" : "contour1"})
2150		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point1", "segmentType" : "move", "smooth" : False})
2151		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point2", "segmentType" : "line", "smooth" : False})
2152		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point3", "segmentType" : "curve", "smooth" : False})
2153		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point4", "segmentType" : "qcurve", "smooth" : False})
2154		pointPen.endPath()
2155		pointPen.beginPath(**{"identifier" : "contour2"})
2156		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point5", "segmentType" : "move", "smooth" : False})
2157		pointPen.endPath()
2158		pointPen.addComponent(*["x", (1, 1, 1, 1, 1, 1)], **{"identifier" : "component1"})
2159		pointPen.addComponent(*["x", (1, 1, 1, 1, 1, 1)], **{"identifier" : "component1"})
2160		"""
2161		self.assertRaises(GlifLibError, self.pyToGLIF, py)
2162		self.assertRaises(GlifLibError, self.glifToPy, glif)
2163
2164	def testIdentifierConflict_component_guideline(self):
2165		# component - guideline
2166		glif = """
2167		<glyph name="a" format="2">
2168			<guideline x="0" identifier="component1"/>
2169			<guideline x="0" identifier="guideline2"/>
2170			<anchor x="0" y="0" identifier="anchor1"/>
2171			<anchor x="0" y="0" identifier="anchor2"/>
2172			<outline>
2173				<contour identifier="contour1">
2174					<point x="1" y="-2" type="move" identifier="point1"/>
2175					<point x="1" y="-2" type="line" identifier="point2"/>
2176					<point x="1" y="-2" type="curve" identifier="point3"/>
2177					<point x="1" y="-2" type="qcurve" identifier="point4"/>
2178				</contour>
2179				<contour identifier="contour2">
2180					<point x="1" y="-2" type="move" identifier="point5"/>
2181				</contour>
2182				<component base="x" xyScale="1" yxScale="1" xOffset="1" yOffset="1" identifier="component1"/>
2183				<component base="x" xyScale="1" yxScale="1" xOffset="1" yOffset="1" identifier="component2"/>
2184			</outline>
2185		</glyph>
2186		"""
2187		py = """
2188		glyph.name = "a"
2189		glyph.guidelines = [{"identifier" : "component1", "x" : 0}, {"identifier" : "guideline2", "x" : 0}]
2190		glyph.anchors = [{"identifier" : "anchor1", "x" : 0, "y" : 0}, {"identifier" : "anchor2", "x" : 0, "y" : 0}]
2191		pointPen.beginPath(**{"identifier" : "contour1"})
2192		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point1", "segmentType" : "move", "smooth" : False})
2193		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point2", "segmentType" : "line", "smooth" : False})
2194		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point3", "segmentType" : "curve", "smooth" : False})
2195		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point4", "segmentType" : "qcurve", "smooth" : False})
2196		pointPen.endPath()
2197		pointPen.beginPath(**{"identifier" : "contour2"})
2198		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point5", "segmentType" : "move", "smooth" : False})
2199		pointPen.endPath()
2200		pointPen.addComponent(*["x", (1, 1, 1, 1, 1, 1)], **{"identifier" : "component1"})
2201		pointPen.addComponent(*["x", (1, 1, 1, 1, 1, 1)], **{"identifier" : "component2"})
2202		"""
2203		self.assertRaises(GlifLibError, self.pyToGLIF, py)
2204		self.assertRaises(GlifLibError, self.glifToPy, glif)
2205
2206	def testIdentifierConflict_component_anchor(self):
2207		# component - anchor
2208		glif = """
2209		<glyph name="a" format="2">
2210			<guideline x="0" identifier="guideline1"/>
2211			<guideline x="0" identifier="guideline2"/>
2212			<anchor x="0" y="0" identifier="anchor1"/>
2213			<anchor x="0" y="0" identifier="anchor2"/>
2214			<outline>
2215				<contour identifier="contour1">
2216					<point x="1" y="-2" type="move" identifier="point1"/>
2217					<point x="1" y="-2" type="line" identifier="point2"/>
2218					<point x="1" y="-2" type="curve" identifier="point3"/>
2219					<point x="1" y="-2" type="qcurve" identifier="point4"/>
2220				</contour>
2221				<contour identifier="contour2">
2222					<point x="1" y="-2" type="move" identifier="point5"/>
2223				</contour>
2224				<component base="x" xyScale="1" yxScale="1" xOffset="1" yOffset="1" identifier="anchor1"/>
2225				<component base="x" xyScale="1" yxScale="1" xOffset="1" yOffset="1" identifier="component2"/>
2226			</outline>
2227		</glyph>
2228		"""
2229		py = """
2230		glyph.name = "a"
2231		glyph.guidelines = [{"identifier" : "guideline1", "x" : 0}, {"identifier" : "guideline2", "x" : 0}]
2232		glyph.anchors = [{"identifier" : "anchor1", "x" : 0, "y" : 0}, {"identifier" : "anchor2", "x" : 0, "y" : 0}]
2233		pointPen.beginPath(**{"identifier" : "contour1"})
2234		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point1", "segmentType" : "move", "smooth" : False})
2235		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point2", "segmentType" : "line", "smooth" : False})
2236		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point3", "segmentType" : "curve", "smooth" : False})
2237		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point4", "segmentType" : "qcurve", "smooth" : False})
2238		pointPen.endPath()
2239		pointPen.beginPath(**{"identifier" : "contour2"})
2240		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point5", "segmentType" : "move", "smooth" : False})
2241		pointPen.endPath()
2242		pointPen.addComponent(*["x", (1, 1, 1, 1, 1, 1)], **{"identifier" : "anchor1"})
2243		pointPen.addComponent(*["x", (1, 1, 1, 1, 1, 1)], **{"identifier" : "component2"})
2244		"""
2245		self.assertRaises(GlifLibError, self.pyToGLIF, py)
2246		self.assertRaises(GlifLibError, self.glifToPy, glif)
2247
2248	def testIdentifierConflict_guideline_guideline(self):
2249		# guideline - guideline
2250		glif = """
2251		<glyph name="a" format="2">
2252			<guideline x="0" identifier="guideline1"/>
2253			<guideline x="0" identifier="guideline1"/>
2254			<anchor x="0" y="0" identifier="anchor1"/>
2255			<anchor x="0" y="0" identifier="anchor2"/>
2256			<outline>
2257				<contour identifier="contour1">
2258					<point x="1" y="-2" type="move" identifier="point1"/>
2259					<point x="1" y="-2" type="line" identifier="point2"/>
2260					<point x="1" y="-2" type="curve" identifier="point3"/>
2261					<point x="1" y="-2" type="qcurve" identifier="point4"/>
2262				</contour>
2263				<contour identifier="contour2">
2264					<point x="1" y="-2" type="move" identifier="point5"/>
2265				</contour>
2266				<component base="x" xyScale="1" yxScale="1" xOffset="1" yOffset="1" identifier="component1"/>
2267				<component base="x" xyScale="1" yxScale="1" xOffset="1" yOffset="1" identifier="component2"/>
2268			</outline>
2269		</glyph>
2270		"""
2271		py = """
2272		glyph.name = "a"
2273		glyph.guidelines = [{"identifier" : "guideline1", "x" : 0}, {"identifier" : "guideline1", "x" : 0}]
2274		glyph.anchors = [{"identifier" : "anchor1", "x" : 0, "y" : 0}, {"identifier" : "anchor2", "x" : 0, "y" : 0}]
2275		pointPen.beginPath(**{"identifier" : "contour1"})
2276		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point1", "segmentType" : "move", "smooth" : False})
2277		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point2", "segmentType" : "line", "smooth" : False})
2278		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point3", "segmentType" : "curve", "smooth" : False})
2279		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point4", "segmentType" : "qcurve", "smooth" : False})
2280		pointPen.endPath()
2281		pointPen.beginPath(**{"identifier" : "contour2"})
2282		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point5", "segmentType" : "move", "smooth" : False})
2283		pointPen.endPath()
2284		pointPen.addComponent(*["x", (1, 1, 1, 1, 1, 1)], **{"identifier" : "component1"})
2285		pointPen.addComponent(*["x", (1, 1, 1, 1, 1, 1)], **{"identifier" : "component2"})
2286		"""
2287		self.assertRaises(GlifLibError, self.pyToGLIF, py)
2288		self.assertRaises(GlifLibError, self.glifToPy, glif)
2289
2290	def testIdentifierConflict_guideline_anchor(self):
2291		# guideline - anchor
2292		glif = """
2293		<glyph name="a" format="2">
2294			<guideline x="0" identifier="anchor1"/>
2295			<guideline x="0" identifier="guideline2"/>
2296			<anchor x="0" y="0" identifier="anchor1"/>
2297			<anchor x="0" y="0" identifier="anchor2"/>
2298			<outline>
2299				<contour identifier="contour1">
2300					<point x="1" y="-2" type="move" identifier="point1"/>
2301					<point x="1" y="-2" type="line" identifier="point2"/>
2302					<point x="1" y="-2" type="curve" identifier="point3"/>
2303					<point x="1" y="-2" type="qcurve" identifier="point4"/>
2304				</contour>
2305				<contour identifier="contour2">
2306					<point x="1" y="-2" type="move" identifier="point5"/>
2307				</contour>
2308				<component base="x" xyScale="1" yxScale="1" xOffset="1" yOffset="1" identifier="component1"/>
2309				<component base="x" xyScale="1" yxScale="1" xOffset="1" yOffset="1" identifier="component2"/>
2310			</outline>
2311		</glyph>
2312		"""
2313		py = """
2314		glyph.name = "a"
2315		glyph.guidelines = [{"identifier" : "anchor1", "x" : 0}, {"identifier" : "guideline2", "x" : 0}]
2316		glyph.anchors = [{"identifier" : "anchor1", "x" : 0, "y" : 0}, {"identifier" : "anchor2", "x" : 0, "y" : 0}]
2317		pointPen.beginPath(**{"identifier" : "contour1"})
2318		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point1", "segmentType" : "move", "smooth" : False})
2319		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point2", "segmentType" : "line", "smooth" : False})
2320		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point3", "segmentType" : "curve", "smooth" : False})
2321		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point4", "segmentType" : "qcurve", "smooth" : False})
2322		pointPen.endPath()
2323		pointPen.beginPath(**{"identifier" : "contour2"})
2324		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point5", "segmentType" : "move", "smooth" : False})
2325		pointPen.endPath()
2326		pointPen.addComponent(*["x", (1, 1, 1, 1, 1, 1)], **{"identifier" : "component1"})
2327		pointPen.addComponent(*["x", (1, 1, 1, 1, 1, 1)], **{"identifier" : "component2"})
2328		"""
2329		self.assertRaises(GlifLibError, self.pyToGLIF, py)
2330		self.assertRaises(GlifLibError, self.glifToPy, glif)
2331
2332	def testIdentifierConflict_anchor_anchor(self):
2333		# anchor - anchor
2334		glif = """
2335		<glyph name="a" format="2">
2336			<guideline x="0" identifier="guideline1"/>
2337			<guideline x="0" identifier="guideline2"/>
2338			<anchor x="0" y="0" identifier="anchor1"/>
2339			<anchor x="0" y="0" identifier="anchor1"/>
2340			<outline>
2341				<contour identifier="contour1">
2342					<point x="1" y="-2" type="move" identifier="point1"/>
2343					<point x="1" y="-2" type="line" identifier="point2"/>
2344					<point x="1" y="-2" type="curve" identifier="point3"/>
2345					<point x="1" y="-2" type="qcurve" identifier="point4"/>
2346				</contour>
2347				<contour identifier="contour2">
2348					<point x="1" y="-2" type="move" identifier="point5"/>
2349				</contour>
2350				<component base="x" xyScale="1" yxScale="1" xOffset="1" yOffset="1" identifier="component1"/>
2351				<component base="x" xyScale="1" yxScale="1" xOffset="1" yOffset="1" identifier="component2"/>
2352			</outline>
2353		</glyph>
2354		"""
2355		py = """
2356		glyph.name = "a"
2357		glyph.guidelines = [{"identifier" : "guideline1", "x" : 0}, {"identifier" : "guideline2", "x" : 0}]
2358		glyph.anchors = [{"identifier" : "anchor1", "x" : 0, "y" : 0}, {"identifier" : "anchor1", "x" : 0, "y" : 0}]
2359		pointPen.beginPath(**{"identifier" : "contour1"})
2360		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point1", "segmentType" : "move", "smooth" : False})
2361		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point2", "segmentType" : "line", "smooth" : False})
2362		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point3", "segmentType" : "curve", "smooth" : False})
2363		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point4", "segmentType" : "qcurve", "smooth" : False})
2364		pointPen.endPath()
2365		pointPen.beginPath(**{"identifier" : "contour2"})
2366		pointPen.addPoint(*[(1, -2)], **{"identifier" : "point5", "segmentType" : "move", "smooth" : False})
2367		pointPen.endPath()
2368		pointPen.addComponent(*["x", (1, 1, 1, 1, 1, 1)], **{"identifier" : "component1"})
2369		pointPen.addComponent(*["x", (1, 1, 1, 1, 1, 1)], **{"identifier" : "component2"})
2370		"""
2371		self.assertRaises(GlifLibError, self.pyToGLIF, py)
2372		self.assertRaises(GlifLibError, self.glifToPy, glif)
2373