From aca004c51385798790ad38b58e8e6bc225a65dc5 Mon Sep 17 00:00:00 2001 From: mid Date: Sun, 9 Aug 2026 15:41:13 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E5=BC=BA=E5=88=86=E4=BA=AB=E5=85=83?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E4=B8=8E=E7=89=88=E6=9C=AC=E4=B8=80=E8=87=B4?= =?UTF-8?q?=E6=80=A7=E6=A3=80=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 2 +- tests/appIcons.test.mjs | 6 ++++-- tests/deploymentConfig.test.mjs | 21 +++++++++++++++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 523263e..f0c2fe8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ ### Verification -- 86 条 Vitest 测试通过,页面元数据测试覆盖标准 description、`og:description`、Manifest 描述、favicon 回退入口以及无自定义分享图约束。 +- 87 条 Vitest 测试通过,页面元数据测试覆盖标准 description、唯一允许的 `og:description`、Manifest 描述、favicon 回退入口和无自定义分享图约束,并增加发布版本跨文件一致性检查。 - Vue/TypeScript 类型检查和生产构建通过。 ## 0.0.6 - 2026-08-08 diff --git a/tests/appIcons.test.mjs b/tests/appIcons.test.mjs index 5e46999..88f2670 100644 --- a/tests/appIcons.test.mjs +++ b/tests/appIcons.test.mjs @@ -154,13 +154,15 @@ describe('application branding assets', () => { it('declares one product description for standard and Open Graph consumers without a custom image', async () => { const html = (await readProjectFile('index.html')).toString('utf8') + const socialMetadata = [...html.matchAll(/ match[1].toLowerCase()) expect(html).toContain('') expect(html).toContain('') expect(html.match(/一个匿名访问、自托管的浏览器本地工具箱/g)).toHaveLength(2) + expect(socialMetadata).toEqual(['og:description']) expect(html).not.toContain('share-preview.png') - expect(html).not.toMatch(/(?:name|property)="(?:og|twitter):[^\"]*image/i) - expect(html).not.toMatch(/(?:name|property)="twitter:/i) + await expect(access(path.join(publicRoot, 'share-preview.png'))).rejects.toMatchObject({ code: 'ENOENT' }) }) it('includes public assets in container builds', async () => { diff --git a/tests/deploymentConfig.test.mjs b/tests/deploymentConfig.test.mjs index 933611c..264bcde 100644 --- a/tests/deploymentConfig.test.mjs +++ b/tests/deploymentConfig.test.mjs @@ -11,6 +11,27 @@ async function readProjectFile(relativePath) { } describe('deployment configuration', () => { + it('keeps the release version synchronized across project and deployment metadata', async () => { + const [packageText, lockText, compose, readme, changelog] = await Promise.all([ + readProjectFile('package.json'), + readProjectFile('package-lock.json'), + readProjectFile('docker-compose.yml'), + readProjectFile('README.zh-CN.md'), + readProjectFile('CHANGELOG.md'), + ]) + const packageJson = JSON.parse(packageText) + const packageLock = JSON.parse(lockText) + const version = packageJson.version + + expect(version).toMatch(/^\d+\.\d+\.\d+$/) + expect(packageLock.version).toBe(version) + expect(packageLock.packages[''].version).toBe(version) + expect(compose.match(/^\s*image:\s*personal-web-tools:(\S+)$/m)?.[1]).toBe(version) + expect(readme).toContain(`当前应用版本:\`${version}\`。`) + expect(readme).toContain(`personal-web-tools-${version}-amd64.tar`) + expect(changelog.match(/^## (\d+\.\d+\.\d+) - /m)?.[1]).toBe(version) + }) + it('keeps the default production port synchronized', async () => { const [dockerfile, compose, environment, script, readme] = await Promise.all([ readProjectFile('Dockerfile'),