You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

227 lines
8.1 KiB

import { describe, it, expect } from 'vitest';
7 months ago
import { createCurr } from '@/glob/lib/curr_engine.ts';
import { createLing, p } from '@/ling/lib/engine.ts';
import type { CurrDefinition } from '../lib/curr_types.ts';
// =============================================================================
// FIXTURES
// =============================================================================
const ling = createLing({ common: { ok: { es: 'Aceptar', en: 'OK' } } } as const, 'es');
const definitions: Record<string, CurrDefinition> = {
EUR: {
symbol : '€',
code : 'EUR',
name : p({ es: { one: 'euro', other: 'euros' }, en: { one: 'euro', other: 'euros' } }),
conversionValue: 1,
},
USD: {
symbol : '$',
code : 'USD',
name : p({ es: { one: 'dólar', other: 'dólares' }, en: { one: 'dollar', other: 'dollars' } }),
conversionValue: 1.08,
},
MXN: {
symbol : '$',
code : 'MXN',
name : p({ es: { one: 'peso mexicano', other: 'pesos mexicanos' }, en: { one: 'Mexican peso', other: 'Mexican pesos' } }),
conversionValue: 18.5,
},
GBP: {
symbol : '£',
code : 'GBP',
name : p({ es: { one: 'libra esterlina', other: 'libras esterlinas' }, en: { one: 'pound sterling', other: 'pounds sterling' } }),
conversionValue: 0.85,
},
JPY: {
symbol : '¥',
code : 'JPY',
name : p({ es: { one: 'yen', other: 'yenes' }, en: { one: 'yen', other: 'yen' } }),
conversionValue: null, // sin conversión disponible
},
};
// =============================================================================
// CURR — Formato y conversión de moneda
// =============================================================================
describe('createCurr', () => {
describe('selectedCurrency', () => {
it('usa la primera moneda definida por defecto', () => {
const curr = createCurr(definitions, ling, {}, 'es');
expect(curr.getCurrency()).toBe('EUR');
});
it('acepta selectedCurrency en la configuración', () => {
const curr = createCurr(definitions, ling, { selectedCurrency: 'MXN' }, 'es');
expect(curr.getCurrency()).toBe('MXN');
});
it('setCurrency cambia la moneda activa', () => {
const curr = createCurr(definitions, ling, { selectedCurrency: 'EUR' }, 'es');
curr.setCurrency('USD');
expect(curr.getCurrency()).toBe('USD');
});
it('setCurrency acepta minúsculas', () => {
const curr = createCurr(definitions, ling, {}, 'es');
curr.setCurrency('gbp');
expect(curr.getCurrency()).toBe('GBP');
});
});
describe('f() — display symbol (por defecto)', () => {
it('formatea con símbolo en es', () => {
const curr = createCurr(definitions, ling, { selectedCurrency: 'EUR' }, 'es');
expect(curr.f(99.5)).toBe('99,50 €');
});
it('formatea con símbolo en en', () => {
const curr = createCurr(definitions, ling, { selectedCurrency: 'EUR' }, 'en');
expect(curr.f(99.5)).toBe('99.50 €');
});
it('usa selectedCurrency activa', () => {
const curr = createCurr(definitions, ling, { selectedCurrency: 'EUR' }, 'es');
curr.setCurrency('GBP');
expect(curr.f(99.5)).toBe('99,50 £');
});
});
describe('f() — display code', () => {
it('formatea con código ISO', () => {
const curr = createCurr(definitions, ling, { selectedCurrency: 'EUR' }, 'es');
expect(curr.f(99.5, 'code')).toBe('99,50 EUR');
});
});
describe('f() — display name (pluralización)', () => {
it('singular en es', () => {
const curr = createCurr(definitions, ling, { selectedCurrency: 'EUR' }, 'es');
expect(curr.f(1, 'name')).toBe('1,00 euro');
});
it('plural en es', () => {
const curr = createCurr(definitions, ling, { selectedCurrency: 'EUR' }, 'es');
expect(curr.f(99.5, 'name')).toBe('99,50 euros');
});
it('singular en en', () => {
const curr = createCurr(definitions, ling, { selectedCurrency: 'EUR' }, 'en');
expect(curr.f(1, 'name')).toBe('1.00 euro');
});
it('plural MXN en es', () => {
const curr = createCurr(definitions, ling, { selectedCurrency: 'MXN' }, 'es');
expect(curr.f(2, 'name')).toBe('2,00 pesos mexicanos');
});
});
describe('f() — locale reactivo via función', () => {
it('responde a cambios de locale sin recrear el módulo', () => {
let locale = 'es';
const curr = createCurr(definitions, ling, { selectedCurrency: 'EUR' }, () => locale);
expect(curr.f(99.5)).toContain(',50 €');
locale = 'en';
expect(curr.f(99.5)).toContain('.50 €');
});
});
describe('f() — moneda no registrada', () => {
it('fallback al código ISO si la moneda no está definida', () => {
const curr = createCurr(definitions, ling, {}, 'es');
curr.setCurrency('XXX');
expect(curr.f(99.5)).toBe('99,50 XXX');
});
});
describe('convert()', () => {
it('convierte EUR a USD', () => {
const curr = createCurr(definitions, ling, { selectedCurrency: 'EUR' }, 'es');
expect(curr.convert(100, 'EUR', 'USD')).toBeCloseTo(108, 1);
});
it('convierte EUR a MXN', () => {
const curr = createCurr(definitions, ling, { selectedCurrency: 'EUR' }, 'es');
expect(curr.convert(100, 'EUR', 'MXN')).toBeCloseTo(1850, 0);
});
it('misma moneda devuelve el mismo valor', () => {
const curr = createCurr(definitions, ling, { selectedCurrency: 'EUR' }, 'es');
expect(curr.convert(100, 'EUR', 'EUR')).toBe(100);
});
it('devuelve null si conversionValue es null', () => {
const curr = createCurr(definitions, ling, { selectedCurrency: 'EUR' }, 'es');
expect(curr.convert(100, 'EUR', 'JPY')).toBeNull();
});
it('conversionValue como función dinámica', () => {
let rate = 1.08;
const defs = {
EUR: { ...definitions.EUR },
USD: { ...definitions.USD, conversionValue: () => rate },
};
const curr = createCurr(defs, ling, { selectedCurrency: 'EUR' }, 'es');
expect(curr.convert(100, 'EUR', 'USD')).toBeCloseTo(108, 1);
rate = 1.20;
expect(curr.convert(100, 'EUR', 'USD')).toBeCloseTo(120, 1);
});
});
describe('convertTo()', () => {
it('convierte desde selectedCurrency a otra moneda', () => {
const curr = createCurr(definitions, ling, { selectedCurrency: 'EUR' }, 'es');
expect(curr.convertTo(100, 'USD')).toBeCloseTo(108, 1);
});
it('respeta la moneda activa cambiada con setCurrency', () => {
const curr = createCurr(definitions, ling, { selectedCurrency: 'EUR' }, 'es');
curr.setCurrency('USD');
expect(curr.convertTo(108, 'EUR')).toBeCloseTo(100, 1);
});
});
describe('get()', () => {
it('devuelve la definición de una moneda registrada', () => {
const curr = createCurr(definitions, ling, {}, 'es');
expect(curr.get('EUR')?.symbol).toBe('€');
});
it('devuelve undefined para moneda no registrada', () => {
const curr = createCurr(definitions, ling, {}, 'es');
expect(curr.get('XXX')).toBeUndefined();
});
it('acepta minúsculas', () => {
const curr = createCurr(definitions, ling, {}, 'es');
expect(curr.get('eur')).toBeDefined();
});
});
});

Powered by TurnKey Linux.