def test_perform_guesswork__ignore(capfd, reset_sys_argv, move_home_pypackage): """If the user responds with 'all', ignore all guesses.""" conf = Config() conf.name = "previously existing" sys.argv = ["py-build", "-i"] guesses = OrderedDict([ ("name", "some name"), ("py_modules", "some_thing"), ("scripts", ["bin/something"]), ("package_data", { "some name": ["thing/data/file_1"] }), ]) with mock.patch.object(guessing, "_guess_at_things", return_value=guesses): with mock.patch.object(guessing, "INPUT", return_value="all"): guessing.perform_guesswork(conf, get_options()) assert conf.name == "previously existing" assert not hasattr(conf, "py_modules") assert not hasattr(conf, "package_data") assert not hasattr(conf, "scripts") out, err = capfd.readouterr() assert "ignoring all guesses" in out assert not err
def test_verify_key__failure_coerce(): """Should try to coerce values into their types when not list or dict.""" conf = Config() conf.foo = 3.14 conf._verify_key("foo", str) assert conf.foo == "3.14"
def test_verify_key__str_list_values(): """If the type is list, the items inside should be strings.""" conf = Config() conf.foo = ["bar", 3.14, "baz"] conf._verify_key("foo", list) assert conf.foo == ["bar", "3.14", "baz"]
def test_perform_guesswork(capfd, reset_sys_argv, move_home_pypackage): """Ensure the user can deselect guesses when using interactive.""" conf = Config() conf.name = "previously existing" sys.argv = ["py-build", "-i"] guesses = OrderedDict([ ("name", "some name"), ("py_modules", "some_thing"), ("scripts", ["bin/something"]), ("package_data", ["thing/data/file_1"]), ]) with mock.patch.object(guessing, "_guess_at_things", return_value=guesses): with mock.patch.object(guessing, "INPUT", side_effect=iter(["1", "-3", "2", ""])): guessing.perform_guesswork(conf, get_options()) assert conf.name == "previously existing" assert not hasattr(conf, "py_modules") assert conf.package_data == {"previously existing": ["thing/data/file_1"]} assert conf.scripts == ["bin/something"] out, err = capfd.readouterr() assert "name will not be guessed" in out assert "py_modules will not be guessed" in out assert not err
def test_verify_key__list_object(): """If an attribute should be a list, it should be listed.""" conf = Config() conf.foo = "not a list" conf._verify_key("foo", list) assert conf.foo == ["not a list"]
def test_verify_key__dict_types(): """If a dict is provided with types, the key/values should be coerced.""" conf = Config() conf.foo = {3.14: "500.123"} conf._verify_key("foo", {str: float}) assert conf.foo == {"3.14": 500.123}
def test_perform_guesswork__ignore(capfd, reset_sys_argv, move_home_pypackage): """If the user responds with 'all', ignore all guesses.""" conf = Config() conf.name = "previously existing" sys.argv = ["py-build", "-i"] guesses = OrderedDict([ ("name", "some name"), ("py_modules", "some_thing"), ("scripts", ["bin/something"]), ("package_data", {"some name": ["thing/data/file_1"]}), ]) with mock.patch.object(guessing, "_guess_at_things", return_value=guesses): with mock.patch.object(guessing, "INPUT", return_value="all"): guessing.perform_guesswork(conf, get_options()) assert conf.name == "previously existing" assert not hasattr(conf, "py_modules") assert not hasattr(conf, "package_data") assert not hasattr(conf, "scripts") out, err = capfd.readouterr() assert "ignoring all guesses" in out assert not err
def test_verify_key__dict_failure(): """Do not try to coerce something that should be a dict into one.""" conf = Config() conf.foo = "not a dict" with pytest.raises(TypeError) as error: conf._verify_key("foo", {}) assert error.value.args[0] == "foo should be a dict, not str!"
def test_standard_attributes__re_classify(reset_sys_argv): """If reclassify is set, classifiers should be in the unconfigured set.""" conf = Config() conf.classifiers = ["fake things"] sys.argv = ["py-build", "-R"] attrs = configure.standard_attributes(conf, get_options()) assert "classifiers" in attrs
def test_cmdclass_string(): """Ensure the cmdclass string outputting is correct.""" conf = Config(cmdclass={"foo": "MyFooClass", "test": "gets overridden"}) cmdcls_str = conf._cmdclass_string() assert cmdcls_str.startswith("cmdclass={") assert "'foo': MyFooClass" in cmdcls_str assert "'test': PyPackageTest" in cmdcls_str
def test_malformed_packages_fallback(): """Invalid values using find_packages should fallback to their string.""" garbage = "find_packages(!@!^%&)%*_!()$*!*^!%&*(!)$@_!*)" conf = Config(packages=[garbage]) assert conf.packages == [garbage] assert conf._as_kwargs.get("packages") == [garbage] assert conf._packages_string() == ("packages={}".format(garbage), True)
def test_verify_key__failure(): """If unable to coerce into the expected type, raise TypeError.""" conf = Config() conf.foo = "something" with pytest.raises(TypeError) as error: conf._verify_key("foo", float) assert error.value.args[0] == "foo should be a float, not str!"
def test_runner_args_only_when_set(runner): """runner_args should only be in the metadata when they're non-default.""" conf = Config(test_runner=runner) assert "runner_args" not in conf._metadata conf2 = Config(test_runner=runner, runner_args=["-vv", "--pdb"]) assert conf2._metadata.get("runner_args") == ["-vv", "--pdb"]
def test_verify_key__multiple__fallthrough(): """If the first coerce fails, try the second.""" conf = Config() conf.bar = mock.MagicMock(spec=False) conf.bar.__float__ = mock.Mock(side_effect=ValueError) conf.bar.__str__ = mock.Mock(return_value="mock str") conf._verify_key("bar", (float, str)) assert conf.bar == "mock str"
def test_standard_attributes__re_config(reset_sys_argv): """If reconfig is set, all standard attributes should be unconfigured.""" conf = Config() conf.name = "something" sys.argv = ["py-build", "-r"] attrs = configure.standard_attributes(conf, get_options()) expected = list(conf._KEYS.keys())[:conf._STD_TO_EXTD_INDEX] assert attrs == expected
def test_feature_attributes(reset_sys_argv, move_home_pypackage): """If we have default runner args they should appear unconfigured.""" conf = Config() conf.runner_args = ["fake", "args"] conf._configured_runner_args = False attrs = configure.feature_attributes(conf, get_options()) expected = list(conf._PYPACKAGE_KEYS.keys()) assert attrs == expected
def test_feature_attributes__re_config(reset_sys_argv): """When --rebuild is used, all features should appear unconfigured.""" conf = Config() conf.test_runner = "pytest" sys.argv = ["py-build", "--rebuild"] attrs = configure.feature_attributes(conf, get_options()) expected = list(conf._PYPACKAGE_KEYS.keys()) assert attrs == expected
def test_extended_attributes(reset_sys_argv, move_home_pypackage): """Extended attributes should return unset keys past _STD_TO_EXTD_INDEX.""" conf = Config() expected = list(conf._KEYS.keys())[conf._STD_TO_EXTD_INDEX:] conf.use_2to3 = True expected.remove("use_2to3") attrs = configure.extended_attributes(conf, get_options()) assert attrs == expected
def test_extended_attributes__re_config(reset_sys_argv): """If --rebuild is used, all extended attributes should be unconfigured.""" conf = Config() conf.use_2to3 = True sys.argv = ["py-build", "-r"] attrs = configure.extended_attributes(conf, get_options()) expected = list(conf._KEYS.keys())[conf._STD_TO_EXTD_INDEX:] assert attrs == expected
def test_extended_attributes__re_config(reset_sys_argv): """If --rebuild is used, all extended attributes should be unconfigured.""" conf = Config() conf.use_2to3 = True sys.argv = ["py-build", "-r"] attrs = configure.extended_attributes(conf, get_options()) expected = list(conf._KEYS.keys())[17:] assert attrs == expected
def test_standard_attributes__re_config(reset_sys_argv): """If reconfig is set, all standard attributes should be unconfigured.""" conf = Config() conf.name = "something" sys.argv = ["py-build", "-r"] attrs = configure.standard_attributes(conf, get_options()) expected = list(conf._KEYS.keys())[:17] assert attrs == expected
def test_extended_attributes(reset_sys_argv, move_home_pypackage): """Extended attributes should return any unset keys past 17.""" conf = Config() expected = list(conf._KEYS.keys())[17:] conf.use_2to3 = True expected.remove("use_2to3") attrs = configure.extended_attributes(conf, get_options()) assert attrs == expected
def test_verify_key__multiple__failure(): """When unable to coerce to any type, raise TypeError.""" conf = Config() conf.foo = mock.MagicMock(spec=False) conf.foo.__float__ = mock.Mock(side_effect=ValueError) conf.foo.__str__ = mock.Mock(side_effect=ValueError) with pytest.raises(TypeError) as err: conf._verify_key("foo", (float, str)) assert err.value.args[0] == "foo should be a float or str, not MagicMock!"
def test_runner_string__unittest(): """Ensure the correct template and formatting is used for unittest.""" conf = Config( test_runner="unittest is the default when provided nonsense", tests_dir="my_non_std_tests", ) template_str = conf._test_runner_string() assert "import unittest" in template_str assert "my_non_std_tests" in template_str
def test_standard_attributes(reset_sys_argv, move_home_pypackage): """Ensure the standard attribute set.""" conf = Config() expected_attrs = list(conf._KEYS.keys())[:17] conf.name = "foobar" conf.classifiers = ["fake classifier"] expected_attrs.remove("name") expected_attrs.remove("classifiers") attrs = configure.standard_attributes(conf, get_options()) assert attrs == expected_attrs
def test_standard_attributes(reset_sys_argv, move_home_pypackage): """Ensure the standard attribute set.""" conf = Config() expected_attrs = list(conf._KEYS.keys())[:conf._STD_TO_EXTD_INDEX] conf.name = "foobar" conf.classifiers = ["fake classifier"] expected_attrs.remove("name") expected_attrs.remove("classifiers") attrs = configure.standard_attributes(conf, get_options()) assert attrs == expected_attrs
def test_additional_tests_require(runner): """If there are provided tests_require, they should be mixed in.""" # we get runner-cov here becuase we provide a name conf = Config(name="test", test_runner=runner, tests_require=["my_thing"]) assert conf.tests_require == ["my_thing", runner, "{}-cov".format(runner)] assert conf.runner_args[-1] == "test" # change our name here, we should get our new name in runner_args conf.name = "changed" # also we can reset tests_require and they should re-populate conf.tests_require = ["my_thing"] conf._verify() assert conf.runner_args[-1] == "changed"
def test_invalid__feedback(capfd): """The user should receive some feedback when the value doesn't coerce.""" class TestObject(object): def __init__(self): self.str_count = 0 def __str__(self): self.str_count += 1 if self.str_count == 1: raise IOError else: return "test object" conf = Config(name="foo") coerce_patch = mock.patch.object( configure, "coerce_to_expected", return_value=TestObject(), ) with mock.patch.object(configure, "ask_for_value"): with coerce_patch: configure.set_value_in_config("name", conf, conf._KEYS) out, err = capfd.readouterr() assert "name as test object failed to verify. should be str" in err assert "name set to: 'test object'\n" == out
def test_site_defaults_mixin(move_home_pypackage): """Ensure the site defaults are mixed in if available.""" with open(move_home_pypackage, "w") as opensite: opensite.write(json.dumps({"author": "you!"})) conf = Config() assert conf.author == "you!"
def test_runner_args_with_tests_dir(runner): """If pytest or nose is used, the tests dir should be the last runner arg. When unittest is used, the tests_dir is injected into UNITTEST_TEMPLATE. """ conf = Config(test_runner=runner, tests_dir="somewhere") assert conf.runner_args[-1] == "somewhere"
def test_extras_require_mixin(): """Ensure you can provide both extras_require and X_requires.""" conf = Config( extras_require={"my_thing": ["foo"]}, feature_x_requires="bar", ) assert conf.extras_require == {"my_thing": ["foo"], "feature_x": ["bar"]}
def test_value_in_config__not_classifiers(capfd): """Any other key should be the same.""" conf = Config() with mock.patch.object(configure, "ask_for_value", return_value="Frank"): configure.set_value_in_config("author", conf, conf._KEYS) out, err = capfd.readouterr() assert out == "author set to: 'Frank'\n" assert not err
def test_value_in_config__classifiers(capfd): """The key 'classifiers' should be handled.""" conf = Config() with mock.patch.object(configure, "handle_classifiers", return_value="ok"): configure.set_value_in_config("classifiers", conf, conf._KEYS) out, err = capfd.readouterr() assert out == "classifiers set to: ['ok']\n" assert not err
def test_as_kwargs_finds_packages(): """The _as_kwargs property should use find_packages.""" conf = Config() with mock.patch.object(config, "find_packages", return_value=4) as patched: conf_args = conf._as_kwargs assert conf_args["packages"] == 4 patched.assert_called_once_with(exclude=["test", "tests"])
def test_verify_key__multiple__allowed(): """There are some keys where multiple types are allowed.""" conf = Config() conf.foo = 3.14 conf._verify_key("foo", (list, str)) assert conf.foo == [3.14] conf.foo = 3.14 conf._verify_key("foo", (str, list)) # assert order matters assert conf.foo == "3.14"
def test_metadata_excludes_set_once(): """Ensure you can only add to _metadata_excludes once.""" conf = Config() conf._metadata_exclusions.append("foo") conf._metadata_exclusions.append("foo") conf._metadata_exclusions.append("foo") conf._metadata_exclusions.append("bar") conf._metadata_exclusions.append("foo") conf._metadata_exclusions.append("bar") assert conf._metadata_exclusions == ["foo", "bar"]
def test_supplied_packages(): """Ensure the user can provide the packages list.""" conf = Config(packages="my_package") assert conf._packages_string() == ("packages=['my_package']", False)
def test_runner_string(runner): """Ensure the correct template is used for nose and pytest.""" conf = Config(test_runner=runner) template_str = conf._test_runner_string() assert "import {}".format(runner) in template_str