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