138 行
6.7 KiB
PHP
138 行
6.7 KiB
PHP
<?php
|
||
/**
|
||
* 服务独立页改版规范与内容完整性测试 (TDD 模式)
|
||
* 验证服务页必备板块:分类、能力、流程、交付、FAQ、色彩体系、去AI味道与禁止项
|
||
*/
|
||
|
||
class ServicesPageTest
|
||
{
|
||
private $passed = 0;
|
||
private $failed = 0;
|
||
private $htmlContent = '';
|
||
private $cssContent = '';
|
||
|
||
public function __construct()
|
||
{
|
||
$baseDir = dirname(__DIR__);
|
||
$serviceFile = $baseDir . '/addons/official/view/web/official_product/service_page.html';
|
||
$listFile = $baseDir . '/addons/official/view/web/official_product/list.html';
|
||
$cssFile = $baseDir . '/public/assets/addons/official/css/modern_nhc.css';
|
||
|
||
$this->htmlContent = '';
|
||
if (file_exists($serviceFile)) {
|
||
$this->htmlContent .= file_get_contents($serviceFile) . "\n";
|
||
}
|
||
if (file_exists($listFile)) {
|
||
$this->htmlContent .= file_get_contents($listFile) . "\n";
|
||
}
|
||
if (file_exists($cssFile)) {
|
||
$this->cssContent = file_get_contents($cssFile);
|
||
}
|
||
}
|
||
|
||
public function run()
|
||
{
|
||
echo "=== 开始执行服务独立页设计规范与内容完整性测试 (TDD) ===\n";
|
||
|
||
// 1. 品牌名称必须为纳海川
|
||
$this->testBrandName();
|
||
|
||
// 2. 必备三大服务领域
|
||
$this->testServiceCategories();
|
||
|
||
// 3. 必备板块测试:分类、能力、流程、交付、FAQ
|
||
$this->testEssentialSections();
|
||
|
||
// 4. 去除 AI 味道:真实技术栈与真实业务交付物
|
||
$this->testNoAiCharacteristics();
|
||
|
||
// 5. 禁止项测试(严禁 emoji)
|
||
$this->testForbiddenElements();
|
||
|
||
// 6. 色彩与设计规范
|
||
$this->testDesignTokens();
|
||
|
||
echo "\n测试结果: {$this->passed} 通过, {$this->failed} 失败\n";
|
||
if ($this->failed > 0) {
|
||
exit(1);
|
||
}
|
||
}
|
||
|
||
private function assert($condition, $message)
|
||
{
|
||
if ($condition) {
|
||
echo " [PASS] {$message}\n";
|
||
$this->passed++;
|
||
} else {
|
||
echo " [FAIL] {$message}\n";
|
||
$this->failed++;
|
||
}
|
||
}
|
||
|
||
public function testBrandName()
|
||
{
|
||
$this->assert(strpos($this->htmlContent, '纳海川') !== false, "服务页必须明确包含品牌名称【纳海川】");
|
||
$hasWrongAbbr = preg_match('/纳川(?![海])/u', $this->htmlContent);
|
||
$this->assert(!$hasWrongAbbr, "服务页严禁错误简称为【纳川】");
|
||
}
|
||
|
||
public function testServiceCategories()
|
||
{
|
||
$this->assert(strpos($this->htmlContent, '软件开发') !== false, "必须深度包含【软件开发】服务分类");
|
||
$this->assert(strpos($this->htmlContent, 'APP与小程序定制') !== false || (strpos($this->htmlContent, 'APP定制') !== false && strpos($this->htmlContent, '小程序定制') !== false), "必须深度包含【APP与小程序定制】服务分类");
|
||
$this->assert(strpos($this->htmlContent, '智能体开发') !== false, "必须深度包含【智能体开发】服务分类");
|
||
}
|
||
|
||
public function testEssentialSections()
|
||
{
|
||
// 按照 AGENTS.md 规范:服务页含分类、能力、流程、交付、FAQ
|
||
$hasCategory = (strpos($this->htmlContent, 'nhc-services-categories') !== false || strpos($this->htmlContent, '服务分类') !== false || strpos($this->htmlContent, '服务矩阵') !== false);
|
||
$this->assert($hasCategory, "服务页必须包含【分类】板块");
|
||
|
||
$hasCapability = (strpos($this->htmlContent, 'nhc-tech-capabilities') !== false || strpos($this->htmlContent, '技术能力') !== false || strpos($this->htmlContent, '技术底座') !== false);
|
||
$this->assert($hasCapability, "服务页必须包含【能力】(技术底座/核心能力)板块");
|
||
|
||
$hasProcess = (strpos($this->htmlContent, 'nhc-delivery-process') !== false || strpos($this->htmlContent, '交付流程') !== false || strpos($this->htmlContent, '研发流程') !== false);
|
||
$this->assert($hasProcess, "服务页必须包含【流程】(研发交付流程)板块");
|
||
|
||
$hasDeliverables = (strpos($this->htmlContent, 'nhc-deliverables') !== false || strpos($this->htmlContent, '交付物') !== false || strpos($this->htmlContent, '交付标准') !== false);
|
||
$this->assert($hasDeliverables, "服务页必须包含【交付】(标准交付物与SLA保障)板块");
|
||
|
||
$hasFaq = (strpos($this->htmlContent, 'nhc-faq') !== false || strpos($this->htmlContent, '常见问答') !== false || strpos($this->htmlContent, '技术问答') !== false);
|
||
$this->assert($hasFaq, "服务页必须包含【FAQ】(技术与合作问答)板块");
|
||
}
|
||
|
||
public function testNoAiCharacteristics()
|
||
{
|
||
// 必须包含具体真实技术栈,去除空话
|
||
$hasTechStack = (strpos($this->htmlContent, 'Vue') !== false || strpos($this->htmlContent, 'React') !== false || strpos($this->htmlContent, 'Spring') !== false || strpos($this->htmlContent, 'Docker') !== false || strpos($this->htmlContent, '微服务') !== false);
|
||
$this->assert($hasTechStack, "去AI味道:必须展示具体的企业级技术栈与架构,而非空泛套话");
|
||
|
||
// 必须包含具体的交付物明细(如源码、数据库字典、API规范等)
|
||
$hasRealDeliverables = (strpos($this->htmlContent, '源码') !== false && (strpos($this->htmlContent, '数据库') !== false || strpos($this->htmlContent, 'API') !== false || strpos($this->htmlContent, '文档') !== false));
|
||
$this->assert($hasRealDeliverables, "去AI味道:必须列出实体交付物清单(源码移交、数据库字典、API文档等)");
|
||
|
||
// 包含真实的 SLA 运维时效标准
|
||
$hasSla = (strpos($this->htmlContent, 'SLA') !== false || strpos($this->htmlContent, '7×24') !== false || strpos($this->htmlContent, '响应') !== false);
|
||
$this->assert($hasSla, "去AI味道:必须包含具体的运维 SLA 保障标准");
|
||
}
|
||
|
||
public function testForbiddenElements()
|
||
{
|
||
$hasEmoji = preg_match('/[\x{1F600}-\x{1F64F}\x{1F300}-\x{1F5FF}\x{1F680}-\x{1F6FF}\x{2600}-\x{26FF}\x{2700}-\x{27BF}]/u', $this->htmlContent);
|
||
$this->assert(!$hasEmoji, "服务页严禁使用任何 emoji 表情符号");
|
||
}
|
||
|
||
public function testDesignTokens()
|
||
{
|
||
$hasSerif = (stripos($this->cssContent, 'SimSun') !== false || stripos($this->cssContent, 'Songti') !== false || stripos($this->cssContent, 'Noto Serif SC') !== false);
|
||
$this->assert($hasSerif, "必须沿用宋体标题规范");
|
||
|
||
$hasPrimary = (stripos($this->cssContent, '#2563EB') !== false || stripos($this->cssContent, '#2563eb') !== false);
|
||
$this->assert($hasPrimary, "必须沿用科技蓝 #2563EB 主色规范");
|
||
}
|
||
}
|
||
|
||
$test = new ServicesPageTest();
|
||
$test->run();
|