general: move most core tests inside my.core.tests package
- distributes tests alongside the package, might be convenient for package users - removes some weird indirection (e.g. dummy test files improting tests from modules) - makes the command line for tests cleaner (e.g. no need to remember to manually add files to tox.ini) - tests automatically covered by mypy (so makes mypy runs cleaner and ultimately better coverage) The (vague) convention is - tests/somemodule.py -- testing my.core.somemodule, contains tests directly re - tests/test_something.py -- testing a specific feature, e.g. test_get_files.py tests get_files methon only
This commit is contained in:
parent
04d976f937
commit
075f0df2fb
18 changed files with 77 additions and 102 deletions
|
@ -1,164 +0,0 @@
|
|||
import os
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from my.core.compat import windows
|
||||
from my.core.common import get_files
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
# hack to replace all /tmp with 'real' tmp dir
|
||||
# not ideal, but makes tests more concise
|
||||
def _get_files(x, *args, **kwargs):
|
||||
import my.core.common as C
|
||||
def repl(x):
|
||||
if isinstance(x, str):
|
||||
return x.replace('/tmp', TMP)
|
||||
elif isinstance(x, Path):
|
||||
assert x.parts[:2] == (os.sep, 'tmp') # meh
|
||||
return Path(TMP) / Path(*x.parts[2:])
|
||||
else:
|
||||
# iterable?
|
||||
return [repl(i) for i in x]
|
||||
|
||||
x = repl(x)
|
||||
res = C.get_files(x, *args, **kwargs)
|
||||
return tuple(Path(str(i).replace(TMP, '/tmp')) for i in res) # hack back for asserts..
|
||||
|
||||
|
||||
if not TYPE_CHECKING:
|
||||
get_files = _get_files
|
||||
|
||||
|
||||
def test_single_file() -> None:
|
||||
'''
|
||||
Regular file path is just returned as is.
|
||||
'''
|
||||
|
||||
"Exception if it doesn't exist"
|
||||
with pytest.raises(Exception):
|
||||
get_files('/tmp/hpi_test/file.ext')
|
||||
|
||||
|
||||
create('/tmp/hpi_test/file.ext')
|
||||
|
||||
'''
|
||||
Couple of things:
|
||||
1. Return type is a tuple, it's friendlier for hashing/caching
|
||||
2. It always return pathlib.Path instead of plain strings
|
||||
'''
|
||||
assert get_files('/tmp/hpi_test/file.ext') == (
|
||||
Path('/tmp/hpi_test/file.ext'),
|
||||
)
|
||||
|
||||
|
||||
"if the path starts with ~, we expand it"
|
||||
if not windows: # windows dowsn't have bashrc.. ugh
|
||||
assert get_files('~/.bashrc') == (
|
||||
Path('~').expanduser() / '.bashrc',
|
||||
)
|
||||
|
||||
|
||||
def test_multiple_files() -> None:
|
||||
'''
|
||||
If you pass a directory/multiple directories, it flattens the contents
|
||||
'''
|
||||
create('/tmp/hpi_test/dir1/')
|
||||
create('/tmp/hpi_test/dir1/zzz')
|
||||
create('/tmp/hpi_test/dir1/yyy')
|
||||
# create('/tmp/hpi_test/dir1/whatever/') # TODO not sure about this... should really allow extra dirs
|
||||
create('/tmp/hpi_test/dir2/')
|
||||
create('/tmp/hpi_test/dir2/mmm')
|
||||
create('/tmp/hpi_test/dir2/nnn')
|
||||
create('/tmp/hpi_test/dir3/')
|
||||
create('/tmp/hpi_test/dir3/ttt')
|
||||
|
||||
assert get_files([
|
||||
Path('/tmp/hpi_test/dir3'), # it takes in Path as well as str
|
||||
'/tmp/hpi_test/dir1',
|
||||
]) == (
|
||||
# the paths are always returned in sorted order (unless you pass sort=False)
|
||||
Path('/tmp/hpi_test/dir1/yyy'),
|
||||
Path('/tmp/hpi_test/dir1/zzz'),
|
||||
Path('/tmp/hpi_test/dir3/ttt'),
|
||||
)
|
||||
|
||||
|
||||
def test_explicit_glob() -> None:
|
||||
'''
|
||||
You can pass a glob to restrict the extensions
|
||||
'''
|
||||
|
||||
create('/tmp/hpi_test/file_3.zip')
|
||||
create('/tmp/hpi_test/file_2.zip')
|
||||
create('/tmp/hpi_test/ignoreme')
|
||||
create('/tmp/hpi_test/file.zip')
|
||||
|
||||
# todo walrus operator would be great here...
|
||||
expected = (
|
||||
Path('/tmp/hpi_test/file_2.zip'),
|
||||
Path('/tmp/hpi_test/file_3.zip'),
|
||||
)
|
||||
assert get_files('/tmp/hpi_test', 'file_*.zip') == expected
|
||||
|
||||
"named argument should work too"
|
||||
assert get_files('/tmp/hpi_test', glob='file_*.zip') == expected
|
||||
|
||||
|
||||
def test_implicit_glob() -> None:
|
||||
'''
|
||||
Asterisc in the path results in globing too.
|
||||
'''
|
||||
# todo hopefully that makes sense? dunno why would anyone actually rely on asteriscs in names..
|
||||
# this is very convenient in configs, so people don't have to use some special types
|
||||
|
||||
create('/tmp/hpi_test/123/')
|
||||
create('/tmp/hpi_test/123/dummy')
|
||||
create('/tmp/hpi_test/123/file.zip')
|
||||
create('/tmp/hpi_test/456/')
|
||||
create('/tmp/hpi_test/456/dummy')
|
||||
create('/tmp/hpi_test/456/file.zip')
|
||||
|
||||
assert get_files(['/tmp/hpi_test/*/*.zip']) == (
|
||||
Path('/tmp/hpi_test/123/file.zip'),
|
||||
Path('/tmp/hpi_test/456/file.zip'),
|
||||
)
|
||||
|
||||
|
||||
def test_no_files() -> None:
|
||||
'''
|
||||
Test for empty matches. They work, but should result in warning
|
||||
'''
|
||||
assert get_files('') == ()
|
||||
|
||||
# todo test these for warnings?
|
||||
assert get_files([]) == ()
|
||||
assert get_files('bad*glob') == ()
|
||||
|
||||
|
||||
# TODO not sure if should uniquify if the filenames end up same?
|
||||
# TODO not sure about the symlinks? and hidden files?
|
||||
|
||||
import tempfile
|
||||
TMP = tempfile.gettempdir()
|
||||
test_path = Path(TMP) / 'hpi_test'
|
||||
|
||||
def setup():
|
||||
teardown()
|
||||
test_path.mkdir()
|
||||
|
||||
|
||||
def teardown():
|
||||
import shutil
|
||||
if test_path.is_dir():
|
||||
shutil.rmtree(test_path)
|
||||
|
||||
|
||||
def create(f: str) -> None:
|
||||
# in test body easier to use /tmp regardless the OS...
|
||||
f = f.replace('/tmp', TMP)
|
||||
if f.endswith('/'):
|
||||
Path(f).mkdir()
|
||||
else:
|
||||
Path(f).touch()
|
Loading…
Add table
Add a link
Reference in a new issue