blob: 58163913ed17ec0aab08368b0d2f4aae0019b189 [file] [log] [blame]
from fontTools.misc.configTools import AbstractConfig, Options
import pytest
from fontTools.config import (
OPTIONS,
Config,
ConfigUnknownOptionError,
ConfigValueParsingError,
ConfigValueValidationError,
)
from fontTools.ttLib import TTFont
def test_can_register_option():
MY_OPTION = Config.register_option(
name="tests:MY_OPTION",
help="Test option, value should be True or False, default = True",
default=True,
parse=lambda v: v in ("True", "true", 1, True),
validate=lambda v: v == True or v == False,
)
assert MY_OPTION.name == "tests:MY_OPTION"
assert (
MY_OPTION.help == "Test option, value should be True or False, default = True"
)
assert MY_OPTION.default == True
assert MY_OPTION.parse("true") == True
assert MY_OPTION.validate("hello") == False
ttFont = TTFont(cfg={"tests:MY_OPTION": True})
assert True == ttFont.cfg.get("tests:MY_OPTION")
assert True == ttFont.cfg.get(MY_OPTION)
# to parametrize tests of Config mapping interface accepting either a str or Option
@pytest.fixture(
params=[
pytest.param("fontTools.otlLib.optimize.gpos:COMPRESSION_LEVEL", id="str"),
pytest.param(
OPTIONS["fontTools.otlLib.optimize.gpos:COMPRESSION_LEVEL"], id="Option"
),
]
)
def COMPRESSION_LEVEL(request):
return request.param
def test_ttfont_has_config(COMPRESSION_LEVEL):
ttFont = TTFont(cfg={COMPRESSION_LEVEL: 8})
assert 8 == ttFont.cfg.get(COMPRESSION_LEVEL)
def test_ttfont_can_take_superset_of_fonttools_config(COMPRESSION_LEVEL):
# Create MyConfig with all options from fontTools.config plus some
my_options = Options(Config.options)
MY_OPTION = my_options.register("custom:my_option", "help", "default", str, any)
class MyConfig(AbstractConfig):
options = my_options
ttFont = TTFont(cfg=MyConfig({"custom:my_option": "my_value"}))
assert 0 == ttFont.cfg.get(COMPRESSION_LEVEL)
assert "my_value" == ttFont.cfg.get(MY_OPTION)
# but the default Config doens't know about MY_OPTION
with pytest.raises(ConfigUnknownOptionError):
TTFont(cfg={MY_OPTION: "my_value"})
def test_no_config_returns_default_values(COMPRESSION_LEVEL):
ttFont = TTFont()
assert 0 == ttFont.cfg.get(COMPRESSION_LEVEL)
assert 3 == ttFont.cfg.get(COMPRESSION_LEVEL, 3)
def test_can_set_config(COMPRESSION_LEVEL):
ttFont = TTFont()
ttFont.cfg.set(COMPRESSION_LEVEL, 5)
assert 5 == ttFont.cfg.get(COMPRESSION_LEVEL)
ttFont.cfg.set(COMPRESSION_LEVEL, 6)
assert 6 == ttFont.cfg.get(COMPRESSION_LEVEL)
def test_different_ttfonts_have_different_configs(COMPRESSION_LEVEL):
cfg = Config({COMPRESSION_LEVEL: 5})
ttFont1 = TTFont(cfg=cfg)
ttFont2 = TTFont(cfg=cfg)
ttFont2.cfg.set(COMPRESSION_LEVEL, 6)
assert 5 == ttFont1.cfg.get(COMPRESSION_LEVEL)
assert 6 == ttFont2.cfg.get(COMPRESSION_LEVEL)
def test_cannot_set_inexistent_key():
with pytest.raises(ConfigUnknownOptionError):
TTFont(cfg={"notALib.notAModule.inexistent": 4})
def test_value_not_parsed_by_default(COMPRESSION_LEVEL):
# Note: value given as a string
with pytest.raises(ConfigValueValidationError):
TTFont(cfg={COMPRESSION_LEVEL: "8"})
def test_value_gets_parsed_if_asked(COMPRESSION_LEVEL):
# Note: value given as a string
ttFont = TTFont(cfg=Config({COMPRESSION_LEVEL: "8"}, parse_values=True))
assert 8 == ttFont.cfg.get(COMPRESSION_LEVEL)
def test_value_parsing_can_error(COMPRESSION_LEVEL):
with pytest.raises(ConfigValueParsingError):
TTFont(
cfg=Config(
{COMPRESSION_LEVEL: "not an int"},
parse_values=True,
)
)
def test_value_gets_validated(COMPRESSION_LEVEL):
# Note: 12 is not a valid value for GPOS compression level (must be in 0-9)
with pytest.raises(ConfigValueValidationError):
TTFont(cfg={COMPRESSION_LEVEL: 12})
def test_implements_mutable_mapping(COMPRESSION_LEVEL):
cfg = Config()
cfg[COMPRESSION_LEVEL] = 2
assert 2 == cfg[COMPRESSION_LEVEL]
assert list(iter(cfg))
assert 1 == len(cfg)
del cfg[COMPRESSION_LEVEL]
assert 0 == cfg[COMPRESSION_LEVEL]
assert not list(iter(cfg))
assert 0 == len(cfg)