1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
|
from __future__ import print_function, division, absolute_import
import sys
import os
import unittest
import pytest
from fontPens.digestPointPen import DigestPointPen
import defcon
import booleanOperations
VERBOSE = False
class BooleanTests(unittest.TestCase):
pass
def _makeTestCase(glyph, booleanMethodName, args=None):
# get the font
font = glyph.font
# skip if the booleanMethodName does not exist as layer
if booleanMethodName not in font.layers:
return False, None
expectedLayer = font.layers[booleanMethodName]
# skip if the glyph name does not exist in the expected layer
if glyph.name not in expectedLayer:
return False, None
expectedGlyph = expectedLayer[glyph.name]
if args is None:
if len(glyph) < 2:
# skip if not args are given and the glyph has only 1 contour
return False, None
# set the first contour as subject contour and the rest as clip contour
args = [[glyph[0]], glyph[1:]]
func = getattr(booleanOperations, booleanMethodName)
def test(self):
if VERBOSE:
print("test: '%s' for '%s'" % (glyph.name, booleanMethodName))
testPen = DigestPointPen()
func(*args, outPen=testPen)
expectedPen = DigestPointPen()
expectedGlyph.drawPoints(expectedPen)
self.assertEqual(testPen.getDigest(), expectedPen.getDigest(), "Glyph name '%s' failed for '%s'." % (glyph.name, booleanMethodName))
return True, test
def _makeUnionTestCase(glyph, method):
return _makeTestCase(glyph, method, args=[glyph])
def _addGlyphTests():
root = os.path.join(os.path.dirname(__file__), 'testData')
path = os.path.join(root, "test.ufo")
font = defcon.Font(path)
booleanMethods = {
"union": _makeUnionTestCase,
"difference": _makeTestCase,
"intersection": _makeTestCase,
"xor": _makeTestCase,
}
for glyph in font:
for booleanMethod, testMaker in booleanMethods.items():
shouldPerformTest, testMethod = testMaker(glyph, booleanMethod)
if shouldPerformTest:
testMethodName = "test_%s_%s" % (glyph.name, booleanMethod)
testMethod.__name__ = str(testMethodName)
setattr(BooleanTests, testMethodName, testMethod)
_addGlyphTests()
def test_unsupported_qcurve():
font = defcon.Font()
g = font.newGlyph("test")
p = g.getPointPen()
p.beginPath()
p.addPoint((0, 0), segmentType="line")
p.addPoint((100, 0), segmentType="line")
p.addPoint((100, 100), segmentType="line")
p.addPoint((50, 100))
p.addPoint((0, 100), segmentType="qcurve")
p.endPath()
with pytest.raises(booleanOperations.exceptions.UnsupportedContourError):
booleanOperations.union(g, None)
if __name__ == '__main__':
sys.exit(unittest.main())
|