refactor(doctor): extract note emission (#52076)

* refactor(doctor): extract note emission

* test(doctor): cover optional note emission paths
This commit is contained in:
Vincent Koc
2026-03-21 21:52:14 -07:00
committed by GitHub
parent 8790c54635
commit 7a0dacbfba
3 changed files with 70 additions and 18 deletions

View File

@@ -7,6 +7,7 @@ import { noteOpencodeProviderOverrides } from "./doctor-config-analysis.js";
import { runDoctorConfigPreflight } from "./doctor-config-preflight.js";
import { normalizeCompatibilityConfigValues } from "./doctor-legacy-config.js";
import type { DoctorOptions } from "./doctor-prompter.js";
import { emitDoctorNotes } from "./doctor/emit-notes.js";
import { finalizeDoctorConfigFlow } from "./doctor/finalize-config-flow.js";
import { runMatrixDoctorSequence } from "./doctor/providers/matrix.js";
import { runDoctorRepairSequence } from "./doctor/repair-sequencing.js";
@@ -80,12 +81,11 @@ export async function loadAndMaybeMigrateDoctorConfig(params: {
env: process.env,
shouldRepair,
});
for (const change of matrixSequence.changeNotes) {
note(change, "Doctor changes");
}
for (const warning of matrixSequence.warningNotes) {
note(warning, "Doctor warnings");
}
emitDoctorNotes({
note,
changeNotes: matrixSequence.changeNotes,
warningNotes: matrixSequence.warningNotes,
});
const missingDefaultAccountBindingWarnings =
collectMissingDefaultAccountBindingWarnings(candidate);
@@ -103,19 +103,19 @@ export async function loadAndMaybeMigrateDoctorConfig(params: {
doctorFixCommand,
});
({ cfg, candidate, pendingChanges, fixHints } = repairSequence.state);
for (const change of repairSequence.changeNotes) {
note(change, "Doctor changes");
}
for (const warning of repairSequence.warningNotes) {
note(warning, "Doctor warnings");
}
emitDoctorNotes({
note,
changeNotes: repairSequence.changeNotes,
warningNotes: repairSequence.warningNotes,
});
} else {
for (const warning of collectDoctorPreviewWarnings({
cfg: candidate,
doctorFixCommand,
})) {
note(warning, "Doctor warnings");
}
emitDoctorNotes({
note,
warningNotes: collectDoctorPreviewWarnings({
cfg: candidate,
doctorFixCommand,
}),
});
}
const mutableAllowlistHits = scanMutableAllowlistEntries(candidate);

View File

@@ -0,0 +1,40 @@
import { describe, expect, it, vi } from "vitest";
import { emitDoctorNotes } from "./emit-notes.js";
describe("doctor note emission", () => {
it("emits grouped change and warning notes with the correct titles", () => {
const note = vi.fn();
emitDoctorNotes({
note,
changeNotes: ["change one", "change two"],
warningNotes: ["warning one"],
});
expect(note.mock.calls).toEqual([
["change one", "Doctor changes"],
["change two", "Doctor changes"],
["warning one", "Doctor warnings"],
]);
});
it("emits only warning notes when changeNotes is omitted", () => {
const note = vi.fn();
emitDoctorNotes({
note,
warningNotes: ["warning only"],
});
expect(note.mock.calls).toEqual([["warning only", "Doctor warnings"]]);
});
it("emits nothing when note groups are omitted or empty", () => {
const note = vi.fn();
emitDoctorNotes({ note });
emitDoctorNotes({ note, changeNotes: [], warningNotes: [] });
expect(note).not.toHaveBeenCalled();
});
});

View File

@@ -0,0 +1,12 @@
export function emitDoctorNotes(params: {
note: (message: string, title?: string) => void;
changeNotes?: string[];
warningNotes?: string[];
}): void {
for (const change of params.changeNotes ?? []) {
params.note(change, "Doctor changes");
}
for (const warning of params.warningNotes ?? []) {
params.note(warning, "Doctor warnings");
}
}