feat: better supported hybrid units

This commit is contained in:
Leyla Becker 2026-02-22 17:37:00 -06:00
parent 93837aaf20
commit bac7a14f95
4 changed files with 273 additions and 8 deletions

View file

@ -244,4 +244,83 @@ describe('tools section scaling', () => {
// Both should exist in countScalables
expect(countScalables.length).toBeGreaterThanOrEqual(1);
});
});
// ─── Hybrid Weight/Volume Measurements ───────────────────
function getHybridAttrs(html) {
const matches = [];
const re = /data-hybrid="true"[^>]*data-volume-default="([^"]*)"[^>]*data-volume-alt="([^"]*)"(?:[^>]*data-volume-scalable="([^"]*)")?/g;
let m;
while ((m = re.exec(html)) !== null) {
matches.push({
volumeDefault: decodeHtmlEntities(m[1]),
volumeAlt: decodeHtmlEntities(m[2]),
volumeScalable: m[3] ? JSON.parse(decodeHtmlEntities(m[3])) : null,
});
}
return matches;
}
describe('hybrid weight/volume measurements', () => {
it('adds hybrid data attributes for weight with volume alt', () => {
const md = '- unsalted butter 80g (6 tablespoons)';
const html = render(md);
expect(html).toContain('data-hybrid="true"');
expect(html).toContain('data-volume-default=');
expect(html).toContain('data-volume-alt=');
expect(html).toContain('data-volume-scalable=');
});
it('does NOT add hybrid attributes for weight-to-weight alt', () => {
const md = '- butter 227g (8 oz)';
const html = render(md);
expect(html).not.toContain('data-hybrid');
});
it('generates correct volume texts for simple hybrid', () => {
const md = '- unsalted butter 80g (6 tablespoons)';
const html = render(md);
const hybrids = getHybridAttrs(html);
expect(hybrids.length).toBe(1);
// 6 tbsp = 6 * 14.787 = 88.722ml -> metric: "88.7ml"
expect(hybrids[0].volumeDefault).toBe('88.7ml');
expect(hybrids[0].volumeAlt).toBe('6 tbsp');
});
it('handles nested hybrid with intermediate', () => {
const md = '- milk 860g (800mL (3 1/3 cups))';
const html = render(md);
const hybrids = getHybridAttrs(html);
expect(hybrids.length).toBe(1);
expect(hybrids[0].volumeDefault).toBe('800ml');
});
it('includes volume scalable data with base in ml', () => {
const md = '- unsalted butter 80g (6 tablespoons)';
const html = render(md);
const hybrids = getHybridAttrs(html);
expect(hybrids.length).toBe(1);
expect(hybrids[0].volumeScalable).toBeDefined();
expect(hybrids[0].volumeScalable.type).toBe('volume');
// 6 tablespoons = 6 * 14.787 = 88.722 ml
expect(hybrids[0].volumeScalable.base).toBeCloseTo(88.722, 0);
});
it('includes volume scalable data for nested hybrid', () => {
const md = '- milk 860g (800mL (3 1/3 cups))';
const html = render(md);
const hybrids = getHybridAttrs(html);
expect(hybrids.length).toBe(1);
expect(hybrids[0].volumeScalable.type).toBe('volume');
expect(hybrids[0].volumeScalable.base).toBeCloseTo(800, 0);
});
it('still has weight data attributes alongside hybrid attrs', () => {
const md = '- unsalted butter 80g (6 tablespoons)';
const html = render(md);
// Should still have the weight default/alt
expect(html).toContain('data-default="80g"');
expect(html).toContain('data-measurement-type="weight"');
});
});