Skip to content

Commit

Permalink
test(cli): add unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
tdari committed Jun 14, 2024
1 parent 0983aa8 commit 75df892
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 11 deletions.
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ cli = [
"docker>=7.0.0",
"kubernetes==23.6.0",
"bottle==0.12.25",
"requests==2.31.0"
"requests==2.31.0",
"pytest==8.2.2"
]
airflow = [
"apache-airflow==2.7.2",
Expand Down
9 changes: 5 additions & 4 deletions src/domino/cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,22 +282,22 @@ def cli_create_piece(name: str, repository_path: str = None):
"""Create piece."""
try:
if repository_path is not None:
pieces_repository.create_piece(f"{repository_path}/pieces", name)
pieces_repository.create_piece(name, f"{repository_path}/pieces")
elif not (Path.cwd() / "pieces").is_dir():
# might be called inside the pieces directory
if Path.cwd().name == "pieces":
pieces_repository.create_piece(str(Path.cwd()), name)
pieces_repository.create_piece(name, str(Path.cwd()))
else:
raise FileNotFoundError("No pieces directory found.")
else:
pieces_repository.create_piece(f"{Path.cwd()}/pieces", name)
pieces_repository.create_piece(name, f"{Path.cwd()}/pieces")
except FileNotFoundError as err:
console.print(err, style=f"bold {COLOR_PALETTE.get('error')}")

@click.group()
def cli_pieces():
"""Manage pieces in a repository."""
console.print("Manage piece folders.")
pass

cli_pieces.add_command(cli_create_piece, name="create")

Expand Down Expand Up @@ -455,6 +455,7 @@ def cli(ctx):

cli.add_command(cli_platform, name="platform")
cli.add_command(cli_piece_repository, name="piece-repository")
cli.add_command(cli_pieces, name="pieces")
cli.add_command(cli_run_piece_k8s, name="run-piece-k8s")
cli.add_command(cli_run_piece_docker, name='run-piece-docker')

Expand Down
109 changes: 109 additions & 0 deletions src/domino/cli/tests/test_create_piece.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
from pathlib import Path

import pytest
from click.testing import CliRunner
from domino.cli import cli


@pytest.fixture
def runner():
return CliRunner()


def test_create_piece_success_in_pieces_dir_without_repository_path(
runner, tmpdir, monkeypatch
):
pieces_path = str(Path(tmpdir.mkdir("pieces")))
piece_name = "TestPiece"
monkeypatch.chdir(pieces_path)
result = runner.invoke(cli.cli_create_piece, ["--name", f"{piece_name}"])
assert result.exit_code == 0


def test_create_piece_success_in_repository_dir_without_repository_path(
runner, tmpdir, monkeypatch
):
repository_path = Path(tmpdir.mkdir("repo"))
piece_name = "TestPiece"
monkeypatch.chdir(repository_path)
result = runner.invoke(cli.cli_create_piece, ["--name", f"{piece_name}"])
assert result.exit_code == 0


def test_create_piece_success_with_repository_path(runner, tmpdir):
repository_path = Path(tmpdir.mkdir("repo"))
tmpdir.mkdir("repo/pieces")
piece_name = "TestPiece"
result = runner.invoke(
cli.cli_create_piece,
["--name", f"{piece_name}", "--repository-path", f"{repository_path}"],
)
assert result.exit_code == 0


def test_create_piece_success_in_pieces_dir_without_args(runner, tmpdir):
tmpdir.mkdir("repo")
tmpdir.mkdir("repo/pieces")
result = runner.invoke(cli.cli_create_piece)
assert result.exit_code == 0


@pytest.mark.parametrize(
"piece_name",
[
"1TestPiece",
"Test",
"TestPiec",
"Test Piece",
"Testpiece",
"TESTPIECE",
"",
" ",
".",
],
)
def test_create_piece_fail_invalid_piece_name(runner, tmpdir, piece_name):
repository_path = (Path(tmpdir.mkdir("repo")),)
result = runner.invoke(
cli.cli_create_piece,
["--name", f"{piece_name}", "--repository-path", f"{repository_path}"],
)
if len(piece_name) < 1:
assert "Piece name must have at least one character." in result.output
else:
assert (
f"Validation Error: {piece_name} is not a valid piece name."
in result.output
)


def test_create_piece_already_exists(runner, tmpdir):
repository_path = Path(tmpdir.mkdir("repo"))
tmpdir.mkdir("repo/pieces")
piece_name = "TestPiece"
runner.invoke(
cli.cli_create_piece,
["--name", f"{piece_name}", "--repository-path", f"{repository_path}"],
)
result = runner.invoke(
cli.cli_create_piece,
["--name", f"{piece_name}", "--repository-path", f"{repository_path}"],
)
assert f"{piece_name} is already exists" in result.output


def test_create_piece_invalid_pieces_path(runner, tmpdir):
repository_path = Path(tmpdir.mkdir("repo"))
piece_name = "TestPiece"
result = runner.invoke(
cli.cli_create_piece,
["--name", f"{piece_name}", "--repository-path", f"{repository_path}"],
)
assert f"{repository_path / 'pieces'} is not a valid repository path."


def test_create_piece_pieces_directory_not_exists(runner, tmpdir, monkeypatch):
repository_path = Path(tmpdir.mkdir("repo"))
monkeypatch.chdir(repository_path)
result = runner.invoke(cli.cli_create_piece, ["--name", "TestPiece"])
assert "No pieces directory found." in result.output
15 changes: 9 additions & 6 deletions src/domino/cli/utils/pieces_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,20 +218,23 @@ def validate_pieces_folders() -> None:
raise Exception("\n" + "\n".join(missing_dependencies_errors))

def _validate_piece_name(name: str):
"""
Validate given piece name.
"""
if len(name) == 0:
raise ValidationError(f"Piece name must have at least one character.")
regex = r'^[A-Za-z_][A-Za-z0-9_]*Piece$'
pattern = re.compile(regex)
if not pattern.match(name):
raise ValidationError(f"{name} is not a valid piece name. Piece name must be valid Python class name and must end with 'Piece'.")

def create_piece(pieces_path: str, name: str):
def create_piece(name: str, piece_repository: str):
"""
Create a new piece.
Create a new piece directory with necessary files.
"""
try:
_validate_piece_name(name)
piece_dir = os.path.join(pieces_path, name)
piece_dir = os.path.join(piece_repository, name)
os.mkdir(piece_dir)

with open(f"{piece_dir}/piece.py", "x") as f:
Expand All @@ -250,14 +253,14 @@ def create_piece(pieces_path: str, name: str):
metadata = templates.piece_metadata(name)
json.dump(metadata, f, indent = 4)

console.print(f"{name} is created in {pieces_path}.", style=f"bold {COLOR_PALETTE.get('success')}")
console.print(f"{name} is created in {piece_repository}.", style=f"bold {COLOR_PALETTE.get('success')}")
except ValidationError as err:
console.print(f"{err}", style=f"bold {COLOR_PALETTE.get('error')}")
except OSError as err: # todo: create a wrapper for this
if err.errno == 17:
console.print(f"{name} is already exists in {pieces_path}.", style=f"bold {COLOR_PALETTE.get('error')}")
console.print(f"{name} is already exists in {piece_repository}.", style=f"bold {COLOR_PALETTE.get('error')}")
elif err.errno == 2:
console.print(f"{pieces_path} is not a valid repository path.", style=f"bold {COLOR_PALETTE.get('error')}")
console.print(f"{piece_repository} is not a valid repository path.", style=f"bold {COLOR_PALETTE.get('error')}")
else:
console.print(f"{err}", style=f"bold {COLOR_PALETTE.get('error')}")

Expand Down

0 comments on commit 75df892

Please sign in to comment.