Replace the silent generic-record fallback for product requests and expose semantic validation diagnostics before publishing. Co-authored-by: Cursor <cursoragent@cursor.com>
110 lines
3.6 KiB
Python
110 lines
3.6 KiB
Python
import copy
|
|
import unittest
|
|
|
|
from app import (
|
|
build_blueprint,
|
|
has_product_semantics,
|
|
validate_generated_semantics,
|
|
)
|
|
from generation_rules import wants_screenshot_layout
|
|
|
|
|
|
class Z41GenerationTests(unittest.TestCase):
|
|
def test_product_prompt_builds_product_blueprint_without_attachment(self):
|
|
draft, warnings, confidence = build_blueprint(
|
|
"商品展示页",
|
|
None,
|
|
"schema_per_app",
|
|
0,
|
|
0,
|
|
)
|
|
|
|
self.assertTrue(has_product_semantics(draft))
|
|
self.assertEqual(draft["entities"][0]["name"], "product")
|
|
self.assertEqual(draft["apis"]["resources"][0]["path"], "/products")
|
|
self.assertEqual(draft["meta"]["ui_preset"], "default")
|
|
self.assertGreater(confidence, 0.55)
|
|
self.assertTrue(any("商品语义" in warning for warning in warnings))
|
|
self.assertIn("编辑商品", [page["title"] for page in draft["pages"]])
|
|
|
|
def test_product_validator_rejects_generic_record_blueprint(self):
|
|
generic, _, _ = build_blueprint(
|
|
"普通记录页",
|
|
None,
|
|
"schema_per_app",
|
|
0,
|
|
0,
|
|
)
|
|
|
|
warnings = validate_generated_semantics(
|
|
"商品展示页",
|
|
generic,
|
|
image_count=0,
|
|
html_count=0,
|
|
)
|
|
|
|
self.assertFalse(has_product_semantics(generic))
|
|
self.assertTrue(any("语义不合格" in warning for warning in warnings))
|
|
|
|
def test_product_excel_fields_stay_on_product_entity(self):
|
|
excel_meta = {
|
|
"sheets": [
|
|
{
|
|
"name": "商品表",
|
|
"headers": ["商品名称", "价格", "商品图片", "分类"],
|
|
"columns": {
|
|
"商品名称": ["咖啡"],
|
|
"价格": [19.9],
|
|
"商品图片": ["coffee.png"],
|
|
"分类": ["饮品"],
|
|
},
|
|
"inferred": {
|
|
"商品名称": {"type": "string", "enum_values": []},
|
|
"价格": {"type": "decimal", "enum_values": []},
|
|
"商品图片": {"type": "file_ref", "enum_values": []},
|
|
"分类": {"type": "string", "enum_values": []},
|
|
},
|
|
}
|
|
]
|
|
}
|
|
|
|
draft, _, _ = build_blueprint(
|
|
"商品展示页",
|
|
excel_meta,
|
|
"schema_per_app",
|
|
0,
|
|
0,
|
|
)
|
|
|
|
self.assertEqual(draft["entities"][0]["name"], "product")
|
|
self.assertEqual(draft["entities"][0]["label"], "商品")
|
|
self.assertTrue(has_product_semantics(draft))
|
|
|
|
def test_no_media_removes_hallucinated_screenshot_preset(self):
|
|
draft, _, _ = build_blueprint(
|
|
"商品展示页",
|
|
None,
|
|
"schema_per_app",
|
|
0,
|
|
0,
|
|
)
|
|
hallucinated = copy.deepcopy(draft)
|
|
hallucinated["meta"]["ui_preset"] = "screenshot_faithful"
|
|
hallucinated["pages"][0]["layout"]["preset"] = "screenshot_faithful"
|
|
|
|
warnings = validate_generated_semantics(
|
|
"商品展示页",
|
|
hallucinated,
|
|
image_count=0,
|
|
html_count=0,
|
|
)
|
|
|
|
self.assertEqual(hallucinated["meta"]["ui_preset"], "default")
|
|
self.assertEqual(hallucinated["pages"][0]["layout"]["preset"], "default")
|
|
self.assertTrue(any("screenshot_faithful" in warning for warning in warnings))
|
|
self.assertFalse(wants_screenshot_layout("请还原截图", 0, 0))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|