mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-22 13:42:12 -03:00
Add test coverage for trigger word refresh functionality when LoRA syntax is edited in the input widget. The test verifies that after modifying LoRA syntax in the input field, the connected trigger words are properly updated to reflect the active LoRAs. Additionally, implement the actual trigger word update logic in lora_loader.js by calling updateConnectedTriggerWords after merging LoRAs, ensuring the UI stays synchronized with the current LoRA state.
132 lines
3.8 KiB
JavaScript
132 lines
3.8 KiB
JavaScript
import { describe, it, expect, beforeEach, vi } from "vitest";
|
|
|
|
const {
|
|
APP_MODULE,
|
|
API_MODULE,
|
|
UTILS_MODULE,
|
|
LORAS_WIDGET_MODULE,
|
|
LORA_LOADER_MODULE,
|
|
} = vi.hoisted(() => ({
|
|
APP_MODULE: new URL("../../../scripts/app.js", import.meta.url).pathname,
|
|
API_MODULE: new URL("../../../scripts/api.js", import.meta.url).pathname,
|
|
UTILS_MODULE: new URL("../../../web/comfyui/utils.js", import.meta.url).pathname,
|
|
LORAS_WIDGET_MODULE: new URL("../../../web/comfyui/loras_widget.js", import.meta.url).pathname,
|
|
LORA_LOADER_MODULE: new URL("../../../web/comfyui/lora_loader.js", import.meta.url).pathname,
|
|
}));
|
|
|
|
const extensionState = { current: null };
|
|
const registerExtensionMock = vi.fn((extension) => {
|
|
extensionState.current = extension;
|
|
});
|
|
|
|
vi.mock(APP_MODULE, () => ({
|
|
app: {
|
|
registerExtension: registerExtensionMock,
|
|
graph: {},
|
|
},
|
|
}));
|
|
|
|
vi.mock(API_MODULE, () => ({
|
|
api: {
|
|
addEventListener: vi.fn(),
|
|
},
|
|
}));
|
|
|
|
const collectActiveLorasFromChain = vi.fn();
|
|
const updateConnectedTriggerWords = vi.fn();
|
|
const mergeLoras = vi.fn();
|
|
const setupInputWidgetWithAutocomplete = vi.fn();
|
|
const getAllGraphNodes = vi.fn();
|
|
const getNodeFromGraph = vi.fn();
|
|
|
|
vi.mock(UTILS_MODULE, () => ({
|
|
collectActiveLorasFromChain,
|
|
updateConnectedTriggerWords,
|
|
mergeLoras,
|
|
setupInputWidgetWithAutocomplete,
|
|
chainCallback: (proto, property, callback) => {
|
|
proto[property] = callback;
|
|
},
|
|
getAllGraphNodes,
|
|
getNodeFromGraph,
|
|
LORA_PATTERN: /<lora:([^:]+):([-\d.]+)(?::([-\d.]+))?>/g,
|
|
}));
|
|
|
|
const addLorasWidget = vi.fn();
|
|
|
|
vi.mock(LORAS_WIDGET_MODULE, () => ({
|
|
addLorasWidget,
|
|
}));
|
|
|
|
describe("Lora Loader trigger word updates", () => {
|
|
beforeEach(() => {
|
|
vi.resetModules();
|
|
|
|
extensionState.current = null;
|
|
registerExtensionMock.mockClear();
|
|
|
|
collectActiveLorasFromChain.mockClear();
|
|
collectActiveLorasFromChain.mockImplementation(() => new Set(["Alpha"]));
|
|
|
|
updateConnectedTriggerWords.mockClear();
|
|
|
|
mergeLoras.mockClear();
|
|
mergeLoras.mockImplementation(() => [{ name: "Alpha", active: true }]);
|
|
|
|
setupInputWidgetWithAutocomplete.mockClear();
|
|
setupInputWidgetWithAutocomplete.mockImplementation(
|
|
(_node, _widget, originalCallback) => originalCallback
|
|
);
|
|
|
|
addLorasWidget.mockClear();
|
|
addLorasWidget.mockImplementation((_node, _name, _opts, callback) => ({
|
|
widget: { value: [], callback },
|
|
}));
|
|
});
|
|
|
|
it("refreshes trigger word toggles after LoRA syntax edits in the input widget", async () => {
|
|
await import(LORA_LOADER_MODULE);
|
|
|
|
expect(registerExtensionMock).toHaveBeenCalled();
|
|
const extension = extensionState.current;
|
|
expect(extension).toBeDefined();
|
|
|
|
const nodeType = { comfyClass: "Lora Loader (LoraManager)", prototype: {} };
|
|
await extension.beforeRegisterNodeDef(nodeType, {}, {});
|
|
|
|
const node = {
|
|
comfyClass: "Lora Loader (LoraManager)",
|
|
widgets: [
|
|
{
|
|
value: "",
|
|
options: {},
|
|
inputEl: {},
|
|
},
|
|
],
|
|
addInput: vi.fn(),
|
|
graph: {},
|
|
};
|
|
|
|
nodeType.prototype.onNodeCreated.call(node);
|
|
|
|
expect(setupInputWidgetWithAutocomplete).toHaveBeenCalled();
|
|
expect(node.lorasWidget).toBeDefined();
|
|
|
|
const inputCallback = node.widgets[0].callback;
|
|
expect(typeof inputCallback).toBe("function");
|
|
|
|
inputCallback("<lora:Alpha:1.0>");
|
|
|
|
expect(mergeLoras).toHaveBeenCalledWith("<lora:Alpha:1.0>", []);
|
|
expect(node.lorasWidget.value).toEqual([{ name: "Alpha", active: true }]);
|
|
expect(collectActiveLorasFromChain).toHaveBeenCalledWith(node);
|
|
|
|
const activeSet = collectActiveLorasFromChain.mock.results.at(-1)?.value;
|
|
const [[targetNode, triggerWordSet]] = updateConnectedTriggerWords.mock.calls;
|
|
expect(targetNode).toBe(node);
|
|
expect(triggerWordSet).toBe(activeSet);
|
|
expect([...triggerWordSet]).toEqual(["Alpha"]);
|
|
});
|
|
});
|
|
|