Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TST: use sybil for doctests #250

Merged
merged 18 commits into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion audbackend/core/backend/minio.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class Minio(Base):
>>> auth = ("Q3AM3UQ867SPQQA43P2F", "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG")
>>> repository = "my-data" + audeer.uid()
>>> Minio.create(host, repository, authentication=auth)
>>> file = audeer.touch("file.txt")
>>> file = audeer.touch("src.txt")
>>> backend = Minio(host, repository, authentication=auth)
>>> try:
... with backend:
Expand Down
104 changes: 71 additions & 33 deletions audbackend/core/conftest.py
Original file line number Diff line number Diff line change
@@ -1,50 +1,88 @@
import datetime
import os
import tempfile
import doctest

import pytest
import sybil
from sybil.parsers.rest import DocTestParser

import audeer

import audbackend


class DoctestFileSystem(audbackend.backend.FileSystem):
def _date(
self,
path: str,
) -> str:
# Collect doctests
pytest_collect_file = sybil.Sybil(
parsers=[DocTestParser(optionflags=doctest.ELLIPSIS)],
patterns=["*.py"],
fixtures=[
"filesystem",
"mock_date",
"mock_owner",
"mock_repr",
"prepare_docstring_tests",
],
).pytest()


@pytest.fixture(scope="function")
def filesystem(tmpdir):
"""Filesystem backend.

A repository with unique name is created
for the filesystem backend.
The filesystem backend is marked as opened
and returned.

Args:
tmpdir: tmpdir fixture

Returns:
filesystem backend object

"""
repo = f"repo-{audeer.uid()[:8]}"
host = audeer.mkdir(tmpdir, "host")
audeer.mkdir(host, repo)
backend = audbackend.backend.FileSystem(host, repo)
backend.opened = True
yield backend


@pytest.fixture(scope="function")
def mock_date():
r"""Custom date method to return a fixed date."""

def date(path: str, version: str = None) -> str:
date = datetime.datetime(1991, 2, 20)
date = audbackend.core.utils.date_format(date)
return date

def _owner(
self,
path: str,
) -> str:
yield date


@pytest.fixture(scope="function")
def mock_owner():
r"""Custom owner method to return a fixed owner."""

def owner(path: str, version: str = None) -> str:
return "doctest"

yield owner


@pytest.fixture(scope="function")
def mock_repr():
"""Custom __repr__ method to return fixed string."""
return 'audbackend.interface.FileSystem("host", "repo")'


@pytest.fixture(scope="function", autouse=True)
def prepare_docstring_tests(doctest_namespace):
with tempfile.TemporaryDirectory() as tmp:
# Change to tmp dir
current_dir = os.getcwd()
os.chdir(tmp)
# Prepare backend
audeer.mkdir("host")
audbackend.backend.FileSystem.create("host", "repo")
# Provide example file `src.txt`
audeer.touch("src.txt")
# Provide DoctestFileSystem as FileSystem,
# and audbackend
# in docstring examples
doctest_namespace["DoctestFileSystem"] = DoctestFileSystem
doctest_namespace["audbackend"] = audbackend

yield

# Remove backend
audbackend.backend.FileSystem.delete("host", "repo")
# Change back to current dir
os.chdir(current_dir)
def prepare_docstring_tests(tmpdir, monkeypatch):
r"""Code to be run before each doctest."""
# Change to tmp dir
monkeypatch.chdir(tmpdir)

# Provide example file `src.txt`
audeer.touch("src.txt")

yield
7 changes: 4 additions & 3 deletions audbackend/core/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ class BackendError(Exception):
.. Prepare backend and interface for docstring examples

>>> import audeer
>>> audeer.rmdir("host", "repo")
>>> _ = audeer.mkdir("host", "repo")
>>> import audbackend

Examples:
>>> backend = audbackend.backend.FileSystem("host", "repo")
>>> host = audeer.mkdir("host")
>>> audbackend.backend.FileSystem.create(host, "repo")
>>> backend = audbackend.backend.FileSystem(host, "repo")
>>> backend.open()
>>> try:
... interface = audbackend.interface.Unversioned(backend)
Expand Down
21 changes: 1 addition & 20 deletions audbackend/core/interface/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def backend(self) -> Backend:
backend object

..
>>> import audbackend
>>> backend = audbackend.backend.FileSystem("host", "repo")
>>> interface = Base(backend)

Expand All @@ -52,10 +53,6 @@ def host(self) -> str:

Returns: host path

..
>>> backend = audbackend.backend.FileSystem("host", "repo")
>>> interface = Base(backend)

Examples:
>>> interface.host
'host'
Expand All @@ -82,10 +79,6 @@ def join(
or does not start with ``'/'``,
or if joined path contains invalid character

..
>>> backend = audbackend.backend.FileSystem("host", "repo")
>>> interface = Base(backend)

Examples:
>>> interface.join("/", "file.txt")
'/file.txt'
Expand All @@ -104,10 +97,6 @@ def repository(self) -> str:
Returns:
repository name

..
>>> backend = audbackend.backend.FileSystem("host", "repo")
>>> interface = Base(backend)

Examples:
>>> interface.repository
'repo'
Expand All @@ -122,10 +111,6 @@ def sep(self) -> str:
Returns:
file separator

..
>>> backend = audbackend.backend.FileSystem("host", "repo")
>>> interface = Base(backend)

Examples:
>>> interface.sep
'/'
Expand All @@ -149,10 +134,6 @@ def split(
ValueError: if ``path`` does not start with ``'/'`` or
does not match ``'[A-Za-z0-9/._-]+'``

..
>>> backend = audbackend.backend.FileSystem("host", "repo")
>>> interface = Base(backend)

Examples:
>>> interface.split("/")
('/', '')
Expand Down
14 changes: 9 additions & 5 deletions audbackend/core/interface/maven.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,17 @@ class Maven(Versioned):
...
as extensions

..
>>> import audbackend
>>> import audeer

Examples:
>>> file = "src.txt"
>>> backend = audbackend.backend.FileSystem("host", "repo")
>>> host = audeer.mkdir("host")
>>> audbackend.backend.FileSystem.create(host, "repo")
>>> backend = audbackend.backend.FileSystem(host, "repo")
>>> backend.open()
>>> interface = Maven(backend)
>>> file = "src.txt"
>>> interface.put_archive(".", "/sub/archive.zip", "1.0.0", files=[file])
>>> for version in ["1.0.0", "2.0.0"]:
... interface.put_file(file, "/file.txt", version)
Expand Down Expand Up @@ -139,9 +145,7 @@ def ls(
RuntimeError: if backend was not opened

..
>>> backend = audbackend.backend.FileSystem("host", "repo")
>>> backend.open()
>>> interface = Maven(backend)
>>> interface = Maven(filesystem)

Examples:
>>> file = "src.txt"
Expand Down
Loading