xref: /aosp_15_r20/external/fonttools/Tests/misc/configTools_test.py (revision e1fe3e4ad2793916b15cccdc4a7da52a7e1dd0e9)
1import dataclasses
2import pytest
3
4from fontTools.misc.configTools import (
5    AbstractConfig,
6    Option,
7    Options,
8    ConfigUnknownOptionError,
9)
10
11
12def test_can_create_custom_config_system():
13    class MyConfig(AbstractConfig):
14        options = Options()
15
16    MyConfig.register_option(
17        "test:option_name",
18        "This is an option",
19        0,
20        int,
21        lambda v: isinstance(v, int),
22    )
23
24    cfg = MyConfig({"test:option_name": "10"}, parse_values=True)
25
26    assert 10 == cfg["test:option_name"]
27
28    # This config is independent from "the" fontTools config
29    with pytest.raises(ConfigUnknownOptionError):
30        MyConfig({"fontTools.otlLib.optimize.gpos:COMPRESSION_LEVEL": 4})
31
32    # Test the repr()
33    assert repr(cfg) == "MyConfig({'test:option_name': 10})"
34
35    # Test the skip_unknown param: just check that the following does not raise
36    MyConfig({"test:unknown": "whatever"}, skip_unknown=True)
37
38    # Test that it raises on unknown option
39    with pytest.raises(ConfigUnknownOptionError):
40        cfg.get("test:unknown")
41
42
43def test_options_are_unique():
44    class MyConfig(AbstractConfig):
45        options = Options()
46
47    opt1 = MyConfig.register_option("test:OPT_1", "", "foo", str, any)
48    cfg = MyConfig({opt1: "bar"})
49    assert cfg[opt1] == "bar"
50
51    opt2 = Option("test:OPT_1", "", "foo", str, any)
52
53    assert dataclasses.asdict(opt1) == dataclasses.asdict(opt2)
54    assert opt1 != opt2
55
56    with pytest.raises(ConfigUnknownOptionError):
57        cfg.get(opt2)
58    with pytest.raises(ConfigUnknownOptionError):
59        cfg.set(opt2, "bar")
60
61
62def test_optional_bool():
63    for v in ("yes", "YES", "Yes", "1", "True", "true", "TRUE"):
64        assert Option.parse_optional_bool(v) is True
65
66    for v in ("no", "NO", "No", "0", "False", "false", "FALSE"):
67        assert Option.parse_optional_bool(v) is False
68
69    for v in ("auto", "AUTO", "Auto", "None", "none", "NONE"):
70        assert Option.parse_optional_bool(v) is None
71
72    with pytest.raises(ValueError, match="invalid optional bool"):
73        Option.parse_optional_bool("foobar")
74
75    assert Option.validate_optional_bool(True)
76    assert Option.validate_optional_bool(False)
77    assert Option.validate_optional_bool(None)
78    assert not Option.validate_optional_bool(1)
79    assert not Option.validate_optional_bool(0)
80    assert not Option.validate_optional_bool("1")
81