import { describe, it, expect } from 'vitest';
import { createHash } from 'crypto';
import { bodyRevision } from './revisions.js';

describe('bodyRevision', () => {
  it('returns the sha1 hex digest of the body string', () => {
    const body = 'The user prefers markdown output.\n';
    const expected = createHash('sha1').update(body).digest('hex');
    expect(bodyRevision(body)).toBe(expected);
  });

  it('is deterministic for the same input', () => {
    expect(bodyRevision('same input')).toBe(bodyRevision('same input'));
  });

  it('produces different digests for different bodies', () => {
    expect(bodyRevision('body A')).not.toBe(bodyRevision('body B'));
  });

  it('is sensitive to trailing whitespace (gray-matter newline normalization matters)', () => {
    // The doc comment in revisions.ts says the parsed body (which gray-matter
    // round-trips with a trailing newline) is the canonical input. A body with
    // and without the trailing newline must therefore hash differently.
    expect(bodyRevision('content')).not.toBe(bodyRevision('content\n'));
  });

  it('returns a 40-char lowercase hex string', () => {
    expect(bodyRevision('anything')).toMatch(/^[0-9a-f]{40}$/);
  });

  it('handles the empty string (well-known sha1)', () => {
    expect(bodyRevision('')).toBe('da39a3ee5e6b4b0d3255bfef95601890afd80709');
  });

  it('handles multibyte (Japanese) content as UTF-8', () => {
    const body = '教訓: ユーザーは簡潔な回答を好む。';
    const expected = createHash('sha1').update(body, 'utf8').digest('hex');
    expect(bodyRevision(body)).toBe(expected);
  });
});
