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