57 lines
2.6 KiB
TypeScript
57 lines
2.6 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { deterministicExtractor } from '@/lib/voice/extractor';
|
|
import type { RawCallData } from '@/lib/voice/preferences';
|
|
import type { CatalogItem } from '@/budget/types';
|
|
|
|
const catalog: CatalogItem[] = [
|
|
{ id: 'suelo-m', categoria: 'suelo', nombre: 'Cerámico', calidad: 'media', precioUnit: 2800, unidad: 'm2', descriptorRender: 'suelo cerámico gris', esDefault: true, sku: 'SUE-M' },
|
|
{ id: 'suelo-p', categoria: 'suelo', nombre: 'Tarima madera clara', calidad: 'premium', precioUnit: 4500, unidad: 'm2', descriptorRender: 'tarima madera clara', esDefault: true, sku: 'SUE-P' },
|
|
{ id: 'mob-p', categoria: 'mobiliario', nombre: 'Muebles premium con encimera', calidad: 'premium', precioUnit: 52000, unidad: 'ml', descriptorRender: 'muebles lacados blancos', esDefault: true, sku: 'MOB-P' },
|
|
];
|
|
|
|
function raw(partial: Partial<RawCallData>): RawCallData {
|
|
return {
|
|
tipoReforma: 'cocina',
|
|
m2Suelo: 16,
|
|
calidad: null,
|
|
estructural: null,
|
|
urgencia: 'media',
|
|
presupuestoTarget: null,
|
|
tasteText: '',
|
|
...partial,
|
|
};
|
|
}
|
|
|
|
describe('deterministicExtractor', () => {
|
|
it('abstrae calidad, material, elemento, estilo y ajuste de un texto de gustos', () => {
|
|
const r = deterministicExtractor.extract(
|
|
raw({ tasteText: 'Quiero algo premium, estilo nórdico con madera clara. Me encantaría una isla y encimera de cuarzo.' }),
|
|
catalog,
|
|
);
|
|
expect(r.calidadGlobal).toBe('premium');
|
|
expect(r.materialSelections.suelo).toBe('suelo-p');
|
|
expect(r.elementos.map((e) => e.key)).toContain('isla_cocina');
|
|
expect(r.estiloRender).toContain('nordico');
|
|
expect(r.estiloRender).toContain('madera clara');
|
|
expect(r.ajustes.map((a) => a.label)).toContain('Encimera de piedra natural');
|
|
expect(r.confianza).toBe('alta'); // m² + ≥2 señales
|
|
});
|
|
|
|
it('el slot de calidad explícito gana al texto', () => {
|
|
const r = deterministicExtractor.extract(raw({ calidad: 'basica', tasteText: 'algo premium de lujo' }), catalog);
|
|
expect(r.calidadGlobal).toBe('basica');
|
|
});
|
|
|
|
it('detecta cambio estructural desde el texto libre', () => {
|
|
const r = deterministicExtractor.extract(raw({ tasteText: 'quiero tirar el muro entre cocina y salón' }), catalog);
|
|
expect(r.estructural).toBe(true);
|
|
});
|
|
|
|
it('texto vacío y sin m² → confianza baja y campos faltantes', () => {
|
|
const r = deterministicExtractor.extract(raw({ m2Suelo: null, urgencia: null, tasteText: '' }), catalog);
|
|
expect(r.confianza).toBe('baja');
|
|
expect(r.camposFaltantes).toContain('m2');
|
|
expect(r.camposFaltantes).toContain('preferencias');
|
|
});
|
|
});
|