/**
 * Property-Based Testing Helpers
 *
 * Shared generators and utilities for property-based tests using fast-check.
 *
 * @module __tests__/property-test-helpers
 */
import * as fc from "fast-check";
/**
 * Arbitrary generators for common security testing patterns
 */
export const arbitraries = {
    /**
     * Valid identifier characters for path parameters
     * Matches common conventions: alphanumeric + underscore, starting with letter/underscore
     */
    paramName: fc.stringMatching(/^[a-zA-Z_][a-zA-Z0-9_]{0,15}$/),
    /**
     * Generate a valid file path segment (no special chars)
     */
    pathSegment: fc.stringMatching(/^[a-zA-Z0-9_-]{1,20}$/),
    /**
     * Generate a valid file extension
     */
    fileExtension: fc.constantFrom("ts", "js", "tsx", "jsx", "py", "go", "rb", "java"),
    /**
     * Generate a plural noun for singularization testing
     */
    pluralNoun: fc.oneof(
    // Regular plurals (add 's')
    fc.constant("users"), fc.constant("products"), fc.constant("orders"), fc.constant("items"), 
    // -ies plurals (y -> ies)
    fc.constant("categories"), fc.constant("companies"), fc.constant("stories"), fc.constant("entries"), 
    // -es plurals
    fc.constant("addresses"), fc.constant("statuses"), fc.constant("boxes"), fc.constant("matches"), fc.constant("bushes"), 
    // Irregular or edge cases
    fc.constant("data"), fc.constant("media"), fc.constant("sheep"), fc.constant("fish")),
    /**
     * Generate an API path prefix
     */
    apiPrefix: fc.constantFrom("/api", "/api/v1", "/api/v2", "/v1", "/v2", ""),
};
/**
 * Generate a path with Express-style parameters (:param)
 */
export function expressPath(paramNames) {
    if (paramNames.length === 0)
        return "/api/resource";
    return "/api/" + paramNames.map((p) => `:${p}`).join("/");
}
/**
 * Generate a path with Next.js-style parameters ([param])
 */
export function nextjsPath(paramNames) {
    if (paramNames.length === 0)
        return "/api/resource";
    return "/api/" + paramNames.map((p) => `[${p}]`).join("/");
}
/**
 * Generate a path with Flask-style parameters (<param> or <param:type>)
 */
export function flaskPath(paramNames, withTypes = false) {
    if (paramNames.length === 0)
        return "/api/resource";
    const types = ["int", "string", "path", "float"];
    return ("/api/" +
        paramNames
            .map((p, i) => {
            if (withTypes && i % 2 === 0) {
                return `<${p}:${types[i % types.length]}>`;
            }
            return `<${p}>`;
        })
            .join("/"));
}
/**
 * Generate a path with Spring-style parameters ({param})
 */
export function springPath(paramNames) {
    if (paramNames.length === 0)
        return "/api/resource";
    return "/api/" + paramNames.map((p) => `{${p}}`).join("/");
}
/**
 * Generate a test file path
 */
export function testFilePath(stem, extension) {
    return `src/__tests__/${stem}.test.${extension}`;
}
/**
 * Generate a spec file path
 */
export function specFilePath(stem, extension) {
    return `src/${stem}.spec.${extension}`;
}
/**
 * Generate a node_modules file path
 */
export function nodeModulesPath(pkg, file) {
    return `node_modules/${pkg}/${file}`;
}
/**
 * Generate a generated code file path
 */
export function generatedFilePath(stem) {
    return `src/${stem}.generated.ts`;
}
/**
 * Generate a type definition file path
 */
export function dtsFilePath(stem) {
    return `src/${stem}.d.ts`;
}
/**
 * Arbitrary for generating arrays of unique parameter names
 */
export const uniqueParamNames = fc
    .array(arbitraries.paramName, { minLength: 1, maxLength: 5 })
    .map((names) => [...new Set(names)]);
/**
 * Arbitrary for generating a file path with random structure
 */
export const filePath = fc
    .tuple(fc.array(arbitraries.pathSegment, { minLength: 1, maxLength: 4 }), arbitraries.pathSegment, arbitraries.fileExtension)
    .map(([dirs, name, ext]) => `${dirs.join("/")}/${name}.${ext}`);
/**
 * Check if a string contains any of the given characters
 */
export function containsAny(str, chars) {
    return chars.some((c) => str.includes(c));
}
/**
 * Path parameter delimiter characters that should never appear in extracted params
 */
export const PARAM_DELIMITERS = [":", "[", "]", "<", ">", "{", "}"];
//# sourceMappingURL=property-test-helpers.js.map