Bit layout [atlas:8][tile_id:20][rot:2][res:2] matches lib-core.maps init.lua so JS-produced GIDs are byte-identical to engine-produced ones. >>> 0 forces unsigned u32 output.
84 lines
2.8 KiB
JavaScript
84 lines
2.8 KiB
JavaScript
'use strict';
|
|
|
|
const test = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const { encodeGid, decodeGid } = require('../src/gid');
|
|
|
|
test('encodeGid: known reference value (0,12,1) = 196', () => {
|
|
assert.equal(encodeGid(0, 12, 1), 196);
|
|
});
|
|
|
|
test('encodeGid: default rotation is 0', () => {
|
|
assert.equal(encodeGid(0, 12), 192);
|
|
});
|
|
|
|
test('encodeGid: zero tuple yields 0', () => {
|
|
assert.equal(encodeGid(0, 0, 0), 0);
|
|
});
|
|
|
|
test('encodeGid: high atlas (255) produces unsigned u32', () => {
|
|
// 255 << 24 = 0xFF000000 = 4278190080 (must NOT be negative)
|
|
assert.equal(encodeGid(255, 0, 0), 4278190080);
|
|
});
|
|
|
|
test('encodeGid: max tile_id (1048575) fits 20 bits', () => {
|
|
// tile << 4 = 0xFFFFF0 = 16777200
|
|
assert.equal(encodeGid(0, 1048575, 0), 16777200);
|
|
});
|
|
|
|
test('encodeGid: throws on out-of-range atlas', () => {
|
|
assert.throws(() => encodeGid(256, 0, 0), /atlas/);
|
|
assert.throws(() => encodeGid(-1, 0, 0), /atlas/);
|
|
});
|
|
|
|
test('encodeGid: throws on out-of-range tile', () => {
|
|
assert.throws(() => encodeGid(0, 1048576, 0), /tile/);
|
|
assert.throws(() => encodeGid(0, -1, 0), /tile/);
|
|
});
|
|
|
|
test('encodeGid: throws on out-of-range rotation', () => {
|
|
assert.throws(() => encodeGid(0, 0, 4), /rotation/);
|
|
assert.throws(() => encodeGid(0, 0, -1), /rotation/);
|
|
});
|
|
|
|
test('encodeGid: throws on non-integer inputs', () => {
|
|
assert.throws(() => encodeGid(1.5, 0, 0), /atlas/);
|
|
assert.throws(() => encodeGid(0, '12', 0), /tile/);
|
|
});
|
|
|
|
test('decodeGid: empty (0) returns zeros', () => {
|
|
assert.deepEqual(decodeGid(0), { atlas: 0, tile: 0, rotation: 0 });
|
|
});
|
|
|
|
test('decodeGid: 196 unpacks to (0,12,1)', () => {
|
|
assert.deepEqual(decodeGid(196), { atlas: 0, tile: 12, rotation: 1 });
|
|
});
|
|
|
|
test('decodeGid: 16777232 from real demo map unpacks to (1,1,0)', () => {
|
|
// demo_v2.map.json wall layer uses 16777232 = (1<<24)|(1<<4)
|
|
assert.deepEqual(decodeGid(16777232), { atlas: 1, tile: 1, rotation: 0 });
|
|
});
|
|
|
|
test('decodeGid: high atlas (255,0,0) round-trip', () => {
|
|
assert.deepEqual(decodeGid(4278190080), { atlas: 255, tile: 0, rotation: 0 });
|
|
});
|
|
|
|
test('decodeGid: throws on non-integer or negative', () => {
|
|
assert.throws(() => decodeGid(-1), /gid/);
|
|
assert.throws(() => decodeGid(1.5), /gid/);
|
|
assert.throws(() => decodeGid(0x100000000), /gid/); // > u32 max
|
|
});
|
|
|
|
test('round-trip: 100 random tuples encode→decode losslessly', () => {
|
|
for (let i = 0; i < 100; i++) {
|
|
const atlas = Math.floor(Math.random() * 256);
|
|
const tile = Math.floor(Math.random() * 1048576);
|
|
const rotation = Math.floor(Math.random() * 4);
|
|
const gid = encodeGid(atlas, tile, rotation);
|
|
const decoded = decodeGid(gid);
|
|
assert.equal(decoded.atlas, atlas, `atlas mismatch for ${gid}`);
|
|
assert.equal(decoded.tile, tile, `tile mismatch for ${gid}`);
|
|
assert.equal(decoded.rotation, rotation, `rotation mismatch for ${gid}`);
|
|
}
|
|
});
|