summaryrefslogtreecommitdiff
path: root/misc/pylib/robofab/test
diff options
context:
space:
mode:
Diffstat (limited to 'misc/pylib/robofab/test')
-rwxr-xr-xmisc/pylib/robofab/test/__init__.py8
-rw-r--r--misc/pylib/robofab/test/runAll.py27
-rwxr-xr-xmisc/pylib/robofab/test/testSupport.py278
-rw-r--r--misc/pylib/robofab/test/test_RInfoFL.py111
-rw-r--r--misc/pylib/robofab/test/test_RInfoRF.py56
-rw-r--r--misc/pylib/robofab/test/test_dialogs.py218
-rw-r--r--misc/pylib/robofab/test/test_fontLabUFOReadWrite.py565
-rw-r--r--misc/pylib/robofab/test/test_glifLib.py150
-rw-r--r--misc/pylib/robofab/test/test_noneLabUFOReadWrite.py321
-rwxr-xr-xmisc/pylib/robofab/test/test_objectsFL.py54
-rwxr-xr-xmisc/pylib/robofab/test/test_objectsUFO.py203
-rwxr-xr-xmisc/pylib/robofab/test/test_pens.py149
-rw-r--r--misc/pylib/robofab/test/test_psHints.py110
-rw-r--r--misc/pylib/robofab/test/test_ufoLib.py1659
14 files changed, 3909 insertions, 0 deletions
diff --git a/misc/pylib/robofab/test/__init__.py b/misc/pylib/robofab/test/__init__.py
new file mode 100755
index 000000000..f34415804
--- /dev/null
+++ b/misc/pylib/robofab/test/__init__.py
@@ -0,0 +1,8 @@
+"""Directory for unit tests.
+
+Modules here are typically named text_<something>.py, where <something> is
+usually a module name, for example "test_flPen.py", but it can also be the name
+of an area or concept to be tested, for example "test_drawing.py".
+
+Testmodules should use the unittest framework.
+"""
diff --git a/misc/pylib/robofab/test/runAll.py b/misc/pylib/robofab/test/runAll.py
new file mode 100644
index 000000000..28446a7b8
--- /dev/null
+++ b/misc/pylib/robofab/test/runAll.py
@@ -0,0 +1,27 @@
+import os
+import glob
+import unittest
+
+import robofab.test
+
+if __name__ == "__main__":
+ testDir = os.path.dirname(robofab.test.__file__)
+ testFiles = glob.glob1(testDir, "test_*.py")
+
+ loader = unittest.TestLoader()
+ suites = []
+ for fileName in testFiles:
+ modName = "robofab.test." + fileName[:-3]
+ print "importing", fileName
+ try:
+ mod = __import__(modName, {}, {}, ["*"])
+ except ImportError:
+ print "*** skipped", fileName
+ continue
+
+ suites.append(loader.loadTestsFromModule(mod))
+
+ print "running tests..."
+ testRunner = unittest.TextTestRunner(verbosity=0)
+ testSuite = unittest.TestSuite(suites)
+ testRunner.run(testSuite)
diff --git a/misc/pylib/robofab/test/testSupport.py b/misc/pylib/robofab/test/testSupport.py
new file mode 100755
index 000000000..f7f96c9ff
--- /dev/null
+++ b/misc/pylib/robofab/test/testSupport.py
@@ -0,0 +1,278 @@
+"""Miscellaneous helpers for our test suite."""
+
+
+import sys
+import os
+import types
+import unittest
+
+
+def getDemoFontPath():
+ """Return the path to Data/DemoFont.ufo/."""
+ import robofab
+ root = os.path.dirname(os.path.dirname(os.path.dirname(robofab.__file__)))
+ return os.path.join(root, "Data", "DemoFont.ufo")
+
+
+def getDemoFontGlyphSetPath():
+ """Return the path to Data/DemoFont.ufo/glyphs/."""
+ return os.path.join(getDemoFontPath(), "glyphs")
+
+
+def _gatherTestCasesFromCallerByMagic():
+ # UGLY magic: fetch TestClass subclasses from the globals of our
+ # caller's caller.
+ frame = sys._getframe(2)
+ return _gatherTestCasesFromDict(frame.f_globals)
+
+
+def _gatherTestCasesFromDict(d):
+ testCases = []
+ for ob in d.values():
+ if isinstance(ob, type) and issubclass(ob, unittest.TestCase):
+ testCases.append(ob)
+ return testCases
+
+
+def runTests(testCases=None, verbosity=1):
+ """Run a series of tests."""
+ if testCases is None:
+ testCases = _gatherTestCasesFromCallerByMagic()
+ loader = unittest.TestLoader()
+ suites = []
+ for testCase in testCases:
+ suites.append(loader.loadTestsFromTestCase(testCase))
+
+ testRunner = unittest.TextTestRunner(verbosity=verbosity)
+ testSuite = unittest.TestSuite(suites)
+ testRunner.run(testSuite)
+
+# font info values used by several tests
+
+fontInfoVersion1 = {
+ "familyName" : "Some Font (Family Name)",
+ "styleName" : "Regular (Style Name)",
+ "fullName" : "Some Font-Regular (Postscript Full Name)",
+ "fontName" : "SomeFont-Regular (Postscript Font Name)",
+ "menuName" : "Some Font Regular (Style Map Family Name)",
+ "fontStyle" : 64,
+ "note" : "A note.",
+ "versionMajor" : 1,
+ "versionMinor" : 0,
+ "year" : 2008,
+ "copyright" : "Copyright Some Foundry.",
+ "notice" : "Some Font by Some Designer for Some Foundry.",
+ "trademark" : "Trademark Some Foundry",
+ "license" : "License info for Some Foundry.",
+ "licenseURL" : "http://somefoundry.com/license",
+ "createdBy" : "Some Foundry",
+ "designer" : "Some Designer",
+ "designerURL" : "http://somedesigner.com",
+ "vendorURL" : "http://somefoundry.com",
+ "unitsPerEm" : 1000,
+ "ascender" : 750,
+ "descender" : -250,
+ "capHeight" : 750,
+ "xHeight" : 500,
+ "defaultWidth" : 400,
+ "slantAngle" : -12.5,
+ "italicAngle" : -12.5,
+ "widthName" : "Medium (normal)",
+ "weightName" : "Medium",
+ "weightValue" : 500,
+ "fondName" : "SomeFont Regular (FOND Name)",
+ "otFamilyName" : "Some Font (Preferred Family Name)",
+ "otStyleName" : "Regular (Preferred Subfamily Name)",
+ "otMacName" : "Some Font Regular (Compatible Full Name)",
+ "msCharSet" : 0,
+ "fondID" : 15000,
+ "uniqueID" : 4000000,
+ "ttVendor" : "SOME",
+ "ttUniqueID" : "OpenType name Table Unique ID",
+ "ttVersion" : "OpenType name Table Version",
+}
+
+fontInfoVersion2 = {
+ "familyName" : "Some Font (Family Name)",
+ "styleName" : "Regular (Style Name)",
+ "styleMapFamilyName" : "Some Font Regular (Style Map Family Name)",
+ "styleMapStyleName" : "regular",
+ "versionMajor" : 1,
+ "versionMinor" : 0,
+ "year" : 2008,
+ "copyright" : "Copyright Some Foundry.",
+ "trademark" : "Trademark Some Foundry",
+ "unitsPerEm" : 1000,
+ "descender" : -250,
+ "xHeight" : 500,
+ "capHeight" : 750,
+ "ascender" : 750,
+ "italicAngle" : -12.5,
+ "note" : "A note.",
+ "openTypeHeadCreated" : "2000/01/01 00:00:00",
+ "openTypeHeadLowestRecPPEM" : 10,
+ "openTypeHeadFlags" : [0, 1],
+ "openTypeHheaAscender" : 750,
+ "openTypeHheaDescender" : -250,
+ "openTypeHheaLineGap" : 200,
+ "openTypeHheaCaretSlopeRise" : 1,
+ "openTypeHheaCaretSlopeRun" : 0,
+ "openTypeHheaCaretOffset" : 0,
+ "openTypeNameDesigner" : "Some Designer",
+ "openTypeNameDesignerURL" : "http://somedesigner.com",
+ "openTypeNameManufacturer" : "Some Foundry",
+ "openTypeNameManufacturerURL" : "http://somefoundry.com",
+ "openTypeNameLicense" : "License info for Some Foundry.",
+ "openTypeNameLicenseURL" : "http://somefoundry.com/license",
+ "openTypeNameVersion" : "OpenType name Table Version",
+ "openTypeNameUniqueID" : "OpenType name Table Unique ID",
+ "openTypeNameDescription" : "Some Font by Some Designer for Some Foundry.",
+ "openTypeNamePreferredFamilyName" : "Some Font (Preferred Family Name)",
+ "openTypeNamePreferredSubfamilyName" : "Regular (Preferred Subfamily Name)",
+ "openTypeNameCompatibleFullName" : "Some Font Regular (Compatible Full Name)",
+ "openTypeNameSampleText" : "Sample Text for Some Font.",
+ "openTypeNameWWSFamilyName" : "Some Font (WWS Family Name)",
+ "openTypeNameWWSSubfamilyName" : "Regular (WWS Subfamily Name)",
+ "openTypeOS2WidthClass" : 5,
+ "openTypeOS2WeightClass" : 500,
+ "openTypeOS2Selection" : [3],
+ "openTypeOS2VendorID" : "SOME",
+ "openTypeOS2Panose" : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
+ "openTypeOS2FamilyClass" : [1, 1],
+ "openTypeOS2UnicodeRanges" : [0, 1],
+ "openTypeOS2CodePageRanges" : [0, 1],
+ "openTypeOS2TypoAscender" : 750,
+ "openTypeOS2TypoDescender" : -250,
+ "openTypeOS2TypoLineGap" : 200,
+ "openTypeOS2WinAscent" : 750,
+ "openTypeOS2WinDescent" : -250,
+ "openTypeOS2Type" : [],
+ "openTypeOS2SubscriptXSize" : 200,
+ "openTypeOS2SubscriptYSize" : 400,
+ "openTypeOS2SubscriptXOffset" : 0,
+ "openTypeOS2SubscriptYOffset" : -100,
+ "openTypeOS2SuperscriptXSize" : 200,
+ "openTypeOS2SuperscriptYSize" : 400,
+ "openTypeOS2SuperscriptXOffset" : 0,
+ "openTypeOS2SuperscriptYOffset" : 200,
+ "openTypeOS2StrikeoutSize" : 20,
+ "openTypeOS2StrikeoutPosition" : 300,
+ "openTypeVheaVertTypoAscender" : 750,
+ "openTypeVheaVertTypoDescender" : -250,
+ "openTypeVheaVertTypoLineGap" : 200,
+ "openTypeVheaCaretSlopeRise" : 0,
+ "openTypeVheaCaretSlopeRun" : 1,
+ "openTypeVheaCaretOffset" : 0,
+ "postscriptFontName" : "SomeFont-Regular (Postscript Font Name)",
+ "postscriptFullName" : "Some Font-Regular (Postscript Full Name)",
+ "postscriptSlantAngle" : -12.5,
+ "postscriptUniqueID" : 4000000,
+ "postscriptUnderlineThickness" : 20,
+ "postscriptUnderlinePosition" : -200,
+ "postscriptIsFixedPitch" : False,
+ "postscriptBlueValues" : [500, 510],
+ "postscriptOtherBlues" : [-250, -260],
+ "postscriptFamilyBlues" : [500, 510],
+ "postscriptFamilyOtherBlues" : [-250, -260],
+ "postscriptStemSnapH" : [100, 120],
+ "postscriptStemSnapV" : [80, 90],
+ "postscriptBlueFuzz" : 1,
+ "postscriptBlueShift" : 7,
+ "postscriptBlueScale" : 0.039625,
+ "postscriptForceBold" : True,
+ "postscriptDefaultWidthX" : 400,
+ "postscriptNominalWidthX" : 400,
+ "postscriptWeightName" : "Medium",
+ "postscriptDefaultCharacter" : ".notdef",
+ "postscriptWindowsCharacterSet" : 1,
+ "macintoshFONDFamilyID" : 15000,
+ "macintoshFONDName" : "SomeFont Regular (FOND Name)",
+}
+
+expectedFontInfo1To2Conversion = {
+ "familyName" : "Some Font (Family Name)",
+ "styleMapFamilyName" : "Some Font Regular (Style Map Family Name)",
+ "styleMapStyleName" : "regular",
+ "styleName" : "Regular (Style Name)",
+ "unitsPerEm" : 1000,
+ "ascender" : 750,
+ "capHeight" : 750,
+ "xHeight" : 500,
+ "descender" : -250,
+ "italicAngle" : -12.5,
+ "versionMajor" : 1,
+ "versionMinor" : 0,
+ "year" : 2008,
+ "copyright" : "Copyright Some Foundry.",
+ "trademark" : "Trademark Some Foundry",
+ "note" : "A note.",
+ "macintoshFONDFamilyID" : 15000,
+ "macintoshFONDName" : "SomeFont Regular (FOND Name)",
+ "openTypeNameCompatibleFullName" : "Some Font Regular (Compatible Full Name)",
+ "openTypeNameDescription" : "Some Font by Some Designer for Some Foundry.",
+ "openTypeNameDesigner" : "Some Designer",
+ "openTypeNameDesignerURL" : "http://somedesigner.com",
+ "openTypeNameLicense" : "License info for Some Foundry.",
+ "openTypeNameLicenseURL" : "http://somefoundry.com/license",
+ "openTypeNameManufacturer" : "Some Foundry",
+ "openTypeNameManufacturerURL" : "http://somefoundry.com",
+ "openTypeNamePreferredFamilyName" : "Some Font (Preferred Family Name)",
+ "openTypeNamePreferredSubfamilyName": "Regular (Preferred Subfamily Name)",
+ "openTypeNameCompatibleFullName" : "Some Font Regular (Compatible Full Name)",
+ "openTypeNameUniqueID" : "OpenType name Table Unique ID",
+ "openTypeNameVersion" : "OpenType name Table Version",
+ "openTypeOS2VendorID" : "SOME",
+ "openTypeOS2WeightClass" : 500,
+ "openTypeOS2WidthClass" : 5,
+ "postscriptDefaultWidthX" : 400,
+ "postscriptFontName" : "SomeFont-Regular (Postscript Font Name)",
+ "postscriptFullName" : "Some Font-Regular (Postscript Full Name)",
+ "postscriptSlantAngle" : -12.5,
+ "postscriptUniqueID" : 4000000,
+ "postscriptWeightName" : "Medium",
+ "postscriptWindowsCharacterSet" : 1
+}
+
+expectedFontInfo2To1Conversion = {
+ "familyName" : "Some Font (Family Name)",
+ "menuName" : "Some Font Regular (Style Map Family Name)",
+ "fontStyle" : 64,
+ "styleName" : "Regular (Style Name)",
+ "unitsPerEm" : 1000,
+ "ascender" : 750,
+ "capHeight" : 750,
+ "xHeight" : 500,
+ "descender" : -250,
+ "italicAngle" : -12.5,
+ "versionMajor" : 1,
+ "versionMinor" : 0,
+ "copyright" : "Copyright Some Foundry.",
+ "trademark" : "Trademark Some Foundry",
+ "note" : "A note.",
+ "fondID" : 15000,
+ "fondName" : "SomeFont Regular (FOND Name)",
+ "fullName" : "Some Font Regular (Compatible Full Name)",
+ "notice" : "Some Font by Some Designer for Some Foundry.",
+ "designer" : "Some Designer",
+ "designerURL" : "http://somedesigner.com",
+ "license" : "License info for Some Foundry.",
+ "licenseURL" : "http://somefoundry.com/license",
+ "createdBy" : "Some Foundry",
+ "vendorURL" : "http://somefoundry.com",
+ "otFamilyName" : "Some Font (Preferred Family Name)",
+ "otStyleName" : "Regular (Preferred Subfamily Name)",
+ "otMacName" : "Some Font Regular (Compatible Full Name)",
+ "ttUniqueID" : "OpenType name Table Unique ID",
+ "ttVersion" : "OpenType name Table Version",
+ "ttVendor" : "SOME",
+ "weightValue" : 500,
+ "widthName" : "Medium (normal)",
+ "defaultWidth" : 400,
+ "fontName" : "SomeFont-Regular (Postscript Font Name)",
+ "fullName" : "Some Font-Regular (Postscript Full Name)",
+ "slantAngle" : -12.5,
+ "uniqueID" : 4000000,
+ "weightName" : "Medium",
+ "msCharSet" : 0,
+ "year" : 2008
+}
diff --git a/misc/pylib/robofab/test/test_RInfoFL.py b/misc/pylib/robofab/test/test_RInfoFL.py
new file mode 100644
index 000000000..bfbd13477
--- /dev/null
+++ b/misc/pylib/robofab/test/test_RInfoFL.py
@@ -0,0 +1,111 @@
+import unittest
+from cStringIO import StringIO
+import sys
+from robofab import ufoLib
+from robofab.objects.objectsFL import NewFont
+from robofab.test.testSupport import fontInfoVersion1, fontInfoVersion2
+
+
+class RInfoRFTestCase(unittest.TestCase):
+
+ def testRoundTripVersion2(self):
+ font = NewFont()
+ infoObject = font.info
+ for attr, value in fontInfoVersion2.items():
+ if attr in infoObject._ufoToFLAttrMapping and infoObject._ufoToFLAttrMapping[attr]["nakedAttribute"] is None:
+ continue
+ setattr(infoObject, attr, value)
+ newValue = getattr(infoObject, attr)
+ self.assertEqual((attr, newValue), (attr, value))
+ font.close()
+
+ def testVersion2UnsupportedSet(self):
+ saveStderr = sys.stderr
+ saveStdout = sys.stdout
+ tempStderr = StringIO()
+ sys.stderr = tempStderr
+ sys.stdout = tempStderr
+ font = NewFont()
+ infoObject = font.info
+ requiredWarnings = []
+ try:
+ for attr, value in fontInfoVersion2.items():
+ if attr in infoObject._ufoToFLAttrMapping and infoObject._ufoToFLAttrMapping[attr]["nakedAttribute"] is not None:
+ continue
+ setattr(infoObject, attr, value)
+ s = "The attribute %s is not supported by FontLab." % attr
+ requiredWarnings.append((attr, s))
+ finally:
+ sys.stderr = saveStderr
+ sys.stdout = saveStdout
+ tempStderr = tempStderr.getvalue()
+ for attr, line in requiredWarnings:
+ self.assertEquals((attr, line in tempStderr), (attr, True))
+ font.close()
+
+ def testVersion2UnsupportedGet(self):
+ saveStderr = sys.stderr
+ saveStdout = sys.stdout
+ tempStderr = StringIO()
+ sys.stderr = tempStderr
+ sys.stdout = tempStderr
+ font = NewFont()
+ infoObject = font.info
+ requiredWarnings = []
+ try:
+ for attr, value in fontInfoVersion2.items():
+ if attr in infoObject._ufoToFLAttrMapping and infoObject._ufoToFLAttrMapping[attr]["nakedAttribute"] is not None:
+ continue
+ getattr(infoObject, attr, value)
+ s = "The attribute %s is not supported by FontLab." % attr
+ requiredWarnings.append((attr, s))
+ finally:
+ sys.stderr = saveStderr
+ sys.stdout = saveStdout
+ tempStderr = tempStderr.getvalue()
+ for attr, line in requiredWarnings:
+ self.assertEquals((attr, line in tempStderr), (attr, True))
+ font.close()
+
+ def testRoundTripVersion1(self):
+ font = NewFont()
+ infoObject = font.info
+ for attr, value in fontInfoVersion1.items():
+ if attr not in ufoLib.deprecatedFontInfoAttributesVersion2:
+ setattr(infoObject, attr, value)
+ for attr, expectedValue in fontInfoVersion1.items():
+ if attr not in ufoLib.deprecatedFontInfoAttributesVersion2:
+ value = getattr(infoObject, attr)
+ self.assertEqual((attr, expectedValue), (attr, value))
+ font.close()
+
+ def testVersion1DeprecationRoundTrip(self):
+ saveStderr = sys.stderr
+ saveStdout = sys.stdout
+ tempStderr = StringIO()
+ sys.stderr = tempStderr
+ sys.stdout = tempStderr
+ font = NewFont()
+ infoObject = font.info
+ requiredWarnings = []
+ try:
+ for attr, value in fontInfoVersion1.items():
+ if attr in ufoLib.deprecatedFontInfoAttributesVersion2:
+ setattr(infoObject, attr, value)
+ v = getattr(infoObject, attr)
+ self.assertEquals((attr, value), (attr, v))
+ s = "DeprecationWarning: The %s attribute has been deprecated." % attr
+ requiredWarnings.append((attr, s))
+ finally:
+ sys.stderr = saveStderr
+ sys.stdout = saveStdout
+ tempStderr = tempStderr.getvalue()
+ for attr, line in requiredWarnings:
+ self.assertEquals((attr, line in tempStderr), (attr, True))
+ font.close()
+
+
+if __name__ == "__main__":
+ from robofab.test.testSupport import runTests
+ runTests()
+
diff --git a/misc/pylib/robofab/test/test_RInfoRF.py b/misc/pylib/robofab/test/test_RInfoRF.py
new file mode 100644
index 000000000..3a8747033
--- /dev/null
+++ b/misc/pylib/robofab/test/test_RInfoRF.py
@@ -0,0 +1,56 @@
+import unittest
+from cStringIO import StringIO
+import sys
+from robofab import ufoLib
+from robofab.objects.objectsRF import RInfo
+from robofab.test.testSupport import fontInfoVersion1, fontInfoVersion2
+
+
+class RInfoRFTestCase(unittest.TestCase):
+
+ def testRoundTripVersion2(self):
+ infoObject = RInfo()
+ for attr, value in fontInfoVersion2.items():
+ setattr(infoObject, attr, value)
+ newValue = getattr(infoObject, attr)
+ self.assertEqual((attr, newValue), (attr, value))
+
+ def testRoundTripVersion1(self):
+ infoObject = RInfo()
+ for attr, value in fontInfoVersion1.items():
+ if attr not in ufoLib.deprecatedFontInfoAttributesVersion2:
+ setattr(infoObject, attr, value)
+ for attr, expectedValue in fontInfoVersion1.items():
+ if attr not in ufoLib.deprecatedFontInfoAttributesVersion2:
+ value = getattr(infoObject, attr)
+ self.assertEqual((attr, expectedValue), (attr, value))
+
+ def testVersion1DeprecationRoundTrip(self):
+ """
+ unittest doesn't catch warnings in self.assertRaises,
+ so some hackery is required to catch the warnings
+ that are raised when setting deprecated attributes.
+ """
+ saveStderr = sys.stderr
+ tempStderr = StringIO()
+ sys.stderr = tempStderr
+ infoObject = RInfo()
+ requiredWarnings = []
+ try:
+ for attr, value in fontInfoVersion1.items():
+ if attr in ufoLib.deprecatedFontInfoAttributesVersion2:
+ setattr(infoObject, attr, value)
+ v = getattr(infoObject, attr)
+ self.assertEquals((attr, value), (attr, v))
+ s = "DeprecationWarning: The %s attribute has been deprecated." % attr
+ requiredWarnings.append((attr, s))
+ finally:
+ sys.stderr = saveStderr
+ tempStderr = tempStderr.getvalue()
+ for attr, line in requiredWarnings:
+ self.assertEquals((attr, line in tempStderr), (attr, True))
+
+
+if __name__ == "__main__":
+ from robofab.test.testSupport import runTests
+ runTests()
diff --git a/misc/pylib/robofab/test/test_dialogs.py b/misc/pylib/robofab/test/test_dialogs.py
new file mode 100644
index 000000000..c296a6bd7
--- /dev/null
+++ b/misc/pylib/robofab/test/test_dialogs.py
@@ -0,0 +1,218 @@
+import robofab.interface.all.dialogs
+reload(robofab.interface.all.dialogs)
+from robofab.interface.all.dialogs import *
+
+import unittest
+
+
+__all__ = [
+ "AskString", #x
+ "AskYesNoCancel", #x
+ "FindGlyph",
+ "GetFile", #x
+ "GetFolder", #x
+ "GetFileOrFolder", #x
+ "Message", #x
+ "OneList",
+ "PutFile", #x
+ "SearchList",
+ "SelectFont",
+ "SelectGlyph",
+ "TwoChecks",
+ "TwoFields",
+ "ProgressBar",
+]
+
+class DialogRunner(object):
+ def __init__(self):
+ prompt = "The prompt for %s."
+ message = "The message for %s."
+ title = "The title for %s."
+ informativeText = "The informative text for %s."
+ fileTypes = ['ufo']
+ fileName = "The_filename.txt"
+
+ self.fonts = fonts = [self.makeTestFont(n) for n in range(4)]
+
+ t = "AskString"
+ try:
+ print "About to try", t
+ print "\t>>>", AskString(
+ message=prompt%t,
+ value='',
+ title=title%t
+ )
+ except NotImplementedError:
+ print t, "is not implemented."
+
+ t = "AskYesNoCancel"
+ try:
+ print "About to try", t
+ print "\t>>>", AskYesNoCancel(
+ message=prompt%t+" default set to 0",
+ title=title%t,
+ default=0,
+ informativeText=informativeText%t
+ )
+ print "\t>>>", AskYesNoCancel(
+ message=prompt%t+" default set to 1",
+ title=title%t,
+ default=1,
+ informativeText=informativeText%t
+ )
+ except NotImplementedError:
+ print t, "is not implemented."
+
+ t = "GetFile"
+ try:
+ print "About to try", t
+ print "\t>>>", GetFile(
+ message=message%t+" Only fileTypes "+`fileTypes`,
+ title=title%t,
+ directory=None,
+ fileName=fileName,
+ allowsMultipleSelection=False,
+ fileTypes=fileTypes
+ )
+ print "\t>>>", GetFile(
+ message=message%t+" All filetypes, allow multiple selection.",
+ title=title%t,
+ directory=None,
+ fileName=fileName,
+ allowsMultipleSelection=True,
+ fileTypes=None
+ )
+ except NotImplementedError:
+ print t, "is not implemented."
+
+ t = "GetFolder"
+ try:
+ print "About to try", t
+ print "\t>>>", GetFolder(
+ message=message%t,
+ title=title%t,
+ directory=None,
+ allowsMultipleSelection=False
+ )
+ print "\t>>>", GetFolder(
+ message=message%t + " Allow multiple selection.",
+ title=title%t,
+ directory=None,
+ allowsMultipleSelection=True
+ )
+ except NotImplementedError:
+ print t, "is not implemented."
+
+ t = "GetFileOrFolder"
+ try:
+ print "About to try", t
+ print "\t>>>", GetFileOrFolder(
+ message=message%t+" Only fileTypes "+`fileTypes`,
+ title=title%t,
+ directory=None,
+ fileName=fileName,
+ allowsMultipleSelection=False,
+ fileTypes=fileTypes
+ )
+ print "\t>>>", GetFileOrFolder(
+ message=message%t + " Allow multiple selection.",
+ title=title%t,
+ directory=None,
+ fileName=fileName,
+ allowsMultipleSelection=True,
+ fileTypes=None
+ )
+ except NotImplementedError:
+ print t, "is not implemented."
+
+ t = "Message"
+ try:
+ print "About to try", t
+ print "\t>>>", Message(
+ message=message%t,
+ title=title%t,
+ informativeText=informativeText%t
+ )
+ except NotImplementedError:
+ print t, "is not implemented."
+
+ t = "PutFile"
+ try:
+ print "About to try", t
+ print "\t>>>", PutFile(
+ message=message%t,
+ fileName=fileName,
+ )
+ except NotImplementedError:
+ print t, "is not implemented."
+
+ # t = "SelectFont"
+ # try:
+ #print "About to try", t
+ # print "\t>>>", SelectFont(
+ # message=message%t,
+ # title=title%t,
+ # allFonts=fonts,
+ # )
+ # except NotImplementedError:
+ # print t, "is not implemented."
+
+ # t = 'SelectGlyph'
+ # try:
+ #print "About to try", t
+ # print "\t>>>", SelectGlyph(
+ # font=fonts[0],
+ # message=message%t,
+ # title=title%t,
+ # )
+ # except NotImplementedError:
+ # print t, "is not implemented."
+
+ print 'No more tests.'
+
+ def makeTestFont(self, number):
+ from robofab.objects.objectsRF import RFont as _RFont
+ f = _RFont()
+ f.info.familyName = "TestFamily"
+ f.info.styleName = "weight%d"%number
+ f.info.postscriptFullName = "%s %s"%(f.info.familyName, f.info.styleName)
+ # make some glyphs
+ for name in ['A', 'B', 'C']:
+ g = f.newGlyph(name)
+ pen = g.getPen()
+ pen.moveTo((0,0))
+ pen.lineTo((500, 0))
+ pen.lineTo((500, 800))
+ pen.lineTo((0, 800))
+ pen.closePath()
+ return f
+
+
+class DialogTests(unittest.TestCase):
+ def setUp(self):
+ from robofab.interface.all.dialogs import test
+ test()
+
+ def tearDown(self):
+ pass
+
+ def testDialogs(self):
+ import robofab.interface.all.dialogs
+ dialogModuleName = robofab.interface.all.dialogs.platformApplicationModuleName
+ application = robofab.interface.all.dialogs.application
+
+ if application is None and dialogModuleName == "dialogs_mac_vanilla":
+ # in vanilla, but not in a host application, run with executeVanillaTest
+ print
+ print "I'm running these tests with executeVanillaTest"
+ from vanilla.test.testTools import executeVanillaTest
+ executeVanillaTest(DialogRunner)
+ else:
+ print
+ print "I'm running these tests natively in"
+ DialogRunner()
+
+
+if __name__ == "__main__":
+ from robofab.test.testSupport import runTests
+ runTests()
diff --git a/misc/pylib/robofab/test/test_fontLabUFOReadWrite.py b/misc/pylib/robofab/test/test_fontLabUFOReadWrite.py
new file mode 100644
index 000000000..91c072d26
--- /dev/null
+++ b/misc/pylib/robofab/test/test_fontLabUFOReadWrite.py
@@ -0,0 +1,565 @@
+import os
+import shutil
+import unittest
+import tempfile
+from robofab.plistlib import readPlist
+import robofab
+from robofab.ufoLib import UFOReader, UFOWriter
+from robofab.test.testSupport import fontInfoVersion2, expectedFontInfo1To2Conversion
+from robofab.objects.objectsFL import NewFont, OpenFont
+
+vfbPath = os.path.dirname(robofab.__file__)
+vfbPath = os.path.dirname(vfbPath)
+vfbPath = os.path.dirname(vfbPath)
+vfbPath = os.path.join(vfbPath, "TestData", "TestFont1.vfb")
+
+ufoPath1 = os.path.dirname(robofab.__file__)
+ufoPath1 = os.path.dirname(ufoPath1)
+ufoPath1 = os.path.dirname(ufoPath1)
+ufoPath1 = os.path.join(ufoPath1, "TestData", "TestFont1 (UFO1).ufo")
+ufoPath2 = ufoPath1.replace("TestFont1 (UFO1).ufo", "TestFont1 (UFO2).ufo")
+
+
+expectedFormatVersion1Features = """@myClass = [A B];
+
+feature liga {
+ sub A A by b;
+} liga;
+"""
+
+# robofab should remove these from the lib after a load.
+removeFromFormatVersion1Lib = [
+ "org.robofab.opentype.classes",
+ "org.robofab.opentype.features",
+ "org.robofab.opentype.featureorder",
+ "org.robofab.postScriptHintData"
+]
+
+
+class ReadUFOFormatVersion1TestCase(unittest.TestCase):
+
+ def setUpFont(self, doInfo=False, doKerning=False, doGroups=False, doLib=False, doFeatures=False):
+ self.font = NewFont()
+ self.ufoPath = ufoPath1
+ self.font.readUFO(ufoPath1, doInfo=doInfo, doKerning=doKerning, doGroups=doGroups, doLib=doLib, doFeatures=doFeatures)
+ self.font.update()
+
+ def tearDownFont(self):
+ self.font.close()
+ self.font = None
+
+ def compareToUFO(self, doInfo=True, doKerning=True, doGroups=True, doLib=True, doFeatures=True):
+ reader = UFOReader(self.ufoPath)
+ results = {}
+ if doInfo:
+ infoMatches = True
+ info = self.font.info
+ for attr, expectedValue in expectedFontInfo1To2Conversion.items():
+ writtenValue = getattr(info, attr)
+ if expectedValue != writtenValue:
+ infoMatches = False
+ break
+ results["info"]= infoMatches
+ if doKerning:
+ kerning = self.font.kerning.asDict()
+ expectedKerning = reader.readKerning()
+ results["kerning"] = expectedKerning == kerning
+ if doGroups:
+ groups = dict(self.font.groups)
+ expectedGroups = reader.readGroups()
+ results["groups"] = expectedGroups == groups
+ if doFeatures:
+ features = self.font.features.text
+ expectedFeatures = expectedFormatVersion1Features
+ # FontLab likes to add lines to the features, so skip blank lines.
+ features = [line for line in features.splitlines() if line]
+ expectedFeatures = [line for line in expectedFeatures.splitlines() if line]
+ results["features"] = expectedFeatures == features
+ if doLib:
+ lib = dict(self.font.lib)
+ expectedLib = reader.readLib()
+ for key in removeFromFormatVersion1Lib:
+ if key in expectedLib:
+ del expectedLib[key]
+ results["lib"] = expectedLib == lib
+ return results
+
+ def testFull(self):
+ self.setUpFont(doInfo=True, doKerning=True, doGroups=True, doFeatures=True, doLib=True)
+ otherResults = self.compareToUFO()
+ self.assertEqual(otherResults["info"], True)
+ self.assertEqual(otherResults["kerning"], True)
+ self.assertEqual(otherResults["groups"], True)
+ self.assertEqual(otherResults["features"], True)
+ self.assertEqual(otherResults["lib"], True)
+ self.tearDownFont()
+
+ def testInfo(self):
+ self.setUpFont(doInfo=True)
+ otherResults = self.compareToUFO(doInfo=False)
+ self.assertEqual(otherResults["kerning"], False)
+ self.assertEqual(otherResults["groups"], False)
+ self.assertEqual(otherResults["features"], False)
+ self.assertEqual(otherResults["lib"], False)
+ info = self.font.info
+ for attr, expectedValue in expectedFontInfo1To2Conversion.items():
+ writtenValue = getattr(info, attr)
+ self.assertEqual((attr, expectedValue), (attr, writtenValue))
+ self.tearDownFont()
+
+ def testFeatures(self):
+ self.setUpFont(doFeatures=True)
+ otherResults = self.compareToUFO()
+ self.assertEqual(otherResults["info"], False)
+ self.assertEqual(otherResults["kerning"], False)
+ self.assertEqual(otherResults["groups"], False)
+ self.assertEqual(otherResults["features"], True)
+ self.assertEqual(otherResults["lib"], False)
+ self.tearDownFont()
+
+ def testKerning(self):
+ self.setUpFont(doKerning=True)
+ otherResults = self.compareToUFO()
+ self.assertEqual(otherResults["info"], False)
+ self.assertEqual(otherResults["kerning"], True)
+ self.assertEqual(otherResults["groups"], False)
+ self.assertEqual(otherResults["features"], False)
+ self.assertEqual(otherResults["lib"], False)
+ self.tearDownFont()
+
+ def testGroups(self):
+ self.setUpFont(doGroups=True)
+ otherResults = self.compareToUFO()
+ self.assertEqual(otherResults["info"], False)
+ self.assertEqual(otherResults["kerning"], False)
+ self.assertEqual(otherResults["groups"], True)
+ self.assertEqual(otherResults["features"], False)
+ self.assertEqual(otherResults["lib"], False)
+ self.tearDownFont()
+
+ def testLib(self):
+ self.setUpFont(doLib=True)
+ otherResults = self.compareToUFO()
+ self.assertEqual(otherResults["info"], False)
+ self.assertEqual(otherResults["kerning"], False)
+ self.assertEqual(otherResults["groups"], False)
+ self.assertEqual(otherResults["features"], False)
+ self.assertEqual(otherResults["lib"], True)
+ self.tearDownFont()
+
+
+class ReadUFOFormatVersion2TestCase(unittest.TestCase):
+
+ def setUpFont(self, doInfo=False, doKerning=False, doGroups=False, doLib=False, doFeatures=False):
+ self.font = NewFont()
+ self.ufoPath = ufoPath2
+ self.font.readUFO(ufoPath2, doInfo=doInfo, doKerning=doKerning, doGroups=doGroups, doLib=doLib, doFeatures=doFeatures)
+ self.font.update()
+
+ def tearDownFont(self):
+ self.font.close()
+ self.font = None
+
+ def compareToUFO(self, doInfo=True, doKerning=True, doGroups=True, doLib=True, doFeatures=True):
+ reader = UFOReader(self.ufoPath)
+ results = {}
+ if doInfo:
+ infoMatches = True
+ info = self.font.info
+ for attr, expectedValue in fontInfoVersion2.items():
+ # cheat by skipping attrs that aren't supported
+ if info._ufoToFLAttrMapping[attr]["nakedAttribute"] is None:
+ continue
+ writtenValue = getattr(info, attr)
+ if expectedValue != writtenValue:
+ infoMatches = False
+ break
+ results["info"]= infoMatches
+ if doKerning:
+ kerning = self.font.kerning.asDict()
+ expectedKerning = reader.readKerning()
+ results["kerning"] = expectedKerning == kerning
+ if doGroups:
+ groups = dict(self.font.groups)
+ expectedGroups = reader.readGroups()
+ results["groups"] = expectedGroups == groups
+ if doFeatures:
+ features = self.font.features.text
+ expectedFeatures = reader.readFeatures()
+ results["features"] = expectedFeatures == features
+ if doLib:
+ lib = dict(self.font.lib)
+ expectedLib = reader.readLib()
+ results["lib"] = expectedLib == lib
+ return results
+
+ def testFull(self):
+ self.setUpFont(doInfo=True, doKerning=True, doGroups=True, doFeatures=True, doLib=True)
+ otherResults = self.compareToUFO()
+ self.assertEqual(otherResults["info"], True)
+ self.assertEqual(otherResults["kerning"], True)
+ self.assertEqual(otherResults["groups"], True)
+ self.assertEqual(otherResults["features"], True)
+ self.assertEqual(otherResults["lib"], True)
+ self.tearDownFont()
+
+ def testInfo(self):
+ self.setUpFont(doInfo=True)
+ otherResults = self.compareToUFO(doInfo=False)
+ self.assertEqual(otherResults["kerning"], False)
+ self.assertEqual(otherResults["groups"], False)
+ self.assertEqual(otherResults["features"], False)
+ self.assertEqual(otherResults["lib"], False)
+ info = self.font.info
+ for attr, expectedValue in fontInfoVersion2.items():
+ # cheat by skipping attrs that aren't supported
+ if info._ufoToFLAttrMapping[attr]["nakedAttribute"] is None:
+ continue
+ writtenValue = getattr(info, attr)
+ self.assertEqual((attr, expectedValue), (attr, writtenValue))
+ self.tearDownFont()
+
+ def testFeatures(self):
+ self.setUpFont(doFeatures=True)
+ otherResults = self.compareToUFO()
+ self.assertEqual(otherResults["info"], False)
+ self.assertEqual(otherResults["kerning"], False)
+ self.assertEqual(otherResults["groups"], False)
+ self.assertEqual(otherResults["features"], True)
+ self.assertEqual(otherResults["lib"], False)
+ self.tearDownFont()
+
+ def testKerning(self):
+ self.setUpFont(doKerning=True)
+ otherResults = self.compareToUFO()
+ self.assertEqual(otherResults["info"], False)
+ self.assertEqual(otherResults["kerning"], True)
+ self.assertEqual(otherResults["groups"], False)
+ self.assertEqual(otherResults["features"], False)
+ self.assertEqual(otherResults["lib"], False)
+ self.tearDownFont()
+
+ def testGroups(self):
+ self.setUpFont(doGroups=True)
+ otherResults = self.compareToUFO()
+ self.assertEqual(otherResults["info"], False)
+ self.assertEqual(otherResults["kerning"], False)
+ self.assertEqual(otherResults["groups"], True)
+ self.assertEqual(otherResults["features"], False)
+ self.assertEqual(otherResults["lib"], False)
+ self.tearDownFont()
+
+ def testLib(self):
+ self.setUpFont(doLib=True)
+ otherResults = self.compareToUFO()
+ self.assertEqual(otherResults["info"], False)
+ self.assertEqual(otherResults["kerning"], False)
+ self.assertEqual(otherResults["groups"], False)
+ self.assertEqual(otherResults["features"], False)
+ self.assertEqual(otherResults["lib"], True)
+ self.tearDownFont()
+
+
+class WriteUFOFormatVersion1TestCase(unittest.TestCase):
+
+ def setUpFont(self, doInfo=False, doKerning=False, doGroups=False):
+ self.dstDir = tempfile.mktemp()
+ os.mkdir(self.dstDir)
+ self.font = OpenFont(vfbPath)
+ self.font.writeUFO(self.dstDir, doInfo=doInfo, doKerning=doKerning, doGroups=doGroups, formatVersion=1)
+ self.font.close()
+
+ def tearDownFont(self):
+ shutil.rmtree(self.dstDir)
+
+ def compareToUFO(self, doInfo=True, doKerning=True, doGroups=True, doLib=True, doFeatures=True):
+ readerExpected = UFOReader(ufoPath1)
+ readerWritten = UFOReader(self.dstDir)
+ results = {}
+ if doInfo:
+ matches = True
+ expectedPath = os.path.join(ufoPath1, "fontinfo.plist")
+ writtenPath = os.path.join(self.dstDir, "fontinfo.plist")
+ if not os.path.exists(writtenPath):
+ matches = False
+ else:
+ expected = readPlist(expectedPath)
+ written = readPlist(writtenPath)
+ for attr, expectedValue in expected.items():
+ if expectedValue != written[attr]:
+ matches = False
+ break
+ results["info"] = matches
+ if doKerning:
+ matches = True
+ expectedPath = os.path.join(ufoPath1, "kerning.plist")
+ writtenPath = os.path.join(self.dstDir, "kerning.plist")
+ if not os.path.exists(writtenPath):
+ matches = False
+ else:
+ matches = readPlist(expectedPath) == readPlist(writtenPath)
+ results["kerning"] = matches
+ if doGroups:
+ matches = True
+ expectedPath = os.path.join(ufoPath1, "groups.plist")
+ writtenPath = os.path.join(self.dstDir, "groups.plist")
+ if not os.path.exists(writtenPath):
+ matches = False
+ else:
+ matches = readPlist(expectedPath) == readPlist(writtenPath)
+ results["groups"] = matches
+ if doFeatures:
+ matches = True
+ featuresPath = os.path.join(self.dstDir, "features.fea")
+ libPath = os.path.join(self.dstDir, "lib.plist")
+ if os.path.exists(featuresPath):
+ matches = False
+ else:
+ fontLib = readPlist(libPath)
+ writtenText = [fontLib.get("org.robofab.opentype.classes", "")]
+ features = fontLib.get("org.robofab.opentype.features", {})
+ featureOrder= fontLib.get("org.robofab.opentype.featureorder", [])
+ for featureName in featureOrder:
+ writtenText.append(features.get(featureName, ""))
+ writtenText = "\n".join(writtenText)
+ # FontLab likes to add lines to the features, so skip blank lines.
+ expectedText = [line for line in expectedFormatVersion1Features.splitlines() if line]
+ writtenText = [line for line in writtenText.splitlines() if line]
+ matches = "\n".join(expectedText) == "\n".join(writtenText)
+ results["features"] = matches
+ if doLib:
+ matches = True
+ expectedPath = os.path.join(ufoPath1, "lib.plist")
+ writtenPath = os.path.join(self.dstDir, "lib.plist")
+ if not os.path.exists(writtenPath):
+ matches = False
+ else:
+ # the test file doesn't have the glyph order
+ # so purge it from the written
+ writtenLib = readPlist(writtenPath)
+ del writtenLib["org.robofab.glyphOrder"]
+ matches = readPlist(expectedPath) == writtenLib
+ results["lib"] = matches
+ return results
+
+ def testFull(self):
+ self.setUpFont(doInfo=True, doKerning=True, doGroups=True)
+ otherResults = self.compareToUFO()
+ self.assertEqual(otherResults["info"], True)
+ self.assertEqual(otherResults["kerning"], True)
+ self.assertEqual(otherResults["groups"], True)
+ self.assertEqual(otherResults["features"], True)
+ self.assertEqual(otherResults["lib"], True)
+ self.tearDownFont()
+
+ def testInfo(self):
+ self.setUpFont(doInfo=True)
+ otherResults = self.compareToUFO(doInfo=False)
+ self.assertEqual(otherResults["kerning"], False)
+ self.assertEqual(otherResults["groups"], False)
+ expectedPath = os.path.join(ufoPath1, "fontinfo.plist")
+ writtenPath = os.path.join(self.dstDir, "fontinfo.plist")
+ expected = readPlist(expectedPath)
+ written = readPlist(writtenPath)
+ for attr, expectedValue in expected.items():
+ self.assertEqual((attr, expectedValue), (attr, written[attr]))
+ self.tearDownFont()
+
+ def testFeatures(self):
+ self.setUpFont()
+ otherResults = self.compareToUFO()
+ self.assertEqual(otherResults["info"], False)
+ self.assertEqual(otherResults["kerning"], False)
+ self.assertEqual(otherResults["groups"], False)
+ self.assertEqual(otherResults["features"], True)
+ self.tearDownFont()
+
+ def testKerning(self):
+ self.setUpFont(doKerning=True)
+ otherResults = self.compareToUFO()
+ self.assertEqual(otherResults["info"], False)
+ self.assertEqual(otherResults["kerning"], True)
+ self.assertEqual(otherResults["groups"], False)
+ self.tearDownFont()
+
+ def testGroups(self):
+ self.setUpFont(doGroups=True)
+ otherResults = self.compareToUFO()
+ self.assertEqual(otherResults["info"], False)
+ self.assertEqual(otherResults["kerning"], False)
+ self.assertEqual(otherResults["groups"], True)
+ self.tearDownFont()
+
+ def testLib(self):
+ self.setUpFont()
+ otherResults = self.compareToUFO()
+ self.assertEqual(otherResults["info"], False)
+ self.assertEqual(otherResults["kerning"], False)
+ self.assertEqual(otherResults["groups"], False)
+ self.assertEqual(otherResults["lib"], True)
+ self.tearDownFont()
+
+
+
+class WriteUFOFormatVersion2TestCase(unittest.TestCase):
+
+ def setUpFont(self, doInfo=False, doKerning=False, doGroups=False, doLib=False, doFeatures=False):
+ self.dstDir = tempfile.mktemp()
+ os.mkdir(self.dstDir)
+ self.font = OpenFont(vfbPath)
+ self.font.writeUFO(self.dstDir, doInfo=doInfo, doKerning=doKerning, doGroups=doGroups, doLib=doLib, doFeatures=doFeatures)
+ self.font.close()
+
+ def tearDownFont(self):
+ shutil.rmtree(self.dstDir)
+
+ def compareToUFO(self, doInfo=True, doKerning=True, doGroups=True, doLib=True, doFeatures=True):
+ readerExpected = UFOReader(ufoPath2)
+ readerWritten = UFOReader(self.dstDir)
+ results = {}
+ if doInfo:
+ matches = True
+ expectedPath = os.path.join(ufoPath2, "fontinfo.plist")
+ writtenPath = os.path.join(self.dstDir, "fontinfo.plist")
+ if not os.path.exists(writtenPath):
+ matches = False
+ else:
+ dummyFont = NewFont()
+ _ufoToFLAttrMapping = dict(dummyFont.info._ufoToFLAttrMapping)
+ dummyFont.close()
+ expected = readPlist(expectedPath)
+ written = readPlist(writtenPath)
+ for attr, expectedValue in expected.items():
+ # cheat by skipping attrs that aren't supported
+ if _ufoToFLAttrMapping[attr]["nakedAttribute"] is None:
+ continue
+ if expectedValue != written[attr]:
+ matches = False
+ break
+ results["info"] = matches
+ if doKerning:
+ matches = True
+ expectedPath = os.path.join(ufoPath2, "kerning.plist")
+ writtenPath = os.path.join(self.dstDir, "kerning.plist")
+ if not os.path.exists(writtenPath):
+ matches = False
+ else:
+ matches = readPlist(expectedPath) == readPlist(writtenPath)
+ results["kerning"] = matches
+ if doGroups:
+ matches = True
+ expectedPath = os.path.join(ufoPath2, "groups.plist")
+ writtenPath = os.path.join(self.dstDir, "groups.plist")
+ if not os.path.exists(writtenPath):
+ matches = False
+ else:
+ matches = readPlist(expectedPath) == readPlist(writtenPath)
+ results["groups"] = matches
+ if doFeatures:
+ matches = True
+ expectedPath = os.path.join(ufoPath2, "features.fea")
+ writtenPath = os.path.join(self.dstDir, "features.fea")
+ if not os.path.exists(writtenPath):
+ matches = False
+ else:
+ f = open(expectedPath, "r")
+ expectedText = f.read()
+ f.close()
+ f = open(writtenPath, "r")
+ writtenText = f.read()
+ f.close()
+ # FontLab likes to add lines to the features, so skip blank lines.
+ expectedText = [line for line in expectedText.splitlines() if line]
+ writtenText = [line for line in writtenText.splitlines() if line]
+ matches = "\n".join(expectedText) == "\n".join(writtenText)
+ results["features"] = matches
+ if doLib:
+ matches = True
+ expectedPath = os.path.join(ufoPath2, "lib.plist")
+ writtenPath = os.path.join(self.dstDir, "lib.plist")
+ if not os.path.exists(writtenPath):
+ matches = False
+ else:
+ # the test file doesn't have the glyph order
+ # so purge it from the written
+ writtenLib = readPlist(writtenPath)
+ del writtenLib["org.robofab.glyphOrder"]
+ matches = readPlist(expectedPath) == writtenLib
+ results["lib"] = matches
+ return results
+
+ def testFull(self):
+ self.setUpFont(doInfo=True, doKerning=True, doGroups=True, doFeatures=True, doLib=True)
+ otherResults = self.compareToUFO()
+ self.assertEqual(otherResults["info"], True)
+ self.assertEqual(otherResults["kerning"], True)
+ self.assertEqual(otherResults["groups"], True)
+ self.assertEqual(otherResults["features"], True)
+ self.assertEqual(otherResults["lib"], True)
+ self.tearDownFont()
+
+ def testInfo(self):
+ self.setUpFont(doInfo=True)
+ otherResults = self.compareToUFO(doInfo=False)
+ self.assertEqual(otherResults["kerning"], False)
+ self.assertEqual(otherResults["groups"], False)
+ self.assertEqual(otherResults["features"], False)
+ self.assertEqual(otherResults["lib"], False)
+ expectedPath = os.path.join(ufoPath2, "fontinfo.plist")
+ writtenPath = os.path.join(self.dstDir, "fontinfo.plist")
+ expected = readPlist(expectedPath)
+ written = readPlist(writtenPath)
+ dummyFont = NewFont()
+ _ufoToFLAttrMapping = dict(dummyFont.info._ufoToFLAttrMapping)
+ dummyFont.close()
+ for attr, expectedValue in expected.items():
+ # cheat by skipping attrs that aren't supported
+ if _ufoToFLAttrMapping[attr]["nakedAttribute"] is None:
+ continue
+ self.assertEqual((attr, expectedValue), (attr, written[attr]))
+ self.tearDownFont()
+
+ def testFeatures(self):
+ self.setUpFont(doFeatures=True)
+ otherResults = self.compareToUFO()
+ self.assertEqual(otherResults["info"], False)
+ self.assertEqual(otherResults["kerning"], False)
+ self.assertEqual(otherResults["groups"], False)
+ self.assertEqual(otherResults["features"], True)
+ self.assertEqual(otherResults["lib"], False)
+ self.tearDownFont()
+
+ def testKerning(self):
+ self.setUpFont(doKerning=True)
+ otherResults = self.compareToUFO()
+ self.assertEqual(otherResults["info"], False)
+ self.assertEqual(otherResults["kerning"], True)
+ self.assertEqual(otherResults["groups"], False)
+ self.assertEqual(otherResults["features"], False)
+ self.assertEqual(otherResults["lib"], False)
+ self.tearDownFont()
+
+ def testGroups(self):
+ self.setUpFont(doGroups=True)
+ otherResults = self.compareToUFO()
+ self.assertEqual(otherResults["info"], False)
+ self.assertEqual(otherResults["kerning"], False)
+ self.assertEqual(otherResults["groups"], True)
+ self.assertEqual(otherResults["features"], False)
+ self.assertEqual(otherResults["lib"], False)
+ self.tearDownFont()
+
+ def testLib(self):
+ self.setUpFont(doLib=True)
+ otherResults = self.compareToUFO()
+ self.assertEqual(otherResults["info"], False)
+ self.assertEqual(otherResults["kerning"], False)
+ self.assertEqual(otherResults["groups"], False)
+ self.assertEqual(otherResults["features"], False)
+ self.assertEqual(otherResults["lib"], True)
+ self.tearDownFont()
+
+
+if __name__ == "__main__":
+ from robofab.test.testSupport import runTests
+ runTests()
diff --git a/misc/pylib/robofab/test/test_glifLib.py b/misc/pylib/robofab/test/test_glifLib.py
new file mode 100644
index 000000000..13eca3a6a
--- /dev/null
+++ b/misc/pylib/robofab/test/test_glifLib.py
@@ -0,0 +1,150 @@
+import os
+import tempfile
+import shutil
+import unittest
+
+from robofab.test.testSupport import getDemoFontGlyphSetPath
+from robofab.glifLib import GlyphSet, glyphNameToFileName, READ_MODE
+from robofab.tools.glyphNameSchemes import glyphNameToShortFileName
+
+
+GLYPHSETDIR = getDemoFontGlyphSetPath()
+
+
+class GlyphSetTests(unittest.TestCase):
+
+ def setUp(self):
+ self.dstDir = tempfile.mktemp()
+ os.mkdir(self.dstDir)
+
+ def tearDown(self):
+ shutil.rmtree(self.dstDir)
+
+ def testRoundTrip(self):
+ srcDir = GLYPHSETDIR
+ dstDir = self.dstDir
+ src = GlyphSet(srcDir)
+ dst = GlyphSet(dstDir)
+ for glyphName in src.keys():
+ g = src[glyphName]
+ g.drawPoints(None) # load attrs
+ dst.writeGlyph(glyphName, g, g.drawPoints)
+ # compare raw file data:
+ for glyphName in src.keys():
+ fileName = src.contents[glyphName]
+ org = file(os.path.join(srcDir, fileName), READ_MODE).read()
+ new = file(os.path.join(dstDir, fileName), READ_MODE).read()
+ self.assertEqual(org, new, "%r .glif file differs after round tripping" % glyphName)
+
+ def testRebuildContents(self):
+ gset = GlyphSet(GLYPHSETDIR)
+ contents = gset.contents
+ gset.rebuildContents()
+ self.assertEqual(contents, gset.contents)
+
+ def testReverseContents(self):
+ gset = GlyphSet(GLYPHSETDIR)
+ d = {}
+ for k, v in gset.getReverseContents().items():
+ d[v] = k
+ org = {}
+ for k, v in gset.contents.items():
+ org[k] = v.lower()
+ self.assertEqual(d, org)
+
+ def testReverseContents2(self):
+ src = GlyphSet(GLYPHSETDIR)
+ dst = GlyphSet(self.dstDir)
+ dstMap = dst.getReverseContents()
+ self.assertEqual(dstMap, {})
+ for glyphName in src.keys():
+ g = src[glyphName]
+ g.drawPoints(None) # load attrs
+ dst.writeGlyph(glyphName, g, g.drawPoints)
+ self.assertNotEqual(dstMap, {})
+ srcMap = dict(src.getReverseContents()) # copy
+ self.assertEqual(dstMap, srcMap)
+ del srcMap["a.glif"]
+ dst.deleteGlyph("a")
+ self.assertEqual(dstMap, srcMap)
+
+ def testCustomFileNamingScheme(self):
+ def myGlyphNameToFileName(glyphName, glyphSet):
+ return "prefix" + glyphNameToFileName(glyphName, glyphSet)
+ src = GlyphSet(GLYPHSETDIR)
+ dst = GlyphSet(self.dstDir, myGlyphNameToFileName)
+ for glyphName in src.keys():
+ g = src[glyphName]
+ g.drawPoints(None) # load attrs
+ dst.writeGlyph(glyphName, g, g.drawPoints)
+ d = {}
+ for k, v in src.contents.items():
+ print k, v
+ d[k] = "prefix" + v
+ self.assertEqual(d, dst.contents)
+
+ def testGetUnicodes(self):
+ src = GlyphSet(GLYPHSETDIR)
+ unicodes = src.getUnicodes()
+ for glyphName in src.keys():
+ g = src[glyphName]
+ g.drawPoints(None) # load attrs
+ if not hasattr(g, "unicodes"):
+ self.assertEqual(unicodes[glyphName], [])
+ else:
+ self.assertEqual(g.unicodes, unicodes[glyphName])
+
+
+class FileNameTests(unittest.TestCase):
+
+ def testDefaultFileNameScheme(self):
+ self.assertEqual(glyphNameToFileName("a", None), "a.glif")
+ self.assertEqual(glyphNameToFileName("A", None), "A_.glif")
+ self.assertEqual(glyphNameToFileName("Aring", None), "Aring_.glif")
+ self.assertEqual(glyphNameToFileName("F_A_B", None), "F__A__B_.glif")
+ self.assertEqual(glyphNameToFileName("A.alt", None), "A_.alt.glif")
+ self.assertEqual(glyphNameToFileName("A.Alt", None), "A_.Alt_.glif")
+ self.assertEqual(glyphNameToFileName(".notdef", None), "_notdef.glif")
+ self.assertEqual(glyphNameToFileName("T_H", None), "T__H_.glif")
+ self.assertEqual(glyphNameToFileName("T_h", None), "T__h.glif")
+ self.assertEqual(glyphNameToFileName("t_h", None), "t_h.glif")
+ self.assertEqual(glyphNameToFileName('F_F_I', None), "F__F__I_.glif")
+ self.assertEqual(glyphNameToFileName('f_f_i', None), "f_f_i.glif")
+
+
+ def testShortFileNameScheme(self):
+ print "testShortFileNameScheme"
+ self.assertEqual(glyphNameToShortFileName("a", None), "a.glif")
+ self.assertEqual(glyphNameToShortFileName("A", None), "A_.glif")
+ self.assertEqual(glyphNameToShortFileName("aE", None), "aE_.glif")
+ self.assertEqual(glyphNameToShortFileName("AE", None), "A_E_.glif")
+ self.assertEqual(glyphNameToShortFileName("a.alt", None), "a_alt.glif")
+ self.assertEqual(glyphNameToShortFileName("A.alt", None), "A__alt.glif")
+ self.assertEqual(glyphNameToShortFileName("a.alt#swash", None), "a_alt_swash.glif")
+ self.assertEqual(glyphNameToShortFileName("A.alt", None), "A__alt.glif")
+ self.assertEqual(glyphNameToShortFileName(".notdef", None), "_notdef.glif")
+ self.assertEqual(glyphNameToShortFileName("f_f_i", None), "f_f_i.glif")
+ self.assertEqual(glyphNameToShortFileName("F_F_I", None), "F__F__I_.glif")
+ self.assertEqual(glyphNameToShortFileName("acircumflexdieresis.swash.alt1", None), "acircumflexdieresi0cfc8352.glif")
+ self.assertEqual(glyphNameToShortFileName("acircumflexdieresis.swash.alt2", None), "acircumflexdieresi95f5d2e8.glif")
+ self.assertEqual(glyphNameToShortFileName("Acircumflexdieresis.swash.alt1", None), "A_circumflexdieresed24fb56.glif")
+ self.assertEqual(glyphNameToShortFileName("F#weight0.800_width0.425", None), "F__weight0_800_width0_425.glif")
+ self.assertEqual(glyphNameToShortFileName("F#weight0.83245511_width0.425693567", None), "F__weight0_8324551c9a4143c.glif")
+ self.assertEqual(len(glyphNameToShortFileName("F#weight0.83245511_width0.425693567", None)), 31)
+
+ def testShortFileNameScheme_clashes(self):
+ # test for the condition in code.robofab.com ticket #5
+ name1 = glyphNameToShortFileName('Adieresis', None)
+ name2 = glyphNameToShortFileName('a_dieresis', None)
+ self.assertNotEqual(name1, name2)
+ name1 = glyphNameToShortFileName('AE', None)
+ name2 = glyphNameToShortFileName('aE', None)
+ self.assertNotEqual(name1, name2)
+
+
+if __name__ == "__main__":
+ from robofab.test.testSupport import runTests
+ import sys
+ if len(sys.argv) > 1 and os.path.isdir(sys.argv[-1]):
+ GLYPHSETDIR = sys.argv.pop()
+ runTests()
diff --git a/misc/pylib/robofab/test/test_noneLabUFOReadWrite.py b/misc/pylib/robofab/test/test_noneLabUFOReadWrite.py
new file mode 100644
index 000000000..36dcc0582
--- /dev/null
+++ b/misc/pylib/robofab/test/test_noneLabUFOReadWrite.py
@@ -0,0 +1,321 @@
+import os
+import shutil
+import unittest
+import tempfile
+from robofab.plistlib import readPlist
+import robofab
+from robofab.test.testSupport import fontInfoVersion2, expectedFontInfo1To2Conversion, expectedFontInfo2To1Conversion
+from robofab.objects.objectsRF import NewFont, OpenFont
+from robofab.ufoLib import UFOReader
+
+ufoPath1 = os.path.dirname(robofab.__file__)
+ufoPath1 = os.path.dirname(ufoPath1)
+ufoPath1 = os.path.dirname(ufoPath1)
+ufoPath1 = os.path.join(ufoPath1, "TestData", "TestFont1 (UFO1).ufo")
+ufoPath2 = ufoPath1.replace("TestFont1 (UFO1).ufo", "TestFont1 (UFO2).ufo")
+
+# robofab should remove these from the lib after a load.
+removeFromFormatVersion1Lib = [
+ "org.robofab.opentype.classes",
+ "org.robofab.opentype.features",
+ "org.robofab.opentype.featureorder",
+ "org.robofab.postScriptHintData"
+]
+
+
+class ReadUFOFormatVersion1TestCase(unittest.TestCase):
+
+ def setUpFont(self):
+ self.font = OpenFont(ufoPath1)
+ self.font.update()
+
+ def tearDownFont(self):
+ self.font.close()
+ self.font = None
+
+ def compareToUFO(self, doInfo=True):
+ reader = UFOReader(ufoPath1)
+ results = {}
+ # info
+ infoMatches = True
+ info = self.font.info
+ for attr, expectedValue in expectedFontInfo1To2Conversion.items():
+ writtenValue = getattr(info, attr)
+ if expectedValue != writtenValue:
+ infoMatches = False
+ break
+ results["info"]= infoMatches
+ # kerning
+ kerning = self.font.kerning.asDict()
+ expectedKerning = reader.readKerning()
+ results["kerning"] = expectedKerning == kerning
+ # groups
+ groups = dict(self.font.groups)
+ expectedGroups = reader.readGroups()
+ results["groups"] = expectedGroups == groups
+ # features
+ features = self.font.features.text
+ f = open(os.path.join(ufoPath2, "features.fea"), "r")
+ expectedFeatures = f.read()
+ f.close()
+ match = True
+ features = [line for line in features.splitlines() if line]
+ expectedFeatures = [line for line in expectedFeatures.splitlines() if line]
+ if expectedFeatures != features or reader.readFeatures() != "":
+ match = False
+ results["features"] = match
+ # lib
+ lib = dict(self.font.lib)
+ expectedLib = reader.readLib()
+ for key in removeFromFormatVersion1Lib:
+ if key in expectedLib:
+ del expectedLib[key]
+ results["lib"] = expectedLib == lib
+ return results
+
+ def testFull(self):
+ self.setUpFont()
+ otherResults = self.compareToUFO()
+ self.assertEqual(otherResults["info"], True)
+ self.assertEqual(otherResults["kerning"], True)
+ self.assertEqual(otherResults["groups"], True)
+ self.assertEqual(otherResults["features"], True)
+ self.assertEqual(otherResults["lib"], True)
+ self.tearDownFont()
+
+ def testInfo(self):
+ self.setUpFont()
+ info = self.font.info
+ for attr, expectedValue in expectedFontInfo1To2Conversion.items():
+ writtenValue = getattr(info, attr)
+ self.assertEqual((attr, expectedValue), (attr, writtenValue))
+ self.tearDownFont()
+
+
+class ReadUFOFormatVersion2TestCase(unittest.TestCase):
+
+ def setUpFont(self):
+ self.font = OpenFont(ufoPath2)
+ self.font.update()
+
+ def tearDownFont(self):
+ self.font.close()
+ self.font = None
+
+ def compareToUFO(self, doInfo=True):
+ reader = UFOReader(ufoPath2)
+ results = {}
+ # info
+ infoMatches = True
+ info = self.font.info
+ for attr, expectedValue in fontInfoVersion2.items():
+ writtenValue = getattr(info, attr)
+ if expectedValue != writtenValue:
+ infoMatches = False
+ break
+ results["info"]= infoMatches
+ # kerning
+ kerning = self.font.kerning.asDict()
+ expectedKerning = reader.readKerning()
+ results["kerning"] = expectedKerning == kerning
+ # groups
+ groups = dict(self.font.groups)
+ expectedGroups = reader.readGroups()
+ results["groups"] = expectedGroups == groups
+ # features
+ features = self.font.features.text
+ expectedFeatures = reader.readFeatures()
+ results["features"] = expectedFeatures == features
+ # lib
+ lib = dict(self.font.lib)
+ expectedLib = reader.readLib()
+ results["lib"] = expectedLib == lib
+ return results
+
+ def testFull(self):
+ self.setUpFont()
+ otherResults = self.compareToUFO()
+ self.assertEqual(otherResults["info"], True)
+ self.assertEqual(otherResults["kerning"], True)
+ self.assertEqual(otherResults["groups"], True)
+ self.assertEqual(otherResults["features"], True)
+ self.assertEqual(otherResults["lib"], True)
+ self.tearDownFont()
+
+ def testInfo(self):
+ self.setUpFont()
+ info = self.font.info
+ for attr, expectedValue in fontInfoVersion2.items():
+ writtenValue = getattr(info, attr)
+ self.assertEqual((attr, expectedValue), (attr, writtenValue))
+ self.tearDownFont()
+
+
+class WriteUFOFormatVersion1TestCase(unittest.TestCase):
+
+ def setUpFont(self):
+ self.dstDir = tempfile.mktemp()
+ os.mkdir(self.dstDir)
+ self.font = OpenFont(ufoPath2)
+ self.font.save(self.dstDir, formatVersion=1)
+
+ def tearDownFont(self):
+ shutil.rmtree(self.dstDir)
+
+ def compareToUFO(self):
+ readerExpected = UFOReader(ufoPath1)
+ readerWritten = UFOReader(self.dstDir)
+ results = {}
+ # info
+ matches = True
+ expectedPath = os.path.join(ufoPath1, "fontinfo.plist")
+ writtenPath = os.path.join(self.dstDir, "fontinfo.plist")
+ if not os.path.exists(writtenPath):
+ matches = False
+ else:
+ expected = readPlist(expectedPath)
+ written = readPlist(writtenPath)
+ for attr, expectedValue in expected.items():
+ if expectedValue != written.get(attr):
+ matches = False
+ break
+ results["info"] = matches
+ # kerning
+ matches = True
+ expectedPath = os.path.join(ufoPath1, "kerning.plist")
+ writtenPath = os.path.join(self.dstDir, "kerning.plist")
+ if not os.path.exists(writtenPath):
+ matches = False
+ else:
+ matches = readPlist(expectedPath) == readPlist(writtenPath)
+ results["kerning"] = matches
+ # groups
+ matches = True
+ expectedPath = os.path.join(ufoPath1, "groups.plist")
+ writtenPath = os.path.join(self.dstDir, "groups.plist")
+ if not os.path.exists(writtenPath):
+ matches = False
+ else:
+ matches = readPlist(expectedPath) == readPlist(writtenPath)
+ results["groups"] = matches
+ # features
+ matches = True
+ expectedPath = os.path.join(ufoPath1, "features.fea")
+ writtenPath = os.path.join(self.dstDir, "features.fea")
+ if os.path.exists(writtenPath):
+ matches = False
+ results["features"] = matches
+ # lib
+ matches = True
+ expectedPath = os.path.join(ufoPath1, "lib.plist")
+ writtenPath = os.path.join(self.dstDir, "lib.plist")
+ if not os.path.exists(writtenPath):
+ matches = False
+ else:
+ writtenLib = readPlist(writtenPath)
+ matches = readPlist(expectedPath) == writtenLib
+ results["lib"] = matches
+ return results
+
+ def testFull(self):
+ self.setUpFont()
+ otherResults = self.compareToUFO()
+ self.assertEqual(otherResults["info"], True)
+ self.assertEqual(otherResults["kerning"], True)
+ self.assertEqual(otherResults["groups"], True)
+ self.assertEqual(otherResults["features"], True)
+ self.assertEqual(otherResults["lib"], True)
+ self.tearDownFont()
+
+
+class WriteUFOFormatVersion2TestCase(unittest.TestCase):
+
+ def setUpFont(self):
+ self.dstDir = tempfile.mktemp()
+ os.mkdir(self.dstDir)
+ self.font = OpenFont(ufoPath2)
+ self.font.save(self.dstDir)
+
+ def tearDownFont(self):
+ shutil.rmtree(self.dstDir)
+
+ def compareToUFO(self):
+ readerExpected = UFOReader(ufoPath2)
+ readerWritten = UFOReader(self.dstDir)
+ results = {}
+ # info
+ matches = True
+ expectedPath = os.path.join(ufoPath2, "fontinfo.plist")
+ writtenPath = os.path.join(self.dstDir, "fontinfo.plist")
+ if not os.path.exists(writtenPath):
+ matches = False
+ else:
+ expected = readPlist(expectedPath)
+ written = readPlist(writtenPath)
+ for attr, expectedValue in expected.items():
+ if expectedValue != written[attr]:
+ matches = False
+ break
+ results["info"] = matches
+ # kerning
+ matches = True
+ expectedPath = os.path.join(ufoPath2, "kerning.plist")
+ writtenPath = os.path.join(self.dstDir, "kerning.plist")
+ if not os.path.exists(writtenPath):
+ matches = False
+ else:
+ matches = readPlist(expectedPath) == readPlist(writtenPath)
+ results["kerning"] = matches
+ # groups
+ matches = True
+ expectedPath = os.path.join(ufoPath2, "groups.plist")
+ writtenPath = os.path.join(self.dstDir, "groups.plist")
+ if not os.path.exists(writtenPath):
+ matches = False
+ else:
+ matches = readPlist(expectedPath) == readPlist(writtenPath)
+ results["groups"] = matches
+ # features
+ matches = True
+ expectedPath = os.path.join(ufoPath2, "features.fea")
+ writtenPath = os.path.join(self.dstDir, "features.fea")
+ if not os.path.exists(writtenPath):
+ matches = False
+ else:
+ f = open(expectedPath, "r")
+ expectedText = f.read()
+ f.close()
+ f = open(writtenPath, "r")
+ writtenText = f.read()
+ f.close()
+ # FontLab likes to add lines to the features, so skip blank lines.
+ expectedText = [line for line in expectedText.splitlines() if line]
+ writtenText = [line for line in writtenText.splitlines() if line]
+ matches = "\n".join(expectedText) == "\n".join(writtenText)
+ results["features"] = matches
+ # lib
+ matches = True
+ expectedPath = os.path.join(ufoPath2, "lib.plist")
+ writtenPath = os.path.join(self.dstDir, "lib.plist")
+ if not os.path.exists(writtenPath):
+ matches = False
+ else:
+ writtenLib = readPlist(writtenPath)
+ matches = readPlist(expectedPath) == writtenLib
+ results["lib"] = matches
+ return results
+
+ def testFull(self):
+ self.setUpFont()
+ otherResults = self.compareToUFO()
+ self.assertEqual(otherResults["info"], True)
+ self.assertEqual(otherResults["kerning"], True)
+ self.assertEqual(otherResults["groups"], True)
+ self.assertEqual(otherResults["features"], True)
+ self.assertEqual(otherResults["lib"], True)
+ self.tearDownFont()
+
+
+if __name__ == "__main__":
+ from robofab.test.testSupport import runTests
+ runTests()
diff --git a/misc/pylib/robofab/test/test_objectsFL.py b/misc/pylib/robofab/test/test_objectsFL.py
new file mode 100755
index 000000000..948897097
--- /dev/null
+++ b/misc/pylib/robofab/test/test_objectsFL.py
@@ -0,0 +1,54 @@
+"""This test suite for various FontLab-specific tests."""
+
+
+import FL # needed to quickly raise ImportError if run outside of FL
+
+
+import os
+import tempfile
+import unittest
+
+from robofab.world import NewFont
+from robofab.test.testSupport import getDemoFontPath, getDemoFontGlyphSetPath
+from robofab.tools.glifImport import importAllGlifFiles
+from robofab.pens.digestPen import DigestPointPen
+from robofab.pens.adapterPens import SegmentToPointPen
+
+
+def getDigests(font):
+ digests = {}
+ for glyphName in font.keys():
+ pen = DigestPointPen()
+ font[glyphName].drawPoints(pen)
+ digests[glyphName] = pen.getDigest()
+ return digests
+
+
+class FLTestCase(unittest.TestCase):
+
+ def testUFOVersusGlifImport(self):
+ font = NewFont()
+ font.readUFO(getDemoFontPath(), doProgress=False)
+ d1 = getDigests(font)
+ font.close(False)
+ font = NewFont()
+ importAllGlifFiles(font.naked(), getDemoFontGlyphSetPath(), doProgress=False)
+ d2 = getDigests(font)
+ self.assertEqual(d1, d2)
+ font.close(False)
+
+ def testTwoUntitledFonts(self):
+ font1 = NewFont()
+ font2 = NewFont()
+ font1.unitsPerEm = 1024
+ font2.unitsPerEm = 2048
+ self.assertNotEqual(font1.unitsPerEm, font2.unitsPerEm)
+ font1.update()
+ font2.update()
+ font1.close(False)
+ font2.close(False)
+
+
+if __name__ == "__main__":
+ from robofab.test.testSupport import runTests
+ runTests()
diff --git a/misc/pylib/robofab/test/test_objectsUFO.py b/misc/pylib/robofab/test/test_objectsUFO.py
new file mode 100755
index 000000000..c974a121c
--- /dev/null
+++ b/misc/pylib/robofab/test/test_objectsUFO.py
@@ -0,0 +1,203 @@
+"""This test suite for ufo glyph methods"""
+
+
+import unittest
+import os
+import tempfile
+import shutil
+
+from robofab.objects.objectsRF import RFont
+from robofab.test.testSupport import getDemoFontPath
+from robofab.pens.digestPen import DigestPointPen
+from robofab.pens.adapterPens import SegmentToPointPen, FabToFontToolsPenAdapter
+
+
+class ContourMethodsTestCase(unittest.TestCase):
+
+ def setUp(self):
+ self.font = RFont(getDemoFontPath())
+
+ def testReverseContour(self):
+ for glyph in self.font:
+ pen = DigestPointPen()
+ glyph.drawPoints(pen)
+ digest1 = pen.getDigest()
+ for contour in glyph:
+ contour.reverseContour()
+ contour.reverseContour()
+ pen = DigestPointPen()
+ glyph.drawPoints(pen)
+ digest2 = pen.getDigest()
+ self.assertEqual(digest1, digest2, "%r not the same after reversing twice" % glyph.name)
+
+ def testStartSegment(self):
+ for glyph in self.font:
+ pen = DigestPointPen()
+ glyph.drawPoints(pen)
+ digest1 = pen.getDigest()
+ for contour in glyph:
+ contour.setStartSegment(2)
+ contour.setStartSegment(-2)
+ pen = DigestPointPen()
+ glyph.drawPoints(pen)
+ digest2 = pen.getDigest()
+ self.assertEqual(digest1, digest2, "%r not the same after seting start segment twice" % glyph.name)
+
+ def testAppendSegment(self):
+ for glyph in self.font:
+ pen = DigestPointPen()
+ glyph.drawPoints(pen)
+ digest1 = pen.getDigest()
+ for contour in glyph:
+ contour.insertSegment(2, "curve", [(100, 100), (200, 200), (300, 300)])
+ contour.removeSegment(2)
+ pen = DigestPointPen()
+ glyph.drawPoints(pen)
+ digest2 = pen.getDigest()
+ self.assertEqual(digest1, digest2, "%r not the same after inserting and removing segment" % glyph.name)
+
+
+class GlyphsMethodsTestCase(ContourMethodsTestCase):
+
+ def testCopyGlyph(self):
+ for glyph in self.font:
+ pen = DigestPointPen()
+ glyph.drawPoints(pen)
+ digest1 = pen.getDigest()
+ copy = glyph.copy()
+ pen = DigestPointPen()
+ copy.drawPoints(pen)
+ digest2 = pen.getDigest()
+ self.assertEqual(digest1, digest2, "%r not the same after copying" % glyph.name)
+ self.assertEqual(glyph.lib, copy.lib, "%r's lib not the same after copying" % glyph.name)
+ self.assertEqual(glyph.width, copy.width, "%r's width not the same after copying" % glyph.name)
+ self.assertEqual(glyph.unicodes, copy.unicodes, "%r's unicodes not the same after copying" % glyph.name)
+
+ def testMoveGlyph(self):
+ for glyph in self.font:
+ pen = DigestPointPen()
+ glyph.drawPoints(pen)
+ digest1 = pen.getDigest()
+ glyph.move((100, 200))
+ glyph.move((-100, -200))
+ pen = DigestPointPen()
+ glyph.drawPoints(pen)
+ digest2 = pen.getDigest()
+ self.assertEqual(digest1, digest2, "%r not the same after moving twice" % glyph.name)
+
+ def testScaleGlyph(self):
+ for glyph in self.font:
+ pen = DigestPointPen()
+ glyph.drawPoints(pen)
+ digest1 = pen.getDigest()
+ glyph.scale((2, 2))
+ glyph.scale((.5, .5))
+ pen = DigestPointPen()
+ glyph.drawPoints(pen)
+ digest2 = pen.getDigest()
+ self.assertEqual(digest1, digest2, "%r not the same after scaling twice" % glyph.name)
+
+ def testSegmentPenInterface(self):
+ for glyph in self.font:
+ digestPen = DigestPointPen(ignoreSmoothAndName=True)
+ pen = SegmentToPointPen(digestPen)
+ glyph.draw(pen)
+ digest1 = digestPen.getDigest()
+ digestPen = DigestPointPen(ignoreSmoothAndName=True)
+ glyph.drawPoints(digestPen)
+ digest2 = digestPen.getDigest()
+ self.assertEqual(digest1, digest2, "%r not the same for gl.draw() and gl.drawPoints()" % glyph.name)
+
+ def testFabPenCompatibility(self):
+ for glyph in self.font:
+ digestPen = DigestPointPen(ignoreSmoothAndName=True)
+ pen = FabToFontToolsPenAdapter(SegmentToPointPen(digestPen))
+ glyph.draw(pen)
+ digest1 = digestPen.getDigest()
+ digestPen = DigestPointPen(ignoreSmoothAndName=True)
+ glyph.drawPoints(digestPen)
+ digest2 = digestPen.getDigest()
+ self.assertEqual(digest1, digest2, "%r not the same for gl.draw() and gl.drawPoints()" % glyph.name)
+
+ def testComponentTransformations(self):
+ from robofab.objects.objectsRF import RComponent
+ name = "baseGlyphName"
+ c = RComponent(name, transform=(1,0,0,1,0,0))
+ # get values
+ assert c.baseGlyph == "baseGlyphName"
+ assert c.transformation == c.transformation
+ assert c.scale == (1,1)
+ assert c.offset == (0,0)
+ # set values
+ c.offset = (12,34)
+ assert c.transformation == (1, 0, 0, 1, 12, 34)
+ c.offset = (0,0)
+ assert c.transformation == (1,0,0,1,0,0)
+ c.scale = (12,34)
+ assert c.transformation == (12, 0, 0, 34, 0, 0)
+
+
+class SaveTestCase(ContourMethodsTestCase):
+
+ def testSaveAs(self):
+ path = tempfile.mktemp(".ufo")
+ try:
+ keys1 = self.font.keys()
+ self.font.save(path)
+ keys2 = self.font.keys()
+ keys1.sort()
+ keys2.sort()
+ self.assertEqual(keys1, keys2)
+ self.assertEqual(self.font.path, path)
+ font2 = RFont(path)
+ keys3 = font2.keys()
+ keys3.sort()
+ self.assertEqual(keys1, keys3)
+ finally:
+ if os.path.exists(path):
+ shutil.rmtree(path)
+
+ def testSaveAs2(self):
+ path = tempfile.mktemp(".ufo")
+ # copy a glyph
+ self.font["X"] = self.font["a"].copy()
+# self.assertEqual(self.font["X"].name, "X")
+ # remove a glyph
+ self.font.removeGlyph("a")
+ keys1 = self.font.keys()
+ try:
+ self.font.save(path)
+ self.assertEqual(self.font.path, path)
+ keys2 = self.font.keys()
+ keys1.sort()
+ keys2.sort()
+ self.assertEqual(keys1, keys2)
+ font2 = RFont(path)
+ keys3 = font2.keys()
+ keys3.sort()
+ self.assertEqual(keys1, keys3)
+ finally:
+ if os.path.exists(path):
+ shutil.rmtree(path)
+
+ def testCustomFileNameScheme(self):
+ path = tempfile.mktemp(".ufo")
+ libKey = "org.robofab.glyphNameToFileNameFuncName"
+ self.font.lib[libKey] = "robofab.test.test_objectsUFO.testGlyphNameToFileName"
+ try:
+ self.font.save(path)
+ self.assertEqual(os.path.exists(os.path.join(path,
+ "glyphs", "test_a.glif")), True)
+ finally:
+ if os.path.exists(path):
+ shutil.rmtree(path)
+
+
+def testGlyphNameToFileName(glyphName, glyphSet):
+ from robofab.glifLib import glyphNameToFileName
+ return "test_" + glyphNameToFileName(glyphName, glyphSet)
+
+
+if __name__ == "__main__":
+ from robofab.test.testSupport import runTests
+ runTests()
diff --git a/misc/pylib/robofab/test/test_pens.py b/misc/pylib/robofab/test/test_pens.py
new file mode 100755
index 000000000..a2a773cb2
--- /dev/null
+++ b/misc/pylib/robofab/test/test_pens.py
@@ -0,0 +1,149 @@
+"""This test suite test general Pen stuff, it should not contain
+FontLab-specific code.
+"""
+
+import unittest
+
+from robofab.pens.digestPen import DigestPointPen
+from robofab.pens.adapterPens import SegmentToPointPen, PointToSegmentPen
+from robofab.pens.adapterPens import GuessSmoothPointPen
+from robofab.pens.reverseContourPointPen import ReverseContourPointPen
+from robofab.test.testSupport import getDemoFontGlyphSetPath
+from robofab.glifLib import GlyphSet
+
+
+class TestShapes:
+
+ # Collection of test shapes. It's probably better to add these as
+ # glyphs to the demo font.
+
+ def square(pen):
+ # a simple square as a closed path (100, 100, 600, 600)
+ pen.beginPath()
+ pen.addPoint((100, 100), "line")
+ pen.addPoint((100, 600), "line")
+ pen.addPoint((600, 600), "line")
+ pen.addPoint((600, 100), "line")
+ pen.endPath()
+ square = staticmethod(square)
+
+ def onCurveLessQuadShape(pen):
+ pen.beginPath()
+ pen.addPoint((100, 100))
+ pen.addPoint((100, 600))
+ pen.addPoint((600, 600))
+ pen.addPoint((600, 100))
+ pen.endPath()
+ onCurveLessQuadShape = staticmethod(onCurveLessQuadShape)
+
+ def openPath(pen):
+ # a simple square as a closed path (100, 100, 600, 600)
+ pen.beginPath()
+ pen.addPoint((100, 100), "move")
+ pen.addPoint((100, 600), "line")
+ pen.addPoint((600, 600), "line")
+ pen.addPoint((600, 100), "line")
+ pen.endPath()
+ openPath = staticmethod(openPath)
+
+ def circle(pen):
+ pen.beginPath()
+ pen.addPoint((0, 500), "curve")
+ pen.addPoint((0, 800))
+ pen.addPoint((200, 1000))
+ pen.addPoint((500, 1000), "curve")
+ pen.addPoint((800, 1000))
+ pen.addPoint((1000, 800))
+ pen.addPoint((1000, 500), "curve")
+ pen.addPoint((1000, 200))
+ pen.addPoint((800, 0))
+ pen.addPoint((500, 0), "curve")
+ pen.addPoint((200, 0))
+ pen.addPoint((0, 200))
+ pen.endPath()
+ circle = staticmethod(circle)
+
+
+class RoundTripTestCase(unittest.TestCase):
+
+ def _doTest(self, shapeFunc, shapeName):
+ pen = DigestPointPen(ignoreSmoothAndName=True)
+ shapeFunc(pen)
+ digest1 = pen.getDigest()
+
+ digestPen = DigestPointPen(ignoreSmoothAndName=True)
+ pen = PointToSegmentPen(SegmentToPointPen(digestPen))
+ shapeFunc(pen)
+ digest2 = digestPen.getDigest()
+ self.assertEqual(digest1, digest2, "%r failed round tripping" % shapeName)
+
+ def testShapes(self):
+ for name in dir(TestShapes):
+ if name[0] != "_":
+ self._doTest(getattr(TestShapes, name), name)
+
+ def testShapesFromGlyphSet(self):
+ glyphSet = GlyphSet(getDemoFontGlyphSetPath())
+ for name in glyphSet.keys():
+ self._doTest(glyphSet[name].drawPoints, name)
+
+ def testGuessSmoothPen(self):
+ glyphSet = GlyphSet(getDemoFontGlyphSetPath())
+ for name in glyphSet.keys():
+ digestPen = DigestPointPen()
+ glyphSet[name].drawPoints(digestPen)
+ digest1 = digestPen.getDigest()
+ digestPen = DigestPointPen()
+ pen = GuessSmoothPointPen(digestPen)
+ glyphSet[name].drawPoints(pen)
+ digest2 = digestPen.getDigest()
+ self.assertEqual(digest1, digest2)
+
+
+class ReverseContourTestCase(unittest.TestCase):
+
+ def testReverseContourClosedPath(self):
+ digestPen = DigestPointPen()
+ TestShapes.square(digestPen)
+ d1 = digestPen.getDigest()
+ digestPen = DigestPointPen()
+ pen = ReverseContourPointPen(digestPen)
+ pen.beginPath()
+ pen.addPoint((100, 100), "line")
+ pen.addPoint((600, 100), "line")
+ pen.addPoint((600, 600), "line")
+ pen.addPoint((100, 600), "line")
+ pen.endPath()
+ d2 = digestPen.getDigest()
+ self.assertEqual(d1, d2)
+
+ def testReverseContourOpenPath(self):
+ digestPen = DigestPointPen()
+ TestShapes.openPath(digestPen)
+ d1 = digestPen.getDigest()
+ digestPen = DigestPointPen()
+ pen = ReverseContourPointPen(digestPen)
+ pen.beginPath()
+ pen.addPoint((600, 100), "move")
+ pen.addPoint((600, 600), "line")
+ pen.addPoint((100, 600), "line")
+ pen.addPoint((100, 100), "line")
+ pen.endPath()
+ d2 = digestPen.getDigest()
+ self.assertEqual(d1, d2)
+
+ def testReversContourFromGlyphSet(self):
+ glyphSet = GlyphSet(getDemoFontGlyphSetPath())
+ digestPen = DigestPointPen()
+ glyphSet["testglyph1"].drawPoints(digestPen)
+ digest1 = digestPen.getDigest()
+ digestPen = DigestPointPen()
+ pen = ReverseContourPointPen(digestPen)
+ glyphSet["testglyph1.reversed"].drawPoints(pen)
+ digest2 = digestPen.getDigest()
+ self.assertEqual(digest1, digest2)
+
+
+if __name__ == "__main__":
+ from robofab.test.testSupport import runTests
+ runTests()
diff --git a/misc/pylib/robofab/test/test_psHints.py b/misc/pylib/robofab/test/test_psHints.py
new file mode 100644
index 000000000..991e9d9cc
--- /dev/null
+++ b/misc/pylib/robofab/test/test_psHints.py
@@ -0,0 +1,110 @@
+def test():
+ """
+ # some tests for the ps Hints operations
+ >>> from robofab.world import RFont, RGlyph
+ >>> g = RGlyph()
+ >>> g.psHints.isEmpty()
+ True
+
+ >>> h = RGlyph()
+ >>> i = g + h
+ >>> i.psHints.isEmpty()
+ True
+
+ >>> i = g - h
+ >>> i.psHints.isEmpty()
+ True
+
+ >>> i = g * 2
+ >>> i.psHints.isEmpty()
+ True
+
+ >>> i = g / 2
+ >>> i.psHints.isEmpty()
+ True
+
+ >>> g.psHints.vHints = [(100, 50), (200, 50)]
+ >>> g.psHints.hHints = [(100, 50), (200, 5)]
+
+ >>> not g.psHints.isEmpty()
+ True
+
+ >>> gc = g.copy()
+ >>> gc.psHints.asDict() == g.psHints.asDict()
+ True
+
+ # multiplication
+ >>> v = g.psHints * 2
+ >>> v.asDict() == {'vHints': [[200, 100], [400, 100]], 'hHints': [[200, 100], [400, 10]]}
+ True
+
+ # division
+ >>> v = g.psHints / 2
+ >>> v.asDict() == {'vHints': [[50.0, 25.0], [100.0, 25.0]], 'hHints': [[50.0, 25.0], [100.0, 2.5]]}
+ True
+
+ # multiplication with x, y, factor
+ # vertically oriented values should respond different
+ >>> v = g.psHints * (.5, 10)
+ >>> v.asDict() == {'vHints': [[1000, 500], [2000, 500]], 'hHints': [[50.0, 25.0], [100.0, 2.5]]}
+ True
+
+ # division with x, y, factor
+ # vertically oriented values should respond different
+ >>> v = g.psHints / (.5, 10)
+ >>> v.asDict() == {'vHints': [[10.0, 5.0], [20.0, 5.0]], 'hHints': [[200.0, 100.0], [400.0, 10.0]]}
+ True
+
+ # rounding to integer
+ >>> v = g.psHints / 2
+ >>> v.round()
+ >>> v.asDict() == {'vHints': [(50, 25), (100, 25)], 'hHints': [(50, 25), (100, 3)]}
+ True
+
+ # "ps hint values calculating with a glyph"
+ # ps hint values as part of glyphmath operations.
+ # multiplication
+ >>> h = g * 10
+ >>> h.psHints.asDict() == {'vHints': [[1000, 500], [2000, 500]], 'hHints': [[1000, 500], [2000, 50]]}
+ True
+
+ # division
+ >>> h = g / 2
+ >>> h.psHints.asDict() == {'vHints': [[50.0, 25.0], [100.0, 25.0]], 'hHints': [[50.0, 25.0], [100.0, 2.5]]}
+ True
+
+ # x, y factor multiplication
+ >>> h = g * (.5, 10)
+ >>> h.psHints.asDict() == {'vHints': [[1000, 500], [2000, 500]], 'hHints': [[50.0, 25.0], [100.0, 2.5]]}
+ True
+
+ # x, y factor division
+ >>> h = g / (.5, 10)
+ >>> h.psHints.asDict() == {'vHints': [[10.0, 5.0], [20.0, 5.0]], 'hHints': [[200.0, 100.0], [400.0, 10.0]]}
+ True
+
+ # "font ps hint values"
+ >>> f = RFont()
+ >>> f.psHints.isEmpty()
+ True
+
+ >>> f.psHints.blueScale = .5
+ >>> f.psHints.blueShift = 1
+ >>> f.psHints.blueFuzz = 1
+ >>> f.psHints.forceBold = True
+ >>> f.psHints.hStems = (100, 90)
+ >>> f.psHints.vStems = (500, 10)
+
+ >>> not f.psHints.isEmpty()
+ True
+
+ >>> f.insertGlyph(g, name="new")
+ <RGlyph for None.new>
+ >>> f["new"].psHints.asDict() == g.psHints.asDict()
+ True
+ """
+
+if __name__ == "__main__":
+ import doctest
+ doctest.testmod()
+
diff --git a/misc/pylib/robofab/test/test_ufoLib.py b/misc/pylib/robofab/test/test_ufoLib.py
new file mode 100644
index 000000000..e1da807bb
--- /dev/null
+++ b/misc/pylib/robofab/test/test_ufoLib.py
@@ -0,0 +1,1659 @@
+import os
+import shutil
+import unittest
+import tempfile
+from plistlib import writePlist, readPlist
+from robofab.ufoLib import UFOReader, UFOWriter, UFOLibError, \
+ convertUFOFormatVersion1ToFormatVersion2, convertUFOFormatVersion2ToFormatVersion1
+from robofab.test.testSupport import fontInfoVersion1, fontInfoVersion2, expectedFontInfo1To2Conversion, expectedFontInfo2To1Conversion
+
+
+# the format version 1 lib.plist contains some data
+# that these tests shouldn't be concerned about.
+removeFromFormatVersion1Lib = [
+ "org.robofab.opentype.classes",
+ "org.robofab.opentype.features",
+ "org.robofab.opentype.featureorder",
+ "org.robofab.postScriptHintData"
+]
+
+
+class TestInfoObject(object): pass
+
+
+class ReadFontInfoVersion1TestCase(unittest.TestCase):
+
+ def setUp(self):
+ self.dstDir = tempfile.mktemp()
+ os.mkdir(self.dstDir)
+ metaInfo = {
+ "creator": "test",
+ "formatVersion": 1
+ }
+ path = os.path.join(self.dstDir, "metainfo.plist")
+ writePlist(metaInfo, path)
+
+ def tearDown(self):
+ shutil.rmtree(self.dstDir)
+
+ def _writeInfoToPlist(self, info):
+ path = os.path.join(self.dstDir, "fontinfo.plist")
+ writePlist(info, path)
+
+ def testRead(self):
+ originalData = dict(fontInfoVersion1)
+ self._writeInfoToPlist(originalData)
+ infoObject = TestInfoObject()
+ reader = UFOReader(self.dstDir)
+ reader.readInfo(infoObject)
+ for attr in dir(infoObject):
+ if attr not in fontInfoVersion2:
+ continue
+ originalValue = fontInfoVersion2[attr]
+ readValue = getattr(infoObject, attr)
+ self.assertEqual(originalValue, readValue)
+
+ def testFontStyleConversion(self):
+ fontStyle1To2 = {
+ 64 : "regular",
+ 1 : "italic",
+ 32 : "bold",
+ 33 : "bold italic"
+ }
+ for old, new in fontStyle1To2.items():
+ info = dict(fontInfoVersion1)
+ info["fontStyle"] = old
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ infoObject = TestInfoObject()
+ reader.readInfo(infoObject)
+ self.assertEqual(new, infoObject.styleMapStyleName)
+
+ def testWidthNameConversion(self):
+ widthName1To2 = {
+ "Ultra-condensed" : 1,
+ "Extra-condensed" : 2,
+ "Condensed" : 3,
+ "Semi-condensed" : 4,
+ "Medium (normal)" : 5,
+ "Semi-expanded" : 6,
+ "Expanded" : 7,
+ "Extra-expanded" : 8,
+ "Ultra-expanded" : 9
+ }
+ for old, new in widthName1To2.items():
+ info = dict(fontInfoVersion1)
+ info["widthName"] = old
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ infoObject = TestInfoObject()
+ reader.readInfo(infoObject)
+ self.assertEqual(new, infoObject.openTypeOS2WidthClass)
+
+
+class ReadFontInfoVersion2TestCase(unittest.TestCase):
+
+ def setUp(self):
+ self.dstDir = tempfile.mktemp()
+ os.mkdir(self.dstDir)
+ metaInfo = {
+ "creator": "test",
+ "formatVersion": 2
+ }
+ path = os.path.join(self.dstDir, "metainfo.plist")
+ writePlist(metaInfo, path)
+
+ def tearDown(self):
+ shutil.rmtree(self.dstDir)
+
+ def _writeInfoToPlist(self, info):
+ path = os.path.join(self.dstDir, "fontinfo.plist")
+ writePlist(info, path)
+
+ def testRead(self):
+ originalData = dict(fontInfoVersion2)
+ self._writeInfoToPlist(originalData)
+ infoObject = TestInfoObject()
+ reader = UFOReader(self.dstDir)
+ reader.readInfo(infoObject)
+ readData = {}
+ for attr in fontInfoVersion2.keys():
+ readData[attr] = getattr(infoObject, attr)
+ self.assertEqual(originalData, readData)
+
+ def testGenericRead(self):
+ # familyName
+ info = dict(fontInfoVersion2)
+ info["familyName"] = 123
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # styleName
+ info = dict(fontInfoVersion2)
+ info["styleName"] = 123
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # styleMapFamilyName
+ info = dict(fontInfoVersion2)
+ info["styleMapFamilyName"] = 123
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # styleMapStyleName
+ ## not a string
+ info = dict(fontInfoVersion2)
+ info["styleMapStyleName"] = 123
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ ## out of range
+ info = dict(fontInfoVersion2)
+ info["styleMapStyleName"] = "REGULAR"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # versionMajor
+ info = dict(fontInfoVersion2)
+ info["versionMajor"] = "1"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # versionMinor
+ info = dict(fontInfoVersion2)
+ info["versionMinor"] = "0"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # copyright
+ info = dict(fontInfoVersion2)
+ info["copyright"] = 123
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # trademark
+ info = dict(fontInfoVersion2)
+ info["trademark"] = 123
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # unitsPerEm
+ info = dict(fontInfoVersion2)
+ info["unitsPerEm"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # descender
+ info = dict(fontInfoVersion2)
+ info["descender"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # xHeight
+ info = dict(fontInfoVersion2)
+ info["xHeight"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # capHeight
+ info = dict(fontInfoVersion2)
+ info["capHeight"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # ascender
+ info = dict(fontInfoVersion2)
+ info["ascender"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # italicAngle
+ info = dict(fontInfoVersion2)
+ info["italicAngle"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+
+ def testHeadRead(self):
+ # openTypeHeadCreated
+ ## not a string
+ info = dict(fontInfoVersion2)
+ info["openTypeHeadCreated"] = 123
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ ## invalid format
+ info = dict(fontInfoVersion2)
+ info["openTypeHeadCreated"] = "2000-Jan-01 00:00:00"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeHeadLowestRecPPEM
+ info = dict(fontInfoVersion2)
+ info["openTypeHeadLowestRecPPEM"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeHeadFlags
+ info = dict(fontInfoVersion2)
+ info["openTypeHeadFlags"] = [-1]
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+
+ def testHheaRead(self):
+ # openTypeHheaAscender
+ info = dict(fontInfoVersion2)
+ info["openTypeHheaAscender"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeHheaDescender
+ info = dict(fontInfoVersion2)
+ info["openTypeHheaDescender"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeHheaLineGap
+ info = dict(fontInfoVersion2)
+ info["openTypeHheaLineGap"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeHheaCaretSlopeRise
+ info = dict(fontInfoVersion2)
+ info["openTypeHheaCaretSlopeRise"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeHheaCaretSlopeRun
+ info = dict(fontInfoVersion2)
+ info["openTypeHheaCaretSlopeRun"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeHheaCaretOffset
+ info = dict(fontInfoVersion2)
+ info["openTypeHheaCaretOffset"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+
+ def testNameRead(self):
+ # openTypeNameDesigner
+ info = dict(fontInfoVersion2)
+ info["openTypeNameDesigner"] = 123
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeNameDesignerURL
+ info = dict(fontInfoVersion2)
+ info["openTypeNameDesignerURL"] = 123
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeNameManufacturer
+ info = dict(fontInfoVersion2)
+ info["openTypeNameManufacturer"] = 123
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeNameManufacturerURL
+ info = dict(fontInfoVersion2)
+ info["openTypeNameManufacturerURL"] = 123
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeNameLicense
+ info = dict(fontInfoVersion2)
+ info["openTypeNameLicense"] = 123
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeNameLicenseURL
+ info = dict(fontInfoVersion2)
+ info["openTypeNameLicenseURL"] = 123
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeNameVersion
+ info = dict(fontInfoVersion2)
+ info["openTypeNameVersion"] = 123
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeNameUniqueID
+ info = dict(fontInfoVersion2)
+ info["openTypeNameUniqueID"] = 123
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeNameDescription
+ info = dict(fontInfoVersion2)
+ info["openTypeNameDescription"] = 123
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeNamePreferredFamilyName
+ info = dict(fontInfoVersion2)
+ info["openTypeNamePreferredFamilyName"] = 123
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeNamePreferredSubfamilyName
+ info = dict(fontInfoVersion2)
+ info["openTypeNamePreferredSubfamilyName"] = 123
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeNameCompatibleFullName
+ info = dict(fontInfoVersion2)
+ info["openTypeNameCompatibleFullName"] = 123
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeNameSampleText
+ info = dict(fontInfoVersion2)
+ info["openTypeNameSampleText"] = 123
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeNameWWSFamilyName
+ info = dict(fontInfoVersion2)
+ info["openTypeNameWWSFamilyName"] = 123
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeNameWWSSubfamilyName
+ info = dict(fontInfoVersion2)
+ info["openTypeNameWWSSubfamilyName"] = 123
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+
+ def testOS2Read(self):
+ # openTypeOS2WidthClass
+ ## not an int
+ info = dict(fontInfoVersion2)
+ info["openTypeOS2WidthClass"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ ## out or range
+ info = dict(fontInfoVersion2)
+ info["openTypeOS2WidthClass"] = 15
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeOS2WeightClass
+ info = dict(fontInfoVersion2)
+ ## not an int
+ info["openTypeOS2WeightClass"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ ## out of range
+ info["openTypeOS2WeightClass"] = -50
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeOS2Selection
+ info = dict(fontInfoVersion2)
+ info["openTypeOS2Selection"] = [-1]
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeOS2VendorID
+ info = dict(fontInfoVersion2)
+ info["openTypeOS2VendorID"] = 1234
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeOS2Panose
+ ## not an int
+ info = dict(fontInfoVersion2)
+ info["openTypeOS2Panose"] = [0, 1, 2, 3, 4, 5, 6, 7, 8, str(9)]
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ ## too few values
+ info = dict(fontInfoVersion2)
+ info["openTypeOS2Panose"] = [0, 1, 2, 3]
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ ## too many values
+ info = dict(fontInfoVersion2)
+ info["openTypeOS2Panose"] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeOS2FamilyClass
+ ## not an int
+ info = dict(fontInfoVersion2)
+ info["openTypeOS2FamilyClass"] = [1, str(1)]
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ ## too few values
+ info = dict(fontInfoVersion2)
+ info["openTypeOS2FamilyClass"] = [1]
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ ## too many values
+ info = dict(fontInfoVersion2)
+ info["openTypeOS2FamilyClass"] = [1, 1, 1]
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ ## out of range
+ info = dict(fontInfoVersion2)
+ info["openTypeOS2FamilyClass"] = [1, 201]
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeOS2UnicodeRanges
+ ## not an int
+ info = dict(fontInfoVersion2)
+ info["openTypeOS2UnicodeRanges"] = ["0"]
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ ## out of range
+ info = dict(fontInfoVersion2)
+ info["openTypeOS2UnicodeRanges"] = [-1]
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeOS2CodePageRanges
+ ## not an int
+ info = dict(fontInfoVersion2)
+ info["openTypeOS2CodePageRanges"] = ["0"]
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ ## out of range
+ info = dict(fontInfoVersion2)
+ info["openTypeOS2CodePageRanges"] = [-1]
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeOS2TypoAscender
+ info = dict(fontInfoVersion2)
+ info["openTypeOS2TypoAscender"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeOS2TypoDescender
+ info = dict(fontInfoVersion2)
+ info["openTypeOS2TypoDescender"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeOS2TypoLineGap
+ info = dict(fontInfoVersion2)
+ info["openTypeOS2TypoLineGap"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeOS2WinAscent
+ info = dict(fontInfoVersion2)
+ info["openTypeOS2WinAscent"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeOS2WinDescent
+ info = dict(fontInfoVersion2)
+ info["openTypeOS2WinDescent"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeOS2Type
+ ## not an int
+ info = dict(fontInfoVersion2)
+ info["openTypeOS2Type"] = ["1"]
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ ## out of range
+ info = dict(fontInfoVersion2)
+ info["openTypeOS2Type"] = [-1]
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeOS2SubscriptXSize
+ info = dict(fontInfoVersion2)
+ info["openTypeOS2SubscriptXSize"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeOS2SubscriptYSize
+ info = dict(fontInfoVersion2)
+ info["openTypeOS2SubscriptYSize"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeOS2SubscriptXOffset
+ info = dict(fontInfoVersion2)
+ info["openTypeOS2SubscriptXOffset"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeOS2SubscriptYOffset
+ info = dict(fontInfoVersion2)
+ info["openTypeOS2SubscriptYOffset"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeOS2SuperscriptXSize
+ info = dict(fontInfoVersion2)
+ info["openTypeOS2SuperscriptXSize"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeOS2SuperscriptYSize
+ info = dict(fontInfoVersion2)
+ info["openTypeOS2SuperscriptYSize"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeOS2SuperscriptXOffset
+ info = dict(fontInfoVersion2)
+ info["openTypeOS2SuperscriptXOffset"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeOS2SuperscriptYOffset
+ info = dict(fontInfoVersion2)
+ info["openTypeOS2SuperscriptYOffset"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeOS2StrikeoutSize
+ info = dict(fontInfoVersion2)
+ info["openTypeOS2StrikeoutSize"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeOS2StrikeoutPosition
+ info = dict(fontInfoVersion2)
+ info["openTypeOS2StrikeoutPosition"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+
+ def testVheaRead(self):
+ # openTypeVheaVertTypoAscender
+ info = dict(fontInfoVersion2)
+ info["openTypeVheaVertTypoAscender"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeVheaVertTypoDescender
+ info = dict(fontInfoVersion2)
+ info["openTypeVheaVertTypoDescender"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeVheaVertTypoLineGap
+ info = dict(fontInfoVersion2)
+ info["openTypeVheaVertTypoLineGap"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeVheaCaretSlopeRise
+ info = dict(fontInfoVersion2)
+ info["openTypeVheaCaretSlopeRise"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeVheaCaretSlopeRun
+ info = dict(fontInfoVersion2)
+ info["openTypeVheaCaretSlopeRun"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # openTypeVheaCaretOffset
+ info = dict(fontInfoVersion2)
+ info["openTypeVheaCaretOffset"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+
+ def testFONDRead(self):
+ # macintoshFONDFamilyID
+ info = dict(fontInfoVersion2)
+ info["macintoshFONDFamilyID"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # macintoshFONDName
+ info = dict(fontInfoVersion2)
+ info["macintoshFONDName"] = 123
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+
+ def testPostscriptRead(self):
+ # postscriptFontName
+ info = dict(fontInfoVersion2)
+ info["postscriptFontName"] = 123
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # postscriptFullName
+ info = dict(fontInfoVersion2)
+ info["postscriptFullName"] = 123
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # postscriptSlantAngle
+ info = dict(fontInfoVersion2)
+ info["postscriptSlantAngle"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
+ # postscriptUniqueID
+ info = dict(fontInfoVersion2)
+ info["postscriptUniqueID"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
+ # postscriptUnderlineThickness
+ info = dict(fontInfoVersion2)
+ info["postscriptUnderlineThickness"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
+ # postscriptUnderlinePosition
+ info = dict(fontInfoVersion2)
+ info["postscriptUnderlinePosition"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
+ # postscriptIsFixedPitch
+ info = dict(fontInfoVersion2)
+ info["postscriptIsFixedPitch"] = 2
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
+ # postscriptBlueValues
+ ## not a list
+ info = dict(fontInfoVersion2)
+ info["postscriptBlueValues"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
+ ## uneven value count
+ info = dict(fontInfoVersion2)
+ info["postscriptBlueValues"] = [500]
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
+ ## too many values
+ info = dict(fontInfoVersion2)
+ info["postscriptBlueValues"] = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
+ # postscriptOtherBlues
+ ## not a list
+ info = dict(fontInfoVersion2)
+ info["postscriptOtherBlues"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
+ ## uneven value count
+ info = dict(fontInfoVersion2)
+ info["postscriptOtherBlues"] = [500]
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
+ ## too many values
+ info = dict(fontInfoVersion2)
+ info["postscriptOtherBlues"] = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
+ # postscriptFamilyBlues
+ ## not a list
+ info = dict(fontInfoVersion2)
+ info["postscriptFamilyBlues"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
+ ## uneven value count
+ info = dict(fontInfoVersion2)
+ info["postscriptFamilyBlues"] = [500]
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
+ ## too many values
+ info = dict(fontInfoVersion2)
+ info["postscriptFamilyBlues"] = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
+ # postscriptFamilyOtherBlues
+ ## not a list
+ info = dict(fontInfoVersion2)
+ info["postscriptFamilyOtherBlues"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
+ ## uneven value count
+ info = dict(fontInfoVersion2)
+ info["postscriptFamilyOtherBlues"] = [500]
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
+ ## too many values
+ info = dict(fontInfoVersion2)
+ info["postscriptFamilyOtherBlues"] = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
+ # postscriptStemSnapH
+ ## not list
+ info = dict(fontInfoVersion2)
+ info["postscriptStemSnapH"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
+ ## too many values
+ info = dict(fontInfoVersion2)
+ info["postscriptStemSnapH"] = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
+ # postscriptStemSnapV
+ ## not list
+ info = dict(fontInfoVersion2)
+ info["postscriptStemSnapV"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
+ ## too many values
+ info = dict(fontInfoVersion2)
+ info["postscriptStemSnapV"] = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
+ # postscriptBlueFuzz
+ info = dict(fontInfoVersion2)
+ info["postscriptBlueFuzz"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
+ # postscriptBlueShift
+ info = dict(fontInfoVersion2)
+ info["postscriptBlueShift"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
+ # postscriptBlueScale
+ info = dict(fontInfoVersion2)
+ info["postscriptBlueScale"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
+ # postscriptForceBold
+ info = dict(fontInfoVersion2)
+ info["postscriptForceBold"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
+ # postscriptDefaultWidthX
+ info = dict(fontInfoVersion2)
+ info["postscriptDefaultWidthX"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
+ # postscriptNominalWidthX
+ info = dict(fontInfoVersion2)
+ info["postscriptNominalWidthX"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
+ # postscriptWeightName
+ info = dict(fontInfoVersion2)
+ info["postscriptWeightName"] = 123
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
+ # postscriptDefaultCharacter
+ info = dict(fontInfoVersion2)
+ info["postscriptDefaultCharacter"] = 123
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
+ # postscriptWindowsCharacterSet
+ info = dict(fontInfoVersion2)
+ info["postscriptWindowsCharacterSet"] = -1
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
+ # macintoshFONDFamilyID
+ info = dict(fontInfoVersion2)
+ info["macintoshFONDFamilyID"] = "abc"
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
+ # macintoshFONDName
+ info = dict(fontInfoVersion2)
+ info["macintoshFONDName"] = 123
+ self._writeInfoToPlist(info)
+ reader = UFOReader(self.dstDir)
+ self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
+
+
+class WriteFontInfoVersion1TestCase(unittest.TestCase):
+
+ def setUp(self):
+ self.dstDir = tempfile.mktemp()
+ os.mkdir(self.dstDir)
+
+ def tearDown(self):
+ shutil.rmtree(self.dstDir)
+
+ def makeInfoObject(self):
+ infoObject = TestInfoObject()
+ for attr, value in fontInfoVersion2.items():
+ setattr(infoObject, attr, value)
+ return infoObject
+
+ def readPlist(self):
+ path = os.path.join(self.dstDir, "fontinfo.plist")
+ return readPlist(path)
+
+ def testWrite(self):
+ infoObject = self.makeInfoObject()
+ writer = UFOWriter(self.dstDir, formatVersion=1)
+ writer.writeInfo(infoObject)
+ writtenData = self.readPlist()
+ for attr, originalValue in fontInfoVersion1.items():
+ newValue = writtenData[attr]
+ self.assertEqual(newValue, originalValue)
+
+ def testFontStyleConversion(self):
+ fontStyle1To2 = {
+ 64 : "regular",
+ 1 : "italic",
+ 32 : "bold",
+ 33 : "bold italic"
+ }
+ for old, new in fontStyle1To2.items():
+ infoObject = self.makeInfoObject()
+ infoObject.styleMapStyleName = new
+ writer = UFOWriter(self.dstDir, formatVersion=1)
+ writer.writeInfo(infoObject)
+ writtenData = self.readPlist()
+ self.assertEqual(writtenData["fontStyle"], old)
+
+ def testWidthNameConversion(self):
+ widthName1To2 = {
+ "Ultra-condensed" : 1,
+ "Extra-condensed" : 2,
+ "Condensed" : 3,
+ "Semi-condensed" : 4,
+ "Medium (normal)" : 5,
+ "Semi-expanded" : 6,
+ "Expanded" : 7,
+ "Extra-expanded" : 8,
+ "Ultra-expanded" : 9
+ }
+ for old, new in widthName1To2.items():
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeOS2WidthClass = new
+ writer = UFOWriter(self.dstDir, formatVersion=1)
+ writer.writeInfo(infoObject)
+ writtenData = self.readPlist()
+ self.assertEqual(writtenData["widthName"], old)
+
+
+class WriteFontInfoVersion2TestCase(unittest.TestCase):
+
+ def setUp(self):
+ self.dstDir = tempfile.mktemp()
+ os.mkdir(self.dstDir)
+
+ def tearDown(self):
+ shutil.rmtree(self.dstDir)
+
+ def makeInfoObject(self):
+ infoObject = TestInfoObject()
+ for attr, value in fontInfoVersion2.items():
+ setattr(infoObject, attr, value)
+ return infoObject
+
+ def readPlist(self):
+ path = os.path.join(self.dstDir, "fontinfo.plist")
+ return readPlist(path)
+
+ def testWrite(self):
+ infoObject = self.makeInfoObject()
+ writer = UFOWriter(self.dstDir)
+ writer.writeInfo(infoObject)
+ writtenData = self.readPlist()
+ for attr, originalValue in fontInfoVersion2.items():
+ newValue = writtenData[attr]
+ self.assertEqual(newValue, originalValue)
+
+ def testGenericWrite(self):
+ # familyName
+ infoObject = self.makeInfoObject()
+ infoObject.familyName = 123
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # styleName
+ infoObject = self.makeInfoObject()
+ infoObject.styleName = 123
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # styleMapFamilyName
+ infoObject = self.makeInfoObject()
+ infoObject.styleMapFamilyName = 123
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # styleMapStyleName
+ ## not a string
+ infoObject = self.makeInfoObject()
+ infoObject.styleMapStyleName = 123
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ ## out of range
+ infoObject = self.makeInfoObject()
+ infoObject.styleMapStyleName = "REGULAR"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # versionMajor
+ infoObject = self.makeInfoObject()
+ infoObject.versionMajor = "1"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # versionMinor
+ infoObject = self.makeInfoObject()
+ infoObject.versionMinor = "0"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # copyright
+ infoObject = self.makeInfoObject()
+ infoObject.copyright = 123
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # trademark
+ infoObject = self.makeInfoObject()
+ infoObject.trademark = 123
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # unitsPerEm
+ infoObject = self.makeInfoObject()
+ infoObject.unitsPerEm = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # descender
+ infoObject = self.makeInfoObject()
+ infoObject.descender = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # xHeight
+ infoObject = self.makeInfoObject()
+ infoObject.xHeight = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # capHeight
+ infoObject = self.makeInfoObject()
+ infoObject.capHeight = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # ascender
+ infoObject = self.makeInfoObject()
+ infoObject.ascender = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # italicAngle
+ infoObject = self.makeInfoObject()
+ infoObject.italicAngle = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+
+ def testHeadWrite(self):
+ # openTypeHeadCreated
+ ## not a string
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeHeadCreated = 123
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ ## invalid format
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeHeadCreated = "2000-Jan-01 00:00:00"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeHeadLowestRecPPEM
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeHeadLowestRecPPEM = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeHeadFlags
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeHeadFlags = [-1]
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+
+ def testHheaWrite(self):
+ # openTypeHheaAscender
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeHheaAscender = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeHheaDescender
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeHheaDescender = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeHheaLineGap
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeHheaLineGap = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeHheaCaretSlopeRise
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeHheaCaretSlopeRise = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeHheaCaretSlopeRun
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeHheaCaretSlopeRun = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeHheaCaretOffset
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeHheaCaretOffset = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+
+ def testNameWrite(self):
+ # openTypeNameDesigner
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeNameDesigner = 123
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeNameDesignerURL
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeNameDesignerURL = 123
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeNameManufacturer
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeNameManufacturer = 123
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeNameManufacturerURL
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeNameManufacturerURL = 123
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeNameLicense
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeNameLicense = 123
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeNameLicenseURL
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeNameLicenseURL = 123
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeNameVersion
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeNameVersion = 123
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeNameUniqueID
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeNameUniqueID = 123
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeNameDescription
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeNameDescription = 123
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeNamePreferredFamilyName
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeNamePreferredFamilyName = 123
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeNamePreferredSubfamilyName
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeNamePreferredSubfamilyName = 123
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeNameCompatibleFullName
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeNameCompatibleFullName = 123
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeNameSampleText
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeNameSampleText = 123
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeNameWWSFamilyName
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeNameWWSFamilyName = 123
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeNameWWSSubfamilyName
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeNameWWSSubfamilyName = 123
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+
+ def testOS2Write(self):
+ # openTypeOS2WidthClass
+ ## not an int
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeOS2WidthClass = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ ## out or range
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeOS2WidthClass = 15
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeOS2WeightClass
+ infoObject = self.makeInfoObject()
+ ## not an int
+ infoObject.openTypeOS2WeightClass = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ ## out of range
+ infoObject.openTypeOS2WeightClass = -50
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeOS2Selection
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeOS2Selection = [-1]
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeOS2VendorID
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeOS2VendorID = 1234
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeOS2Panose
+ ## not an int
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeOS2Panose = [0, 1, 2, 3, 4, 5, 6, 7, 8, str(9)]
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ ## too few values
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeOS2Panose = [0, 1, 2, 3]
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ ## too many values
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeOS2Panose = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeOS2FamilyClass
+ ## not an int
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeOS2FamilyClass = [0, str(1)]
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ ## too few values
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeOS2FamilyClass = [1]
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ ## too many values
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeOS2FamilyClass = [1, 1, 1]
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ ## out of range
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeOS2FamilyClass = [1, 20]
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeOS2UnicodeRanges
+ ## not an int
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeOS2UnicodeRanges = ["0"]
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ ## out of range
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeOS2UnicodeRanges = [-1]
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeOS2CodePageRanges
+ ## not an int
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeOS2CodePageRanges = ["0"]
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ ## out of range
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeOS2CodePageRanges = [-1]
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeOS2TypoAscender
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeOS2TypoAscender = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeOS2TypoDescender
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeOS2TypoDescender = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeOS2TypoLineGap
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeOS2TypoLineGap = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeOS2WinAscent
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeOS2WinAscent = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeOS2WinDescent
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeOS2WinDescent = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeOS2Type
+ ## not an int
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeOS2Type = ["1"]
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ ## out of range
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeOS2Type = [-1]
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeOS2SubscriptXSize
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeOS2SubscriptXSize = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeOS2SubscriptYSize
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeOS2SubscriptYSize = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeOS2SubscriptXOffset
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeOS2SubscriptXOffset = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeOS2SubscriptYOffset
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeOS2SubscriptYOffset = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeOS2SuperscriptXSize
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeOS2SuperscriptXSize = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeOS2SuperscriptYSize
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeOS2SuperscriptYSize = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeOS2SuperscriptXOffset
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeOS2SuperscriptXOffset = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeOS2SuperscriptYOffset
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeOS2SuperscriptYOffset = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeOS2StrikeoutSize
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeOS2StrikeoutSize = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeOS2StrikeoutPosition
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeOS2StrikeoutPosition = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+
+ def testVheaWrite(self):
+ # openTypeVheaVertTypoAscender
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeVheaVertTypoAscender = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeVheaVertTypoDescender
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeVheaVertTypoDescender = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeVheaVertTypoLineGap
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeVheaVertTypoLineGap = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeVheaCaretSlopeRise
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeVheaCaretSlopeRise = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeVheaCaretSlopeRun
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeVheaCaretSlopeRun = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # openTypeVheaCaretOffset
+ infoObject = self.makeInfoObject()
+ infoObject.openTypeVheaCaretOffset = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+
+ def testFONDWrite(self):
+ # macintoshFONDFamilyID
+ infoObject = self.makeInfoObject()
+ infoObject.macintoshFONDFamilyID = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # macintoshFONDName
+ infoObject = self.makeInfoObject()
+ infoObject.macintoshFONDName = 123
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+
+ def testPostscriptWrite(self):
+ # postscriptFontName
+ infoObject = self.makeInfoObject()
+ infoObject.postscriptFontName = 123
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # postscriptFullName
+ infoObject = self.makeInfoObject()
+ infoObject.postscriptFullName = 123
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # postscriptSlantAngle
+ infoObject = self.makeInfoObject()
+ infoObject.postscriptSlantAngle = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # postscriptUniqueID
+ infoObject = self.makeInfoObject()
+ infoObject.postscriptUniqueID = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # postscriptUnderlineThickness
+ infoObject = self.makeInfoObject()
+ infoObject.postscriptUnderlineThickness = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # postscriptUnderlinePosition
+ infoObject = self.makeInfoObject()
+ infoObject.postscriptUnderlinePosition = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # postscriptIsFixedPitch
+ infoObject = self.makeInfoObject()
+ infoObject.postscriptIsFixedPitch = 2
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # postscriptBlueValues
+ ## not a list
+ infoObject = self.makeInfoObject()
+ infoObject.postscriptBlueValues = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ ## uneven value count
+ infoObject = self.makeInfoObject()
+ infoObject.postscriptBlueValues = [500]
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ ## too many values
+ infoObject = self.makeInfoObject()
+ infoObject.postscriptBlueValues = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # postscriptOtherBlues
+ ## not a list
+ infoObject = self.makeInfoObject()
+ infoObject.postscriptOtherBlues = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ ## uneven value count
+ infoObject = self.makeInfoObject()
+ infoObject.postscriptOtherBlues = [500]
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ ## too many values
+ infoObject = self.makeInfoObject()
+ infoObject.postscriptOtherBlues = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # postscriptFamilyBlues
+ ## not a list
+ infoObject = self.makeInfoObject()
+ infoObject.postscriptFamilyBlues = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ ## uneven value count
+ infoObject = self.makeInfoObject()
+ infoObject.postscriptFamilyBlues = [500]
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ ## too many values
+ infoObject = self.makeInfoObject()
+ infoObject.postscriptFamilyBlues = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # postscriptFamilyOtherBlues
+ ## not a list
+ infoObject = self.makeInfoObject()
+ infoObject.postscriptFamilyOtherBlues = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ ## uneven value count
+ infoObject = self.makeInfoObject()
+ infoObject.postscriptFamilyOtherBlues = [500]
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ ## too many values
+ infoObject = self.makeInfoObject()
+ infoObject.postscriptFamilyOtherBlues = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # postscriptStemSnapH
+ ## not list
+ infoObject = self.makeInfoObject()
+ infoObject.postscriptStemSnapH = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ ## too many values
+ infoObject = self.makeInfoObject()
+ infoObject.postscriptStemSnapH = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # postscriptStemSnapV
+ ## not list
+ infoObject = self.makeInfoObject()
+ infoObject.postscriptStemSnapV = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ ## too many values
+ infoObject = self.makeInfoObject()
+ infoObject.postscriptStemSnapV = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # postscriptBlueFuzz
+ infoObject = self.makeInfoObject()
+ infoObject.postscriptBlueFuzz = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # postscriptBlueShift
+ infoObject = self.makeInfoObject()
+ infoObject.postscriptBlueShift = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # postscriptBlueScale
+ infoObject = self.makeInfoObject()
+ infoObject.postscriptBlueScale = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # postscriptForceBold
+ infoObject = self.makeInfoObject()
+ infoObject.postscriptForceBold = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # postscriptDefaultWidthX
+ infoObject = self.makeInfoObject()
+ infoObject.postscriptDefaultWidthX = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # postscriptNominalWidthX
+ infoObject = self.makeInfoObject()
+ infoObject.postscriptNominalWidthX = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # postscriptWeightName
+ infoObject = self.makeInfoObject()
+ infoObject.postscriptWeightName = 123
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # postscriptDefaultCharacter
+ infoObject = self.makeInfoObject()
+ infoObject.postscriptDefaultCharacter = 123
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # postscriptWindowsCharacterSet
+ infoObject = self.makeInfoObject()
+ infoObject.postscriptWindowsCharacterSet = -1
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # macintoshFONDFamilyID
+ infoObject = self.makeInfoObject()
+ infoObject.macintoshFONDFamilyID = "abc"
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+ # macintoshFONDName
+ infoObject = self.makeInfoObject()
+ infoObject.macintoshFONDName = 123
+ writer = UFOWriter(self.dstDir)
+ self.assertRaises(UFOLibError, writer.writeInfo, info=infoObject)
+
+
+
+
+class ConversionFunctionsTestCase(unittest.TestCase):
+
+ def tearDown(self):
+ path = self.getFontPath("TestFont1 (UFO1) converted.ufo")
+ if os.path.exists(path):
+ shutil.rmtree(path)
+ path = self.getFontPath("TestFont1 (UFO2) converted.ufo")
+ if os.path.exists(path):
+ shutil.rmtree(path)
+
+ def getFontPath(self, fileName):
+ import robofab
+ path = os.path.dirname(robofab.__file__)
+ path = os.path.dirname(path)
+ path = os.path.dirname(path)
+ path = os.path.join(path, "TestData", fileName)
+ return path
+
+ def compareFileStructures(self, path1, path2, expectedInfoData, testFeatures):
+ # result
+ metainfoPath1 = os.path.join(path1, "metainfo.plist")
+ fontinfoPath1 = os.path.join(path1, "fontinfo.plist")
+ kerningPath1 = os.path.join(path1, "kerning.plist")
+ groupsPath1 = os.path.join(path1, "groups.plist")
+ libPath1 = os.path.join(path1, "lib.plist")
+ featuresPath1 = os.path.join(path1, "features.plist")
+ glyphsPath1 = os.path.join(path1, "glyphs")
+ glyphsPath1_contents = os.path.join(glyphsPath1, "contents.plist")
+ glyphsPath1_A = os.path.join(glyphsPath1, "A_.glif")
+ glyphsPath1_B = os.path.join(glyphsPath1, "B_.glif")
+ # expected result
+ metainfoPath2 = os.path.join(path2, "metainfo.plist")
+ fontinfoPath2 = os.path.join(path2, "fontinfo.plist")
+ kerningPath2 = os.path.join(path2, "kerning.plist")
+ groupsPath2 = os.path.join(path2, "groups.plist")
+ libPath2 = os.path.join(path2, "lib.plist")
+ featuresPath2 = os.path.join(path2, "features.plist")
+ glyphsPath2 = os.path.join(path2, "glyphs")
+ glyphsPath2_contents = os.path.join(glyphsPath2, "contents.plist")
+ glyphsPath2_A = os.path.join(glyphsPath2, "A_.glif")
+ glyphsPath2_B = os.path.join(glyphsPath2, "B_.glif")
+ # look for existence
+ self.assertEqual(os.path.exists(metainfoPath1), True)
+ self.assertEqual(os.path.exists(fontinfoPath1), True)
+ self.assertEqual(os.path.exists(kerningPath1), True)
+ self.assertEqual(os.path.exists(groupsPath1), True)
+ self.assertEqual(os.path.exists(libPath1), True)
+ self.assertEqual(os.path.exists(glyphsPath1), True)
+ self.assertEqual(os.path.exists(glyphsPath1_contents), True)
+ self.assertEqual(os.path.exists(glyphsPath1_A), True)
+ self.assertEqual(os.path.exists(glyphsPath1_B), True)
+ if testFeatures:
+ self.assertEqual(os.path.exists(featuresPath1), True)
+ # look for aggrement
+ data1 = readPlist(metainfoPath1)
+ data2 = readPlist(metainfoPath2)
+ self.assertEqual(data1, data2)
+ data1 = readPlist(fontinfoPath1)
+ self.assertEqual(sorted(data1.items()), sorted(expectedInfoData.items()))
+ data1 = readPlist(kerningPath1)
+ data2 = readPlist(kerningPath2)
+ self.assertEqual(data1, data2)
+ data1 = readPlist(groupsPath1)
+ data2 = readPlist(groupsPath2)
+ self.assertEqual(data1, data2)
+ data1 = readPlist(libPath1)
+ data2 = readPlist(libPath2)
+ if "UFO1" in libPath1:
+ for key in removeFromFormatVersion1Lib:
+ if key in data1:
+ del data1[key]
+ if "UFO1" in libPath2:
+ for key in removeFromFormatVersion1Lib:
+ if key in data2:
+ del data2[key]
+ self.assertEqual(data1, data2)
+ data1 = readPlist(glyphsPath1_contents)
+ data2 = readPlist(glyphsPath2_contents)
+ self.assertEqual(data1, data2)
+ data1 = readPlist(glyphsPath1_A)
+ data2 = readPlist(glyphsPath2_A)
+ self.assertEqual(data1, data2)
+ data1 = readPlist(glyphsPath1_B)
+ data2 = readPlist(glyphsPath2_B)
+ self.assertEqual(data1, data2)
+
+ def test1To2(self):
+ path1 = self.getFontPath("TestFont1 (UFO1).ufo")
+ path2 = self.getFontPath("TestFont1 (UFO1) converted.ufo")
+ path3 = self.getFontPath("TestFont1 (UFO2).ufo")
+ convertUFOFormatVersion1ToFormatVersion2(path1, path2)
+ self.compareFileStructures(path2, path3, expectedFontInfo1To2Conversion, False)
+
+ def test2To1(self):
+ path1 = self.getFontPath("TestFont1 (UFO2).ufo")
+ path2 = self.getFontPath("TestFont1 (UFO2) converted.ufo")
+ path3 = self.getFontPath("TestFont1 (UFO1).ufo")
+ convertUFOFormatVersion2ToFormatVersion1(path1, path2)
+ self.compareFileStructures(path2, path3, expectedFontInfo2To1Conversion, False)
+
+
+if __name__ == "__main__":
+ from robofab.test.testSupport import runTests
+ runTests()