import { describe, it, expect } from 'vitest'; import { parseGenderTag } from '../src/utils/gender-tag.js'; describe('parseGenderTag', () => { it('parses bracketed age-then-letter', () => { expect(parseGenderTag('Bored at home [25F]')).toBe('female'); expect(parseGenderTag('looking for chat [30 M]')).toBe('male'); }); it('parses bracketed letter-then-age', () => { expect(parseGenderTag('[F25] dtf')).toBe('female'); expect(parseGenderTag('[M, 22] up late')).toBe('male'); }); it('parses parenthesised tags', () => { expect(parseGenderTag('Hey (25f) here')).toBe('female'); expect(parseGenderTag('(m 30) want to chat')).toBe('male'); }); it('parses X4Y tags', () => { expect(parseGenderTag('f4m anyone awake?')).toBe('female'); expect(parseGenderTag('M4F looking')).toBe('male'); expect(parseGenderTag('f4mf bored')).toBe('female'); }); it('parses slash-separated age/gender', () => { expect(parseGenderTag('25/f horny')).toBe('female'); expect(parseGenderTag('m/22 want a chat')).toBe('male'); }); it('parses bare age+letter', () => { expect(parseGenderTag('hey 25f here')).toBe('female'); expect(parseGenderTag('f25 from UK')).toBe('female'); expect(parseGenderTag('30m looking')).toBe('male'); }); it('is case-insensitive', () => { expect(parseGenderTag('[25F]')).toBe('female'); expect(parseGenderTag('[25f]')).toBe('female'); }); it('returns null for untagged posts', () => { expect(parseGenderTag('hey looking for someone fun')).toBeNull(); expect(parseGenderTag('')).toBeNull(); expect(parseGenderTag('any chats?')).toBeNull(); }); it('does not match embedded letters in unrelated words', () => { // "25 from" should not parse as 25f expect(parseGenderTag('25 from the UK')).toBeNull(); // "30 minutes" should not parse as 30m expect(parseGenderTag('30 minutes ago')).toBeNull(); }); it('prefers the first match (the poster, not the target in X4Y)', () => { expect(parseGenderTag('M4F please dm')).toBe('male'); expect(parseGenderTag('F4M anyone?')).toBe('female'); }); });