Skip to content

Commit d16f7d5

Browse files
committed
test: add missing tests for show-all-commands and button-set-manager
show-all-commands.ts had 0% coverage and button-set-manager.ts had 68.53% with key functions untested. Added 3 tests for createShowAllCommandsCommand in show-all-commands. Added 14 tests for createButtonSet, updateActiveSetButtons, global scope in button-set-manager. Improved overall coverage 72.87% → 75.68%, button-set-manager 68.53% → 90.9%.
1 parent a862f05 commit d16f7d5

File tree

2 files changed

+509
-0
lines changed

2 files changed

+509
-0
lines changed

src/internal/managers/button-set-manager.spec.ts

Lines changed: 358 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,364 @@ describe("ButtonSetManager", () => {
641641
});
642642
});
643643

644+
describe("createButtonSet", () => {
645+
it("should create new button set with provided buttons", async () => {
646+
const mockConfig = createMockConfig();
647+
mockConfig.get.mockReturnValue(CONFIGURATION_TARGETS.WORKSPACE);
648+
mockConfig.inspect.mockReturnValue({ workspaceValue: [] });
649+
vi.spyOn(vscode.workspace, "getConfiguration").mockReturnValue(
650+
mockConfig as unknown as vscode.WorkspaceConfiguration
651+
);
652+
653+
const configManager = createMockConfigManager();
654+
const configReader = createMockConfigReader();
655+
const buttonSetWriter = createMockButtonSetWriter();
656+
657+
const manager = ButtonSetManager.create({ buttonSetWriter, configManager, configReader });
658+
const buttons = [{ command: "echo test", id: "btn-1", name: "Test Button" }];
659+
const result = await manager.createButtonSet("New Set", buttons);
660+
661+
expect(result.success).toBe(true);
662+
expect(buttonSetWriter.writeButtonSets).toHaveBeenCalled();
663+
const writtenSets = buttonSetWriter.writeButtonSets.mock.calls[0][0];
664+
expect(writtenSets).toHaveLength(1);
665+
expect(writtenSets[0].name).toBe("New Set");
666+
expect(writtenSets[0].buttons).toHaveLength(1);
667+
});
668+
669+
it("should create empty button set when no buttons provided", async () => {
670+
const mockConfig = createMockConfig();
671+
mockConfig.get.mockReturnValue(CONFIGURATION_TARGETS.WORKSPACE);
672+
mockConfig.inspect.mockReturnValue({ workspaceValue: [] });
673+
vi.spyOn(vscode.workspace, "getConfiguration").mockReturnValue(
674+
mockConfig as unknown as vscode.WorkspaceConfiguration
675+
);
676+
677+
const configManager = createMockConfigManager();
678+
const configReader = createMockConfigReader();
679+
const buttonSetWriter = createMockButtonSetWriter();
680+
681+
const manager = ButtonSetManager.create({ buttonSetWriter, configManager, configReader });
682+
const result = await manager.createButtonSet("Empty Set");
683+
684+
expect(result.success).toBe(true);
685+
const writtenSets = buttonSetWriter.writeButtonSets.mock.calls[0][0];
686+
expect(writtenSets[0].buttons).toHaveLength(0);
687+
});
688+
689+
it("should return error for empty name", async () => {
690+
const mockConfig = createMockConfig();
691+
mockConfig.get.mockReturnValue(CONFIGURATION_TARGETS.WORKSPACE);
692+
vi.spyOn(vscode.workspace, "getConfiguration").mockReturnValue(
693+
mockConfig as unknown as vscode.WorkspaceConfiguration
694+
);
695+
696+
const configManager = createMockConfigManager();
697+
const configReader = createMockConfigReader();
698+
const buttonSetWriter = createMockButtonSetWriter();
699+
700+
const manager = ButtonSetManager.create({ buttonSetWriter, configManager, configReader });
701+
const result = await manager.createButtonSet(" ");
702+
703+
expect(result.success).toBe(false);
704+
if (!result.success) {
705+
expect(result.error).toBe("setNameRequired");
706+
}
707+
});
708+
709+
it("should return error for duplicate name", async () => {
710+
const existingSets = createTestButtonSets();
711+
const mockConfig = createMockConfig();
712+
mockConfig.get.mockReturnValue(CONFIGURATION_TARGETS.WORKSPACE);
713+
mockConfig.inspect.mockReturnValue({
714+
workspaceValue: existingSets.map((s) => ({ buttons: s.buttons, name: s.name })),
715+
});
716+
vi.spyOn(vscode.workspace, "getConfiguration").mockReturnValue(
717+
mockConfig as unknown as vscode.WorkspaceConfiguration
718+
);
719+
720+
const configManager = createMockConfigManager();
721+
const configReader = createMockConfigReader();
722+
const buttonSetWriter = createMockButtonSetWriter();
723+
724+
const manager = ButtonSetManager.create({ buttonSetWriter, configManager, configReader });
725+
const result = await manager.createButtonSet("Frontend");
726+
727+
expect(result.success).toBe(false);
728+
if (!result.success) {
729+
expect(result.error).toBe("duplicateSetName");
730+
}
731+
});
732+
733+
it("should copy buttons from source set when sourceSetId provided", async () => {
734+
const existingSets = createTestButtonSets();
735+
const mockConfig = createMockConfig();
736+
mockConfig.get.mockReturnValue(CONFIGURATION_TARGETS.WORKSPACE);
737+
// Include id in workspaceValue so ensureSetIdsInArray can match
738+
mockConfig.inspect.mockReturnValue({
739+
workspaceValue: existingSets,
740+
});
741+
vi.spyOn(vscode.workspace, "getConfiguration").mockReturnValue(
742+
mockConfig as unknown as vscode.WorkspaceConfiguration
743+
);
744+
745+
const configManager = createMockConfigManager();
746+
const configReader = createMockConfigReader();
747+
const buttonSetWriter = createMockButtonSetWriter();
748+
749+
const manager = ButtonSetManager.create({ buttonSetWriter, configManager, configReader });
750+
const result = await manager.createButtonSet("Copied Set", [], existingSets[0].id);
751+
752+
expect(result.success).toBe(true);
753+
const writtenSets = buttonSetWriter.writeButtonSets.mock.calls[0][0];
754+
const newSet = writtenSets.find((s: { name: string }) => s.name === "Copied Set");
755+
expect(newSet.buttons).toEqual(existingSets[0].buttons);
756+
});
757+
758+
it("should use provided buttons when sourceSetId not found", async () => {
759+
const mockConfig = createMockConfig();
760+
mockConfig.get.mockReturnValue(CONFIGURATION_TARGETS.WORKSPACE);
761+
mockConfig.inspect.mockReturnValue({ workspaceValue: [] });
762+
vi.spyOn(vscode.workspace, "getConfiguration").mockReturnValue(
763+
mockConfig as unknown as vscode.WorkspaceConfiguration
764+
);
765+
766+
const configManager = createMockConfigManager();
767+
const configReader = createMockConfigReader();
768+
const buttonSetWriter = createMockButtonSetWriter();
769+
770+
const manager = ButtonSetManager.create({ buttonSetWriter, configManager, configReader });
771+
const buttons = [{ command: "echo fallback", id: "fb-1", name: "Fallback" }];
772+
const result = await manager.createButtonSet("New Set", buttons, "non-existent-id");
773+
774+
expect(result.success).toBe(true);
775+
const writtenSets = buttonSetWriter.writeButtonSets.mock.calls[0][0];
776+
expect(writtenSets[0].buttons).toEqual(buttons);
777+
});
778+
779+
it("should write to local storage when local scope", async () => {
780+
const mockConfig = createMockConfig();
781+
mockConfig.get.mockReturnValue(CONFIGURATION_TARGETS.LOCAL);
782+
vi.spyOn(vscode.workspace, "getConfiguration").mockReturnValue(
783+
mockConfig as unknown as vscode.WorkspaceConfiguration
784+
);
785+
786+
const configManager = createMockConfigManager();
787+
const configReader = createMockConfigReader();
788+
const buttonSetWriter = createMockButtonSetWriter();
789+
const buttonSetLocalStorage = createMockButtonSetLocalStorage();
790+
791+
const manager = ButtonSetManager.create({
792+
buttonSetLocalStorage,
793+
buttonSetWriter,
794+
configManager,
795+
configReader,
796+
});
797+
const result = await manager.createButtonSet("Local Set");
798+
799+
expect(result.success).toBe(true);
800+
expect(buttonSetLocalStorage.setButtonSets).toHaveBeenCalled();
801+
expect(buttonSetWriter.writeButtonSets).not.toHaveBeenCalled();
802+
});
803+
});
804+
805+
describe("updateActiveSetButtons", () => {
806+
it("should return false when no active set", async () => {
807+
const mockConfig = createMockConfig();
808+
mockConfig.get.mockReturnValue(CONFIGURATION_TARGETS.WORKSPACE);
809+
mockConfig.inspect.mockReturnValue({ workspaceValue: null });
810+
vi.spyOn(vscode.workspace, "getConfiguration").mockReturnValue(
811+
mockConfig as unknown as vscode.WorkspaceConfiguration
812+
);
813+
814+
const configManager = createMockConfigManager();
815+
const configReader = createMockConfigReader();
816+
const buttonSetWriter = createMockButtonSetWriter();
817+
818+
const manager = ButtonSetManager.create({ buttonSetWriter, configManager, configReader });
819+
const result = await manager.updateActiveSetButtons([]);
820+
821+
expect(result).toBe(false);
822+
});
823+
824+
it("should return false when active set not found", async () => {
825+
const mockConfig = createMockConfig();
826+
mockConfig.get.mockReturnValue(CONFIGURATION_TARGETS.WORKSPACE);
827+
mockConfig.inspect.mockImplementation((key: string) => {
828+
if (key === "activeSet") {
829+
return { workspaceValue: "NonExistent" };
830+
}
831+
if (key === "buttonSets") {
832+
return { workspaceValue: [] };
833+
}
834+
return {};
835+
});
836+
vi.spyOn(vscode.workspace, "getConfiguration").mockReturnValue(
837+
mockConfig as unknown as vscode.WorkspaceConfiguration
838+
);
839+
840+
const configManager = createMockConfigManager();
841+
const configReader = createMockConfigReader();
842+
const buttonSetWriter = createMockButtonSetWriter();
843+
844+
const manager = ButtonSetManager.create({ buttonSetWriter, configManager, configReader });
845+
const result = await manager.updateActiveSetButtons([]);
846+
847+
expect(result).toBe(false);
848+
});
849+
850+
it("should update buttons in active set", async () => {
851+
const existingSets = createTestButtonSets();
852+
const mockConfig = createMockConfig();
853+
mockConfig.get.mockReturnValue(CONFIGURATION_TARGETS.WORKSPACE);
854+
mockConfig.inspect.mockImplementation((key: string) => {
855+
if (key === "activeSet") {
856+
return { workspaceValue: "Frontend" };
857+
}
858+
if (key === "buttonSets") {
859+
return {
860+
workspaceValue: existingSets.map((s) => ({ buttons: s.buttons, name: s.name })),
861+
};
862+
}
863+
return {};
864+
});
865+
vi.spyOn(vscode.workspace, "getConfiguration").mockReturnValue(
866+
mockConfig as unknown as vscode.WorkspaceConfiguration
867+
);
868+
869+
const configManager = createMockConfigManager();
870+
const configReader = createMockConfigReader();
871+
const buttonSetWriter = createMockButtonSetWriter();
872+
873+
const manager = ButtonSetManager.create({ buttonSetWriter, configManager, configReader });
874+
const newButtons = [
875+
{ command: "echo updated1", name: "Updated 1" },
876+
{ command: "echo updated2", name: "Updated 2" },
877+
];
878+
const result = await manager.updateActiveSetButtons(newButtons);
879+
880+
expect(result).toBe(true);
881+
expect(buttonSetWriter.writeButtonSets).toHaveBeenCalled();
882+
const writtenSets = buttonSetWriter.writeButtonSets.mock.calls[0][0];
883+
const frontendSet = writtenSets.find((s: { name: string }) => s.name === "Frontend");
884+
expect(frontendSet.buttons).toHaveLength(2);
885+
expect(frontendSet.buttons[0].command).toBe("echo updated1");
886+
});
887+
888+
it("should ensure IDs for buttons without IDs", async () => {
889+
const existingSets = [{ buttons: [], id: "set-1", name: "TestSet" }];
890+
const mockConfig = createMockConfig();
891+
mockConfig.get.mockReturnValue(CONFIGURATION_TARGETS.WORKSPACE);
892+
mockConfig.inspect.mockImplementation((key: string) => {
893+
if (key === "activeSet") {
894+
return { workspaceValue: "TestSet" };
895+
}
896+
if (key === "buttonSets") {
897+
return { workspaceValue: existingSets };
898+
}
899+
return {};
900+
});
901+
vi.spyOn(vscode.workspace, "getConfiguration").mockReturnValue(
902+
mockConfig as unknown as vscode.WorkspaceConfiguration
903+
);
904+
905+
const configManager = createMockConfigManager();
906+
const configReader = createMockConfigReader();
907+
const buttonSetWriter = createMockButtonSetWriter();
908+
909+
const manager = ButtonSetManager.create({ buttonSetWriter, configManager, configReader });
910+
const newButtons = [{ command: "echo no-id", name: "No ID Button" }];
911+
const result = await manager.updateActiveSetButtons(newButtons);
912+
913+
expect(result).toBe(true);
914+
const writtenSets = buttonSetWriter.writeButtonSets.mock.calls[0][0];
915+
expect(writtenSets[0].buttons[0].id).toBeDefined();
916+
});
917+
});
918+
919+
describe("setActiveSet with global scope", () => {
920+
it("should set active set to global scope", async () => {
921+
const mockConfig = createMockConfig();
922+
mockConfig.get.mockReturnValue(CONFIGURATION_TARGETS.GLOBAL);
923+
vi.spyOn(vscode.workspace, "getConfiguration").mockReturnValue(
924+
mockConfig as unknown as vscode.WorkspaceConfiguration
925+
);
926+
927+
const configManager = createMockConfigManager();
928+
const configReader = createMockConfigReader();
929+
const buttonSetWriter = createMockButtonSetWriter();
930+
931+
const manager = ButtonSetManager.create({ buttonSetWriter, configManager, configReader });
932+
await manager.setActiveSet("GlobalSet");
933+
934+
expect(buttonSetWriter.writeActiveSet).toHaveBeenCalledWith(
935+
"GlobalSet",
936+
vscode.ConfigurationTarget.Global
937+
);
938+
});
939+
});
940+
941+
describe("deleteButtonSet with case insensitivity", () => {
942+
it("should delete button set case-insensitively", async () => {
943+
const existingSets = createTestButtonSets();
944+
const mockConfig = createMockConfig();
945+
mockConfig.get.mockReturnValue(CONFIGURATION_TARGETS.WORKSPACE);
946+
mockConfig.inspect.mockImplementation((key: string) => {
947+
if (key === "buttonSets") {
948+
return {
949+
workspaceValue: existingSets.map((s) => ({ buttons: s.buttons, name: s.name })),
950+
};
951+
}
952+
if (key === "activeSet") {
953+
return { workspaceValue: null };
954+
}
955+
return {};
956+
});
957+
vi.spyOn(vscode.workspace, "getConfiguration").mockReturnValue(
958+
mockConfig as unknown as vscode.WorkspaceConfiguration
959+
);
960+
961+
const configManager = createMockConfigManager();
962+
const configReader = createMockConfigReader();
963+
const buttonSetWriter = createMockButtonSetWriter();
964+
965+
const manager = ButtonSetManager.create({ buttonSetWriter, configManager, configReader });
966+
await manager.deleteButtonSet("FRONTEND");
967+
968+
expect(buttonSetWriter.writeButtonSets).toHaveBeenCalled();
969+
const writtenSets = buttonSetWriter.writeButtonSets.mock.calls[0][0];
970+
expect(writtenSets).toHaveLength(1);
971+
expect(writtenSets[0].name).toBe("Backend");
972+
});
973+
974+
it("should delete from local storage when local scope", async () => {
975+
const localSets = createTestButtonSets();
976+
const mockConfig = createMockConfig();
977+
mockConfig.get.mockReturnValue(CONFIGURATION_TARGETS.LOCAL);
978+
vi.spyOn(vscode.workspace, "getConfiguration").mockReturnValue(
979+
mockConfig as unknown as vscode.WorkspaceConfiguration
980+
);
981+
982+
const configManager = createMockConfigManager();
983+
const configReader = createMockConfigReader();
984+
const buttonSetWriter = createMockButtonSetWriter();
985+
const buttonSetLocalStorage = createMockButtonSetLocalStorage();
986+
buttonSetLocalStorage.getButtonSets.mockReturnValue(localSets);
987+
buttonSetLocalStorage.getActiveSet.mockReturnValue(null);
988+
989+
const manager = ButtonSetManager.create({
990+
buttonSetLocalStorage,
991+
buttonSetWriter,
992+
configManager,
993+
configReader,
994+
});
995+
await manager.deleteButtonSet("Frontend");
996+
997+
expect(buttonSetLocalStorage.setButtonSets).toHaveBeenCalled();
998+
expect(buttonSetWriter.writeButtonSets).not.toHaveBeenCalled();
999+
});
1000+
});
1001+
6441002
describe("renameButtonSet", () => {
6451003
it("should return setNotFound error when renaming non-existent set", async () => {
6461004
const existingSets = [{ buttons: [], id: "set-1", name: "SetA" }];

0 commit comments

Comments
 (0)