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