fix(07-15): drop unencodable replay params instead of a zero-length record

- normalizeParam returns null for an unencodable param value, matching its own jsDoc and the documented discard semantics of normalizeParamList
- the command param count, the bytes actually written and the param cursor stay consistent so later commands keep their correct byte offsets
- add the discard-alignment regression case (count 0, later command bytes intact, read stream aligned)
This commit is contained in:
unanmed 2026-09-17 20:48:47 +08:00
parent 53f067a0af
commit a7c9f97c94
2 changed files with 20 additions and 6 deletions

View File

@ -1,4 +1,4 @@
// 测试 ReplayArray 构件级行为:单类型参数编解码与单数组操作单次读回
// 测试 ReplayArray 构件级行为:单类型参数编解码与单数组操作单次读回、不可编码参数丢弃后的计数与偏移对齐
import { logger } from '@motajs/common';
import { afterAll, describe, expect, it, vi } from 'vitest';
import { ReplayArray } from './array';
@ -700,6 +700,24 @@ describe('ReplayArray param codec', () => {
expect(stream.index).toBe(2);
});
// 验证不可编码的参数被丢弃后命令参数计数为 0,且后续命令的字节与读流偏移不错位
it('drops the unencodable param and keeps the later commands aligned', () => {
const array = createArray();
const { info } = logger.catch(() => array.add(1, [undefined!]));
array.add(2, [20]);
expect(info.map(v => v.code)).toContain(148);
expect(new Uint8Array(array.getCommandArray())[0]).toBe(0);
expect(array.get(0)).toEqual({ command: 1, params: [], index: 0 });
expect(array.get(1)).toEqual({ command: 2, params: [20], index: 1 });
const stream = array.createReadStream(0);
expectStepTyped(stream.read()!, 1, [], 1);
expectStepTyped(stream.read()!, 2, [20], 2);
expect(stream.read()).toBeNull();
expect(stream.index).toBe(2);
});
// 验证单条命令参数超过 255 个时触发告警码 153 并忽略溢出参数
it('warns code 153 when a command exceeds 255 params', () => {
const array = createArray({

View File

@ -308,11 +308,7 @@ export class ReplayArray implements IReplayArray {
}
}
logger.warn(148, typeof param, String(param));
return {
paramType: 0,
paramValue: 0,
byteLength: 0
};
return null;
}
/**