From f25af1b6ac24dbfdfb489318be825e63704f67c3 Mon Sep 17 00:00:00 2001 From: SEK1RO Date: Mon, 4 Aug 2025 17:46:42 +0300 Subject: [PATCH] test(Struct): Token --- test/Struct.test.js | 64 +++++++++++++++++++++++++++++++++++---------- test/index.js | 12 ++++----- 2 files changed, 56 insertions(+), 20 deletions(-) diff --git a/test/Struct.test.js b/test/Struct.test.js index a301dc1..99c6b49 100644 --- a/test/Struct.test.js +++ b/test/Struct.test.js @@ -1,5 +1,5 @@ import { describe, expect, test } from "vitest"; -import { parse, serialize, sizeof, Struct } from "../src"; +import { ConstDataView, parse, serialize, sizeof, Struct } from "../src"; import { expectDataViewEqual, filledDataView, sizedDataView } from "."; describe(Struct.name, () => { @@ -7,10 +7,11 @@ describe(Struct.name, () => { const User = Struct({ age: Number, name: String }) const user = { age: 1, name: 'hello' } const user_dv = filledDataView([ - 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0C, - 0x00, 0x00, 0x00, 0x05, - 0x68, 0x65, 0x6C, 0x6C, 0x6F, + 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // age + 0x00, 0x00, 0x00, 0x0C, // name_head + // name + 0x00, 0x00, 0x00, 0x05, // name.size + 0x68, 0x65, 0x6C, 0x6C, 0x6F, // name.data ]) test('serialize, headless', () => { @@ -30,8 +31,8 @@ describe(Struct.name, () => { const Vector2 = Struct({ x: Number, y: Number }) const vector2 = { x: 1, y: 2 } const vector2_dv = filledDataView([ - 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // x + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // y ]) test('serialize, non-headless', () => { @@ -49,13 +50,16 @@ describe(Struct.name, () => { const Nested = Struct({ user: User, vector2: [Vector2] }) const nested = { user, vector2 } const nested_dv = filledDataView([ - 0x00, 0x00, 0x00, 0x14, - 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0C, - 0x00, 0x00, 0x00, 0x05, - 0x68, 0x65, 0x6C, 0x6C, 0x6F, + 0x00, 0x00, 0x00, 0x14, // user_head + // vector2 + 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // vector2.x + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // vector2.y + // user + 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // user.age + 0x00, 0x00, 0x00, 0x0C, // user.name_head + // user.name + 0x00, 0x00, 0x00, 0x05, // user.name.size + 0x68, 0x65, 0x6C, 0x6C, 0x6F, // user.name.data ]) test('serialize, nested', () => { @@ -67,4 +71,36 @@ describe(Struct.name, () => { test('parse, nested', () => { expectDataViewEqual(parse(nested_dv, Nested), nested) }) + + const Token = Struct({ + data: Struct({ name: String }), + header: Struct({ expires: Number }), + signature: ConstDataView(4), + }) + const token = { + data: { name: 'sek1ro' }, + header: { expires: 1 }, + signature: sizedDataView(4), + } + const token_dv = filledDataView([ + 0x00, 0x00, 0x00, 0x10, // data_head + // header + 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // header.expires + 0x00, 0x00, 0x00, 0x00, // signature + // data + 0x00, 0x00, 0x00, 0x04, // data.name_head + // data.name + 0x00, 0x00, 0x00, 0x06, + 0x73, 0x65, 0x6b, 0x31, 0x72, 0x6f, + ]) + + test('serialize, Token', () => { + const dv = sizedDataView(sizeof(token, Token)) + serialize(dv, token, Token) + expectDataViewEqual(dv, token_dv) + }) + + test('parse, Token', () => { + expectDataViewEqual(parse(token_dv, Token), token) + }) }) diff --git a/test/index.js b/test/index.js index e47ea82..63067e9 100644 --- a/test/index.js +++ b/test/index.js @@ -1,5 +1,3 @@ -import { expect } from "vitest" - export function filledDataView(bytes) { const ab = new ArrayBuffer(bytes.length) const dv = new DataView(ab) @@ -19,17 +17,19 @@ export function sizedDataView(length) { export function expectDataViewEqual(actual, expected) { const actualBytes = new Uint8Array(actual.buffer, actual.byteOffset, actual.byteLength) const expectedBytes = new Uint8Array(expected.buffer, expected.byteOffset, expected.byteLength) + const arraysToString = () => { + return `actual: [${Array.from(actualBytes).map(byte => '0x' + byte.toString(16)).join(', ')}]\n` + + `expected: [${Array.from(expectedBytes).map(byte => '0x' + byte.toString(16)).join(', ')}]` + } if (actualBytes.length !== expectedBytes.length) { - throw new Error(`DataView length mismatch: ${actualBytes.length} !== ${expectedBytes.length}`) + throw new Error(`DataView length mismatch: actual: ${actualBytes.length}, expected: ${expectedBytes.length}\n` + arraysToString()) } for (let i = 0; i < actualBytes.length; i++) { if (actualBytes[i] !== expectedBytes[i]) { throw new Error( - `Byte mismatch at offset ${i}: 0x${actualBytes[i].toString(16)} !== 0x${expectedBytes[i].toString(16)}\n` + - `actual: [${Array.from(actualBytes).map(byte => '0x' + byte.toString(16)).join(', ')}]\n` + - `expected: [${Array.from(expectedBytes).map(byte => '0x' + byte.toString(16)).join(', ')}]` + `Byte mismatch at offset ${i}: 0x${actualBytes[i].toString(16)} !== 0x${expectedBytes[i].toString(16)}\n` + arraysToString() ) } }