Init atlas-baker tool with source-dir scan and pair-detection
Creates the sporel-tool-atlas-baker Node CLI scaffold and the first phase of the bake pipeline: scan a source directory for *_diffuse.png files, pair them with optional *_height.png companions, and return alphabetically-sorted sources for deterministic re-bakes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
40
tests/fixtures/_setup.js
vendored
Normal file
40
tests/fixtures/_setup.js
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
// tests/fixtures/_setup.js
|
||||
// Run once to create test fixtures. Not part of regular tests.
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
const { PNG } = require('pngjs');
|
||||
|
||||
function writeSolidPng(filePath, w, h, rgba) {
|
||||
const png = new PNG({ width: w, height: h });
|
||||
for (let y = 0; y < h; y++) {
|
||||
for (let x = 0; x < w; x++) {
|
||||
const i = (y * w + x) * 4;
|
||||
png.data[i + 0] = rgba[0];
|
||||
png.data[i + 1] = rgba[1];
|
||||
png.data[i + 2] = rgba[2];
|
||||
png.data[i + 3] = rgba[3];
|
||||
}
|
||||
}
|
||||
fs.writeFileSync(filePath, PNG.sync.write(png));
|
||||
}
|
||||
|
||||
function writeSolidL8Png(filePath, w, h, v) {
|
||||
const png = new PNG({ width: w, height: h, colorType: 0 }); // grayscale
|
||||
for (let y = 0; y < h; y++) {
|
||||
for (let x = 0; x < w; x++) {
|
||||
png.data[(y * w + x) * 4 + 0] = v;
|
||||
png.data[(y * w + x) * 4 + 1] = v;
|
||||
png.data[(y * w + x) * 4 + 2] = v;
|
||||
png.data[(y * w + x) * 4 + 3] = 255;
|
||||
}
|
||||
}
|
||||
fs.writeFileSync(filePath, PNG.sync.write(png));
|
||||
}
|
||||
|
||||
const dir = path.resolve(__dirname, 'small-fresh');
|
||||
fs.mkdirSync(dir, { recursive: true });
|
||||
writeSolidPng(path.join(dir, 'grass_diffuse.png'), 32, 32, [110, 170, 80, 255]);
|
||||
writeSolidPng(path.join(dir, 'stone_diffuse.png'), 32, 32, [120, 120, 120, 255]);
|
||||
writeSolidPng(path.join(dir, 'water_diffuse.png'), 32, 32, [ 60, 110, 180, 255]);
|
||||
writeSolidL8Png(path.join(dir, 'water_height.png'), 32, 32, 0); // L8=0 plane
|
||||
console.log('fixtures written: small-fresh/');
|
||||
BIN
tests/fixtures/small-fresh/grass_diffuse.png
vendored
Normal file
BIN
tests/fixtures/small-fresh/grass_diffuse.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 128 B |
BIN
tests/fixtures/small-fresh/stone_diffuse.png
vendored
Normal file
BIN
tests/fixtures/small-fresh/stone_diffuse.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 125 B |
BIN
tests/fixtures/small-fresh/water_diffuse.png
vendored
Normal file
BIN
tests/fixtures/small-fresh/water_diffuse.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 128 B |
BIN
tests/fixtures/small-fresh/water_height.png
vendored
Normal file
BIN
tests/fixtures/small-fresh/water_height.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 124 B |
28
tests/scan.test.js
Normal file
28
tests/scan.test.js
Normal file
@@ -0,0 +1,28 @@
|
||||
// tests/scan.test.js
|
||||
const { test } = require('node:test');
|
||||
const assert = require('node:assert');
|
||||
const path = require('node:path');
|
||||
const { scanSourceDir } = require('../src/scan');
|
||||
|
||||
const FIXTURE_DIR = path.resolve(__dirname, 'fixtures/small-fresh');
|
||||
|
||||
test('scan: 3 diffuse + 1 paired height', () => {
|
||||
const { sources, errors } = scanSourceDir(FIXTURE_DIR);
|
||||
assert.deepStrictEqual(errors, []);
|
||||
assert.strictEqual(sources.length, 3);
|
||||
// Sorted alphabetically
|
||||
assert.strictEqual(sources[0].name, 'grass');
|
||||
assert.strictEqual(sources[1].name, 'stone');
|
||||
assert.strictEqual(sources[2].name, 'water');
|
||||
// grass + stone have no height
|
||||
assert.strictEqual(sources[0].heightPath, null);
|
||||
assert.strictEqual(sources[1].heightPath, null);
|
||||
// water has height
|
||||
assert.ok(sources[2].heightPath?.endsWith('water_height.png'));
|
||||
});
|
||||
|
||||
test('scan: empty dir -> error', () => {
|
||||
const { sources, errors } = scanSourceDir(path.resolve(__dirname, 'fixtures/_empty'));
|
||||
assert.strictEqual(sources.length, 0);
|
||||
assert.ok(errors.length > 0);
|
||||
});
|
||||
Reference in New Issue
Block a user