Files
gmtool/tests/art/library.test.js
T
slaguru666andClaude Opus 4.8 028dcb5e4e feat: online art Generate — configured endpoint, cached into the library
Add the art tray's online Generate: prompt → a GM-configured image-gen
endpoint → new pencil image cached into a persisted, searchable library
(offline thereafter). No endpoint or key is hardcoded — the GM pastes
their gen URL (⚙ field, persisted). Degrades gracefully: unconfigured or
offline → Generate disabled, library search fully works; network is never
load-bearing.

- src/art/generate.js: createArtGenerator (injectable fetch/navigator).
- src/art/library.js: pure addGenerated (dedupe + cap 24).
- art-tray: generate row, endpoint config, generated cache (gmd.art.*).

Tests: generate.test.js, library.test.js, art-tray-generate.test.js;
existing art-tray tests unchanged. 206 tests pass; build clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 23:48:05 +01:00

36 lines
1.6 KiB
JavaScript

import { describe, it, expect } from 'vitest';
import { addGenerated, makeAssetId, slugifyLabel } from '../../src/art/library.js';
const BASE = [{ id: 'rain-pier', src: '/a.png', label: 'Pier in the rain', tags: ['rain'] }];
describe('art library helpers', () => {
it('slugifies labels', () => {
expect(slugifyLabel('Tired Detective — in the Rain')).toBe('tired-detective-in-the-rain');
});
it('makes ids unique against taken ids', () => {
expect(makeAssetId('Rainy Pier', [])).toBe('rainy-pier');
expect(makeAssetId('Rainy Pier', ['rainy-pier'])).toBe('rainy-pier-2');
});
it('prepends a generated asset with a unique id and generated flag', () => {
const out = addGenerated([], BASE, { src: 'data:x', label: 'Rainy Pier', tags: ['rain', 'pier'] });
expect(out).toHaveLength(1);
expect(out[0]).toEqual({ id: 'rainy-pier', src: 'data:x', label: 'Rainy Pier', tags: ['rain', 'pier'], generated: true });
});
it('avoids colliding with a base manifest id', () => {
const out = addGenerated([], BASE, { src: 'data:y', label: 'Pier in the rain' });
expect(out[0].id).toBe('pier-in-the-rain'); // differs from base 'rain-pier', so no suffix needed
const out2 = addGenerated(out, BASE, { src: 'data:z', label: 'Pier in the rain' });
expect(out2[0].id).toBe('pier-in-the-rain-2');
});
it('caps the generated list to bound storage (newest kept)', () => {
let gen = [];
for (let i = 0; i < 30; i++) gen = addGenerated(gen, BASE, { src: 'd' + i, label: 'img ' + i }, 24);
expect(gen).toHaveLength(24);
expect(gen[0].label).toBe('img 29'); // newest first
});
});