Add atlas-spec loader with duplicate handling
loadAtlasDirs walks one level deep into each --atlas-dir, picks up */tiles.atlas.json, and builds bidirectional name/id maps. On duplicate atlas_id across paths the first registration wins and a warning string is returned (callers decide whether to print).
This commit is contained in:
63
tests/atlas-loader.test.js
Normal file
63
tests/atlas-loader.test.js
Normal file
@@ -0,0 +1,63 @@
|
||||
'use strict';
|
||||
|
||||
const test = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const path = require('node:path');
|
||||
const { loadAtlasDirs } = require('../src/atlas-loader');
|
||||
|
||||
const FIX = path.join(__dirname, 'fixtures', 'atlases');
|
||||
const FIX_DUP = path.join(__dirname, 'fixtures', 'atlases-dup');
|
||||
|
||||
test('loadAtlasDirs: discovers two atlases in one dir', () => {
|
||||
const { registry, warnings } = loadAtlasDirs([FIX]);
|
||||
assert.equal(warnings.length, 0);
|
||||
assert.deepEqual(Object.keys(registry).sort(), ['atlas_a', 'atlas_b']);
|
||||
});
|
||||
|
||||
test('loadAtlasDirs: builds tilesByName and tilesById maps', () => {
|
||||
const { registry } = loadAtlasDirs([FIX]);
|
||||
const a = registry['atlas_a'];
|
||||
assert.equal(a.tilesByName['grass'], 1);
|
||||
assert.equal(a.tilesByName['stone'], 2);
|
||||
assert.equal(a.tilesById[1], 'grass');
|
||||
assert.equal(a.tilesById[2], 'stone');
|
||||
assert.ok(a.specPath.endsWith('tiles.atlas.json'));
|
||||
});
|
||||
|
||||
test('loadAtlasDirs: empty input → empty registry, no warnings', () => {
|
||||
const { registry, warnings } = loadAtlasDirs([]);
|
||||
assert.deepEqual(registry, {});
|
||||
assert.deepEqual(warnings, []);
|
||||
});
|
||||
|
||||
test('loadAtlasDirs: duplicate atlas_id → first wins, warning emitted', () => {
|
||||
const { registry, warnings } = loadAtlasDirs([FIX, FIX_DUP]);
|
||||
// First dir wins: atlas_a has 'grass' name, not 'ALT_grass'
|
||||
assert.equal(registry['atlas_a'].tilesByName['grass'], 1);
|
||||
assert.equal(registry['atlas_a'].tilesByName['ALT_grass'], undefined);
|
||||
assert.equal(warnings.length, 1);
|
||||
assert.match(warnings[0], /atlas_a/);
|
||||
assert.match(warnings[0], /duplicate/i);
|
||||
});
|
||||
|
||||
test('loadAtlasDirs: reverse path order swaps the winner', () => {
|
||||
const { registry, warnings } = loadAtlasDirs([FIX_DUP, FIX]);
|
||||
assert.equal(registry['atlas_a'].tilesByName['ALT_grass'], 1);
|
||||
assert.equal(registry['atlas_a'].tilesByName['grass'], undefined);
|
||||
assert.equal(warnings.length, 1);
|
||||
});
|
||||
|
||||
test('loadAtlasDirs: missing directory throws', () => {
|
||||
assert.throws(
|
||||
() => loadAtlasDirs(['/no/such/path/exists']),
|
||||
/no such directory/i
|
||||
);
|
||||
});
|
||||
|
||||
test('loadAtlasDirs: dir with no tiles.atlas.json subdirs → empty registry', () => {
|
||||
// Use sporel-tool-mapper/src/ which has no atlas specs
|
||||
const noAtlasDir = path.join(__dirname, '..', 'src');
|
||||
const { registry, warnings } = loadAtlasDirs([noAtlasDir]);
|
||||
assert.deepEqual(registry, {});
|
||||
assert.equal(warnings.length, 0);
|
||||
});
|
||||
Reference in New Issue
Block a user