Skip to content

Commit

Permalink
Dedicated tests of file providers
Browse files Browse the repository at this point in the history
  • Loading branch information
jwodder committed Dec 13, 2023
1 parent 17e4c19 commit f19ce41
Show file tree
Hide file tree
Showing 2 changed files with 174 additions and 7 deletions.
13 changes: 8 additions & 5 deletions src/versioningit/onbuild.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,17 @@ def open(
p = self.provider.build_dir / path
if ("w" in mode or "a" in mode) and path not in self.provider.modified:
self.provider.modified.add(path)
p.parent.mkdir(parents=True, exist_ok=True)
# If setuptools is using hard links for the build files, undo that
# for this file:
with suppress(FileNotFoundError):
try:
p.unlink()
p.parent.mkdir(parents=True, exist_ok=True)
if not p.exists() and "a" in mode:
with suppress(FileNotFoundError):
shutil.copy2(self.provider.src_dir / self.source_path, p)
except FileNotFoundError:
pass
else:
if "a" in mode:
with suppress(FileNotFoundError):
shutil.copy2(self.provider.src_dir / self.source_path, p)
return p.open(mode=mode, encoding=encoding, errors=errors, newline=newline)


Expand Down
168 changes: 166 additions & 2 deletions test/test_methods/test_onbuild.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
from __future__ import annotations
from datetime import datetime, timezone
import os
from pathlib import Path
from shutil import copytree
from typing import Any
from typing import TYPE_CHECKING, Any
import pytest
from versioningit.errors import ConfigError
from versioningit.onbuild import SetuptoolsFileProvider, replace_version_onbuild
from versioningit.onbuild import (
FileProvider,
HatchFileProvider,
SetuptoolsFileProvider,
replace_version_onbuild,
)

if TYPE_CHECKING:
from typing_extensions import Literal

DATA_DIR = Path(__file__).parent.with_name("data")

Expand Down Expand Up @@ -251,3 +260,158 @@ def test_replace_version_onbuild_version_not_captured(tmp_path: Path) -> None:
)
for p in tmp_path.iterdir():
assert p.read_bytes() == (src_dir / p.name).read_bytes()


@pytest.mark.parametrize("is_source", [False, True])
@pytest.mark.parametrize(
"mode,after",
[
("w", "Coconut\n"),
("a", "Apple\nCoconut\n"),
],
)
def test_setuptools_file_provider_read_write_read(
is_source: bool, mode: Literal["w", "a"], after: str, tmp_path: Path
) -> None:
src_dir = tmp_path / "src"
src_dir.mkdir()
build_dir = tmp_path / "build"
build_dir.mkdir()
(src_dir / "apple.txt").write_text("Apple\n")
(build_dir / "apple.txt").write_text("Macintosh\n")
(build_dir / "banana.txt").write_text("Banana\n")
provider = SetuptoolsFileProvider(src_dir=src_dir, build_dir=build_dir)
file = provider.get_file(
source_path="apple.txt", build_path="banana.txt", is_source=is_source
)
with file.open() as fp:
contents = fp.read()
if is_source:
assert contents == "Macintosh\n"
else:
assert contents == "Banana\n"
with file.open(mode) as fp:
fp.write("Coconut\n")
with file.open() as fp:
contents = fp.read()
assert contents == after
assert (src_dir / "apple.txt").read_text() == "Apple\n"
if is_source:
assert (build_dir / "apple.txt").read_text() == after
assert (build_dir / "banana.txt").read_text() == "Banana\n"
else:
assert (build_dir / "apple.txt").read_text() == "Macintosh\n"
assert (build_dir / "banana.txt").read_text() == after


@pytest.mark.parametrize("is_source", [False, True])
@pytest.mark.parametrize(
"mode,after",
[
("w", "Coconut\n"),
("a", "Apple\nCoconut\n"),
],
)
def test_setuptools_file_provider_read_write_read_hard_link(
is_source: bool, mode: Literal["w", "a"], after: str, tmp_path: Path
) -> None:
src_dir = tmp_path / "src"
src_dir.mkdir()
build_dir = tmp_path / "build"
build_dir.mkdir()
(src_dir / "apple.txt").write_text("Apple\n")
if is_source:
os.link(src_dir / "apple.txt", build_dir / "apple.txt")
else:
os.link(src_dir / "apple.txt", build_dir / "banana.txt")
provider = SetuptoolsFileProvider(src_dir=src_dir, build_dir=build_dir)
file = provider.get_file(
source_path="apple.txt", build_path="banana.txt", is_source=is_source
)
with file.open() as fp:
contents = fp.read()
assert contents == "Apple\n"
with file.open(mode) as fp:
fp.write("Coconut\n")
with file.open() as fp:
contents = fp.read()
assert contents == after
assert (src_dir / "apple.txt").read_text() == "Apple\n"
if is_source:
assert (build_dir / "apple.txt").read_text() == after
assert not (build_dir / "banana.txt").exists()
else:
assert not (build_dir / "apple.txt").exists()
assert (build_dir / "banana.txt").read_text() == after


@pytest.mark.parametrize("is_source", [False, True])
@pytest.mark.parametrize(
"mode,after",
[
("w", "Banana\n"),
("a", "Apple\nBanana\n"),
],
)
def test_hatch_file_provider_read_write_read(
is_source: bool, mode: Literal["w", "a"], after: str, tmp_path: Path
) -> None:
src_dir = tmp_path / "src"
src_dir.mkdir()
tmp_dir = tmp_path / "tmp"
tmp_dir.mkdir()
(src_dir / "apple.txt").write_text("Apple\n")
provider = HatchFileProvider(src_dir=src_dir, tmp_dir=tmp_dir)
file = provider.get_file(
source_path="apple.txt", build_path="banana.txt", is_source=is_source
)
with file.open() as fp:
contents = fp.read()
assert contents == "Apple\n"
with file.open(mode) as fp:
fp.write("Banana\n")
with file.open() as fp:
contents = fp.read()
assert contents == after
assert (src_dir / "apple.txt").read_text() == "Apple\n"
if is_source:
assert (tmp_dir / "apple.txt").read_text() == after
assert not (tmp_dir / "banana.txt").exists()
else:
assert not (tmp_dir / "apple.txt").exists()
assert (tmp_dir / "banana.txt").read_text() == after


@pytest.mark.parametrize("backend", ["setuptools", "hatch"])
@pytest.mark.parametrize("is_source", [False, True])
@pytest.mark.parametrize("mode", ["w", "a"])
def test_file_provider_write_new_file(
backend: str, is_source: bool, mode: Literal["w", "a"], tmp_path: Path
) -> None:
src_dir = tmp_path / "src"
src_dir.mkdir()
build_dir = tmp_path / "build"
build_dir.mkdir()
provider: FileProvider
if backend == "setuptools":
provider = SetuptoolsFileProvider(src_dir=src_dir, build_dir=build_dir)
else:
assert backend == "hatch"
provider = HatchFileProvider(src_dir=src_dir, tmp_dir=build_dir)
file = provider.get_file(
source_path="green/apple.txt",
build_path="yellow/banana.txt",
is_source=is_source,
)
with file.open(mode) as fp:
fp.write("Coconut\n")
with file.open() as fp:
contents = fp.read()
assert contents == "Coconut\n"
assert not (src_dir / "green" / "apple.txt").exists()
if is_source:
assert (build_dir / "green" / "apple.txt").read_text() == "Coconut\n"
assert not (build_dir / "yellow" / "banana.txt").exists()
else:
assert not (build_dir / "green" / "apple.txt").exists()
assert (build_dir / "yellow" / "banana.txt").read_text() == "Coconut\n"

0 comments on commit f19ce41

Please sign in to comment.