aboutsummaryrefslogtreecommitdiff
path: root/Tests/designspaceLib/designspace_test.py
diff options
context:
space:
mode:
Diffstat (limited to 'Tests/designspaceLib/designspace_test.py')
-rw-r--r--Tests/designspaceLib/designspace_test.py401
1 files changed, 260 insertions, 141 deletions
diff --git a/Tests/designspaceLib/designspace_test.py b/Tests/designspaceLib/designspace_test.py
index ee2d19e6..ceddfd10 100644
--- a/Tests/designspaceLib/designspace_test.py
+++ b/Tests/designspaceLib/designspace_test.py
@@ -1,12 +1,15 @@
# coding=utf-8
import os
+from pathlib import Path
import re
+import shutil
import pytest
from fontTools import ttLib
from fontTools.designspaceLib import (
AxisDescriptor,
+ AxisMappingDescriptor,
AxisLabelDescriptor,
DesignSpaceDocument,
DesignSpaceDocumentError,
@@ -21,20 +24,22 @@ from fontTools.designspaceLib import (
from fontTools.designspaceLib.types import Range
from fontTools.misc import plistlib
+from .fixtures import datadir
+
def _axesAsDict(axes):
"""
- Make the axis data we have available in
+ Make the axis data we have available in
"""
axesDict = {}
for axisDescriptor in axes:
d = {
- 'name': axisDescriptor.name,
- 'tag': axisDescriptor.tag,
- 'minimum': axisDescriptor.minimum,
- 'maximum': axisDescriptor.maximum,
- 'default': axisDescriptor.default,
- 'map': axisDescriptor.map,
+ "name": axisDescriptor.name,
+ "tag": axisDescriptor.tag,
+ "minimum": axisDescriptor.minimum,
+ "maximum": axisDescriptor.maximum,
+ "default": axisDescriptor.default,
+ "map": axisDescriptor.map,
}
axesDict[axisDescriptor.name] = d
return axesDict
@@ -72,8 +77,8 @@ def test_fill_document(tmpdir):
a1.name = "weight"
a1.tag = "wght"
# note: just to test the element language, not an actual label name recommendations.
- a1.labelNames[u'fa-IR'] = u"قطر"
- a1.labelNames[u'en'] = u"Wéíght"
+ a1.labelNames["fa-IR"] = "قطر"
+ a1.labelNames["en"] = "Wéíght"
doc.addAxis(a1)
a2 = AxisDescriptor()
a2.minimum = 0
@@ -83,7 +88,7 @@ def test_fill_document(tmpdir):
a2.tag = "wdth"
a2.map = [(0.0, 10.0), (15.0, 20.0), (401.0, 66.0), (1000.0, 990.0)]
a2.hidden = True
- a2.labelNames[u'fr'] = u"Chasse"
+ a2.labelNames["fr"] = "Chasse"
doc.addAxis(a2)
# add master 1
@@ -131,18 +136,22 @@ def test_fill_document(tmpdir):
i1.familyName = "InstanceFamilyName"
i1.styleName = "InstanceStyleName"
i1.name = "instance.ufo1"
- i1.location = dict(weight=500, spooky=666) # this adds a dimension that is not defined.
+ i1.location = dict(
+ weight=500, spooky=666
+ ) # this adds a dimension that is not defined.
i1.postScriptFontName = "InstancePostscriptName"
i1.styleMapFamilyName = "InstanceStyleMapFamilyName"
i1.styleMapStyleName = "InstanceStyleMapStyleName"
i1.localisedStyleName = dict(fr="Demigras", ja="半ば")
i1.localisedFamilyName = dict(fr="Montserrat", ja="モンセラート")
i1.localisedStyleMapStyleName = dict(de="Standard")
- i1.localisedStyleMapFamilyName = dict(de="Montserrat Halbfett", ja="モンセラート SemiBold")
+ i1.localisedStyleMapFamilyName = dict(
+ de="Montserrat Halbfett", ja="モンセラート SemiBold"
+ )
glyphData = dict(name="arrow", mute=True, unicodes=[0x123, 0x124, 0x125])
- i1.glyphs['arrow'] = glyphData
- i1.lib['com.coolDesignspaceApp.binaryData'] = plistlib.Data(b'<binary gunk>')
- i1.lib['com.coolDesignspaceApp.specimenText'] = "Hamburgerwhatever"
+ i1.glyphs["arrow"] = glyphData
+ i1.lib["com.coolDesignspaceApp.binaryData"] = plistlib.Data(b"<binary gunk>")
+ i1.lib["com.coolDesignspaceApp.specimenText"] = "Hamburgerwhatever"
doc.addInstance(i1)
# add instance 2
i2 = InstanceDescriptor()
@@ -151,46 +160,51 @@ def test_fill_document(tmpdir):
i2.styleName = "InstanceStyleName"
i2.name = "instance.ufo2"
# anisotropic location
- i2.location = dict(weight=500, width=(400,300))
+ i2.location = dict(weight=500, width=(400, 300))
i2.postScriptFontName = "InstancePostscriptName"
i2.styleMapFamilyName = "InstanceStyleMapFamilyName"
i2.styleMapStyleName = "InstanceStyleMapStyleName"
- glyphMasters = [dict(font="master.ufo1", glyphName="BB", location=dict(width=20,weight=20)), dict(font="master.ufo2", glyphName="CC", location=dict(width=900,weight=900))]
+ glyphMasters = [
+ dict(font="master.ufo1", glyphName="BB", location=dict(width=20, weight=20)),
+ dict(font="master.ufo2", glyphName="CC", location=dict(width=900, weight=900)),
+ ]
glyphData = dict(name="arrow", unicodes=[101, 201, 301])
- glyphData['masters'] = glyphMasters
- glyphData['note'] = "A note about this glyph"
- glyphData['instanceLocation'] = dict(width=100, weight=120)
- i2.glyphs['arrow'] = glyphData
- i2.glyphs['arrow2'] = dict(mute=False)
+ glyphData["masters"] = glyphMasters
+ glyphData["note"] = "A note about this glyph"
+ glyphData["instanceLocation"] = dict(width=100, weight=120)
+ i2.glyphs["arrow"] = glyphData
+ i2.glyphs["arrow2"] = dict(mute=False)
doc.addInstance(i2)
doc.filename = "suggestedFileName.designspace"
- doc.lib['com.coolDesignspaceApp.previewSize'] = 30
+ doc.lib["com.coolDesignspaceApp.previewSize"] = 30
# write some rules
r1 = RuleDescriptor()
r1.name = "named.rule.1"
- r1.conditionSets.append([
- dict(name='axisName_a', minimum=0, maximum=1),
- dict(name='axisName_b', minimum=2, maximum=3)
- ])
+ r1.conditionSets.append(
+ [
+ dict(name="axisName_a", minimum=0, maximum=1),
+ dict(name="axisName_b", minimum=2, maximum=3),
+ ]
+ )
r1.subs.append(("a", "a.alt"))
doc.addRule(r1)
# write the document; without an explicit format it will be 5.0 by default
doc.write(testDocPath5)
assert os.path.exists(testDocPath5)
- assert_equals_test_file(testDocPath5, 'data/test_v5_original.designspace')
+ assert_equals_test_file(testDocPath5, "data/test_v5_original.designspace")
# write again with an explicit format = 4.1
doc.formatVersion = "4.1"
doc.write(testDocPath)
assert os.path.exists(testDocPath)
- assert_equals_test_file(testDocPath, 'data/test_v4_original.designspace')
+ assert_equals_test_file(testDocPath, "data/test_v4_original.designspace")
# import it again
new = DesignSpaceDocument()
new.read(testDocPath)
- assert new.default.location == {'width': 20.0, 'weight': 0.0}
- assert new.filename == 'test_v4.designspace'
+ assert new.default.location == {"width": 20.0, "weight": 0.0}
+ assert new.filename == "test_v4.designspace"
assert new.lib == doc.lib
assert new.instances[0].lib == doc.instances[0].lib
@@ -240,10 +254,10 @@ def test_unicodes(tmpdir):
i1.name = "instance.ufo1"
i1.location = dict(weight=500)
glyphData = dict(name="arrow", mute=True, unicodes=[100, 200, 300])
- i1.glyphs['arrow'] = glyphData
+ i1.glyphs["arrow"] = glyphData
doc.addInstance(i1)
# now we have sources and instances, but no axes yet.
- doc.axes = [] # clear the axes
+ doc.axes = [] # clear the axes
# write some axes
a1 = AxisDescriptor()
a1.minimum = 0
@@ -260,13 +274,13 @@ def test_unicodes(tmpdir):
new.read(testDocPath)
new.write(testDocPath2)
# compare the file contents
- with open(testDocPath, 'r', encoding='utf-8') as f1:
+ with open(testDocPath, "r", encoding="utf-8") as f1:
t1 = f1.read()
- with open(testDocPath2, 'r', encoding='utf-8') as f2:
+ with open(testDocPath2, "r", encoding="utf-8") as f2:
t2 = f2.read()
assert t1 == t2
# check the unicode values read from the document
- assert new.instances[0].glyphs['arrow']['unicodes'] == [100,200,300]
+ assert new.instances[0].glyphs["arrow"]["unicodes"] == [100, 200, 300]
def test_localisedNames(tmpdir):
@@ -299,20 +313,22 @@ def test_localisedNames(tmpdir):
i1.styleMapFamilyName = "Montserrat SemiBold"
i1.styleMapStyleName = "Regular"
i1.setFamilyName("Montserrat", "fr")
- i1.setFamilyName(u"モンセラート", "ja")
+ i1.setFamilyName("モンセラート", "ja")
i1.setStyleName("Demigras", "fr")
- i1.setStyleName(u"半ば", "ja")
- i1.setStyleMapStyleName(u"Standard", "de")
+ i1.setStyleName("半ば", "ja")
+ i1.setStyleMapStyleName("Standard", "de")
i1.setStyleMapFamilyName("Montserrat Halbfett", "de")
- i1.setStyleMapFamilyName(u"モンセラート SemiBold", "ja")
+ i1.setStyleMapFamilyName("モンセラート SemiBold", "ja")
i1.name = "instance.ufo1"
- i1.location = dict(weight=500, spooky=666) # this adds a dimension that is not defined.
+ i1.location = dict(
+ weight=500, spooky=666
+ ) # this adds a dimension that is not defined.
i1.postScriptFontName = "InstancePostscriptName"
glyphData = dict(name="arrow", mute=True, unicodes=[0x123])
- i1.glyphs['arrow'] = glyphData
+ i1.glyphs["arrow"] = glyphData
doc.addInstance(i1)
# now we have sources and instances, but no axes yet.
- doc.axes = [] # clear the axes
+ doc.axes = [] # clear the axes
# write some axes
a1 = AxisDescriptor()
a1.minimum = 0
@@ -321,8 +337,8 @@ def test_localisedNames(tmpdir):
a1.name = "weight"
a1.tag = "wght"
# note: just to test the element language, not an actual label name recommendations.
- a1.labelNames[u'fa-IR'] = u"قطر"
- a1.labelNames[u'en'] = u"Wéíght"
+ a1.labelNames["fa-IR"] = "قطر"
+ a1.labelNames["en"] = "Wéíght"
doc.addAxis(a1)
a2 = AxisDescriptor()
a2.minimum = 0
@@ -331,7 +347,7 @@ def test_localisedNames(tmpdir):
a2.name = "width"
a2.tag = "wdth"
a2.map = [(0.0, 10.0), (401.0, 66.0), (1000.0, 990.0)]
- a2.labelNames[u'fr'] = u"Poids"
+ a2.labelNames["fr"] = "Poids"
doc.addAxis(a2)
# add an axis that is not part of any location to see if that works
a3 = AxisDescriptor()
@@ -341,14 +357,16 @@ def test_localisedNames(tmpdir):
a3.name = "spooky"
a3.tag = "spok"
a3.map = [(0.0, 10.0), (401.0, 66.0), (1000.0, 990.0)]
- #doc.addAxis(a3) # uncomment this line to test the effects of default axes values
+ # doc.addAxis(a3) # uncomment this line to test the effects of default axes values
# write some rules
r1 = RuleDescriptor()
r1.name = "named.rule.1"
- r1.conditionSets.append([
- dict(name='weight', minimum=200, maximum=500),
- dict(name='width', minimum=0, maximum=150)
- ])
+ r1.conditionSets.append(
+ [
+ dict(name="weight", minimum=200, maximum=500),
+ dict(name="width", minimum=0, maximum=150),
+ ]
+ )
r1.subs.append(("a", "a.alt"))
doc.addRule(r1)
# write the document
@@ -358,9 +376,9 @@ def test_localisedNames(tmpdir):
new = DesignSpaceDocument()
new.read(testDocPath)
new.write(testDocPath2)
- with open(testDocPath, 'r', encoding='utf-8') as f1:
+ with open(testDocPath, "r", encoding="utf-8") as f1:
t1 = f1.read()
- with open(testDocPath2, 'r', encoding='utf-8') as f2:
+ with open(testDocPath2, "r", encoding="utf-8") as f2:
t2 = f2.read()
assert t1 == t2
@@ -378,7 +396,7 @@ def test_handleNoAxes(tmpdir):
# Case 1: No axes element in the document, but there are sources and instances
doc = DesignSpaceDocument()
- for name, value in [('One', 1),('Two', 2),('Three', 3)]:
+ for name, value in [("One", 1), ("Two", 2), ("Three", 3)]:
a = AxisDescriptor()
a.minimum = 0
a.maximum = 1000
@@ -417,7 +435,7 @@ def test_handleNoAxes(tmpdir):
i1.familyName = "InstanceFamilyName"
i1.styleName = "InstanceStyleName"
i1.name = "instance.ufo1"
- i1.location = dict(axisNameOne=(-1000,500), axisNameTwo=100)
+ i1.location = dict(axisNameOne=(-1000, 500), axisNameTwo=100)
i1.postScriptFontName = "InstancePostscriptName"
i1.styleMapFamilyName = "InstanceStyleMapFamilyName"
i1.styleMapStyleName = "InstanceStyleMapStyleName"
@@ -428,6 +446,7 @@ def test_handleNoAxes(tmpdir):
verify.read(testDocPath)
verify.write(testDocPath2)
+
def test_pathNameResolve(tmpdir):
tmpdir = str(tmpdir)
# test how descriptor.path and descriptor.filename are resolved
@@ -499,7 +518,9 @@ def test_pathNameResolve(tmpdir):
verify.read(testDocPath3)
assert verify.sources[0].filename == "../somewhere/over/the/rainbow.ufo"
# make the absolute path for filename so we can see if it matches the path
- p = os.path.abspath(os.path.join(os.path.dirname(testDocPath3), verify.sources[0].filename))
+ p = os.path.abspath(
+ os.path.join(os.path.dirname(testDocPath3), verify.sources[0].filename)
+ )
assert verify.sources[0].path == posix(p)
# Case 4: the filename points to one file, the path points to another. The path takes precedence.
@@ -529,7 +550,7 @@ def test_pathNameResolve(tmpdir):
s.familyName = "MasterFamilyName"
s.styleName = "MasterStyleNameOne"
doc.addSource(s)
- doc.write(testDocPath5) # so that the document has a path
+ doc.write(testDocPath5) # so that the document has a path
doc.updateFilenameFromPath()
assert doc.sources[0].filename == "masters/masterTest1.ufo"
@@ -543,7 +564,7 @@ def test_pathNameResolve(tmpdir):
s.location = dict(weight=0)
s.familyName = "MasterFamilyName"
s.styleName = "MasterStyleNameOne"
- doc.write(testDocPath5) # so that the document has a path
+ doc.write(testDocPath5) # so that the document has a path
doc.addSource(s)
assert doc.sources[0].filename == "../somewhere/over/the/rainbow.ufo"
doc.updateFilenameFromPath(force=True)
@@ -561,21 +582,22 @@ def test_normalise1():
a1.name = "axisName_a"
a1.tag = "TAGA"
doc.addAxis(a1)
- assert doc.normalizeLocation(dict(axisName_a=0)) == {'axisName_a': 0.0}
- assert doc.normalizeLocation(dict(axisName_a=1000)) == {'axisName_a': 1.0}
+ assert doc.normalizeLocation(dict(axisName_a=0)) == {"axisName_a": 0.0}
+ assert doc.normalizeLocation(dict(axisName_a=1000)) == {"axisName_a": 1.0}
# clipping beyond max values:
- assert doc.normalizeLocation(dict(axisName_a=1001)) == {'axisName_a': 1.0}
- assert doc.normalizeLocation(dict(axisName_a=500)) == {'axisName_a': 0.5}
- assert doc.normalizeLocation(dict(axisName_a=-1000)) == {'axisName_a': -1.0}
- assert doc.normalizeLocation(dict(axisName_a=-1001)) == {'axisName_a': -1.0}
+ assert doc.normalizeLocation(dict(axisName_a=1001)) == {"axisName_a": 1.0}
+ assert doc.normalizeLocation(dict(axisName_a=500)) == {"axisName_a": 0.5}
+ assert doc.normalizeLocation(dict(axisName_a=-1000)) == {"axisName_a": -1.0}
+ assert doc.normalizeLocation(dict(axisName_a=-1001)) == {"axisName_a": -1.0}
# anisotropic coordinates normalise to isotropic
- assert doc.normalizeLocation(dict(axisName_a=(1000, -1000))) == {'axisName_a': 1.0}
+ assert doc.normalizeLocation(dict(axisName_a=(1000, -1000))) == {"axisName_a": 1.0}
doc.normalize()
r = []
for axis in doc.axes:
r.append((axis.name, axis.minimum, axis.default, axis.maximum))
r.sort()
- assert r == [('axisName_a', -1.0, 0.0, 1.0)]
+ assert r == [("axisName_a", -1.0, 0.0, 1.0)]
+
def test_normalise2():
# normalisation with minimum > 0
@@ -587,22 +609,25 @@ def test_normalise2():
a2.default = 100
a2.name = "axisName_b"
doc.addAxis(a2)
- assert doc.normalizeLocation(dict(axisName_b=0)) == {'axisName_b': 0.0}
- assert doc.normalizeLocation(dict(axisName_b=1000)) == {'axisName_b': 1.0}
+ assert doc.normalizeLocation(dict(axisName_b=0)) == {"axisName_b": 0.0}
+ assert doc.normalizeLocation(dict(axisName_b=1000)) == {"axisName_b": 1.0}
# clipping beyond max values:
- assert doc.normalizeLocation(dict(axisName_b=1001)) == {'axisName_b': 1.0}
- assert doc.normalizeLocation(dict(axisName_b=500)) == {'axisName_b': 0.4444444444444444}
- assert doc.normalizeLocation(dict(axisName_b=-1000)) == {'axisName_b': 0.0}
- assert doc.normalizeLocation(dict(axisName_b=-1001)) == {'axisName_b': 0.0}
+ assert doc.normalizeLocation(dict(axisName_b=1001)) == {"axisName_b": 1.0}
+ assert doc.normalizeLocation(dict(axisName_b=500)) == {
+ "axisName_b": 0.4444444444444444
+ }
+ assert doc.normalizeLocation(dict(axisName_b=-1000)) == {"axisName_b": 0.0}
+ assert doc.normalizeLocation(dict(axisName_b=-1001)) == {"axisName_b": 0.0}
# anisotropic coordinates normalise to isotropic
- assert doc.normalizeLocation(dict(axisName_b=(1000,-1000))) == {'axisName_b': 1.0}
- assert doc.normalizeLocation(dict(axisName_b=1001)) == {'axisName_b': 1.0}
+ assert doc.normalizeLocation(dict(axisName_b=(1000, -1000))) == {"axisName_b": 1.0}
+ assert doc.normalizeLocation(dict(axisName_b=1001)) == {"axisName_b": 1.0}
doc.normalize()
r = []
for axis in doc.axes:
r.append((axis.name, axis.minimum, axis.default, axis.maximum))
r.sort()
- assert r == [('axisName_b', 0.0, 0.0, 1.0)]
+ assert r == [("axisName_b", 0.0, 0.0, 1.0)]
+
def test_normalise3():
# normalisation of negative values, with default == maximum
@@ -614,16 +639,17 @@ def test_normalise3():
a3.default = 0
a3.name = "ccc"
doc.addAxis(a3)
- assert doc.normalizeLocation(dict(ccc=0)) == {'ccc': 0.0}
- assert doc.normalizeLocation(dict(ccc=1)) == {'ccc': 0.0}
- assert doc.normalizeLocation(dict(ccc=-1000)) == {'ccc': -1.0}
- assert doc.normalizeLocation(dict(ccc=-1001)) == {'ccc': -1.0}
+ assert doc.normalizeLocation(dict(ccc=0)) == {"ccc": 0.0}
+ assert doc.normalizeLocation(dict(ccc=1)) == {"ccc": 0.0}
+ assert doc.normalizeLocation(dict(ccc=-1000)) == {"ccc": -1.0}
+ assert doc.normalizeLocation(dict(ccc=-1001)) == {"ccc": -1.0}
doc.normalize()
r = []
for axis in doc.axes:
r.append((axis.name, axis.minimum, axis.default, axis.maximum))
r.sort()
- assert r == [('ccc', -1.0, 0.0, 0.0)]
+ assert r == [("ccc", -1.0, 0.0, 0.0)]
+
def test_normalise4():
# normalisation with a map
@@ -634,14 +660,15 @@ def test_normalise4():
a4.maximum = 1000
a4.default = 0
a4.name = "ddd"
- a4.map = [(0,100), (300, 500), (600, 500), (1000,900)]
+ a4.map = [(0, 100), (300, 500), (600, 500), (1000, 900)]
doc.addAxis(a4)
doc.normalize()
r = []
for axis in doc.axes:
r.append((axis.name, axis.map))
r.sort()
- assert r == [('ddd', [(0, 0.0), (300, 0.5), (600, 0.5), (1000, 1.0)])]
+ assert r == [("ddd", [(0, 0.0), (300, 0.5), (600, 0.5), (1000, 1.0)])]
+
def test_axisMapping():
# note: because designspance lib does not do any actual
@@ -653,68 +680,113 @@ def test_axisMapping():
a4.maximum = 1000
a4.default = 0
a4.name = "ddd"
- a4.map = [(0,100), (300, 500), (600, 500), (1000,900)]
+ a4.map = [(0, 100), (300, 500), (600, 500), (1000, 900)]
doc.addAxis(a4)
doc.normalize()
r = []
for axis in doc.axes:
r.append((axis.name, axis.map))
r.sort()
- assert r == [('ddd', [(0, 0.0), (300, 0.5), (600, 0.5), (1000, 1.0)])]
+ assert r == [("ddd", [(0, 0.0), (300, 0.5), (600, 0.5), (1000, 1.0)])]
+
+
+def test_axisMappingsRoundtrip(tmpdir):
+ # tests of axisMappings in a document, roundtripping.
+
+ tmpdir = str(tmpdir)
+ srcDocPath = (Path(__file__) / "../data/test_avar2.designspace").resolve()
+ testDocPath = os.path.join(tmpdir, "test_avar2.designspace")
+ shutil.copy(srcDocPath, testDocPath)
+ testDocPath2 = os.path.join(tmpdir, "test_avar2_roundtrip.designspace")
+ doc = DesignSpaceDocument()
+ doc.read(testDocPath)
+ assert doc.axisMappings
+ assert len(doc.axisMappings) == 1
+ assert doc.axisMappings[0].inputLocation == {"Justify": -100.0, "Width": 100.0}
+
+ # This is a bit of a hack, but it's the only way to make sure
+ # that the save works on Windows if the tempdir and the data
+ # dir are on different drives.
+ for descriptor in doc.sources + doc.instances:
+ descriptor.path = None
+
+ doc.write(testDocPath2)
+ # verify these results
+ doc2 = DesignSpaceDocument()
+ doc2.read(testDocPath2)
+ assert [mapping.inputLocation for mapping in doc.axisMappings] == [
+ mapping.inputLocation for mapping in doc2.axisMappings
+ ]
+ assert [mapping.outputLocation for mapping in doc.axisMappings] == [
+ mapping.outputLocation for mapping in doc2.axisMappings
+ ]
+
def test_rulesConditions(tmpdir):
# tests of rules, conditionsets and conditions
r1 = RuleDescriptor()
r1.name = "named.rule.1"
- r1.conditionSets.append([
- dict(name='axisName_a', minimum=0, maximum=1000),
- dict(name='axisName_b', minimum=0, maximum=3000)
- ])
+ r1.conditionSets.append(
+ [
+ dict(name="axisName_a", minimum=0, maximum=1000),
+ dict(name="axisName_b", minimum=0, maximum=3000),
+ ]
+ )
r1.subs.append(("a", "a.alt"))
- assert evaluateRule(r1, dict(axisName_a = 500, axisName_b = 0)) == True
- assert evaluateRule(r1, dict(axisName_a = 0, axisName_b = 0)) == True
- assert evaluateRule(r1, dict(axisName_a = 1000, axisName_b = 0)) == True
- assert evaluateRule(r1, dict(axisName_a = 1000, axisName_b = -100)) == False
- assert evaluateRule(r1, dict(axisName_a = 1000.0001, axisName_b = 0)) == False
- assert evaluateRule(r1, dict(axisName_a = -0.0001, axisName_b = 0)) == False
- assert evaluateRule(r1, dict(axisName_a = -100, axisName_b = 0)) == False
- assert processRules([r1], dict(axisName_a = 500, axisName_b = 0), ["a", "b", "c"]) == ['a.alt', 'b', 'c']
- assert processRules([r1], dict(axisName_a = 500, axisName_b = 0), ["a.alt", "b", "c"]) == ['a.alt', 'b', 'c']
- assert processRules([r1], dict(axisName_a = 2000, axisName_b = 0), ["a", "b", "c"]) == ['a', 'b', 'c']
+ assert evaluateRule(r1, dict(axisName_a=500, axisName_b=0)) == True
+ assert evaluateRule(r1, dict(axisName_a=0, axisName_b=0)) == True
+ assert evaluateRule(r1, dict(axisName_a=1000, axisName_b=0)) == True
+ assert evaluateRule(r1, dict(axisName_a=1000, axisName_b=-100)) == False
+ assert evaluateRule(r1, dict(axisName_a=1000.0001, axisName_b=0)) == False
+ assert evaluateRule(r1, dict(axisName_a=-0.0001, axisName_b=0)) == False
+ assert evaluateRule(r1, dict(axisName_a=-100, axisName_b=0)) == False
+ assert processRules([r1], dict(axisName_a=500, axisName_b=0), ["a", "b", "c"]) == [
+ "a.alt",
+ "b",
+ "c",
+ ]
+ assert processRules(
+ [r1], dict(axisName_a=500, axisName_b=0), ["a.alt", "b", "c"]
+ ) == ["a.alt", "b", "c"]
+ assert processRules([r1], dict(axisName_a=2000, axisName_b=0), ["a", "b", "c"]) == [
+ "a",
+ "b",
+ "c",
+ ]
# rule with only a maximum
r2 = RuleDescriptor()
r2.name = "named.rule.2"
- r2.conditionSets.append([dict(name='axisName_a', maximum=500)])
+ r2.conditionSets.append([dict(name="axisName_a", maximum=500)])
r2.subs.append(("b", "b.alt"))
- assert evaluateRule(r2, dict(axisName_a = 0)) == True
- assert evaluateRule(r2, dict(axisName_a = -500)) == True
- assert evaluateRule(r2, dict(axisName_a = 1000)) == False
+ assert evaluateRule(r2, dict(axisName_a=0)) == True
+ assert evaluateRule(r2, dict(axisName_a=-500)) == True
+ assert evaluateRule(r2, dict(axisName_a=1000)) == False
# rule with only a minimum
r3 = RuleDescriptor()
r3.name = "named.rule.3"
- r3.conditionSets.append([dict(name='axisName_a', minimum=500)])
+ r3.conditionSets.append([dict(name="axisName_a", minimum=500)])
r3.subs.append(("c", "c.alt"))
- assert evaluateRule(r3, dict(axisName_a = 0)) == False
- assert evaluateRule(r3, dict(axisName_a = 1000)) == True
- assert evaluateRule(r3, dict(axisName_a = 1000)) == True
+ assert evaluateRule(r3, dict(axisName_a=0)) == False
+ assert evaluateRule(r3, dict(axisName_a=1000)) == True
+ assert evaluateRule(r3, dict(axisName_a=1000)) == True
# rule with only a minimum, maximum in separate conditions
r4 = RuleDescriptor()
r4.name = "named.rule.4"
- r4.conditionSets.append([
- dict(name='axisName_a', minimum=500),
- dict(name='axisName_b', maximum=500)
- ])
+ r4.conditionSets.append(
+ [dict(name="axisName_a", minimum=500), dict(name="axisName_b", maximum=500)]
+ )
r4.subs.append(("c", "c.alt"))
- assert evaluateRule(r4, dict(axisName_a = 1000, axisName_b = 0)) == True
- assert evaluateRule(r4, dict(axisName_a = 0, axisName_b = 0)) == False
- assert evaluateRule(r4, dict(axisName_a = 1000, axisName_b = 1000)) == False
+ assert evaluateRule(r4, dict(axisName_a=1000, axisName_b=0)) == True
+ assert evaluateRule(r4, dict(axisName_a=0, axisName_b=0)) == False
+ assert evaluateRule(r4, dict(axisName_a=1000, axisName_b=1000)) == False
+
def test_rulesDocument(tmpdir):
# tests of rules in a document, roundtripping.
@@ -739,26 +811,51 @@ def test_rulesDocument(tmpdir):
doc.addAxis(b1)
r1 = RuleDescriptor()
r1.name = "named.rule.1"
- r1.conditionSets.append([
- dict(name='axisName_a', minimum=0, maximum=1000),
- dict(name='axisName_b', minimum=0, maximum=3000)
- ])
+ r1.conditionSets.append(
+ [
+ dict(name="axisName_a", minimum=0, maximum=1000),
+ dict(name="axisName_b", minimum=0, maximum=3000),
+ ]
+ )
r1.subs.append(("a", "a.alt"))
# rule with minium and maximum
doc.addRule(r1)
assert len(doc.rules) == 1
assert len(doc.rules[0].conditionSets) == 1
assert len(doc.rules[0].conditionSets[0]) == 2
- assert _axesAsDict(doc.axes) == {'axisName_a': {'map': [], 'name': 'axisName_a', 'default': 0, 'minimum': 0, 'maximum': 1000, 'tag': 'TAGA'}, 'axisName_b': {'map': [], 'name': 'axisName_b', 'default': 2000, 'minimum': 2000, 'maximum': 3000, 'tag': 'TAGB'}}
- assert doc.rules[0].conditionSets == [[
- {'minimum': 0, 'maximum': 1000, 'name': 'axisName_a'},
- {'minimum': 0, 'maximum': 3000, 'name': 'axisName_b'}]]
- assert doc.rules[0].subs == [('a', 'a.alt')]
+ assert _axesAsDict(doc.axes) == {
+ "axisName_a": {
+ "map": [],
+ "name": "axisName_a",
+ "default": 0,
+ "minimum": 0,
+ "maximum": 1000,
+ "tag": "TAGA",
+ },
+ "axisName_b": {
+ "map": [],
+ "name": "axisName_b",
+ "default": 2000,
+ "minimum": 2000,
+ "maximum": 3000,
+ "tag": "TAGB",
+ },
+ }
+ assert doc.rules[0].conditionSets == [
+ [
+ {"minimum": 0, "maximum": 1000, "name": "axisName_a"},
+ {"minimum": 0, "maximum": 3000, "name": "axisName_b"},
+ ]
+ ]
+ assert doc.rules[0].subs == [("a", "a.alt")]
doc.normalize()
- assert doc.rules[0].name == 'named.rule.1'
- assert doc.rules[0].conditionSets == [[
- {'minimum': 0.0, 'maximum': 1.0, 'name': 'axisName_a'},
- {'minimum': 0.0, 'maximum': 1.0, 'name': 'axisName_b'}]]
+ assert doc.rules[0].name == "named.rule.1"
+ assert doc.rules[0].conditionSets == [
+ [
+ {"minimum": 0.0, "maximum": 1.0, "name": "axisName_a"},
+ {"minimum": 0.0, "maximum": 1.0, "name": "axisName_b"},
+ ]
+ ]
# still one conditionset
assert len(doc.rules[0].conditionSets) == 1
doc.write(testDocPath)
@@ -778,17 +875,22 @@ def test_rulesDocument(tmpdir):
assert len(doc3.rules) == 1
assert len(doc3.rules[0].conditionSets) == 2
+
def _addUnwrappedCondition(path):
# only for testing, so we can make an invalid designspace file
# older designspace files may have conditions that are not wrapped in a conditionset
# These can be read into a new conditionset.
- with open(path, 'r', encoding='utf-8') as f:
+ with open(path, "r", encoding="utf-8") as f:
d = f.read()
print(d)
- d = d.replace('<rule name="named.rule.1">', '<rule name="named.rule.1">\n\t<condition maximum="22" minimum="33" name="axisName_a" />')
- with open(path, 'w', encoding='utf-8') as f:
+ d = d.replace(
+ '<rule name="named.rule.1">',
+ '<rule name="named.rule.1">\n\t<condition maximum="22" minimum="33" name="axisName_a" />',
+ )
+ with open(path, "w", encoding="utf-8") as f:
f.write(d)
+
def test_documentLib(tmpdir):
# roundtrip test of the document lib with some nested data
tmpdir = str(tmpdir)
@@ -801,7 +903,7 @@ def test_documentLib(tmpdir):
a1.maximum = 1000
a1.default = 0
doc.addAxis(a1)
- dummyData = dict(a=123, b=u"äbc", c=[1,2,3], d={'a':123})
+ dummyData = dict(a=123, b="äbc", c=[1, 2, 3], d={"a": 123})
dummyKey = "org.fontTools.designspaceLib"
doc.lib = {dummyKey: dummyData}
doc.write(testDocPath1)
@@ -855,17 +957,15 @@ def test_updatePaths(tmpdir):
def test_read_with_path_object():
- import pathlib
- source = (pathlib.Path(__file__) / "../data/test_v4_original.designspace").resolve()
+ source = (Path(__file__) / "../data/test_v4_original.designspace").resolve()
assert source.exists()
doc = DesignSpaceDocument()
doc.read(source)
def test_with_with_path_object(tmpdir):
- import pathlib
tmpdir = str(tmpdir)
- dest = pathlib.Path(tmpdir) / "test_v4_original.designspace"
+ dest = Path(tmpdir) / "test_v4_original.designspace"
doc = DesignSpaceDocument()
doc.write(dest)
assert dest.exists()
@@ -934,7 +1034,6 @@ def test_findDefault_axis_mapping():
def test_loadSourceFonts():
-
def opener(path):
font = ttLib.TTFont()
font.importXML(path)
@@ -945,7 +1044,7 @@ def test_loadSourceFonts():
os.path.dirname(os.path.dirname(__file__)),
"varLib",
"data",
- "SparseMasters.designspace"
+ "SparseMasters.designspace",
)
designspace = DesignSpaceDocument.fromfile(path)
@@ -976,7 +1075,7 @@ def test_addAxisDescriptor():
ds = DesignSpaceDocument()
axis = ds.addAxisDescriptor(
- name="Weight", tag="wght", minimum=100, default=400, maximum=900
+ name="Weight", tag="wght", minimum=100, default=400, maximum=900
)
assert ds.axes[0] is axis
@@ -988,6 +1087,19 @@ def test_addAxisDescriptor():
assert axis.maximum == 900
+def test_addAxisDescriptor():
+ ds = DesignSpaceDocument()
+
+ mapping = ds.addAxisMappingDescriptor(
+ inputLocation={"weight": 900, "width": 150}, outputLocation={"weight": 870}
+ )
+
+ assert ds.axisMappings[0] is mapping
+ assert isinstance(mapping, AxisMappingDescriptor)
+ assert mapping.inputLocation == {"weight": 900, "width": 150}
+ assert mapping.outputLocation == {"weight": 870}
+
+
def test_addSourceDescriptor():
ds = DesignSpaceDocument()
@@ -1003,10 +1115,10 @@ def test_addInstanceDescriptor():
ds = DesignSpaceDocument()
instance = ds.addInstanceDescriptor(
- name="TestInstance",
- location={"Weight": 400},
- styleName="Regular",
- styleMapStyleName="regular",
+ name="TestInstance",
+ location={"Weight": 400},
+ styleName="Regular",
+ styleMapStyleName="regular",
)
assert ds.instances[0] is instance
@@ -1064,3 +1176,10 @@ def test_Range_post_init():
assert r.minimum == -1
assert r.maximum == 2
assert r.default == -1
+
+
+def test_get_axes(datadir: Path) -> None:
+ ds = DesignSpaceDocument.fromfile(datadir / "test_v5.designspace")
+
+ assert ds.getAxis("Width") is ds.getAxisByTag("wdth")
+ assert ds.getAxis("Italic") is ds.getAxisByTag("ital")