Files
clawsec/skills/clawsec-suite/test/fuzz_properties.js
T
davida-ps 938eb929f3 feat: add property-based fuzz tests for advisory parsing, semver matc… (#69)
* feat: add property-based fuzz tests for advisory parsing, semver matching, and suppression config

* fix(ci): install deps before fuzz test jobs
2026-02-25 17:48:48 +02:00

63 lines
2.0 KiB
JavaScript

import assert from "node:assert/strict";
import path from "node:path";
import fc from "fast-check";
import { parseAffectedSpecifier } from "../hooks/clawsec-advisory-guardian/lib/feed.mjs";
import { normalizeSkillName, resolveConfiguredPath, uniqueStrings } from "../hooks/clawsec-advisory-guardian/lib/utils.mjs";
const SAFE_SEGMENT = fc
.array(fc.constantFrom(...("abcdefghijklmnopqrstuvwxyz0123456789-_")), { minLength: 1, maxLength: 24 })
.map((chars) => chars.join(""));
/**
* Runs property-based fuzz checks for advisory parsing and utility behavior.
*/
export function runFuzzProperties() {
fc.assert(
fc.property(fc.string(), (raw) => {
const expected = String(raw ?? "")
.trim()
.toLowerCase();
assert.equal(normalizeSkillName(raw), expected);
}),
{ numRuns: 300 },
);
fc.assert(
fc.property(fc.array(fc.string(), { maxLength: 40 }), (values) => {
const deduped = uniqueStrings(values);
assert.deepEqual(deduped, Array.from(new Set(values)));
}),
{ numRuns: 200 },
);
fc.assert(
fc.property(fc.string(), fc.string(), (left, right) => {
const rawSpecifier = `${left}@${right}`;
const specifier = rawSpecifier.trim();
const parsed = parseAffectedSpecifier(rawSpecifier);
assert.ok(parsed !== null);
const atIndex = specifier.lastIndexOf("@");
if (atIndex <= 0) {
assert.equal(parsed.name, specifier);
assert.equal(parsed.versionSpec, "*");
} else {
assert.equal(parsed.name, specifier.slice(0, atIndex));
assert.equal(parsed.versionSpec, specifier.slice(atIndex + 1));
}
}),
{ numRuns: 300 },
);
fc.assert(
fc.property(SAFE_SEGMENT, (suffix) => {
const fallback = `/tmp/clawsec-suite/${suffix}`;
const resolved = resolveConfiguredPath(`\\$HOME/${suffix}`, fallback, {
label: "FUZZ_PATH",
});
assert.equal(resolved, path.normalize(fallback));
}),
{ numRuns: 200 },
);
}