// engine/test-generators/platform-test-templates-b.ts
// SPEC-015b: Advanced test scaffold generators — Anchor (Solana) and ML robustness
// === Anchor (Solana) test scaffold ===
function buildAnchorTestContent(specTitle) {
    return [
        '// Anchor (Solana) test scaffold',
        `// Spec: ${specTitle}`,
        '',
        'import * as anchor from "@coral-xyz/anchor";',
        'import { Program } from "@coral-xyz/anchor";',
        'import { MyProgram } from "../target/types/my_program";',
        'import { assert } from "chai";',
        '',
        'describe("my-program", () => {',
        '  const provider = anchor.AnchorProvider.env();',
        '  anchor.setProvider(provider);',
        '',
        '  const program = anchor.workspace.MyProgram as Program<MyProgram>;',
        '  const wallet = provider.wallet as anchor.Wallet;',
        '',
        '  it("initializes the program state", async () => {',
        '    const [statePda] = anchor.web3.PublicKey.findProgramAddressSync(',
        '      [Buffer.from("state"), wallet.publicKey.toBuffer()],',
        '      program.programId,',
        '    );',
        '',
        '    await program.methods',
        '      .initialize()',
        '      .accounts({ state: statePda, user: wallet.publicKey })',
        '      .rpc();',
        '',
        '    const account = await program.account.state.fetch(statePda);',
        '    assert.ok(account.owner.equals(wallet.publicKey));',
        '  });',
        '',
        '  it("reverts on unauthorized call", async () => {',
        '    const attacker = anchor.web3.Keypair.generate();',
        '    try {',
        '      await program.methods',
        '        .adminAction()',
        '        .accounts({ signer: attacker.publicKey })',
        '        .signers([attacker])',
        '        .rpc();',
        '      assert.fail("Should have thrown");',
        '    } catch (err: unknown) {',
        '      if (err instanceof anchor.AnchorError) {',
        '        assert.include(err.error.errorMessage, "Unauthorized");',
        '      }',
        '    }',
        '  });',
        '',
        '  it("emits event on state change", async () => {',
        '    let eventReceived = false;',
        '    const listener = program.addEventListener("StateChanged", () => {',
        '      eventReceived = true;',
        '    });',
        '    await program.methods.doStateChange().rpc();',
        '    await program.removeEventListener(listener);',
        '    assert.isTrue(eventReceived, "StateChanged event not emitted");',
        '  });',
        '});',
    ].join('\n');
}
/**
 * Build Anchor (Solana) test file.
 */
export function buildAnchorTestFile(title, slug, testDir, autoGenerate) {
    return {
        path: `${testDir}/contracts/${slug}.test.ts`,
        framework: 'anchor',
        content: buildAnchorTestContent(title),
        ready: autoGenerate,
    };
}
// === ML robustness + reproducibility tests ===
function buildMLRobustnessHeader(specTitle) {
    return [
        '"""',
        `ML robustness and reproducibility test scaffold — ${specTitle}`,
        'SPEC-015b: Tests for OOD inputs, adversarial robustness, and reproducibility.',
        '"""',
        '',
        'import pytest',
        'import numpy as np',
        '# from your_model import load_model, predict',
        '',
        '',
        'class TestModelRobustness:',
        '    """SPEC-015b: Robustness tests for adversarial and OOD inputs."""',
        '',
        '    def test_ood_input_returns_low_confidence(self, trained_model, ood_sample):',
        '        """Model must return low confidence for out-of-distribution inputs."""',
        '        proba = trained_model.predict_proba(ood_sample)',
        '        max_confidence = float(np.max(proba))',
        '        assert max_confidence < 0.95, f"Model too confident on OOD input: {max_confidence:.2%}"',
        '',
        '    def test_missing_features_handled_gracefully(self, trained_model):',
        '        """Model must handle NaN/missing feature values without crashing."""',
        '        sample_with_nans = np.array([[np.nan, 1.0, np.nan]])',
        '        try:',
        '            result = trained_model.predict(sample_with_nans)',
        '            assert result is not None',
        '        except (ValueError, TypeError) as e:',
        '            assert "NaN" in str(e) or "missing" in str(e).lower()',
    ];
}
function buildMLRobustnessAdversarialSection() {
    return [
        '',
        '    def test_adversarial_boundary_inputs(self, trained_model):',
        '        """Model output must be stable at decision boundaries (small perturbations)."""',
        '        base_input = np.array([[0.5, 0.5, 0.5]])',
        '        perturbation = np.array([[1e-4, -1e-4, 1e-4]])',
        '        pred_base = trained_model.predict(base_input)',
        '        pred_perturbed = trained_model.predict(base_input + perturbation)',
        '        assert pred_base.shape == pred_perturbed.shape',
        '',
        '',
        'class TestModelReproducibility:',
        '    """SPEC-015b: Reproducibility tests — same seed = same result."""',
        '',
        '    def test_same_seed_same_output(self):',
        '        """Training with same seed must produce identical weights."""',
        '        import random',
        '        seed = 42',
        '',
        '        def train_with_seed(s: int) -> np.ndarray:',
        '            random.seed(s)',
        '            np.random.seed(s)',
        '            rng = np.random.RandomState(s)',
        '            return rng.randn(10)',
        '',
        '        weights_1 = train_with_seed(seed)',
        '        weights_2 = train_with_seed(seed)',
        '        np.testing.assert_array_equal(weights_1, weights_2, err_msg="Same seed produced different weights")',
    ];
}
function buildMLRobustnessPerformanceSection() {
    return [
        '',
        '    def test_inference_performance_under_load(self, trained_model, sample_input):',
        '        """Inference latency must stay under 100ms per request under 10 concurrent requests."""',
        '        import time',
        '        from concurrent.futures import ThreadPoolExecutor',
        '',
        '        def predict_one(_: int) -> float:',
        '            start = time.perf_counter()',
        '            trained_model.predict(sample_input)',
        '            return (time.perf_counter() - start) * 1000',
        '',
        '        with ThreadPoolExecutor(max_workers=10) as executor:',
        '            latencies = list(executor.map(predict_one, range(10)))',
        '',
        '        p95_latency = float(np.percentile(latencies, 95))',
        '        assert p95_latency < 100, f"P95 inference latency {p95_latency:.1f}ms exceeds 100ms limit"',
        '',
        '',
        '@pytest.fixture',
        'def ood_sample():',
        '    """OOD sample: values far outside training distribution."""',
        '    return np.array([[1e6, -1e6, 999.9]])',
        '',
        '',
        '@pytest.fixture',
        'def sample_input():',
        '    """Standard in-distribution sample input."""',
        '    return np.array([[0.5, 0.3, 0.7]])',
    ];
}
function buildMLRobustnessContent(specTitle) {
    return [
        ...buildMLRobustnessHeader(specTitle),
        ...buildMLRobustnessAdversarialSection(),
        ...buildMLRobustnessPerformanceSection(),
    ].join('\n');
}
/**
 * Build ML robustness test file (OOD, adversarial, reproducibility, performance).
 */
export function buildMLRobustnessTestFile(title, slug, testDir, autoGenerate) {
    return {
        path: `${testDir}/ml/test_${slug}_robustness.py`,
        framework: 'pytest',
        content: buildMLRobustnessContent(title),
        ready: autoGenerate,
    };
}
//# sourceMappingURL=platform-test-templates-b.js.map