feat(activity): 活动大厅全面以陪吃·陪唱·陪喝为主,增加品类快捷胶囊筛选并完善TDD门禁
这个提交包含在:
@@ -0,0 +1,93 @@
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
describe('ActivityListContent (TDD 测试套件: 活动大厅陪吃·陪唱·陪喝内容与零Emoji校验)', () => {
|
||||
const rootDir = path.resolve(__dirname, '../../');
|
||||
const mockFilePath = path.join(rootDir, 'pwuniapp', 'common', 'mock.js');
|
||||
const listVuePath = path.join(rootDir, 'pwuniapp', 'pages', 'activity', 'list.vue');
|
||||
const emojiRegex = /(?:\p{Extended_Pictographic}|\p{Emoji_Presentation}|[\u2600-\u27BF])/u;
|
||||
|
||||
describe('1. mock.js 中 ACTIVITIES_LIST 内容规范校验', () => {
|
||||
it('活动列表中陪吃·陪唱·陪喝三大核心品类应占主导地位 (>= 80%)', () => {
|
||||
const mockContent = fs.readFileSync(mockFilePath, 'utf-8');
|
||||
|
||||
// 提取 ACTIVITIES_LIST 数组对象文本
|
||||
const listMatch = mockContent.match(/export const ACTIVITIES_LIST\s*=\s*(\[[\s\S]*?\n\];)/);
|
||||
expect(listMatch).not.toBeNull();
|
||||
|
||||
// 解析执行提取对象
|
||||
const evalList = new Function(`return ${listMatch![1].replace(/;\s*$/, '')}`)();
|
||||
expect(Array.isArray(evalList)).toBe(true);
|
||||
expect(evalList.length).toBeGreaterThanOrEqual(4);
|
||||
|
||||
const mainCategories = ['美食陪吃', '同城陪唱', '下午茶陪喝', '同城微醺'];
|
||||
const mainCategoryCount = evalList.filter((item: any) =>
|
||||
mainCategories.includes(item.game || item.category)
|
||||
).length;
|
||||
|
||||
const mainRatio = mainCategoryCount / evalList.length;
|
||||
expect(mainRatio).toBeGreaterThanOrEqual(0.8);
|
||||
});
|
||||
|
||||
it('所有活动必须包含合法公开场所、时间与发起人信息', () => {
|
||||
const mockContent = fs.readFileSync(mockFilePath, 'utf-8');
|
||||
const listMatch = mockContent.match(/export const ACTIVITIES_LIST\s*=\s*(\[[\s\S]*?\n\];)/);
|
||||
const evalList = new Function(`return ${listMatch![1].replace(/;\s*$/, '')}`)();
|
||||
|
||||
for (const item of evalList) {
|
||||
expect(item.id).toBeDefined();
|
||||
expect(item.title).toBeDefined();
|
||||
expect(item.location).toBeDefined();
|
||||
expect(item.startTime).toBeDefined();
|
||||
expect(item.creatorNickname).toBeDefined();
|
||||
expect(item.creatorAvatar).toBeDefined();
|
||||
expect(['AA', 'PROJECT']).toContain(item.payType);
|
||||
|
||||
// 验证地点均为公开合法商圈/门店,不能有私人住宅等违规词
|
||||
expect(item.location).not.toMatch(/(酒店客房|私人住宅|私密公寓)/);
|
||||
}
|
||||
});
|
||||
|
||||
it('ACTIVITIES_LIST 数据中严禁包含任何系统 Emoji 字符', () => {
|
||||
const mockContent = fs.readFileSync(mockFilePath, 'utf-8');
|
||||
const listMatch = mockContent.match(/export const ACTIVITIES_LIST\s*=\s*(\[[\s\S]*?\n\];)/);
|
||||
expect(listMatch).not.toBeNull();
|
||||
|
||||
const listContent = listMatch![1];
|
||||
const lines = listContent.split('\n');
|
||||
const violations: string[] = [];
|
||||
|
||||
lines.forEach((line, idx) => {
|
||||
if (emojiRegex.test(line)) {
|
||||
violations.push(`Line ${idx + 1}: ${line.trim()}`);
|
||||
}
|
||||
});
|
||||
|
||||
expect(violations).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('2. pages/activity/list.vue 页面规范校验', () => {
|
||||
it('活动列表页面模板与样式中严禁包含任何 Emoji 字符', () => {
|
||||
const content = fs.readFileSync(listVuePath, 'utf-8');
|
||||
const lines = content.split('\n');
|
||||
const violations: string[] = [];
|
||||
|
||||
lines.forEach((line, idx) => {
|
||||
if (emojiRegex.test(line)) {
|
||||
violations.push(`Line ${idx + 1}: ${line.trim()}`);
|
||||
}
|
||||
});
|
||||
|
||||
expect(violations).toEqual([]);
|
||||
});
|
||||
|
||||
it('页面应包含陪吃·陪唱·陪喝相关的分类快捷切换或展示逻辑', () => {
|
||||
const content = fs.readFileSync(listVuePath, 'utf-8');
|
||||
// 验证包含美食陪吃、同城陪唱等核心品类关键词
|
||||
expect(content).toMatch(/(美食陪吃|陪吃)/);
|
||||
expect(content).toMatch(/(同城陪唱|陪唱)/);
|
||||
expect(content).toMatch(/(下午茶陪喝|陪喝)/);
|
||||
});
|
||||
});
|
||||
});
|
||||
在新工单中引用
屏蔽一个用户