import { describe, it, expect } from 'vitest' import { splitByTokenLength } from '../../../composables/autoGroup/tokenLength' import type { SampleClass } from '../../../types/auto-group' function cls(partial: Partial & Pick): SampleClass { return { kind: 'biological', label: 'Biological / Plasma', subKind: 'Plasma', classTagPositions: [], disposition: 'group', ...partial, } } describe('splitByTokenLength', () => { it('should split a ragged class into one class per token-length, preserving member order', () => { const tokenized = [ ['a', 'b', 'c', '01'], // len 4 ['a', 'b', 'c', '02'], // len 4 ['a', 'b', 'c', 'd', '03'], // len 5 ] const out = splitByTokenLength([cls({ members: [0, 1, 2] })], tokenized) expect(out).toHaveLength(2) const four = out.find(c => c.tokenLength === 4) const five = out.find(c => c.tokenLength === 5) expect(four?.members).toEqual([0, 1]) expect(five?.members).toEqual([2]) }) it('should disambiguate the label with the field count only when a class spans multiple lengths', () => { const tokenized = [ ['a', 'b', 'c', '01'], ['a', 'b', 'c', 'd', '02'], ] const out = splitByTokenLength([cls({ members: [0, 1] })], tokenized) const labels = out.map(c => c.label).sort() expect(labels).toEqual([ 'Biological / Plasma · 4 fields', 'Biological / Plasma · 5 fields', ]) }) it('should leave the label unchanged but still set tokenLength when a class has a single length', () => { const tokenized = [ ['a', 'b', 'c'], ['a', 'b', 'c'], ] const out = splitByTokenLength([cls({ members: [0, 1] })], tokenized) expect(out).toHaveLength(1) expect(out[0].label).toBe('Biological / Plasma') expect(out[0].tokenLength).toBe(3) }) it('should clamp classTagPositions to the split token-length', () => { const tokenized = [ ['a', 'b', 'c'], // len 3 ['a', 'b', 'c', 'd', 'e'], // len 5 ] const out = splitByTokenLength( [cls({ members: [0, 1], classTagPositions: [1, 4] })], tokenized, ) const short = out.find(c => c.tokenLength === 3) const long = out.find(c => c.tokenLength === 5) expect(short?.classTagPositions).toEqual([1]) expect(long?.classTagPositions).toEqual([1, 4]) }) it('should keep distinct input classes separate and ordered', () => { const tokenized = [ ['x', '01'], // class A, len 2 ['y', 'z', '02'], // class B, len 3 ] const a = cls({ kind: 'unknown', subKind: undefined, label: 'Unknown', members: [0] }) const b = cls({ members: [1] }) const out = splitByTokenLength([a, b], tokenized) expect(out.map(c => c.label)).toEqual(['Unknown', 'Biological / Plasma']) }) }) describe('splitByTokenLength for QC-kind classes', () => { it('should keep a QC-kind class whole when its members have two token lengths', () => { const iqc = cls({ kind: 'iqc', label: 'IQC', subKind: undefined, members: [0, 1] }) expect(splitByTokenLength([iqc], [['IQC', '1'], ['x', 'IQC', '2']])).toHaveLength(1) }) })