import { describe, expect, it } from 'vitest' import { useChemicalFormula } from '../../composables/useChemicalFormula' const { parseFormula, calculateMW, renderFormulaParts } = useChemicalFormula() describe('useChemicalFormula parser (4b)', () => { it('should multiply a parenthesised group when it carries a count', () => { expect(parseFormula('Ca(OH)2').elements).toEqual({ Ca: 1, O: 2, H: 2 }) }) it('should add hydrate water when the formula uses a middle dot', () => { expect(parseFormula('CuSO4·5H2O').elements).toEqual({ Cu: 1, S: 1, O: 9, H: 10 }) }) it('should accept an asterisk as the hydrate separator', () => { expect(parseFormula('CuSO4*5H2O').elements).toEqual({ Cu: 1, S: 1, O: 9, H: 10 }) }) it('should name the symbol when an element is unknown', () => { expect(parseFormula('C6Xx2').error).toBe('Unknown element: Xx') }) it('should compute the molecular weight of glucose when parsed', () => { expect(calculateMW(parseFormula('C6H12O6').elements)).toBeCloseTo(180.156, 2) }) it('should render a hydrate coefficient as full-size text when it follows the dot', () => { expect(renderFormulaParts('CuSO4·5H2O')).toContainEqual({ type: 'coefficient', text: '5' }) }) it('should render the asterisk hydrate separator as a middle dot', () => { expect(renderFormulaParts('CuSO4*5H2O')).toContainEqual({ type: 'dot', text: '·' }) }) }) describe('useChemicalFormula charges', () => { it('should keep the subscript when a polyatomic ion has a bare trailing sign', () => { expect(parseFormula('NH4+').elements).toEqual({ N: 1, H: 4 }) }) it('should read the digits as the charge when a lone element has a bare trailing sign', () => { expect(parseFormula('Fe2+').elements).toEqual({ Fe: 1 }) }) it('should strip a caret charge when the formula ends with one', () => { expect(parseFormula('SO4^2-').elements).toEqual({ S: 1, O: 4 }) }) it('should reject the formula when it is only a charge', () => { expect(parseFormula('+').valid).toBe(false) }) it('should render the subscript when a polyatomic ion has a bare trailing sign', () => { expect(renderFormulaParts('NH4+')).toContainEqual({ type: 'subscript', text: '4' }) }) it('should render the digits as the charge when a lone element has a bare trailing sign', () => { expect(renderFormulaParts('Fe2+')).toEqual([{ type: 'element', text: 'Fe' }, { type: 'charge', text: '2+' }]) }) })