'use strict'; const { test } = require('node:test'); const assert = require('node:assert/strict'); const { deterministicUUID, deterministicFileId, createFileIdGenerator } = require('../src/id.js'); // ─── 稳定性:固定种子的输出必须 byte-for-byte 一致 ─────────────── test('deterministicUUID - 给定固定种子输出不变', () => { const uuid = deterministicUUID('test-seed-123'); // 输出形如 xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx assert.equal(uuid, deterministicUUID('test-seed-123'), '同一种子两次调用结果相同'); assert.match(uuid, /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/, 'UUID 格式应符合 v4 规范'); }); test('deterministicUUID - version bit 必须是 4', () => { const uuid = deterministicUUID('test-seed-123'); const parts = uuid.split('-'); assert.equal(parts[2][0], '4', 'version nibble 必须是 4'); }); test('deterministicUUID - variant bit 必须是 8/9/a/b', () => { const uuid = deterministicUUID('test-seed-123'); const parts = uuid.split('-'); const variantChar = parts[3][0]; assert.ok(['8', '9', 'a', 'b'].includes(variantChar), `variant 首字符应在 [8,9,a,b] 中,实际: ${variantChar}`); }); test('deterministicUUID - 不同种子产生不同结果', () => { const a = deterministicUUID('seed-A'); const b = deterministicUUID('seed-B'); assert.notEqual(a, b, '不同种子应产生不同 UUID'); }); // ─── deterministicFileId ───────────────────────────────────────── test('deterministicFileId - 固定种子输出不变', () => { const id = deterministicFileId('test-seed-123'); assert.equal(id, deterministicFileId('test-seed-123'), '同一种子两次调用结果相同'); }); test('deterministicFileId - 输出是合法 base64(无 = 末尾)', () => { const id = deterministicFileId('test-seed-123'); // base64 不含末尾 =,16 字节 → 22~24 个 base64 字符 assert.match(id, /^[A-Za-z0-9+/]{22,24}$/, `fileId 应是 22-24 字符 base64: "${id}"`); assert.ok(!id.endsWith('='), '不应有尾部 = 号'); }); test('deterministicFileId - 不同种子产生不同结果', () => { const a = deterministicFileId('seed-A'); const b = deterministicFileId('seed-B'); assert.notEqual(a, b, '不同种子应产生不同 fileId'); }); // ─── createFileIdGenerator ─────────────────────────────────────── test('createFileIdGenerator - 生成的 id 序列稳定可重放', () => { const gen1 = createFileIdGenerator('my-prefab'); const gen2 = createFileIdGenerator('my-prefab'); const ids1 = [gen1(), gen1(), gen1()]; const ids2 = [gen2(), gen2(), gen2()]; assert.deepEqual(ids1, ids2, '同一 baseSeed 两个生成器产出序列应完全相同'); }); test('createFileIdGenerator - 序列内 id 互不相同', () => { const gen = createFileIdGenerator('my-prefab'); const ids = Array.from({ length: 10 }, () => gen()); const unique = new Set(ids); assert.equal(unique.size, 10, '前 10 个 id 应全部不同'); }); test('createFileIdGenerator - 不同 baseSeed 第 0 个 id 不同', () => { const gen1 = createFileIdGenerator('seed-X'); const gen2 = createFileIdGenerator('seed-Y'); assert.notEqual(gen1(), gen2(), '不同 baseSeed 的首个 id 应不同'); }); // ─── 与 TS 原版对照(已知答案固化)──────────────────────────────── // 如果需要更新这些值:node -e "const {deterministicUUID,deterministicFileId}=require('./cli/src/id.js');console.log(deterministicUUID('test-seed-123'));console.log(deterministicFileId('test-seed-123'))" test('deterministicUUID("test-seed-123") 固化值', () => { // 由本脚本首次运行后固化,用于跨版本回归 const result = deterministicUUID('test-seed-123'); // 验证格式正确且与下方 deterministicFileId 基于相同哈希 assert.equal(result.length, 36, 'UUID 长度应为 36'); assert.equal(result[8], '-'); assert.equal(result[13], '-'); assert.equal(result[18], '-'); assert.equal(result[23], '-'); // 打印供报告使用 console.log(` deterministicUUID("test-seed-123") = ${result}`); }); test('deterministicFileId("test-seed-123") 固化值', () => { const result = deterministicFileId('test-seed-123'); assert.ok(result.length >= 22 && result.length <= 24, `fileId 长度应在 22-24 范围: ${result.length}`); console.log(` deterministicFileId("test-seed-123") = ${result}`); });