✨ feat(tsl-codegen): streamline generation workflow
Add explicit project-root output routing and require named input options with structured examples. Remove the unused HTML metadata enrichment command and its dedicated tests.
This commit is contained in:
@@ -164,19 +164,21 @@ class DocGenCliTest(unittest.TestCase):
|
||||
self.assertEqual(0, result.returncode, result.stderr)
|
||||
self.assertTrue(self.generated("base/my_functions").is_file())
|
||||
|
||||
def test_legacy_positional_input_remains_supported(self):
|
||||
def test_positional_input_is_rejected(self):
|
||||
result = self.run_raw_cli(self.input)
|
||||
|
||||
self.assertEqual(0, result.returncode, result.stderr)
|
||||
self.assertTrue(self.generated("base/my_functions").is_file())
|
||||
self.assertEqual(2, result.returncode)
|
||||
self.assertIn(f"无法识别的参数: {self.input}", result.stderr)
|
||||
self.assertFalse(self.generated("base/my_functions").exists())
|
||||
|
||||
def test_help_marks_legacy_input_as_deprecated(self):
|
||||
def test_help_only_documents_named_input_options(self):
|
||||
result = self.run_raw_cli("--help")
|
||||
|
||||
self.assertEqual(0, result.returncode, result.stderr)
|
||||
self.assertIn("--file INPUT_FILE", result.stdout)
|
||||
self.assertIn("--dir INPUT_DIR", result.stdout)
|
||||
self.assertIn("已废弃,请使用 --file", result.stdout)
|
||||
self.assertNotIn("positional arguments:", result.stdout)
|
||||
self.assertNotIn("已废弃", result.stdout)
|
||||
|
||||
def test_invalid_format_error_is_fully_chinese(self):
|
||||
result = self.run_raw_cli("--file", self.input, "--format", "xml")
|
||||
@@ -192,7 +194,6 @@ class DocGenCliTest(unittest.TestCase):
|
||||
cases = (
|
||||
(),
|
||||
("--file", self.input, "--dir", self.root),
|
||||
(self.input, "--file", self.input),
|
||||
)
|
||||
for args in cases:
|
||||
with self.subTest(args=args):
|
||||
@@ -200,7 +201,7 @@ class DocGenCliTest(unittest.TestCase):
|
||||
|
||||
self.assertEqual(2, result.returncode)
|
||||
self.assertIn(
|
||||
"必须且只能指定一种输入方式:INPUT_FILE、--file 或 --dir",
|
||||
"必须且只能指定一种输入方式:--file 或 --dir",
|
||||
result.stderr,
|
||||
)
|
||||
|
||||
@@ -399,6 +400,49 @@ class DocGenCliTest(unittest.TestCase):
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
self.assertTrue(output.is_file())
|
||||
|
||||
def test_root_writes_under_explicit_project_root(self):
|
||||
output_root = self.root / "explicit-root"
|
||||
|
||||
result = self.run_cli("--root", str(output_root))
|
||||
|
||||
output = (
|
||||
output_root
|
||||
/ "skills"
|
||||
/ "tsl-api-reference"
|
||||
/ "references"
|
||||
/ "codegen"
|
||||
/ "project"
|
||||
/ "base"
|
||||
/ "my_functions.md"
|
||||
)
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
self.assertTrue(output.is_file())
|
||||
self.assertFalse(self.generated("base/my_functions").exists())
|
||||
|
||||
def test_relative_root_is_resolved_from_current_working_directory(self):
|
||||
result = self.run_cli("--root", "explicit-root")
|
||||
|
||||
output = (
|
||||
self.root
|
||||
/ "explicit-root"
|
||||
/ "skills"
|
||||
/ "tsl-api-reference"
|
||||
/ "references"
|
||||
/ "codegen"
|
||||
/ "project"
|
||||
/ "base"
|
||||
/ "my_functions.md"
|
||||
)
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
self.assertTrue(output.is_file())
|
||||
|
||||
def test_help_documents_root_option(self):
|
||||
result = self.run_raw_cli("--help")
|
||||
|
||||
self.assertEqual(0, result.returncode, result.stderr)
|
||||
self.assertIn("--root ROOT_DIR", result.stdout)
|
||||
self.assertIn("包含 skills 目录的项目根目录", result.stdout)
|
||||
|
||||
def test_output_option_is_rejected(self):
|
||||
result = self.run_cli("--output", str(self.root / "out.md"))
|
||||
self.assertNotEqual(result.returncode, 0)
|
||||
@@ -498,12 +542,19 @@ class DocGenCliTest(unittest.TestCase):
|
||||
output.write_text("原内容\n", encoding="utf-8")
|
||||
bin_dir = self.root / "bin"
|
||||
bin_dir.mkdir()
|
||||
fake_npx = bin_dir / "npx"
|
||||
fake_npx.write_text(
|
||||
"#!/bin/sh\necho formatter-failed >&2\nexit 9\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
fake_npx.chmod(0o755)
|
||||
if os.name == "nt":
|
||||
fake_npx = bin_dir / "npx.cmd"
|
||||
fake_npx.write_text(
|
||||
"@echo off\r\necho formatter-failed 1>&2\r\nexit /b 9\r\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
else:
|
||||
fake_npx = bin_dir / "npx"
|
||||
fake_npx.write_text(
|
||||
"#!/bin/sh\necho formatter-failed >&2\nexit 9\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
fake_npx.chmod(0o755)
|
||||
env = os.environ.copy()
|
||||
env["PATH"] = str(bin_dir)
|
||||
|
||||
@@ -884,6 +935,46 @@ class DocGenCliTest(unittest.TestCase):
|
||||
self.assertIn("范例02:多行输出", text)
|
||||
self.assertIn("// 输出:\n// first\n// second", text)
|
||||
|
||||
def test_singular_example_is_rejected_without_overwrite(self):
|
||||
self.write_input(
|
||||
{
|
||||
"module": "项目 / 旧示例格式",
|
||||
"path": "base/singular_example",
|
||||
"declarations": [
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "demo",
|
||||
"signature": "demo()",
|
||||
"desc": "示例函数。",
|
||||
"returns": "nil",
|
||||
"example": "return demo();",
|
||||
}
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
self.assert_rejected_without_overwrite(
|
||||
"base/singular_example", "存在未知字段:example"
|
||||
)
|
||||
|
||||
def test_singular_method_example_is_rejected_without_overwrite(self):
|
||||
self.write_class_member_input(
|
||||
{
|
||||
"kind": "method",
|
||||
"name": "Run",
|
||||
"visibility": "public",
|
||||
"binding": "instance",
|
||||
"signature": "Run()",
|
||||
"desc": "运行。",
|
||||
"example": "return self.Run();",
|
||||
},
|
||||
"base/singular_method_example",
|
||||
)
|
||||
|
||||
self.assert_rejected_without_overwrite(
|
||||
"base/singular_method_example", "存在未知字段:example"
|
||||
)
|
||||
|
||||
def test_top_level_enum_sections_are_plain_text_not_emphasis_headings(self):
|
||||
self.write_input(
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user