chore: initial commit

This commit is contained in:
2026-10-22 17:07:08 +08:00
commit 0acef64f48
200 changed files with 35546 additions and 0 deletions
+111
View File
@@ -0,0 +1,111 @@
import assert from 'node:assert/strict';
import {fileURLToPath} from 'node:url';
import test from 'node:test';
import {build} from 'esbuild';
const compiled = await build({
entryPoints: [fileURLToPath(new URL('../utils/message_json_parser.ts', import.meta.url))],
bundle: true,
platform: 'node',
format: 'esm',
write: false,
});
const {MinecraftJsonParser: parser} = await import(`data:text/javascript;base64,${Buffer.from(compiled.outputFiles[0].text).toString('base64')}`);
test('log fragments inherit styles and respect explicit false / zero overrides', () => {
const input = {text: 'parent', color: 'red', bold: 1, extra: [
{text: 'child', italic: true},
{text: 'plain', bold: 0},
{text: 'tail', bold: false},
]};
assert.deepEqual(parser.toLog(input), [
{message: 'parent', font_color: '#FF5555', font_style: ['bold']},
{message: 'child', font_color: '#FF5555', font_style: ['bold', 'italic']},
{message: 'plaintail', font_color: '#FF5555', font_style: ['normal']},
]);
assert.equal(input.extra[1].bold, 0);
});
test('translations keep parameter styles, trailing extras and chat message contents', () => {
const parsed = parser.parse({translate: 'chat.type.text', color: 'gold', with: [
{text: 'Alex', color: 'green'}, 'hello » world',
], extra: ['!']});
assert.equal(parsed.plainText, '<Alex> hello » world!');
assert.equal(parsed.username, 'Alex');
assert.equal(parsed.message, 'hello » world!');
assert.equal(parsed.log[1].font_color, '#55FF55');
assert.equal(parsed.log.at(-1).font_color, '#FFAA00');
assert.equal('html' in parsed, false);
assert.equal(parser.toHTML, undefined);
});
test('fallback translations support indexed parameters, literal percent and missing arguments', () => {
assert.equal(parser.extractPlainText({translate: 'missing.key', fallback: '%2$s %% %s %3$s',
with: [0, false]}), 'false % 0 %3$s');
});
test('ChatMessage uses lossless raw JSON, including arrays and inherited URL style', () => {
const raw = [{text: '链接', color: '#123456', click_event: {action: 'open_url', url: 'https://example.com'}},
'😀', {text: '<&>', underlined: 1}];
const parsed = parser.parse({text: 'lossy', json: raw, warn() {}});
assert.equal(parsed.plainText, '链接😀<&>');
assert.deepEqual(parsed.log, [
{message: '链接😀', font_color: '#123456', font_style: ['url'], clickEvent: {action: 'open_url', value: 'https://example.com'}},
{message: '<&>', font_color: '#123456', font_style: ['underline', 'url'], clickEvent: {action: 'open_url', value: 'https://example.com'}},
]);
});
test('empty, primitive and cyclic inputs are bounded and preserve valid text', () => {
assert.deepEqual(parser.toLog(null), []);
assert.equal(parser.extractPlainText([0, false, '']), '0false');
const cyclic = {text: 'x'};
cyclic.extra = [cyclic];
const text = parser.extractPlainText(cyclic);
assert.ok(text.length > 0 && text.length <= 65);
assert.deepEqual(parser.parseUsernameAndMessage('[rank] Alex » hello » world'),
{username: 'Alex', message: 'hello » world'});
});
test('logs retain inherited hover, click and insertion without merging different events', () => {
const result = parser.toLog({text: '', hover_event: {action: 'show_text', contents: {
translate: 'chat.type.text', with: ['Alex', 'tooltip'],
}}, click_event: {action: 'suggest_command', command: '/msg Alex '}, insertion: 'Alex', extra: [
{text: 'A'}, {text: 'B', hoverEvent: {action: 'show_item', contents: {id: 'minecraft:stone', count: 1}}},
{text: 'C', click_event: {action: 'copy_to_clipboard', text: 'copied'}},
]});
assert.equal(result.length, 3);
assert.deepEqual(result[0].hoverEvent, {action: 'show_text', value: '<Alex> tooltip', segments: [{message: '<Alex> tooltip', font_color: '#FFFFFF', font_style: ['normal']}]});
assert.deepEqual(result[0].clickEvent, {action: 'suggest_command', value: '/msg Alex '});
assert.equal(result[0].insertion, 'Alex');
assert.deepEqual(JSON.parse(result[1].hoverEvent.value), {id: 'minecraft:stone', count: 1});
assert.deepEqual(result[2].clickEvent, {action: 'copy_to_clipboard', value: 'copied'});
});
test('NBT disconnect reasons unwrap compound, list and string tags', () => {
const reason = {type: 'compound', value: {
text: {type: 'string', value: '登录失败: '},
color: {type: 'string', value: 'red'},
extra: {type: 'list', value: {type: 'compound', value: [
{text: {type: 'string', value: '连接超时'}, bold: {type: 'byte', value: 1}},
]}},
}};
assert.equal(parser.extractPlainText(reason), '登录失败: 连接超时');
assert.equal(parser.toLog(reason)[1].font_color, '#FF5555');
assert.deepEqual(parser.toLog(reason)[1].font_style, ['bold']);
assert.equal(parser.extractPlainText({type: 'string', value: '服务器已关闭'}), '服务器已关闭');
});
test('hover text preserves inherited colors and formats without recursive events', () => {
const result = parser.toLog({text: 'player', hoverEvent: {action: 'show_text', contents: {
text: '称号 ', color: 'gold', bold: true, extra: [
{text: 'Alex', color: 'aqua', bold: false, italic: true, hoverEvent: {action: 'show_text', value: 'nested'}, clickEvent: {action: 'run_command', value: '/nested'}},
],
}}});
assert.equal(result[0].hoverEvent.value, '称号 Alex');
assert.deepEqual(result[0].hoverEvent.segments, [
{message: '称号 ', font_color: '#FFAA00', font_style: ['bold']},
{message: 'Alex', font_color: '#55FFFF', font_style: ['italic']},
]);
const long = parser.toLog({text: 'player', hoverEvent: {action: 'show_text', contents: {text: 'x'.repeat(5000)}}});
assert.equal(long[0].hoverEvent.segments[0].message.length, 4096);
});