// engine/test-framework-detector/detectors.ts — SPEC-018
// Individual testing framework detectors. Pure functions — no I/O.
// === Unit test framework detection ===
const TESTING_FRAMEWORK_DEPS = [
    ['vitest', 'vitest'],
    ['jest', 'jest'],
    ['mocha', 'mocha'],
    ['pytest', 'pytest'],
    ['junit', 'junit'],
    ['xunit', 'xunit'],
    ['rspec', 'rspec'],
    ['go-test', 'go-test'],
];
export function detectTestingFramework(deps) {
    const depSet = new Set(deps.map((d) => d.toLowerCase()));
    for (const [dep, framework] of TESTING_FRAMEWORK_DEPS) {
        if (depSet.has(dep)) {
            return framework;
        }
    }
    return null;
}
// === BDD framework detection ===
const BDD_FILE_PATTERNS = [
    ['features/', 'cucumber'],
    ['.feature', 'cucumber'],
    ['behave.ini', 'behave'],
    ['Steps.cs', 'specflow'],
    ['.steps.cs', 'specflow'],
    ['godog', 'godog'],
    ['.spec.md', 'gauge'],
    ['jbehave', 'jbehave'],
];
const BDD_DEP_PATTERNS = [
    ['@cucumber/cucumber', 'cucumber'],
    ['cucumber', 'cucumber'],
    ['behave', 'behave'],
    ['specflow', 'specflow'],
    ['reqnroll', 'specflow'],
    ['godog', 'godog'],
    ['gauge', 'gauge'],
    ['jbehave', 'jbehave'],
];
export function detectBDDFramework(files, deps) {
    const depSet = new Set(deps.map((d) => d.toLowerCase()));
    for (const [dep, fw] of BDD_DEP_PATTERNS) {
        if (depSet.has(dep)) {
            return fw;
        }
    }
    for (const file of files) {
        for (const [pattern, fw] of BDD_FILE_PATTERNS) {
            if (file.includes(pattern)) {
                return fw;
            }
        }
    }
    return null;
}
// === Property-based testing detection ===
const PROPERTY_DEP_PATTERNS = [
    ['fast-check', 'fast-check'],
    ['@fast-check/vitest', 'fast-check'],
    ['hypothesis', 'hypothesis'],
    ['quickcheck', 'quickcheck'],
    ['hedgehog', 'quickcheck'],
    ['proptest', 'proptest'],
    ['jqwik', 'jqwik'],
    ['scalacheck', 'scalacheck'],
];
export function detectPropertyTestFramework(deps) {
    const depSet = new Set(deps.map((d) => d.toLowerCase()));
    for (const [dep, fw] of PROPERTY_DEP_PATTERNS) {
        if (depSet.has(dep)) {
            return fw;
        }
    }
    return null;
}
// === Mutation testing detection ===
const MUTATION_FILE_PATTERNS = [
    ['stryker.config', 'stryker'],
    ['.stryker', 'stryker'],
    ['mutmut', 'mutmut'],
    ['pitest', 'pitest'],
    ['cargo-mutants', 'cargo-mutants'],
    ['cosmic-ray', 'cosmic-ray'],
];
const MUTATION_DEP_PATTERNS = [
    ['@stryker-mutator/core', 'stryker'],
    ['stryker', 'stryker'],
    ['mutmut', 'mutmut'],
    ['com.pitest', 'pitest'],
    ['cargo-mutants', 'cargo-mutants'],
    ['cosmic-ray', 'cosmic-ray'],
];
export function detectMutationFramework(files, deps) {
    const depSet = new Set(deps.map((d) => d.toLowerCase()));
    for (const [dep, fw] of MUTATION_DEP_PATTERNS) {
        if (depSet.has(dep)) {
            return fw;
        }
    }
    for (const file of files) {
        for (const [pattern, fw] of MUTATION_FILE_PATTERNS) {
            if (file.includes(pattern)) {
                return fw;
            }
        }
    }
    return null;
}
// === Load testing detection ===
const LOAD_FILE_PATTERNS = [
    ['k6.config', 'k6'],
    ['.k6.js', 'k6'],
    ['locustfile.py', 'locust'],
    ['locustfile', 'locust'],
    ['gatling', 'gatling'],
    ['.jmx', 'jmeter'],
    ['artillery.yml', 'artillery'],
    ['artillery.yaml', 'artillery'],
];
const LOAD_DEP_PATTERNS = [
    ['k6', 'k6'],
    ['locust', 'locust'],
    ['artillery', 'artillery'],
    ['autocannon', 'autocannon'],
    ['wrk', 'wrk'],
    ['hey', 'hey'],
    ['bombardier', 'bombardier'],
];
export function detectLoadTestFramework(files, deps) {
    const depSet = new Set(deps.map((d) => d.toLowerCase()));
    for (const [dep, fw] of LOAD_DEP_PATTERNS) {
        if (depSet.has(dep)) {
            return fw;
        }
    }
    for (const file of files) {
        for (const [pattern, fw] of LOAD_FILE_PATTERNS) {
            if (file.includes(pattern)) {
                return fw;
            }
        }
    }
    return null;
}
// === Chaos engineering detection ===
const CHAOS_FILE_PATTERNS = [
    ['chaosengine.yaml', 'litmuschaos'],
    ['chaosengine.yml', 'litmuschaos'],
    ['toxiproxy', 'toxiproxy'],
];
const CHAOS_DEP_PATTERNS = [
    ['litmuschaos', 'litmuschaos'],
    ['chaos-monkey', 'chaos-monkey'],
    ['spring-boot-chaos-monkey', 'chaos-monkey'],
    ['gremlin', 'gremlin'],
    ['toxiproxy', 'toxiproxy'],
    ['aws-fault-injection-simulator', 'aws-fis'],
];
export function detectChaosFramework(files, deps) {
    const depSet = new Set(deps.map((d) => d.toLowerCase()));
    for (const [dep, fw] of CHAOS_DEP_PATTERNS) {
        if (depSet.has(dep)) {
            return fw;
        }
    }
    for (const file of files) {
        for (const [pattern, fw] of CHAOS_FILE_PATTERNS) {
            if (file.includes(pattern)) {
                return fw;
            }
        }
    }
    return null;
}
// === Visual regression detection ===
const VISUAL_FILE_PATTERNS = [
    ['percy.yml', 'percy'],
    ['backstop.json', 'backstopjs'],
    ['.chromatic', 'chromatic'],
];
const VISUAL_DEP_PATTERNS = [
    ['@percy/playwright', 'percy'],
    ['@percy/cypress', 'percy'],
    ['chromatic', 'chromatic'],
    ['backstopjs', 'backstopjs'],
    ['@applitools/eyes-playwright', 'applitools'],
    ['@applitools/eyes-cypress', 'applitools'],
    ['@argos-ci/playwright', 'argos'],
    ['@argos-ci/cypress', 'argos'],
];
export function detectVisualRegFramework(deps, files) {
    const depSet = new Set(deps.map((d) => d.toLowerCase()));
    for (const [dep, fw] of VISUAL_DEP_PATTERNS) {
        if (depSet.has(dep)) {
            return fw;
        }
    }
    for (const file of files) {
        for (const [pattern, fw] of VISUAL_FILE_PATTERNS) {
            if (file.includes(pattern)) {
                return fw;
            }
        }
    }
    // Playwright with toMatchSnapshot is detected by playwright presence + snapshot usage
    if (depSet.has('@playwright/test') || depSet.has('playwright')) {
        return 'playwright-snapshot';
    }
    return null;
}
// === Test double pattern detection ===
const TEST_DOUBLE_DEP_MAP = [
    ['sinon', 'sinon-stub'],
    ['vitest', 'vitest-mock'],
    ['jest', 'jest-mock'],
];
export function detectTestDoublePattern(deps, fileContents) {
    const depSet = new Set(deps.map((d) => d.toLowerCase()));
    const allContent = fileContents.join('\n');
    if (depSet.has('sinon')) {
        if (allContent.includes('.spy(') || allContent.includes('sinon.spy')) {
            return 'sinon-spy';
        }
        return 'sinon-stub';
    }
    if (allContent.includes('vi.mock(') || allContent.includes('vi.fn()')) {
        return 'vitest-mock';
    }
    if (allContent.includes('jest.mock(') || allContent.includes('jest.fn()')) {
        return 'jest-mock';
    }
    if (allContent.includes('InMemory') || allContent.includes('FakeRepository')) {
        return 'in-memory';
    }
    for (const [dep, pattern] of TEST_DOUBLE_DEP_MAP) {
        if (depSet.has(dep)) {
            return pattern;
        }
    }
    return null;
}
//# sourceMappingURL=detectors.js.map