feat(DataView, ConstDataView)

This commit is contained in:
2025-08-04 15:33:12 +03:00
parent 72f6102f0c
commit 504bfbeae8
11 changed files with 179 additions and 37 deletions

View File

@ -1,6 +1,6 @@
import { describe, expect, test } from "vitest";
import { ConstArray, parse, serialize, sizeof, sizeofHead } from "../src";
import { filledDataView, sizedDataView } from ".";
import { expectDataViewEqual, filledDataView, sizedDataView } from ".";
describe(ConstArray.name, () => {
test('serialize, Number', () => {
@ -15,7 +15,7 @@ describe(ConstArray.name, () => {
expect(16).toEqual(dv.byteLength)
serialize(dv, [1, 2], ConstArray(2), Number)
expect(dv).toEqual(expected)
expectDataViewEqual(dv, expected)
})
test('parse, Number', () => {
@ -25,7 +25,7 @@ describe(ConstArray.name, () => {
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
])
const actual = parse(dv, ConstArray(2), Number)
expect(actual).toEqual(expected)
expectDataViewEqual(actual, expected)
})
test('sizeof', () => {

View File

@ -0,0 +1,31 @@
import { describe, expect, test } from "vitest";
import { ConstDataView, parse, serialize, sizeofHead } from "../src";
import { expectDataViewEqual, filledDataView } from ".";
describe(ConstDataView.name, () => {
test('serialize', () => {
const expected = filledDataView([0x00, 0x00, 0x01, 0x02, 0x00, 0x00])
const dv = filledDataView([0x01, 0x02])
const buffer = new ArrayBuffer(6)
let actual = new DataView(buffer, 2, 1)
expect(() => serialize(actual, dv, ConstDataView(2))).toThrow()
actual = new DataView(buffer, 2, 2)
serialize(actual, dv, ConstDataView(2))
expectDataViewEqual(new DataView(actual.buffer), expected)
})
test('parse', () => {
const expected = filledDataView([0x01, 0x02])
const dv = filledDataView([0x00, 0x00, 0x01, 0x02, 0x00, 0x00])
const frame = new DataView(dv.buffer, dv.byteOffset + 2, 2)
const actual = parse(frame, ConstDataView(2))
expectDataViewEqual(actual, expected)
})
test('sizeof', () => {
expect(sizeofHead(ConstDataView(2))).toEqual(2)
})
})

View File

@ -1,6 +1,6 @@
import { describe, expect, test } from "vitest";
import { ConstString, parse, serialize, sizeofHead } from "../src";
import { filledDataView, sizedDataView } from ".";
import { expectDataViewEqual, filledDataView, sizedDataView } from ".";
describe(ConstString.name, () => {
test('serialize', () => {
@ -11,14 +11,14 @@ describe(ConstString.name, () => {
dv = sizedDataView(5)
serialize(dv, 'hello', ConstString(3))
expect(dv).toEqual(expected)
expectDataViewEqual(dv, expected)
})
test('parse', () => {
const expected = 'hel'
const dv = filledDataView([0x68, 0x65, 0x6C, 0x6C, 0x6F])
const actual = parse(dv, ConstString(3))
expect(actual).toEqual(expected)
expectDataViewEqual(actual, expected)
})
test('sizeof', () => {

View File

@ -1,6 +1,6 @@
import { describe, expect, test } from "vitest";
import { parse, serialize, sizeof, Struct } from "../src";
import { filledDataView, sizedDataView } from ".";
import { expectDataViewEqual, filledDataView, sizedDataView } from ".";
describe(Struct.name, () => {
@ -20,11 +20,11 @@ describe(Struct.name, () => {
expect(21).toEqual(dv.byteLength)
serialize(dv, user, User)
expect(dv).toEqual(user_dv)
expectDataViewEqual(dv, user_dv)
})
test('parse, headless', () => {
expect(parse(user_dv, User)).toEqual(user)
expectDataViewEqual(parse(user_dv, User), user)
})
const Vector2 = Struct({ x: Number, y: Number })
@ -39,11 +39,11 @@ describe(Struct.name, () => {
expect(16).toEqual(dv.byteLength)
serialize(dv, vector2, Vector2)
expect(dv).toEqual(vector2_dv)
expectDataViewEqual(dv, vector2_dv)
})
test('parse, non-headless', () => {
expect(parse(vector2_dv, Vector2)).toEqual(vector2)
expectDataViewEqual(parse(vector2_dv, Vector2), vector2)
})
const Nested = Struct({ user: User, vector2: [Vector2] })
@ -61,10 +61,10 @@ describe(Struct.name, () => {
test('serialize, nested', () => {
const dv = sizedDataView(sizeof(nested, Nested))
serialize(dv, nested, Nested)
expect(dv).toEqual(nested_dv)
expectDataViewEqual(dv, nested_dv)
})
test('parse, nested', () => {
expect(parse(nested_dv, Nested)).toEqual(nested)
expectDataViewEqual(parse(nested_dv, Nested), nested)
})
})

View File

@ -1,11 +1,13 @@
import { expect } from "vitest"
export function filledDataView(bytes) {
const ab = new ArrayBuffer(bytes.length)
const dv = new DataView(ab)
for (let i = 0; i < bytes.length; i++) {
dv.setInt8(i, bytes[i])
}
return dv
}
@ -13,3 +15,22 @@ export function sizedDataView(length) {
const ab = new ArrayBuffer(length)
return new DataView(ab)
}
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)
if (actualBytes.length !== expectedBytes.length) {
throw new Error(`DataView length mismatch: ${actualBytes.length} !== ${expectedBytes.length}`)
}
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(', ')}]`
)
}
}
}

View File

@ -1,5 +1,5 @@
import { describe, test, expect } from 'vitest'
import { filledDataView, sizedDataView } from '.'
import { expectDataViewEqual, filledDataView, sizedDataView } from '.'
import { parse, serialize, sizeof, sizeofHead } from '../src'
describe('serialize', () => {
@ -12,7 +12,7 @@ describe('serialize', () => {
expect(8).toEqual(dv.byteLength)
serialize(dv, 1532.625, Number)
expect(dv).toEqual(expected)
expectDataViewEqual(dv, expected)
})
test('String', () => {
const expected = filledDataView([
@ -26,7 +26,7 @@ describe('serialize', () => {
expect(9).toEqual(dv.byteLength)
serialize(dv, 'hello', String)
expect(dv).toEqual(expected)
expectDataViewEqual(dv, expected)
})
test('Array, Number', () => {
const expected = filledDataView([
@ -41,7 +41,22 @@ describe('serialize', () => {
expect(20).toEqual(dv.byteLength)
serialize(dv, [1, 2], Array, Number)
expect(dv).toEqual(expected)
expectDataViewEqual(dv, expected)
})
test('DataView', () => {
const expected = filledDataView([
0x00, 0x00, 0x00, 0x04,
0x00, 0x01, 0x02, 0x03,
])
const dv = filledDataView([
0x00, 0x01, 0x02, 0x03,
])
let actual = sizedDataView(7)
expect(() => serialize(actual, dv, DataView)).toThrow()
actual = sizedDataView(8)
serialize(actual, dv, DataView)
expectDataViewEqual(actual, expected)
})
})
@ -50,7 +65,7 @@ describe('parse', () => {
const expected = 1532.625
const dv = filledDataView([0x40, 0x97, 0xF2, 0x80, 0x00, 0x00, 0x00, 0x00])
const actual = parse(dv, Number)
expect(actual).toEqual(expected)
expectDataViewEqual(actual, expected)
})
test('String', () => {
const expected = 'hello'
@ -59,7 +74,7 @@ describe('parse', () => {
0x68, 0x65, 0x6C, 0x6C, 0x6F
])
const actual = parse(dv, String)
expect(actual).toEqual(expected)
expectDataViewEqual(actual, expected)
})
test('Array, Number', () => {
const expected = [1, 2]
@ -69,7 +84,18 @@ describe('parse', () => {
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
])
const actual = parse(dv, Array, Number)
expect(actual).toEqual(expected)
expectDataViewEqual(actual, expected)
})
test('DataView', () => {
const expected = filledDataView([
0x00, 0x01, 0x02, 0x03,
])
const dv = filledDataView([
0x00, 0x00, 0x00, 0x04,
0x00, 0x01, 0x02, 0x03,
])
const actual = parse(dv, DataView)
expectDataViewEqual(actual, expected)
})
})