mirror of https://github.com/explosion/spaCy.git
Add tests for projects to master (#12303)
* Add tests for projects to master * Fix git clone related issues on Windows * Add stat import
This commit is contained in:
parent
daedc45d05
commit
1e8bac99f3
|
@ -1,5 +1,7 @@
|
||||||
import os
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
import pytest
|
||||||
|
import srsly
|
||||||
from typer.testing import CliRunner
|
from typer.testing import CliRunner
|
||||||
from spacy.tokens import DocBin, Doc
|
from spacy.tokens import DocBin, Doc
|
||||||
|
|
||||||
|
@ -89,3 +91,138 @@ def test_debug_data_trainable_lemmatizer_cli(en_vocab):
|
||||||
# Instead of checking specific wording of the output, which may change,
|
# Instead of checking specific wording of the output, which may change,
|
||||||
# we'll check that this section of the debug output is present.
|
# we'll check that this section of the debug output is present.
|
||||||
assert "= Trainable Lemmatizer =" in result_debug_data.stdout
|
assert "= Trainable Lemmatizer =" in result_debug_data.stdout
|
||||||
|
|
||||||
|
|
||||||
|
# project tests
|
||||||
|
|
||||||
|
SAMPLE_PROJECT = {
|
||||||
|
"title": "Sample project",
|
||||||
|
"description": "This is a project for testing",
|
||||||
|
"assets": [
|
||||||
|
{
|
||||||
|
"dest": "assets/spacy-readme.md",
|
||||||
|
"url": "https://github.com/explosion/spaCy/raw/dec81508d28b47f09a06203c472b37f00db6c869/README.md",
|
||||||
|
"checksum": "411b2c89ccf34288fae8ed126bf652f7",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"dest": "assets/citation.cff",
|
||||||
|
"url": "https://github.com/explosion/spaCy/raw/master/CITATION.cff",
|
||||||
|
"checksum": "c996bfd80202d480eb2e592369714e5e",
|
||||||
|
"extra": True,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"commands": [
|
||||||
|
{
|
||||||
|
"name": "ok",
|
||||||
|
"help": "print ok",
|
||||||
|
"script": ["python -c \"print('okokok')\""],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "create",
|
||||||
|
"help": "make a file",
|
||||||
|
"script": ["touch abc.txt"],
|
||||||
|
"outputs": ["abc.txt"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "clean",
|
||||||
|
"help": "remove test file",
|
||||||
|
"script": ["rm abc.txt"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
SAMPLE_PROJECT_TEXT = srsly.yaml_dumps(SAMPLE_PROJECT)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def project_dir():
|
||||||
|
with make_tempdir() as pdir:
|
||||||
|
(pdir / "project.yml").write_text(SAMPLE_PROJECT_TEXT)
|
||||||
|
yield pdir
|
||||||
|
|
||||||
|
|
||||||
|
def test_project_document(project_dir):
|
||||||
|
readme_path = project_dir / "README.md"
|
||||||
|
assert not readme_path.exists(), "README already exists"
|
||||||
|
result = CliRunner().invoke(
|
||||||
|
app, ["project", "document", str(project_dir), "-o", str(readme_path)]
|
||||||
|
)
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert readme_path.is_file()
|
||||||
|
text = readme_path.read_text("utf-8")
|
||||||
|
assert SAMPLE_PROJECT["description"] in text
|
||||||
|
|
||||||
|
|
||||||
|
def test_project_assets(project_dir):
|
||||||
|
asset_dir = project_dir / "assets"
|
||||||
|
assert not asset_dir.exists(), "Assets dir is already present"
|
||||||
|
result = CliRunner().invoke(app, ["project", "assets", str(project_dir)])
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert (asset_dir / "spacy-readme.md").is_file(), "Assets not downloaded"
|
||||||
|
# check that extras work
|
||||||
|
result = CliRunner().invoke(app, ["project", "assets", "--extra", str(project_dir)])
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert (asset_dir / "citation.cff").is_file(), "Extras not downloaded"
|
||||||
|
|
||||||
|
|
||||||
|
def test_project_run(project_dir):
|
||||||
|
# make sure dry run works
|
||||||
|
test_file = project_dir / "abc.txt"
|
||||||
|
result = CliRunner().invoke(
|
||||||
|
app, ["project", "run", "--dry", "create", str(project_dir)]
|
||||||
|
)
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert not test_file.is_file()
|
||||||
|
result = CliRunner().invoke(app, ["project", "run", "create", str(project_dir)])
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert test_file.is_file()
|
||||||
|
result = CliRunner().invoke(app, ["project", "run", "ok", str(project_dir)])
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert "okokok" in result.stdout
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"options",
|
||||||
|
[
|
||||||
|
"",
|
||||||
|
# "--sparse",
|
||||||
|
"--branch v3",
|
||||||
|
"--repo https://github.com/explosion/projects --branch v3",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_project_clone(options):
|
||||||
|
with make_tempdir() as workspace:
|
||||||
|
out = workspace / "project"
|
||||||
|
target = "benchmarks/ner_conll03"
|
||||||
|
if not options:
|
||||||
|
options = []
|
||||||
|
else:
|
||||||
|
options = options.split()
|
||||||
|
result = CliRunner().invoke(
|
||||||
|
app, ["project", "clone", target, *options, str(out)]
|
||||||
|
)
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert (out / "README.md").is_file()
|
||||||
|
|
||||||
|
|
||||||
|
def test_project_push_pull(project_dir):
|
||||||
|
proj = dict(SAMPLE_PROJECT)
|
||||||
|
remote = "xyz"
|
||||||
|
|
||||||
|
with make_tempdir() as remote_dir:
|
||||||
|
proj["remotes"] = {remote: str(remote_dir)}
|
||||||
|
proj_text = srsly.yaml_dumps(proj)
|
||||||
|
(project_dir / "project.yml").write_text(proj_text)
|
||||||
|
|
||||||
|
test_file = project_dir / "abc.txt"
|
||||||
|
result = CliRunner().invoke(app, ["project", "run", "create", str(project_dir)])
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert test_file.is_file()
|
||||||
|
result = CliRunner().invoke(app, ["project", "push", remote, str(project_dir)])
|
||||||
|
assert result.exit_code == 0
|
||||||
|
result = CliRunner().invoke(app, ["project", "run", "clean", str(project_dir)])
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert not test_file.exists()
|
||||||
|
result = CliRunner().invoke(app, ["project", "pull", remote, str(project_dir)])
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert test_file.is_file()
|
||||||
|
|
|
@ -32,6 +32,7 @@ import inspect
|
||||||
import pkgutil
|
import pkgutil
|
||||||
import logging
|
import logging
|
||||||
import socket
|
import socket
|
||||||
|
import stat
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import cupy.random
|
import cupy.random
|
||||||
|
@ -1050,8 +1051,15 @@ def make_tempdir() -> Generator[Path, None, None]:
|
||||||
"""
|
"""
|
||||||
d = Path(tempfile.mkdtemp())
|
d = Path(tempfile.mkdtemp())
|
||||||
yield d
|
yield d
|
||||||
|
|
||||||
|
# On Windows, git clones use read-only files, which cause permission errors
|
||||||
|
# when being deleted. This forcibly fixes permissions.
|
||||||
|
def force_remove(rmfunc, path, ex):
|
||||||
|
os.chmod(path, stat.S_IWRITE)
|
||||||
|
rmfunc(path)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
shutil.rmtree(str(d))
|
shutil.rmtree(str(d), onerror=force_remove)
|
||||||
except PermissionError as e:
|
except PermissionError as e:
|
||||||
warnings.warn(Warnings.W091.format(dir=d, msg=e))
|
warnings.warn(Warnings.W091.format(dir=d, msg=e))
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue