import pytest import sys from config.config import ( Config, OptionDescription, BoolOption, IntOption, FloatOption, StrOption, ChoiceOption, ArbitraryOption, make_dict, ConfigError ) def make_description(): gcoption = ChoiceOption('name', 'GC name', ['ref', 'framework'], 'ref') gcdummy = BoolOption('dummy', 'dummy', default=False) booloption = BoolOption('bool', 'Test boolean option', default=True) intoption = IntOption('int', 'Test int option', default=0) floatoption = FloatOption('float', 'Test float option', default=2.3) stroption = StrOption('str', 'Test string option', default="abc") wantref_option = BoolOption('wantref', 'Test requires', default=False, requires=[('gc.name', 'ref')]) wantframework_option = BoolOption('wantframework', 'Test requires', default=False, requires=[('gc.name', 'framework')]) gcgroup = OptionDescription('gc', '', [gcoption, gcdummy, floatoption]) descr = OptionDescription('pypy', '', [gcgroup, booloption, wantref_option, stroption, wantframework_option, intoption]) return descr def test_base_config(): descr = make_description() config = Config(descr, bool=False) assert config.gc.name == 'ref' config.gc.name = 'framework' assert config.gc.name == 'framework' assert getattr(config, "gc.name") == 'framework' assert config.gc.float == 2.3 assert config.int == 0 config.gc.float = 3.4 config.int = 123 assert config.gc.float == 3.4 assert config.int == 123 assert not config.wantref assert config.str == "abc" config.str = "def" assert config.str == "def" with pytest.raises(ConfigError): config.gc.name = "foo" with pytest.raises(AttributeError): config.gc.foo = "bar" with pytest.raises(ConfigError): config.bool = 123 with pytest.raises(ConfigError): config.int = "hello" with pytest.raises(ConfigError): config.gc.float = None config = Config(descr, bool=False) assert config.gc.name == 'ref' config.wantframework = True with pytest.raises(ConfigError): config.gc.name = "ref" config.gc.name = "framework" def test___dir__(): descr = make_description() config = Config(descr, bool=False) attrs = dir(config) assert '__repr__' in attrs # from the type assert '_cfgimpl_values' in attrs # from self assert 'gc' in attrs # custom attribute attrs = dir(config.gc) assert 'name' in attrs assert 'dummy' in attrs assert 'float' in attrs def test_arbitrary_option(): descr = OptionDescription("top", "", [ ArbitraryOption("a", "no help", default=None) ]) config = Config(descr) config.a = [] config.a.append(1) assert config.a == [1] descr = OptionDescription("top", "", [ ArbitraryOption("a", "no help", defaultfactory=list) ]) c1 = Config(descr) c2 = Config(descr) c1.a.append(1) assert c2.a == [] assert c1.a == [1] def test_compare_configs(): descr = make_description() conf1 = Config(descr) conf2 = Config(descr) conf2.wantref = True assert conf1 != conf2 assert conf1.getkey() != conf2.getkey() conf1.wantref = True assert conf1 == conf2 assert conf1.getkey() == conf2.getkey() def test_loop(): descr = make_description() conf = Config(descr) for (name, value), (gname, gvalue) in \ zip(conf.gc, [("name", "ref"), ("dummy", False)]): assert name == gname assert value == gvalue def test_getpaths(): descr = make_description() config = Config(descr) assert config.getpaths() == ['gc.name', 'gc.dummy', 'gc.float', 'bool', 'wantref', 'str', 'wantframework', 'int'] assert config.getpaths() == descr.getpaths() assert config.gc.getpaths() == ['name', 'dummy', 'float'] assert config.gc.getpaths() == descr.gc.getpaths() assert config.getpaths(include_groups=True) == [ 'gc', 'gc.name', 'gc.dummy', 'gc.float', 'bool', 'wantref', 'str', 'wantframework', 'int'] assert config.getpaths(True) == descr.getpaths(True) def test_underscore_in_option_name(): descr = OptionDescription("opt", "", [ BoolOption("_foobar", "", default=False), ]) config = Config(descr) def test_requirements_from_top(): descr = OptionDescription("test", '', [ BoolOption("toplevel", "", default=False), OptionDescription("sub", '', [ BoolOption("opt", "", default=False, requires=[("toplevel", True)]) ]) ]) config = Config(descr) config.sub.opt = True assert config.toplevel def test_overrides_are_defaults(): descr = OptionDescription("test", "", [ BoolOption("b1", "", default=False, requires=[("b2", False)]), BoolOption("b2", "", default=False), ]) config = Config(descr) config.b2 = True assert config.b2 config.b1 = True assert not config.b2 def test_make_dict(): descr = OptionDescription("opt", "", [ OptionDescription("s1", "", [ BoolOption("a", "", default=False)]), IntOption("int", "", default=42)]) config = Config(descr) d = make_dict(config) assert d == {"s1.a": False, "int": 42} config.int = 43 config.s1.a = True d = make_dict(config) assert d == {"s1.a": True, "int": 43} def test_copy(): descr = OptionDescription("opt", "", [ OptionDescription("s1", "", [ BoolOption("a", "", default=False)]), IntOption("int", "", default=42)]) c1 = Config(descr) c1.int = 43 c2 = c1.copy() assert c2.int == 43 assert not c2.s1.a c2.s1.a = True assert c2.s1.a with pytest.raises(ConfigError): c2.int = 44 c2 = c1.copy(as_default=True) assert c2.int == 43 assert not c2.s1.a c2.s1.a = True assert c2.s1.a c2.int = 44 def test_bool_suggests(): descr = OptionDescription("test", '', [ BoolOption("toplevel", "", default=False), BoolOption("opt", "", default=False, suggests=[("toplevel", True)]) ]) c = Config(descr) assert not c.toplevel assert not c.opt c.opt = True assert c.opt assert c.toplevel c.toplevel = False assert not c.toplevel # Test that user-set values take precedence over suggestions c = Config(descr) c.toplevel = False assert not c.toplevel c.opt = True assert c.opt assert not c.toplevel def test_delattr(): descr = OptionDescription("opt", "", [ OptionDescription("s1", "", [ BoolOption("a", "", default=False)]), IntOption("int", "", default=42)]) c = Config(descr) c.int = 45 assert c.int == 45 del c.int assert c.int == 42 c.int = 45 assert c.int == 45