Skip to content

Commit

Permalink
tests: move more tests inside src/
Browse files Browse the repository at this point in the history
  • Loading branch information
karlicoss committed Nov 19, 2023
1 parent ddbb65f commit 7715b9f
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 73 deletions.
8 changes: 8 additions & 0 deletions src/promnesia/tests/common.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
import gc
import os
from typing import NoReturn

import pytest


def throw(x: Exception) -> NoReturn:
'''
like raise, but can be an expression...
'''
raise x


@pytest.fixture
def gc_control(gc_on: bool):
if gc_on:
Expand Down
161 changes: 90 additions & 71 deletions tests/config_tests.py → src/promnesia/tests/test_config.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,79 @@
import pytest
from contextlib import contextmanager
from pathlib import Path
from tempfile import TemporaryDirectory
from typing import Union, List

from ..common import Source
from ..config import import_config, Config


from more_itertools import ilen
from typing import Union, Iterable, List
import pytest

from promnesia.common import Source
from .common import throw


def make(body: str) -> Config:
with TemporaryDirectory() as td:
tdir = Path(td)
cp = tdir / 'cfg.py'
cp.write_text(body)
return import_config(cp)


@contextmanager
def with_config(cfg: Union[str, Config]):
from .. import config as C

from common import throw
assert not C.has()
cfg2: Config = make(cfg) if isinstance(cfg, str) else cfg
try:
C.instance = cfg2
assert C.has()
yield
finally:
C.reset()


def index(cfg: Union[str, Config], check=True) -> List[Exception]:
from ..__main__ import _do_index

with with_config(cfg):
errors = list(_do_index())
if check:
assert len(errors) == 0, errors
# visits = cfg.output_dir / 'promnesia.sqlite'
# TODO query visit count too
return errors


def test_minimal() -> None:
'''
Example of a smallest possible config, using a 'demo' source
'''
# import directly from promnesia, not promnesia.common
cfg = make('''
cfg = make(
'''
from promnesia import Source
from promnesia.sources import demo
SOURCES = [
Source(demo.index),
]
''')
'''
)
assert ilen(cfg.sources) == 1
assert all(isinstance(s, Source) for s in cfg.sources)
# todo output dirs?
index(cfg)


def test_sources_style() -> None:
def test_sources_style_1() -> None:
'''
Testing 'styles' of specifying sources
'''
cfg = make('''
cfg = make(
'''
from promnesia.common import Source
from promnesia.sources import demo
Expand Down Expand Up @@ -65,12 +108,16 @@ def test_sources_style() -> None:
# useful when arguments are somehow computed dynamically in config
Source(lambda: demo.index(count=10), name='lazy'),
]
''')
'''
)

srcs = [s if isinstance(s, Source) else throw(s) for s in cfg.sources]

[s1, s2, s3, s4, s5, s55, s6, s7, s77, s777] = srcs

# just a quick check to make sure tests import promnesia package correctly
# (depends on conftests settings)
assert type(srcs[0]).__module__ == 'promnesia.common', srcs
assert s1.name == 'explicit name'
assert s2.name == 'another name'
assert s3.name == 'demo'
Expand All @@ -80,7 +127,7 @@ def test_sources_style() -> None:
assert s6.name == 'demo'

# can't say 'cfg' as name is intended here but anyway
assert s7.name == 'cfg'
assert s7.name == 'cfg'
assert s77.name == 'cfg'
assert s777.name == 'lazy'

Expand All @@ -90,11 +137,12 @@ def test_sources_style() -> None:

# TODO ugh. allow not to have locator
# ideally you can construct a visit with a link and that's it
def test_sources_style_more():
def test_sources_style_2() -> None:
'''
Now, sources are not magic -- they are just functions emitting visits
'''
cfg = make('''
cfg = make(
'''
from typing import Iterable
from promnesia.common import Visit, Source, Loc
Expand Down Expand Up @@ -125,12 +173,13 @@ def index():
MyIndexer,
)
''')
'''
)
[s1, s2, s3] = [s if isinstance(s, Source) else throw(s) for s in cfg.sources]

assert s1.name == 'cfg' # TODO would be nice to guess 'my_indexer' instead...
assert s1.name == 'cfg' # TODO would be nice to guess 'my_indexer' instead...
assert s2.name == 'nice name'
assert s3.name == 'cfg' # TODO fix it, make MyIndexer?
assert s3.name == 'cfg' # TODO fix it, make MyIndexer?

index(cfg)

Expand All @@ -142,7 +191,8 @@ def test_sources_lazy():
Lazy sources could be useful to do some conditional magic or make more defensive against imports, excra configuration. You'll know when you need it ;)
'''

cfg = make('''
cfg = make(
'''
from promnesia.common import Source
def lazy():
Expand All @@ -153,14 +203,16 @@ def lazy():
SOURCES = [
lazy,
]
''')
'''
)
srcs = [s if isinstance(s, Source) else throw(s) for s in cfg.sources]
[s] = srcs

assert s.name == 'cfg' # TODO this should be fixed... but not a big deal
assert s.name == 'cfg' # TODO this should be fixed... but not a big deal

index(cfg)


# TODO later
# or like that:
# (i for i in lazy()),
Expand All @@ -173,15 +225,17 @@ def test_sources_errors() -> None:
'''
Testing defensiveness of config against various errors
'''
cfg = make('''
cfg = make(
'''
SOURCES = [
'non.existing.module',
lambda: bad.attribute,
'promnesia.sources.demo',
]
''')
'''
)

# nothing fails so far! It's defensive!
srcs = list(cfg.sources)
Expand All @@ -193,79 +247,44 @@ def test_sources_errors() -> None:
assert isinstance(s2, Source)

errors = index(cfg, check=False)
assert len(errors) == 2 # errors simply propagate

assert len(errors) == 2 # errors simply propagate


def test_no_sources():
cfg = make('''
''')
def test_no_sources() -> None:
cfg = make(
'''
'''
)
# raises because no SOURCES
with pytest.raises(RuntimeError):
list(cfg.sources)


def test_empty_sources():
cfg = make('''
def test_empty_sources() -> None:
cfg = make(
'''
SOURCES = []
''')
'''
)
# raises because empty SOURCES
with pytest.raises(RuntimeError):
list(cfg.sources)



def test_legacy():
cfg = make('''
def test_legacy() -> None:
cfg = make(
'''
from promnesia.common import Source
from promnesia.sources import demo
INDEXERS = [
Source(demo.index, src='legacy name'),
]
''')
'''
)

[s1] = cfg.sources
assert isinstance(s1, Source)

assert s1.name == 'legacy name'

index(cfg)


from pathlib import Path
from tempfile import TemporaryDirectory

from promnesia.config import import_config, Config


def make(body: str) -> Config:
with TemporaryDirectory() as td:
tdir = Path(td)
cp = tdir / 'cfg.py'
cp.write_text(body)
return import_config(cp)


from contextlib import contextmanager
@contextmanager
def with_config(cfg: Union[str, Config]):
import promnesia.config as C
assert not C.has()
cfg2: Config = make(cfg) if isinstance(cfg, str) else cfg
try:
C.instance = cfg2
assert C.has()
yield
finally:
C.reset()


def index(cfg: Union[str, Config], check=True) -> List[Exception]:
from promnesia.__main__ import _do_index
with with_config(cfg):
errors = list(_do_index())
if check:
assert len(errors) == 0, errors
# visits = cfg.output_dir / 'promnesia.sqlite'
# TODO query visit count too
return errors
2 changes: 1 addition & 1 deletion tests/indexer_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@

from promnesia.common import Visit, Source, Loc, Res, DbVisit, _is_windows
from promnesia.extract import extract_visits
from promnesia.tests.test_config import with_config

from common import tdata, reset_hpi_modules
from config_tests import with_config


# TODO need to expire dbcache in tests..
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ commands =
{envpython} -m my.core module install my.google.takeout.parser
{envpython} -m pytest tests {posargs}
# TODO gradually move tests inside the package
{envpython} -m pytest --import-mode=importlib --pyargs {[testenv]package_name}.tests
{envpython} -m pytest --pyargs {[testenv]package_name}.tests


[testenv:end2end]
Expand Down

0 comments on commit 7715b9f

Please sign in to comment.