aboutsummaryrefslogtreecommitdiff
path: root/Tests/feaLib/parser_test.py
diff options
context:
space:
mode:
Diffstat (limited to 'Tests/feaLib/parser_test.py')
-rw-r--r--Tests/feaLib/parser_test.py68
1 files changed, 60 insertions, 8 deletions
diff --git a/Tests/feaLib/parser_test.py b/Tests/feaLib/parser_test.py
index b281e8ac..c140629a 100644
--- a/Tests/feaLib/parser_test.py
+++ b/Tests/feaLib/parser_test.py
@@ -44,7 +44,7 @@ GLYPHNAMES = (
a.swash b.swash x.swash y.swash z.swash
foobar foo.09 foo.1234 foo.9876
one two five six acute grave dieresis umlaut cedilla ogonek macron
- a_f_f_i o_f_f_i f_i f_f_i one.fitted one.oldstyle a.1 a.2 a.3 c_t
+ a_f_f_i o_f_f_i f_i f_l f_f_i one.fitted one.oldstyle a.1 a.2 a.3 c_t
PRE SUF FIX BACK TRACK LOOK AHEAD ampersand ampersand.1 ampersand.2
cid00001 cid00002 cid00003 cid00004 cid00005 cid00006 cid00007
cid12345 cid78987 cid00999 cid01000 cid01001 cid00998 cid00995
@@ -316,7 +316,9 @@ class ParserTest(unittest.TestCase):
def test_strict_glyph_name_check(self):
self.parse("@bad = [a b ccc];", glyphNames=("a", "b", "ccc"))
- with self.assertRaisesRegex(FeatureLibError, "(?s)missing from the glyph set:.*ccc"):
+ with self.assertRaisesRegex(
+ FeatureLibError, "(?s)missing from the glyph set:.*ccc"
+ ):
self.parse("@bad = [a b ccc];", glyphNames=("a", "b"))
def test_glyphclass(self):
@@ -705,6 +707,17 @@ class ParserTest(unittest.TestCase):
self.assertEqual(glyphstr([s.glyphs]), "f_i")
self.assertEqual(s.carets, [400, 380])
+ def test_ligatureCaretByPos_variable_scalar(self):
+ doc = self.parse(
+ "table GDEF {LigatureCaretByPos f_i (wght=200:400 wght=900:1000) 380;} GDEF;"
+ )
+ s = doc.statements[0].statements[0]
+ self.assertIsInstance(s, ast.LigatureCaretByPosStatement)
+ self.assertEqual(glyphstr([s.glyphs]), "f_i")
+ self.assertEqual(len(s.carets), 2)
+ self.assertEqual(str(s.carets[0]), "(wght=200:400 wght=900:1000)")
+ self.assertEqual(s.carets[1], 380)
+
def test_lookup_block(self):
[lookup] = self.parse("lookup Ligatures {} Ligatures;").statements
self.assertEqual(lookup.name, "Ligatures")
@@ -1608,24 +1621,54 @@ class ParserTest(unittest.TestCase):
doc = self.parse("lookup Look {substitute f_f_i by f f i;} Look;")
sub = doc.statements[0].statements[0]
self.assertIsInstance(sub, ast.MultipleSubstStatement)
- self.assertEqual(sub.glyph, "f_f_i")
- self.assertEqual(sub.replacement, ("f", "f", "i"))
+ self.assertEqual(glyphstr([sub.glyph]), "f_f_i")
+ self.assertEqual(glyphstr(sub.replacement), "f f i")
def test_substitute_multiple_chained(self): # chain to GSUB LookupType 2
doc = self.parse("lookup L {sub [A-C] f_f_i' [X-Z] by f f i;} L;")
sub = doc.statements[0].statements[0]
self.assertIsInstance(sub, ast.MultipleSubstStatement)
- self.assertEqual(sub.glyph, "f_f_i")
- self.assertEqual(sub.replacement, ("f", "f", "i"))
+ self.assertEqual(glyphstr([sub.glyph]), "f_f_i")
+ self.assertEqual(glyphstr(sub.replacement), "f f i")
def test_substitute_multiple_force_chained(self):
doc = self.parse("lookup L {sub f_f_i' by f f i;} L;")
sub = doc.statements[0].statements[0]
self.assertIsInstance(sub, ast.MultipleSubstStatement)
- self.assertEqual(sub.glyph, "f_f_i")
- self.assertEqual(sub.replacement, ("f", "f", "i"))
+ self.assertEqual(glyphstr([sub.glyph]), "f_f_i")
+ self.assertEqual(glyphstr(sub.replacement), "f f i")
self.assertEqual(sub.asFea(), "sub f_f_i' by f f i;")
+ def test_substitute_multiple_classes(self):
+ doc = self.parse("lookup Look {substitute [f_i f_l] by [f f] [i l];} Look;")
+ sub = doc.statements[0].statements[0]
+ self.assertIsInstance(sub, ast.MultipleSubstStatement)
+ self.assertEqual(glyphstr([sub.glyph]), "[f_i f_l]")
+ self.assertEqual(glyphstr(sub.replacement), "[f f] [i l]")
+
+ def test_substitute_multiple_classes_mixed(self):
+ doc = self.parse("lookup Look {substitute [f_i f_l] by f [i l];} Look;")
+ sub = doc.statements[0].statements[0]
+ self.assertIsInstance(sub, ast.MultipleSubstStatement)
+ self.assertEqual(glyphstr([sub.glyph]), "[f_i f_l]")
+ self.assertEqual(glyphstr(sub.replacement), "f [i l]")
+
+ def test_substitute_multiple_classes_mixed_singleton(self):
+ doc = self.parse("lookup Look {substitute [f_i f_l] by [f] [i l];} Look;")
+ sub = doc.statements[0].statements[0]
+ self.assertIsInstance(sub, ast.MultipleSubstStatement)
+ self.assertEqual(glyphstr([sub.glyph]), "[f_i f_l]")
+ self.assertEqual(glyphstr(sub.replacement), "f [i l]")
+
+ def test_substitute_multiple_classes_mismatch(self):
+ self.assertRaisesRegex(
+ FeatureLibError,
+ 'Expected a glyph class with 1 or 3 elements after "by", '
+ "but found a glyph class with 2 elements",
+ self.parse,
+ "lookup Look {substitute [f_i f_l f_f_i] by [f f_f] [i l i];} Look;",
+ )
+
def test_substitute_multiple_by_mutliple(self):
self.assertRaisesRegex(
FeatureLibError,
@@ -2081,6 +2124,15 @@ class ParserTest(unittest.TestCase):
doc = Parser(fea_path, includeDir=include_dir).parse()
assert len(doc.statements) == 1 and doc.statements[0].text == "# Nothing"
+ def test_unmarked_ignore_statement(self):
+ with CapturingLogHandler("fontTools.feaLib.parser", level="WARNING") as caplog:
+ doc = self.parse("lookup foo { ignore sub A; } foo;")
+ self.assertEqual(doc.statements[0].statements[0].asFea(), "ignore sub A';")
+ self.assertEqual(len(caplog.records), 1)
+ caplog.assertRegex(
+ 'Ambiguous "ignore sub", there should be least one marked glyph'
+ )
+
def parse(self, text, glyphNames=GLYPHNAMES, followIncludes=True):
featurefile = StringIO(text)
p = Parser(featurefile, glyphNames, followIncludes=followIncludes)