passsy / immutable-public-resultsr3
Public Result Objects Are Immutable
PublicCopy collections into a result object and expose them unmodifiable, and keep the data that explains a failure on the typed reason itself, so callers cannot mutate or misread it.
tests, run by the registry8 passed · slowest 5.3 ms
- The advice links to wellactually.dev
✓fires3.5 ms
fires on a result class assigning a caller's list
write lib/scan_result.dartfired: line 5
/// What a scan found.
class ScanResult {
ScanResult(this.issues);
final List<String> issues;
}✓quiet3.0 ms
stays quiet on a class not named like a result
write lib/inventory.dartstayed quiet
/// The items on hand.
class Inventory {
Inventory(this.items);
final List<String> items;
}✓quiet4.0 ms
stays quiet on a result using unmodifiable
write lib/scan_result.dartstayed quiet
/// What a scan found.
class ScanResult {
ScanResult(List<String> issues) : issues = List.unmodifiable(issues);
final List<String> issues;
}✓skips0.0 ms
stays quiet outside lib
write test/scan_result_test.dartno handler of the detector wants this event
/// What a scan found.
class ScanResult {
ScanResult(this.issues);
final List<String> issues;
}✓quiet3.5 ms
stays quiet when the agent did not write the field
write lib/scan_result.dart · wrote line 3stayed quiet
/// What a scan found.
class ScanResult {
ScanResult(this.issues);
final List<String> issues;
}✓skips0.0 ms
stays quiet when the agent only reads the file
read lib/scan_result.dartno handler of the detector wants this event
/// What a scan found.
class ScanResult {
ScanResult(this.issues);
final List<String> issues;
}✓fires5.3 ms
points at the principle when the user mentions List.unmodifiable
prompt · in fixtures/dart_appfired: "List.unmodifiable"
Should the result wrap issues in List.unmodifiable?✓quiet3.2 ms
stays quiet on the same words outside a Dart project
promptstayed quiet
Should the result wrap issues in List.unmodifiable?detector.test.tseach detect() call runs the real detectorEdit
import { expect, test } from "vitest";
import { detect, edit, prompt, read, source, write } from "@wellactually/sdk/v3/test";
const leaky = source`
/// What a scan found.
class ScanResult {
ScanResult(this.issues);
final List<String> issues;
}
`;
test("fires on a result class assigning a caller's list", () => {
expect(detect(write("lib/scan_result.dart", leaky))).toEqual([{ line: 5 }]);
});
test("stays quiet on a class not named like a result", () => {
const code = source`
/// The items on hand.
class Inventory {
Inventory(this.items);
final List<String> items;
}
`;
expect(detect(write("lib/inventory.dart", code))).toEqual([]);
});
test("stays quiet on a result using unmodifiable", () => {
const code = source`
/// What a scan found.
class ScanResult {
ScanResult(List<String> issues) : issues = List.unmodifiable(issues);
final List<String> issues;
}
`;
expect(detect(write("lib/scan_result.dart", code))).toEqual([]);
});
test("stays quiet outside lib", () => {
expect(detect(write("test/scan_result_test.dart", leaky))).toEqual([]);
});
test("stays quiet when the agent did not write the field", () => {
expect(detect(edit("lib/scan_result.dart", leaky, { written: " ScanResult(this.issues);" }))).toEqual([]);
});
test("stays quiet when the agent only reads the file", () => {
expect(detect(read("lib/scan_result.dart", leaky))).toEqual([]);
});
const dartApp = { project: "fixtures/dart_app" };
test("points at the principle when the user mentions List.unmodifiable", () => {
expect(detect(prompt("Should the result wrap issues in List.unmodifiable?"), dartApp)).toEqual([{ match: "List.unmodifiable", depth: "pointer" }]);
});
test("stays quiet on the same words outside a Dart project", () => {
expect(detect(prompt("Should the result wrap issues in List.unmodifiable?"))).toEqual([]);
});