chore: initial commit
This commit is contained in:
@@ -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);
|
||||
});
|
||||
Reference in New Issue
Block a user