112 lines
4.5 KiB
Python
112 lines
4.5 KiB
Python
import contextlib
|
|
import io
|
|
import json
|
|
import re
|
|
import shlex
|
|
import unittest
|
|
from pathlib import Path
|
|
from types import SimpleNamespace
|
|
|
|
from scripts import run_offline_checks
|
|
from scripts import run_training_case_package as training_cli
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
README = ROOT / "README.md"
|
|
TRAINING_PUBLIC_DOC = ROOT / "docs" / "training_console_public_surface_v1.md"
|
|
DOC_EXAMPLE = ROOT / "docs" / "examples" / "training_case_package_smoke_m6.md"
|
|
FIXTURE = ROOT / "tests" / "fixtures" / "training_case_package_m6.json"
|
|
FIXTURE_REF = "tests/fixtures/training_case_package_m6.json"
|
|
PACKAGE_SMOKE_COMMAND = ".venv/bin/python scripts/run_training_case_package.py"
|
|
OFFLINE_CHECK_COMMAND = ".venv/bin/python scripts/run_offline_checks.py"
|
|
|
|
|
|
def _documented_command_parts() -> list[str]:
|
|
text = DOC_EXAMPLE.read_text(encoding="utf-8")
|
|
match = re.search(r"```bash\n(?P<command>.*?)\n```", text, flags=re.DOTALL)
|
|
if match is None:
|
|
raise AssertionError("missing documented package smoke command")
|
|
return shlex.split(re.sub(r"\\\n\s*", " ", match.group("command").strip()))
|
|
|
|
|
|
class TrainingCaseDocsCliM10Tests(unittest.TestCase):
|
|
def test_example_doc_uses_current_public_fixture_and_cli(self) -> None:
|
|
parts = _documented_command_parts()
|
|
self.assertEqual(parts[:3], [".venv/bin/python", "scripts/run_training_case_package.py", "--input"])
|
|
self.assertIn(FIXTURE_REF, parts)
|
|
self.assertIn("--output", parts)
|
|
|
|
def test_example_doc_publishes_current_public_smoke_wording(self) -> None:
|
|
text = DOC_EXAMPLE.read_text(encoding="utf-8")
|
|
for snippet in (
|
|
"import/export smoke",
|
|
"public package",
|
|
"public export",
|
|
"public output",
|
|
"one-line JSON",
|
|
"input_file_not_found",
|
|
"input_path_is_directory",
|
|
"output_path_is_directory",
|
|
"output_path_unwritable",
|
|
):
|
|
self.assertIn(snippet, text)
|
|
|
|
def test_training_public_doc_references_console_and_api_surface(self) -> None:
|
|
text = TRAINING_PUBLIC_DOC.read_text(encoding="utf-8")
|
|
for snippet in (
|
|
"The public browser entry is `/training`.",
|
|
"The trading workbench stays at `/`.",
|
|
"| GET | `/training/cases` |",
|
|
"| GET | `/training/progress` |",
|
|
"Training public error catalog:",
|
|
PACKAGE_SMOKE_COMMAND,
|
|
):
|
|
self.assertIn(snippet, text)
|
|
|
|
def test_readme_points_to_current_offline_checks_and_training_console(self) -> None:
|
|
text = README.read_text(encoding="utf-8")
|
|
for snippet in (
|
|
OFFLINE_CHECK_COMMAND,
|
|
"Training Console at `/training`",
|
|
"training_console_js_syntax",
|
|
"python3 scripts/run_api_server.py",
|
|
):
|
|
self.assertIn(snippet, text)
|
|
self.assertNotIn("training_case_engine_m1_m6_product_readme.md", text)
|
|
|
|
def test_offline_checks_registry_includes_both_web_entries(self) -> None:
|
|
commands = dict(run_offline_checks.build_check_commands(env={}))
|
|
self.assertEqual(commands["dashboard_js_syntax"], ["node", "--check", "src/web/app.js"])
|
|
self.assertEqual(commands["training_console_js_syntax"], ["node", "--check", "src/web/training.js"])
|
|
|
|
def test_offline_checks_json_and_node_skip_behavior_cover_new_training_check(self) -> None:
|
|
def fake_runner(command, **_kwargs):
|
|
return SimpleNamespace(returncode=0, stdout="ok\n", stderr="")
|
|
|
|
output = io.StringIO()
|
|
with contextlib.redirect_stdout(output):
|
|
exit_code = run_offline_checks.run_checks(
|
|
commands=[("training_console_js_syntax", ["node", "--check", "src/web/training.js"])],
|
|
runner=fake_runner,
|
|
node_available=False,
|
|
env={},
|
|
)
|
|
|
|
self.assertEqual(exit_code, 0)
|
|
self.assertIn("Offline check skipped: training_console_js_syntax", output.getvalue())
|
|
|
|
def test_package_cli_still_emits_one_line_public_json(self) -> None:
|
|
output = io.StringIO()
|
|
with contextlib.redirect_stdout(output):
|
|
exit_code = training_cli.main(["--input", str(FIXTURE)])
|
|
|
|
summary = json.loads(output.getvalue())
|
|
self.assertEqual(exit_code, 0)
|
|
self.assertTrue(summary["passed"])
|
|
self.assertTrue(str(summary["input"]).endswith("tests\\fixtures\\training_case_package_m6.json"))
|
|
self.assertIsNone(summary["output"])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|