import pytest from bonobo.config.configurables import Configurable from bonobo.config.options import Option from bonobo.util.inspect import inspect_node class NoOptConfigurable(Configurable): pass class MyConfigurable(Configurable): required_str = Option(str) default_str = Option(str, default="foo") integer = Option(int, required=False) class MyHarderConfigurable(MyConfigurable): also_required = Option(bool, required=True) class MyBetterConfigurable(MyConfigurable): required_str = Option(str, required=False, default="kaboom") class MyConfigurableUsingPositionalOptions(MyConfigurable): first = Option(str, required=True, positional=True) second = Option(str, required=True, positional=True) third = Option(str, required=False, positional=True) def test_missing_required_option_error(): with inspect_node(MyConfigurable()) as ni: assert ni.partial with pytest.raises(TypeError) as exc: MyConfigurable(_final=True) assert exc.match("missing 1 required option:") def test_missing_required_options_error(): with inspect_node(MyHarderConfigurable()) as ni: assert ni.partial with pytest.raises(TypeError) as exc: MyHarderConfigurable(_final=True) assert exc.match("missing 2 required options:") def test_extraneous_option_error(): with pytest.raises(TypeError) as exc: MyConfigurable(required_str="foo", hello="world") assert exc.match("got 1 unexpected option:") def test_extraneous_options_error(): with pytest.raises(TypeError) as exc: MyConfigurable(required_str="foo", hello="world", acme="corp") assert exc.match("got 2 unexpected options:") def test_defaults(): o = MyConfigurable(required_str="hello") with inspect_node(o) as ni: assert not ni.partial assert o.required_str == "hello" assert o.default_str == "foo" assert o.integer is None def test_str_type_factory(): o = MyConfigurable(required_str=42) with inspect_node(o) as ni: assert not ni.partial assert o.required_str == "42" assert o.default_str == "foo" assert o.integer is None def test_int_type_factory(): o = MyConfigurable(required_str="yo", default_str="bar", integer="42") with inspect_node(o) as ni: assert not ni.partial assert o.required_str == "yo" assert o.default_str == "bar" assert o.integer == 42 def test_bool_type_factory(): o = MyHarderConfigurable(required_str="yes", also_required="True") with inspect_node(o) as ni: assert not ni.partial assert o.required_str == "yes" assert o.default_str == "foo" assert o.integer is None assert o.also_required is True def test_option_resolution_order(): o = MyBetterConfigurable() with inspect_node(o) as ni: assert not ni.partial assert o.required_str == "kaboom" assert o.default_str == "foo" assert o.integer is None def test_option_positional(): o = MyConfigurableUsingPositionalOptions("1", "2", "3", required_str="hello") with inspect_node(o) as ni: assert not ni.partial assert o.first == "1" assert o.second == "2" assert o.third == "3" assert o.required_str == "hello" assert o.default_str == "foo" assert o.integer is None def test_no_opt_configurable(): o = NoOptConfigurable() with inspect_node(o) as ni: assert not ni.partial