1*e1fe3e4aSElliott Hughesfrom fontTools.misc.configTools import AbstractConfig, Options 2*e1fe3e4aSElliott Hughesimport pytest 3*e1fe3e4aSElliott Hughesfrom fontTools.config import ( 4*e1fe3e4aSElliott Hughes OPTIONS, 5*e1fe3e4aSElliott Hughes Config, 6*e1fe3e4aSElliott Hughes ConfigUnknownOptionError, 7*e1fe3e4aSElliott Hughes ConfigValueParsingError, 8*e1fe3e4aSElliott Hughes ConfigValueValidationError, 9*e1fe3e4aSElliott Hughes) 10*e1fe3e4aSElliott Hughesfrom fontTools.ttLib import TTFont 11*e1fe3e4aSElliott Hughes 12*e1fe3e4aSElliott Hughes 13*e1fe3e4aSElliott Hughesdef test_can_register_option(): 14*e1fe3e4aSElliott Hughes MY_OPTION = Config.register_option( 15*e1fe3e4aSElliott Hughes name="tests:MY_OPTION", 16*e1fe3e4aSElliott Hughes help="Test option, value should be True or False, default = True", 17*e1fe3e4aSElliott Hughes default=True, 18*e1fe3e4aSElliott Hughes parse=lambda v: v in ("True", "true", 1, True), 19*e1fe3e4aSElliott Hughes validate=lambda v: v == True or v == False, 20*e1fe3e4aSElliott Hughes ) 21*e1fe3e4aSElliott Hughes 22*e1fe3e4aSElliott Hughes assert MY_OPTION.name == "tests:MY_OPTION" 23*e1fe3e4aSElliott Hughes assert ( 24*e1fe3e4aSElliott Hughes MY_OPTION.help == "Test option, value should be True or False, default = True" 25*e1fe3e4aSElliott Hughes ) 26*e1fe3e4aSElliott Hughes assert MY_OPTION.default == True 27*e1fe3e4aSElliott Hughes assert MY_OPTION.parse("true") == True 28*e1fe3e4aSElliott Hughes assert MY_OPTION.validate("hello") == False 29*e1fe3e4aSElliott Hughes 30*e1fe3e4aSElliott Hughes ttFont = TTFont(cfg={"tests:MY_OPTION": True}) 31*e1fe3e4aSElliott Hughes assert True == ttFont.cfg.get("tests:MY_OPTION") 32*e1fe3e4aSElliott Hughes assert True == ttFont.cfg.get(MY_OPTION) 33*e1fe3e4aSElliott Hughes 34*e1fe3e4aSElliott Hughes 35*e1fe3e4aSElliott Hughes# to parametrize tests of Config mapping interface accepting either a str or Option 36*e1fe3e4aSElliott Hughes@pytest.fixture( 37*e1fe3e4aSElliott Hughes params=[ 38*e1fe3e4aSElliott Hughes pytest.param("fontTools.otlLib.optimize.gpos:COMPRESSION_LEVEL", id="str"), 39*e1fe3e4aSElliott Hughes pytest.param( 40*e1fe3e4aSElliott Hughes OPTIONS["fontTools.otlLib.optimize.gpos:COMPRESSION_LEVEL"], id="Option" 41*e1fe3e4aSElliott Hughes ), 42*e1fe3e4aSElliott Hughes ] 43*e1fe3e4aSElliott Hughes) 44*e1fe3e4aSElliott Hughesdef COMPRESSION_LEVEL(request): 45*e1fe3e4aSElliott Hughes return request.param 46*e1fe3e4aSElliott Hughes 47*e1fe3e4aSElliott Hughes 48*e1fe3e4aSElliott Hughesdef test_ttfont_has_config(COMPRESSION_LEVEL): 49*e1fe3e4aSElliott Hughes ttFont = TTFont(cfg={COMPRESSION_LEVEL: 8}) 50*e1fe3e4aSElliott Hughes assert 8 == ttFont.cfg.get(COMPRESSION_LEVEL) 51*e1fe3e4aSElliott Hughes 52*e1fe3e4aSElliott Hughes 53*e1fe3e4aSElliott Hughesdef test_ttfont_can_take_superset_of_fonttools_config(COMPRESSION_LEVEL): 54*e1fe3e4aSElliott Hughes # Create MyConfig with all options from fontTools.config plus some 55*e1fe3e4aSElliott Hughes my_options = Options(Config.options) 56*e1fe3e4aSElliott Hughes MY_OPTION = my_options.register("custom:my_option", "help", "default", str, any) 57*e1fe3e4aSElliott Hughes 58*e1fe3e4aSElliott Hughes class MyConfig(AbstractConfig): 59*e1fe3e4aSElliott Hughes options = my_options 60*e1fe3e4aSElliott Hughes 61*e1fe3e4aSElliott Hughes ttFont = TTFont(cfg=MyConfig({"custom:my_option": "my_value"})) 62*e1fe3e4aSElliott Hughes assert 0 == ttFont.cfg.get(COMPRESSION_LEVEL) 63*e1fe3e4aSElliott Hughes assert "my_value" == ttFont.cfg.get(MY_OPTION) 64*e1fe3e4aSElliott Hughes 65*e1fe3e4aSElliott Hughes # but the default Config doens't know about MY_OPTION 66*e1fe3e4aSElliott Hughes with pytest.raises(ConfigUnknownOptionError): 67*e1fe3e4aSElliott Hughes TTFont(cfg={MY_OPTION: "my_value"}) 68*e1fe3e4aSElliott Hughes 69*e1fe3e4aSElliott Hughes 70*e1fe3e4aSElliott Hughesdef test_no_config_returns_default_values(COMPRESSION_LEVEL): 71*e1fe3e4aSElliott Hughes ttFont = TTFont() 72*e1fe3e4aSElliott Hughes assert 0 == ttFont.cfg.get(COMPRESSION_LEVEL) 73*e1fe3e4aSElliott Hughes assert 3 == ttFont.cfg.get(COMPRESSION_LEVEL, 3) 74*e1fe3e4aSElliott Hughes 75*e1fe3e4aSElliott Hughes 76*e1fe3e4aSElliott Hughesdef test_can_set_config(COMPRESSION_LEVEL): 77*e1fe3e4aSElliott Hughes ttFont = TTFont() 78*e1fe3e4aSElliott Hughes ttFont.cfg.set(COMPRESSION_LEVEL, 5) 79*e1fe3e4aSElliott Hughes assert 5 == ttFont.cfg.get(COMPRESSION_LEVEL) 80*e1fe3e4aSElliott Hughes ttFont.cfg.set(COMPRESSION_LEVEL, 6) 81*e1fe3e4aSElliott Hughes assert 6 == ttFont.cfg.get(COMPRESSION_LEVEL) 82*e1fe3e4aSElliott Hughes 83*e1fe3e4aSElliott Hughes 84*e1fe3e4aSElliott Hughesdef test_different_ttfonts_have_different_configs(COMPRESSION_LEVEL): 85*e1fe3e4aSElliott Hughes cfg = Config({COMPRESSION_LEVEL: 5}) 86*e1fe3e4aSElliott Hughes ttFont1 = TTFont(cfg=cfg) 87*e1fe3e4aSElliott Hughes ttFont2 = TTFont(cfg=cfg) 88*e1fe3e4aSElliott Hughes ttFont2.cfg.set(COMPRESSION_LEVEL, 6) 89*e1fe3e4aSElliott Hughes assert 5 == ttFont1.cfg.get(COMPRESSION_LEVEL) 90*e1fe3e4aSElliott Hughes assert 6 == ttFont2.cfg.get(COMPRESSION_LEVEL) 91*e1fe3e4aSElliott Hughes 92*e1fe3e4aSElliott Hughes 93*e1fe3e4aSElliott Hughesdef test_cannot_set_inexistent_key(): 94*e1fe3e4aSElliott Hughes with pytest.raises(ConfigUnknownOptionError): 95*e1fe3e4aSElliott Hughes TTFont(cfg={"notALib.notAModule.inexistent": 4}) 96*e1fe3e4aSElliott Hughes 97*e1fe3e4aSElliott Hughes 98*e1fe3e4aSElliott Hughesdef test_value_not_parsed_by_default(COMPRESSION_LEVEL): 99*e1fe3e4aSElliott Hughes # Note: value given as a string 100*e1fe3e4aSElliott Hughes with pytest.raises(ConfigValueValidationError): 101*e1fe3e4aSElliott Hughes TTFont(cfg={COMPRESSION_LEVEL: "8"}) 102*e1fe3e4aSElliott Hughes 103*e1fe3e4aSElliott Hughes 104*e1fe3e4aSElliott Hughesdef test_value_gets_parsed_if_asked(COMPRESSION_LEVEL): 105*e1fe3e4aSElliott Hughes # Note: value given as a string 106*e1fe3e4aSElliott Hughes ttFont = TTFont(cfg=Config({COMPRESSION_LEVEL: "8"}, parse_values=True)) 107*e1fe3e4aSElliott Hughes assert 8 == ttFont.cfg.get(COMPRESSION_LEVEL) 108*e1fe3e4aSElliott Hughes 109*e1fe3e4aSElliott Hughes 110*e1fe3e4aSElliott Hughesdef test_value_parsing_can_error(COMPRESSION_LEVEL): 111*e1fe3e4aSElliott Hughes with pytest.raises(ConfigValueParsingError): 112*e1fe3e4aSElliott Hughes TTFont( 113*e1fe3e4aSElliott Hughes cfg=Config( 114*e1fe3e4aSElliott Hughes {COMPRESSION_LEVEL: "not an int"}, 115*e1fe3e4aSElliott Hughes parse_values=True, 116*e1fe3e4aSElliott Hughes ) 117*e1fe3e4aSElliott Hughes ) 118*e1fe3e4aSElliott Hughes 119*e1fe3e4aSElliott Hughes 120*e1fe3e4aSElliott Hughesdef test_value_gets_validated(COMPRESSION_LEVEL): 121*e1fe3e4aSElliott Hughes # Note: 12 is not a valid value for GPOS compression level (must be in 0-9) 122*e1fe3e4aSElliott Hughes with pytest.raises(ConfigValueValidationError): 123*e1fe3e4aSElliott Hughes TTFont(cfg={COMPRESSION_LEVEL: 12}) 124*e1fe3e4aSElliott Hughes 125*e1fe3e4aSElliott Hughes 126*e1fe3e4aSElliott Hughesdef test_implements_mutable_mapping(COMPRESSION_LEVEL): 127*e1fe3e4aSElliott Hughes cfg = Config() 128*e1fe3e4aSElliott Hughes cfg[COMPRESSION_LEVEL] = 2 129*e1fe3e4aSElliott Hughes assert 2 == cfg[COMPRESSION_LEVEL] 130*e1fe3e4aSElliott Hughes assert list(iter(cfg)) 131*e1fe3e4aSElliott Hughes assert 1 == len(cfg) 132*e1fe3e4aSElliott Hughes del cfg[COMPRESSION_LEVEL] 133*e1fe3e4aSElliott Hughes assert 0 == cfg[COMPRESSION_LEVEL] 134*e1fe3e4aSElliott Hughes assert not list(iter(cfg)) 135*e1fe3e4aSElliott Hughes assert 0 == len(cfg) 136