51 lines
1.9 KiB
TypeScript
51 lines
1.9 KiB
TypeScript
|
|
import { describe, expect, test } from 'bun:test';
|
||
|
|
import { extractJson, coerceLabel } from '../src/classify-parse.js';
|
||
|
|
|
||
|
|
describe('extractJson', () => {
|
||
|
|
test('pulls a JSON object out of a fenced/chatty reply', () => {
|
||
|
|
const reply = 'Here you go:\n```json\n{"category":"glamour","thumbnailFitness":0.9}\n```\nDone.';
|
||
|
|
expect(extractJson(reply)).toEqual({ category: 'glamour', thumbnailFitness: 0.9 });
|
||
|
|
});
|
||
|
|
test('handles nested braces', () => {
|
||
|
|
expect(extractJson('{"a":{"b":1},"c":2} trailing')).toEqual({ a: { b: 1 }, c: 2 });
|
||
|
|
});
|
||
|
|
test('returns null when there is no object', () => {
|
||
|
|
expect(extractJson('no json here')).toBeNull();
|
||
|
|
expect(extractJson('{ broken')).toBeNull();
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
describe('coerceLabel', () => {
|
||
|
|
test('accepts a valid label', () => {
|
||
|
|
const l = coerceLabel('photo-1', {
|
||
|
|
category: 'headshot',
|
||
|
|
thumbnailFitness: 0.8,
|
||
|
|
faceVisible: true,
|
||
|
|
note: 'close crop',
|
||
|
|
});
|
||
|
|
expect(l).toEqual({
|
||
|
|
photoId: 'photo-1',
|
||
|
|
category: 'headshot',
|
||
|
|
thumbnailFitness: 0.8,
|
||
|
|
faceVisible: true,
|
||
|
|
note: 'close crop',
|
||
|
|
});
|
||
|
|
});
|
||
|
|
test('falls back to portrait on an unknown category', () => {
|
||
|
|
expect(coerceLabel('p', { category: 'banana' }).category).toBe('portrait');
|
||
|
|
});
|
||
|
|
test('unwraps a one-element array category (model quirk)', () => {
|
||
|
|
expect(coerceLabel('p', { category: ['lifestyle'] }).category).toBe('lifestyle');
|
||
|
|
});
|
||
|
|
test('clamps fitness to 0..1 and defaults non-numbers to 0', () => {
|
||
|
|
expect(coerceLabel('p', { thumbnailFitness: 5 }).thumbnailFitness).toBe(1);
|
||
|
|
expect(coerceLabel('p', { thumbnailFitness: -2 }).thumbnailFitness).toBe(0);
|
||
|
|
expect(coerceLabel('p', { thumbnailFitness: 'x' }).thumbnailFitness).toBe(0);
|
||
|
|
});
|
||
|
|
test('coerces faceVisible and note types', () => {
|
||
|
|
const l = coerceLabel('p', { faceVisible: 1, note: 42 });
|
||
|
|
expect(l.faceVisible).toBe(true);
|
||
|
|
expect(l.note).toBe('');
|
||
|
|
});
|
||
|
|
});
|