/**
 * SET 40e — micro-harness vitest surface (.each/.skip/.todo/.only) + catalog row.
 */
import { describe, expect, it } from 'vitest';
import type { GeneratedFile } from '../src/core/types';
import { classifyCataloged } from '../src/tier1/errorCatalog.generated';
import { makeEvalSuiteRunner } from '../src/tier1/testExec';

const impl: GeneratedFile = {
  path: 'src/add.ts',
  content: 'export function add(a: number, b: number): number { return a + b; }\n',
};

describe('SET 40e harness vitest surface', () => {
  it('it.each / test.each / describe.each expand table rows without crashing', async () => {
    const suite: GeneratedFile = {
      path: 'tests/each.test.ts',
      content: [
        "import { describe, it, test, expect } from 'vitest';",
        "import { add } from '../src/add';",
        "describe.each([{ n: 1 }, { n: 2 }])('group $n', ({ n }) => {",
        "  it('identity', () => { expect(n).toBe(n); });",
        '});',
        'it.each([[1, 2, 3], [2, 2, 4]])("add(%i,%i)=%i", (a, b, e) => {',
        '  expect(add(a, b)).toBe(e);',
        '});',
        'test.each([{ a: 1, b: 1, e: 2 }])("obj $a+$b", ({ a, b, e }) => {',
        '  expect(add(a, b)).toBe(e);',
        '});',
      ].join('\n'),
    };
    const r = await makeEvalSuiteRunner()([impl], suite);
    expect(r.crashed, r.crashed).toBeUndefined();
    expect(r.failures).toEqual([]);
    expect(r.total).toBeGreaterThanOrEqual(4);
  });

  it('it.skip / it.todo / it.only / describe.skip|todo|only do not throw .call errors', async () => {
    const suite: GeneratedFile = {
      path: 'tests/surface.test.ts',
      content: [
        "import { describe, it, expect } from 'vitest';",
        "import { add } from '../src/add';",
        "describe.skip('omitted', () => { it('gone', () => { expect(1).toBe(2); }); });",
        "describe.todo('later');",
        "describe.only('kept', () => {",
        "  it.skip('skipped', () => { expect(1).toBe(2); });",
        "  it.todo('todo-case');",
        "  it.only('runs', () => { expect(add(1, 1)).toBe(2); });",
        '});',
      ].join('\n'),
    };
    const r = await makeEvalSuiteRunner()([impl], suite);
    expect(r.crashed, r.crashed).toBeUndefined();
    expect(r.failures).toEqual([]);
    // skipped/todo register as no-op cases; only + skip + todo ≥ 3
    expect(r.total).toBeGreaterThanOrEqual(3);
  });

  it('catalog classifies _vitest.it.call(...) is not a function (drift empty)', () => {
    const msg = '_vitest.it.call(...) is not a function';
    const c = classifyCataloged(msg);
    expect(c.templateId).toBe('harness-vitest-surface');
    expect(c.classKey).toBe('harness-vitest-surface');
    expect(c.stratum).toBe('mechanical-first');
    expect(c.templateId).not.toBe('catalog-drift');
  });
});
