def test_get_package_tree_package_path(mocker, package_omit, exclude): path = Path('foobar') cfg = Configuration(package_paths=[path], package_omit=package_omit) tree = Directory( path=None, entries={ "foobar": Directory( path="foobar/", entries={ "__init__.py": File( ('foobar', '__init__.py'), None, None, ), "foo.py": File( ('foobar', 'foo.py'), None, None, ), "bar.py": File( ('foobar', 'bar.py'), None, None, ), }, ), }, ) fltmock = mocker.patch.object(Directory, 'from_local_tree', return_value=tree) assert cfg.get_package_tree() == tree fltmock.assert_called_once_with(path, exclude=exclude)
def test_resolve_paths_require_dir_not_a_dir(monkeypatch, tmp_path): create_file(tmp_path / 'path/foo') create_file(tmp_path / 'path/bar') monkeypatch.chdir(tmp_path) cfg = Configuration(src_dirs="foo,bar,quux") with pytest.raises(UserInputError) as excinfo: cfg.resolve_paths(Path('path/foo.cfg')) assert str(excinfo.value) \ == f"src_dir: not a directory: '{tmp_path}/path/foo'"
def test_resolve_paths_nonexistent(monkeypatch, tmp_path): create_file(tmp_path / 'path/foo') create_file(tmp_path / 'path/bar') monkeypatch.chdir(tmp_path) cfg = Configuration(package_paths="foo,bar,quux") with pytest.raises(UserInputError) as excinfo: cfg.resolve_paths(Path('path/foo.cfg')) assert str(excinfo.value) == ( f"package: no such file or directory: '{tmp_path}/path/quux'")
def test_from_file(path): datafile = path.with_suffix('.json') try: data = json.loads(datafile.read_text()) except FileNotFoundError: cfg = None else: cfg = Configuration.parse_obj(data) assert Configuration.from_file(path) == cfg
def test_from_config_file_no_arg(mocker, cfgdict): cdmock = mocker.patch('check_wheel_contents.config.ConfigDict', autospec=True) cdmock.find_default.return_value = cfgdict if cfgdict is None: expected = Configuration() else: expected = Configuration.from_config_dict(cfgdict) cfg = Configuration.from_config_file() assert cfg == expected assert cdmock.method_calls == [mocker.call.find_default()]
def test_get_package_tree_package_path_src_dir_conflict(monkeypatch, tmp_path): create_file(tmp_path / 'bar/__init__.py') create_file(tmp_path / 'bar/quux.py') create_file(tmp_path / 'bar/glarch.py') create_file(tmp_path / 'src/bar/gnusto.py') monkeypatch.chdir(tmp_path) cfg = Configuration(package_paths=[Path('bar')], src_dirs=[Path('src')]) with pytest.raises(UserInputError) as excinfo: cfg.get_package_tree() assert str(excinfo.value) == ( "`--src-dir src` adds 'bar' to file tree, but it is already present" " from prior --package or --src-dir option")
def test_from_config_file(mocker, cfgdict): cdmock = mocker.patch('check_wheel_contents.config.ConfigDict', autospec=True) cdmock.from_file.return_value = cfgdict if cfgdict is None: expected = Configuration() else: expected = Configuration.from_config_dict(cfgdict) path = '/foo/bar/quux' cfg = Configuration.from_config_file(path) assert cfg == expected assert cdmock.method_calls == [mocker.call.from_file(Path(path))]
def test_get_package_tree_package_path_src_dir_conflict(fs): fs.create_file('/usr/src/project/bar/__init__.py') fs.create_file('/usr/src/project/bar/quux.py') fs.create_file('/usr/src/project/bar/glarch.py') fs.create_file('/usr/src/project/src/bar/gnusto.py') fs.cwd = '/usr/src/project' cfg = Configuration(package_paths=[Path('bar')], src_dirs=[Path('src')]) with pytest.raises(UserInputError) as excinfo: cfg.get_package_tree() assert str(excinfo.value) == ( "`--src-dir src` adds 'bar' to file tree, but it is already present" " from prior --package or --src-dir option")
def test_from_config_file_no_arg(mocker, cfg): """ Test that calling ``Configuration.from_config_file()`` with no arguments delegates to ``Configuration.find_default()`` and that `None` return values are converted to a default-valued `Configuration` """ mock = mocker.patch.object(Configuration, 'find_default', return_value=cfg) if cfg is None: expected = Configuration() else: expected = cfg assert Configuration.from_config_file() == expected mock.assert_called_once_with()
def test_from_file_in_project(cfgname, cfgsrc, tmp_path): project_dir = tmp_path / "project" copytree(PROJECT_TREE, project_dir) cfgpath = project_dir / cfgname cfgpath.write_text(cfgsrc) assert Configuration.from_file(cfgpath) == Configuration( select={Check.W001, Check.W002}, ignore={Check.W003, Check.W004}, toplevel=["foo.py", "quux"], package_paths=[project_dir / 'bar'], src_dirs=[project_dir / 'src'], package_omit=["__pycache__", "test/data"], )
def test_from_config_file(mocker, cfg): """ Test that calling ``Configuration.from_config_file(path)`` delegates to ``Configuration.from_file()`` and that `None` return values are converted to a default-valued `Configuration` """ mock = mocker.patch.object(Configuration, 'from_file', return_value=cfg) if cfg is None: expected = Configuration() else: expected = cfg path = '/foo/bar/quux' assert Configuration.from_config_file(path) == expected mock.assert_called_once_with(Path(path))
def test_from_config_dict_calls(mocker): cd = mocker.Mock( ConfigDict, **{ "get_comma_list.return_value": ["foo.py", "bar/"], "get_check_set.return_value": sentinel.CHECK_SET, "get_path_list.return_value": sentinel.PATH_LIST, }, ) cfg = Configuration.from_config_dict(cd) assert attr.asdict(cfg, recurse=False) == { "select": sentinel.CHECK_SET, "ignore": sentinel.CHECK_SET, "toplevel": ["foo.py", "bar"], "package_paths": sentinel.PATH_LIST, "src_dirs": sentinel.PATH_LIST, "package_omit": ["foo.py", "bar/"], } assert cd.get_check_set.call_count == 2 cd.get_check_set.assert_any_call("select") cd.get_check_set.assert_any_call("ignore") assert cd.get_comma_list.call_count == 2 cd.get_comma_list.assert_any_call("toplevel") cd.get_comma_list.assert_any_call("package_omit") assert cd.get_path_list.call_count == 2 cd.get_path_list.assert_any_call("package") cd.get_path_list.assert_any_call("src_dir")
def test_find_default(files, cfg, monkeypatch, tmp_path): for path, text in files.items(): create_file(tmp_path / path, text) pwd = tmp_path / "usr" / "src" / "project" pwd.mkdir(parents=True, exist_ok=True) monkeypatch.chdir(pwd) assert Configuration.find_default() == cfg
def test_from_command_options_default(): cfg = Configuration.from_command_options() assert cfg.dict() == { "select": None, "ignore": None, "toplevel": None, "package_paths": None, "src_dirs": None, "package_omit": None, }
def test_from_command_options_default(): cfg = Configuration.from_command_options() assert attr.asdict(cfg, recurse=False) == { "select": None, "ignore": None, "toplevel": None, "package_paths": None, "src_dirs": None, "package_omit": None, }
def test_get_package_tree_package_path_and_src_dir(monkeypatch, tmp_path): create_file(tmp_path / 'src/foo.py') create_file(tmp_path / 'bar/__init__.py') create_file(tmp_path / 'bar/quux.py') create_file(tmp_path / 'bar/glarch.py') monkeypatch.chdir(tmp_path) cfg = Configuration(package_paths=[Path('bar')], src_dirs=[Path('src')]) assert cfg.get_package_tree() == Directory( path=None, entries={ "foo.py": File(('foo.py', ), None, None), "bar": Directory( path='bar/', entries={ "__init__.py": File(('bar', '__init__.py'), None, None), "quux.py": File(('bar', 'quux.py'), None, None), "glarch.py": File(('bar', 'glarch.py'), None, None), }, ), }, )
def test_get_package_tree_package_path_and_src_dir(fs): fs.create_file('/usr/src/project/src/foo.py') fs.create_file('/usr/src/project/bar/__init__.py') fs.create_file('/usr/src/project/bar/quux.py') fs.create_file('/usr/src/project/bar/glarch.py') fs.cwd = '/usr/src/project' cfg = Configuration(package_paths=[Path('bar')], src_dirs=[Path('src')]) assert cfg.get_package_tree() == Directory( path=None, entries={ "foo.py": File(('foo.py', ), None, None), "bar": Directory( path='bar/', entries={ "__init__.py": File(('bar', '__init__.py'), None, None), "quux.py": File(('bar', 'quux.py'), None, None), "glarch.py": File(('bar', 'glarch.py'), None, None), }, ), }, )
def test_from_command_options(toplevel_in, toplevel_out, package_in, package_out, src_dir_in, src_dir_out, package_omit_in, package_omit_out): cfg = Configuration.from_command_options( select=sentinel.SELECT, ignore=sentinel.IGNORE, toplevel=toplevel_in, package=package_in, src_dir=src_dir_in, package_omit=package_omit_in, ) assert attr.asdict(cfg, recurse=False) == { "select": sentinel.SELECT, "ignore": sentinel.IGNORE, "toplevel": toplevel_out, "package_paths": package_out, "src_dirs": src_dir_out, "package_omit": package_omit_out, }
def test_from_command_options(toplevel_in, toplevel_out, package_in, package_out, src_dir_in, src_dir_out, package_omit_in, package_omit_out): cfg = Configuration.from_command_options( select={Check.W001, Check.W002}, ignore={Check.W003, Check.W004}, toplevel=toplevel_in, package=package_in, src_dir=src_dir_in, package_omit=package_omit_in, ) assert cfg.dict() == { "select": {Check.W001, Check.W002}, "ignore": {Check.W003, Check.W004}, "toplevel": toplevel_out, "package_paths": package_out, "src_dirs": src_dir_out, "package_omit": package_omit_out, }
def test_resolve_paths(data, expected, monkeypatch, tmp_path): for path in [ 'usr/src/project/path/foo', 'usr/src/project/path/bar', 'usr/src/project/path/bar,baz', 'usr/src/project/path/test/data', ]: create_file(tmp_path / path) monkeypatch.chdir(tmp_path / "usr" / "src" / "project") if isinstance(data.get("package"), str): data["package"] = data["package"].format(tmp_path=tmp_path) elif isinstance(data.get("package"), list): data["package"] = [ p.format(tmp_path=tmp_path) for p in data["package"] ] cfg = Configuration.parse_obj(data) cfg.resolve_paths(Path('path/foo.cfg')) if expected is not None: expected = [tmp_path / p for p in expected] assert cfg.package_paths == expected
from check_wheel_contents.checks import Check from check_wheel_contents.config import Configuration from check_wheel_contents.filetree import Directory, File def test_defaults(): checker = WheelChecker() assert attr.asdict(checker, recurse=False) == { "selected": set(Check), "toplevel": None, "pkgtree": None, } @pytest.mark.parametrize('kwargs,cfg', [ ({}, Configuration()), ( { "configpath": "custom.cfg", "select": {Check.W001, Check.W002, Check.W003, Check.W004}, }, Configuration( select={Check.W001, Check.W002, Check.W003, Check.W004}, ignore={Check.W001, Check.W002}, ), ), ( { "configpath": None }, Configuration(select={Check.W001, Check.W002}),
def test_from_file_bad_tool_section(): path = DATA_DIR / 'bad-tool-sect.toml' with pytest.raises(UserInputError) as excinfo: Configuration.from_file(path) assert str(excinfo.value).startswith(f'{path}: ')
def test_convert_comma_list(data, expected): cfg = Configuration.parse_obj(data) assert cfg.package_omit == expected
def test_convert_comma_list_error(field, value): if field in ('toplevel', 'package_omit') and value in ([42], ["foo", 42]): pytest.skip("pydantic allows int input to string fields") with pytest.raises(ValidationError): Configuration.parse_obj({field: value})
def test_convert_check_set(data, expected): cfg = Configuration.parse_obj(data) assert cfg.select == expected
def test_get_package_tree_both_none(): cfg = Configuration(package_paths=None, src_dirs=None) assert cfg.get_package_tree() is None
def test_get_selected_checks(select, ignore, expected): select_copy = select and select.copy() cfg = Configuration(select=select, ignore=ignore) assert cfg.get_selected_checks() == expected assert cfg.select == select_copy
def test_convert_check_set_error(field, value, badbit): with pytest.raises(ValidationError) as excinfo: Configuration.parse_obj({field: value}) assert f'Unknown/invalid check prefix: {badbit!r}' in str(excinfo.value)
def test_from_config_dict(cfgdict, expected): assert Configuration.from_config_dict(cfgdict) == expected
cd.get_comma_list.assert_any_call("package_omit") assert cd.get_path_list.call_count == 2 cd.get_path_list.assert_any_call("package") cd.get_path_list.assert_any_call("src_dir") BASE = Path(__file__).with_name('data') / 'project-trees' / 'from-config-dict' @pytest.mark.parametrize('cfgdict,expected', [ ( ConfigDict(configpath=Path('foo.cfg'), data={}), Configuration( select=None, ignore=None, toplevel=None, package_paths=None, src_dirs=None, package_omit=None, ), ), ( ConfigDict( configpath=BASE / 'cfg.ini', data={ "select": "W001,W002", "ignore": "W003,W004", "toplevel": "foo.py,bar/", "package": "foobar", "src_dir": "src", "package_omit": "__pycache__,test/data", },