Skip to content

Commit

Permalink
Add generator testcase for invalid product blocks config
Browse files Browse the repository at this point in the history
Signed-off-by: Mark90 <[email protected]>
  • Loading branch information
Mark90 committed Jun 11, 2024
1 parent d837897 commit 4fedae7
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 41 deletions.
33 changes: 33 additions & 0 deletions test/unit_tests/cli/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import sys
from functools import partial

import pytest
from typer.testing import CliRunner

from orchestrator.cli.database import app as db_app
from test.unit_tests.cli.helpers import create_main


@pytest.fixture(scope="module")
def monkey_module():
with pytest.MonkeyPatch.context() as mp:
yield mp


@pytest.fixture(scope="module")
def tmp_generate_path(tmp_path_factory):
yield tmp_path_factory.mktemp("generate")


@pytest.fixture(scope="module")
def cli_invoke(tmp_generate_path, monkey_module):
monkey_module.chdir(tmp_generate_path)
sys.path.append(str(tmp_generate_path))
create_main()

runner = CliRunner()
# Don't catch exceptions because this will cost you grey hair.
invoke = partial(runner.invoke, catch_exceptions=False)
invoke(db_app, ["init"])

yield invoke
20 changes: 20 additions & 0 deletions test/unit_tests/cli/data/invalid_product_config1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Testcase for invalid config: multiple root product blocks
config:
summary_forms: False
name: invalidexample1
type: InvalidExample4
tag: INVALIDEXAMPLE1
description: "Invalid Product example 1"
product_blocks:
- name: block1
type: Block1
tag: BLOCK1
fields:
- name: num_val
type: int
- name: block2
type: Block2
tag: BLOCK2
fields:
- name: str_val
type: str
24 changes: 24 additions & 0 deletions test/unit_tests/cli/data/invalid_product_config2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Testcase for invalid config: cyclic product blocks
config:
summary_forms: False
name: invalidexample1
type: InvalidExample4
tag: INVALIDEXAMPLE1
description: "Invalid Product example 1"
product_blocks:
- name: block1
type: Block1
tag: BLOCK1
fields:
- name: num_val
type: int
- name: sub_block
type: Block2
- name: block2
type: Block2
tag: BLOCK2
fields:
- name: str_val
type: str
- name: sub_block
type: Block1
19 changes: 19 additions & 0 deletions test/unit_tests/cli/helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from pathlib import Path


def absolute_path(path: str) -> str:
file = Path(__file__).resolve().parent / "data" / path
return str(file)


def create_main():
with open("main.py", "w") as fp:
fp.write(
"from orchestrator import OrchestratorCore\n"
"from orchestrator.cli.main import app as core_cli\n"
"from orchestrator.settings import AppSettings\n"
"\n"
"app = OrchestratorCore(base_settings=AppSettings())\n"
'if __name__ == "__main__":\n'
" core_cli()\n"
)
20 changes: 20 additions & 0 deletions test/unit_tests/cli/test_config_validation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import pytest
import structlog

from orchestrator.cli.generate import app as generate_app
from test.unit_tests.cli.helpers import absolute_path

logger = structlog.get_logger()


@pytest.mark.parametrize(
"config_file,expected_exception,expected_message",
[
("invalid_product_config1.yaml", ValueError, "found multiple"),
("invalid_product_config2.yaml", ValueError, "Cycle detected"),
],
)
def test_product_block_validation(config_file, expected_exception, expected_message, cli_invoke):
config_file = absolute_path(config_file)
with pytest.raises(expected_exception, match=expected_message):
cli_invoke(generate_app, ["product-blocks", "--config-file", config_file])
47 changes: 6 additions & 41 deletions test/unit_tests/cli/test_generate_code.py
Original file line number Diff line number Diff line change
@@ -1,66 +1,31 @@
import re
import sys
from difflib import context_diff
from filecmp import dircmp
from functools import partial
from pathlib import Path

import pytest
import structlog
from more_itertools import one
from typer.testing import CliRunner

from orchestrator.cli.database import app as db_app
from orchestrator.cli.generate import app as generate_app
from test.unit_tests.cli.helpers import absolute_path

logger = structlog.get_logger()


def absolute_path(path: str) -> str:
file = Path(__file__).resolve().parent / "data" / path
return str(file)


def create_main():
with open("main.py", "w") as fp:
fp.write(
"from orchestrator import OrchestratorCore\n"
"from orchestrator.cli.main import app as core_cli\n"
"from orchestrator.settings import AppSettings\n"
"\n"
"app = OrchestratorCore(base_settings=AppSettings())\n"
'if __name__ == "__main__":\n'
" core_cli()\n"
)


@pytest.fixture(scope="module")
def monkey_module():
with pytest.MonkeyPatch.context() as mp:
yield mp


@pytest.fixture(scope="module")
def actual_folder(tmp_path_factory, monkey_module) -> Path:
tmp_path = tmp_path_factory.mktemp("generate")
monkey_module.chdir(tmp_path)
sys.path.append(str(tmp_path))
create_main()
runner = CliRunner()

# Don't catch exceptions because this will cost you grey hair.
invoke = partial(runner.invoke, catch_exceptions=False)
invoke(db_app, ["init"])
def actual_folder(cli_invoke, tmp_generate_path) -> Path:
for config_file in (
absolute_path("product_config2.yaml"),
absolute_path("product_config1.yaml"),
absolute_path("product_config4.yaml"),
):
for cmd in ("product-blocks", "product", "workflows", "unit-tests"):
invoke(generate_app, [cmd, "--config-file", config_file, "--no-dryrun", "--force"])
cli_invoke(generate_app, [cmd, "--config-file", config_file, "--no-dryrun", "--force"])

cli_invoke(generate_app, ["migration", "--config-file", config_file])

invoke(generate_app, ["migration", "--config-file", config_file])
return tmp_path
return tmp_generate_path


@pytest.fixture(scope="module")
Expand Down

0 comments on commit 4fedae7

Please sign in to comment.