import { describe, it, expect } from 'vitest';
import { colorizePassword, PWD_DIGIT, PWD_SYMBOL, PWD_LETTER } from '../password-coloring';

describe('colorizePassword', () => {

  function classes(frag: DocumentFragment): string[] {
    return Array.from(frag.querySelectorAll('span')).map(s => s.className);
  }
  function texts(frag: DocumentFragment): string[] {
    return Array.from(frag.querySelectorAll('span')).map(s => s.textContent ?? '');
  }

  it('returns empty fragment for empty input', () => {
    const frag = colorizePassword('');
    expect(frag.childNodes.length).toBe(0);
  });

  it('classifies a mixed-class run', () => {
    const frag = colorizePassword('aB3$xY');
    expect(classes(frag)).toEqual([PWD_LETTER, PWD_DIGIT, PWD_SYMBOL, PWD_LETTER]);
    expect(texts(frag)).toEqual(['aB', '3', '$', 'xY']);
  });

  it('all-letters produces a single letter span', () => {
    const frag = colorizePassword('passwd');
    expect(classes(frag)).toEqual([PWD_LETTER]);
    expect(texts(frag)).toEqual(['passwd']);
  });

  it('all-digits produces a single digit span', () => {
    const frag = colorizePassword('123456');
    expect(classes(frag)).toEqual([PWD_DIGIT]);
    expect(texts(frag)).toEqual(['123456']);
  });

  it('all-symbols produces a single symbol span', () => {
    const frag = colorizePassword('!@#$%^');
    expect(classes(frag)).toEqual([PWD_SYMBOL]);
    expect(texts(frag)).toEqual(['!@#$%^']);
  });

  it('classifies unicode letters as letters', () => {
    const frag = colorizePassword('áñü');
    expect(classes(frag)).toEqual([PWD_LETTER]);
  });

  it('classifies whitespace as symbol', () => {
    const frag = colorizePassword('a b');
    expect(classes(frag)).toEqual([PWD_LETTER, PWD_SYMBOL, PWD_LETTER]);
    expect(texts(frag)).toEqual(['a', ' ', 'b']);
  });

  it('representative password snapshot: aB3$xY7&_!', () => {
    const frag = colorizePassword('aB3$xY7&_!');
    expect(classes(frag)).toEqual([
      PWD_LETTER, PWD_DIGIT, PWD_SYMBOL, PWD_LETTER, PWD_DIGIT, PWD_SYMBOL,
    ]);
    expect(texts(frag)).toEqual(['aB', '3', '$', 'xY', '7', '&_!']);
  });
});
