95 lines
3.8 KiB
JavaScript
95 lines
3.8 KiB
JavaScript
const assert = require('node:assert/strict');
|
|
const { readFileSync } = require('node:fs');
|
|
const { test } = require('node:test');
|
|
const ts = require('typescript');
|
|
|
|
const source = ts.createSourceFile(
|
|
'WorksGallery.tsx',
|
|
readFileSync(`${__dirname}/../src/components/creator/WorksGallery.tsx`, 'utf8'),
|
|
ts.ScriptTarget.Latest,
|
|
true,
|
|
ts.ScriptKind.TSX,
|
|
);
|
|
|
|
test('作品卡片封面读本地缓存 /works/:id/cover(签名 URL 会过期)', () => {
|
|
assert.match(sourceText(), /cover`/);
|
|
assert.match(sourceText(), /fetchCreatorBinary/);
|
|
assert.doesNotMatch(sourceText(), /cover_url/);
|
|
});
|
|
|
|
test('观看/点赞/评论/分享四项指标全宽 GRID 贴封面下方', () => {
|
|
const grid = /function WorkStatsGrid/.exec(sourceText());
|
|
assert.ok(grid, '应有 WorkStatsGrid 组件');
|
|
const body = sourceText().slice(grid.index, grid.index + 1300);
|
|
for (const key of ['play_count', 'likes', 'comments_count', 'shares']) {
|
|
assert.match(body, new RegExp(key), `GRID 应包含指标 ${key}`);
|
|
}
|
|
// 四列均分占满整行:每列 flex:1,容器自带上下边框贴封面。
|
|
assert.match(body, /flex: 1/);
|
|
assert.match(body, /borderTop/);
|
|
assert.match(body, /borderBottom/);
|
|
});
|
|
|
|
test('无标题作品在卡片和详情中均不显示占位标题', () => {
|
|
const text = sourceText();
|
|
assert.match(text, /\{work\.title \? \(/);
|
|
assert.match(text, /\{detailWork\.title \? \(/);
|
|
assert.doesNotMatch(text, /work\.title \|\| '无标题'|detailWork\.title \|\| '无标题'/);
|
|
});
|
|
|
|
test('卡片展示作品描述(body 省略两行)', () => {
|
|
const card = /work\.body \? \(/.exec(sourceText());
|
|
assert.ok(card, '卡片应有 body 描述分支');
|
|
const body = sourceText().slice(card.index - 120, card.index + 200);
|
|
assert.match(body, /ellipsis=\{\{ rows: 2, tooltip: true \}\}/);
|
|
});
|
|
|
|
for (const [name, tag, content] of [
|
|
['作品简介', 'Typography.Paragraph', '{work.body}'],
|
|
['24h 点赞增量', 'Typography.Text', 'work.likes_growth == null'],
|
|
]) {
|
|
test(`卡片${name}使用默认正文字体和字号`, () => {
|
|
const matches = [];
|
|
function visit(node) {
|
|
if (ts.isJsxElement(node)
|
|
&& node.openingElement.tagName.getText(source) === tag
|
|
&& node.children.some(child => child.getText(source).includes(content))) {
|
|
matches.push(node.openingElement);
|
|
}
|
|
ts.forEachChild(node, visit);
|
|
}
|
|
visit(source);
|
|
assert.equal(matches.length, 1, '应找到对应的卡片文字');
|
|
const attributes = matches[0].attributes.properties;
|
|
for (const attribute of attributes) {
|
|
assert.ok(ts.isJsxAttribute(attribute), '文字不应通过展开属性覆盖默认样式');
|
|
assert.ok(!['type', 'strong', 'italic'].includes(attribute.name.getText(source)));
|
|
}
|
|
assert.doesNotMatch(matches[0].attributes.getText(source), /fontSize|fontFamily|fontWeight|color/);
|
|
});
|
|
}
|
|
|
|
function sourceText() {
|
|
return source.getFullText();
|
|
}
|
|
|
|
for (const [name, pagePath] of [
|
|
['我的账号详情', 'accounts/$id'],
|
|
['监控账号详情', 'accounts/monitoring/$id'],
|
|
['竞品分析', 'creator/competitors'],
|
|
]) {
|
|
test(`${name}使用共用作品列表,列数与封面比例保持一致`, () => {
|
|
const page = readFileSync(`${__dirname}/../src/pages/${pagePath}/index.tsx`, 'utf8');
|
|
assert.match(page, /import WorksGallery from '@\/components\/creator\/WorksGallery'/);
|
|
assert.match(page, /<WorksGallery\b/);
|
|
});
|
|
}
|
|
|
|
const competitorsPageText = readFileSync(`${__dirname}/../src/pages/creator/competitors/index.tsx`, 'utf8');
|
|
|
|
test('竞品分析页复用 WorksGallery,不再自建作品卡片/详情抽屉', () => {
|
|
assert.match(competitorsPageText, /import WorksGallery from '@\/components\/creator\/WorksGallery'/);
|
|
assert.doesNotMatch(competitorsPageText, /\bWorkCover\b|<Drawer|publishedAtStatusMeta|statusTag/);
|
|
});
|
|
|