feat: 完善对象存储上传与真实条码二维码引擎,彻底剥离保底Mock数据
这个提交包含在:
@@ -0,0 +1,90 @@
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as vm from 'vm';
|
||||
|
||||
function loadFrontendEsm(filePath: string) {
|
||||
let code = fs.readFileSync(filePath, 'utf-8');
|
||||
code = code.replace(/export\s+const\s+(\w+)/g, 'const $1');
|
||||
code = code.replace(/export\s+class\s+(\w+)/g, 'class $1');
|
||||
code = code.replace(/export\s+function\s+(\w+)/g, 'function $1');
|
||||
const sandbox: any = { module: { exports: {} }, exports: {} };
|
||||
vm.createContext(sandbox);
|
||||
vm.runInContext(
|
||||
`${code}\nmodule.exports = { ...module.exports, ...(typeof encodeCode128B !== 'undefined' ? { encodeCode128B, getBarcodeBits } : {}), ...(typeof generateQRCodeMatrix !== 'undefined' ? { generateQRCodeMatrix, QRCodeModel } : {}) };`,
|
||||
sandbox
|
||||
);
|
||||
return sandbox.module.exports;
|
||||
}
|
||||
|
||||
describe('Barcode & QRCode Architecture (TDD 门票真实条形码与二维码生成及零Mock门禁)', () => {
|
||||
const rootDir = path.resolve(__dirname, '../..');
|
||||
const barcodeJsPath = path.join(rootDir, 'pwuniapp/common/barcode.js');
|
||||
const qrcodeJsPath = path.join(rootDir, 'pwuniapp/common/qrcode.js');
|
||||
const ticketVuePath = path.join(rootDir, 'pwuniapp/pages/activity/my-ticket.vue');
|
||||
|
||||
describe('1. Code128 条形码算法规范', () => {
|
||||
it('barcode.js 文件必须存在且导出 encodeCode128B 和 getBarcodeBits', () => {
|
||||
expect(fs.existsSync(barcodeJsPath)).toBe(true);
|
||||
const content = fs.readFileSync(barcodeJsPath, 'utf-8');
|
||||
expect(content).toContain('export function encodeCode128B');
|
||||
expect(content).toContain('export function getBarcodeBits');
|
||||
});
|
||||
|
||||
it('Code128 编码能够正确计算校验码并生成标准条空序列', () => {
|
||||
const { encodeCode128B, getBarcodeBits } = loadFrontendEsm(barcodeJsPath);
|
||||
const testCode = 'TICKET-101-8392';
|
||||
const segments = encodeCode128B(testCode);
|
||||
expect(Array.isArray(segments)).toBe(true);
|
||||
expect(segments.length).toBeGreaterThan(10);
|
||||
const bits = getBarcodeBits(testCode);
|
||||
expect(typeof bits).toBe('string');
|
||||
expect(bits).toMatch(/^[01]+$/);
|
||||
});
|
||||
});
|
||||
|
||||
describe('2. QR Code 二维码矩阵算法规范', () => {
|
||||
it('qrcode.js 文件必须存在且导出 generateQRCodeMatrix 和 QRCodeModel', () => {
|
||||
expect(fs.existsSync(qrcodeJsPath)).toBe(true);
|
||||
const content = fs.readFileSync(qrcodeJsPath, 'utf-8');
|
||||
expect(content).toContain('export function generateQRCodeMatrix');
|
||||
expect(content).toContain('export class QRCodeModel');
|
||||
});
|
||||
|
||||
it('QR Code 算法能够为任意门票串生成合法的 N*N 二维点阵矩阵', () => {
|
||||
const { generateQRCodeMatrix } = loadFrontendEsm(qrcodeJsPath);
|
||||
const testText = 'TICKET-101-8392';
|
||||
const matrix = generateQRCodeMatrix(testText, 2);
|
||||
expect(Array.isArray(matrix)).toBe(true);
|
||||
expect(matrix.length).toBe(25); // Ver 2: 25x25 矩阵
|
||||
expect(matrix[0].length).toBe(25);
|
||||
// 验证寻象图形 (Position Probe Pattern: 左上角第 0 行应有黑块)
|
||||
expect(matrix[0][0]).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('3. 门票页面真实接入门禁与移除Mock依赖', () => {
|
||||
it('my-ticket.vue 必须引入真实条形码与二维码生成算法', () => {
|
||||
const content = fs.readFileSync(ticketVuePath, 'utf-8');
|
||||
expect(content).toContain('encodeCode128B');
|
||||
expect(content).toContain('generateQRCodeMatrix');
|
||||
expect(content).toContain('barcodeSegments');
|
||||
expect(content).toContain('qrcodeMatrix');
|
||||
});
|
||||
|
||||
it('my-ticket.vue 必须彻底移除对 ACTIVITIES_LIST 假Mock数据的依赖', () => {
|
||||
const content = fs.readFileSync(ticketVuePath, 'utf-8');
|
||||
expect(content).not.toContain("import { ACTIVITIES_LIST } from '@/common/mock.js';");
|
||||
expect(content).not.toContain('const ticketData = ref(ACTIVITIES_LIST[0])');
|
||||
});
|
||||
|
||||
it('所有新写的代码中严禁包含任何系统 Emoji', () => {
|
||||
const bContent = fs.readFileSync(barcodeJsPath, 'utf-8');
|
||||
const qContent = fs.readFileSync(qrcodeJsPath, 'utf-8');
|
||||
const tContent = fs.readFileSync(ticketVuePath, 'utf-8');
|
||||
const emojiRegex = /[\u{1F300}-\u{1F9FF}\u{2600}-\u{26FF}\u{2700}-\u{27BF}]/u;
|
||||
expect(emojiRegex.test(bContent)).toBe(false);
|
||||
expect(emojiRegex.test(qContent)).toBe(false);
|
||||
expect(emojiRegex.test(tContent)).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
在新工单中引用
屏蔽一个用户