genlayer 0.34.0 → 0.34.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +13 -3
- package/package.json +11 -2
- package/.eslintignore +0 -2
- package/.github/workflows/cli-docs.yml +0 -121
- package/.github/workflows/publish-beta.yml +0 -41
- package/.github/workflows/publish.yml +0 -43
- package/.github/workflows/validate-code.yml +0 -47
- package/.prettierignore +0 -19
- package/.prettierrc +0 -12
- package/.release-it.json +0 -64
- package/CHANGELOG.md +0 -425
- package/CLAUDE.md +0 -55
- package/CONTRIBUTING.md +0 -117
- package/docker-compose.yml +0 -154
- package/docs/delegator-guide.md +0 -203
- package/docs/validator-guide.md +0 -329
- package/esbuild.config.dev.js +0 -17
- package/esbuild.config.js +0 -22
- package/esbuild.config.prod.js +0 -17
- package/eslint.config.js +0 -60
- package/renovate.json +0 -22
- package/src/commands/account/create.ts +0 -30
- package/src/commands/account/export.ts +0 -106
- package/src/commands/account/import.ts +0 -135
- package/src/commands/account/index.ts +0 -129
- package/src/commands/account/list.ts +0 -34
- package/src/commands/account/lock.ts +0 -39
- package/src/commands/account/remove.ts +0 -30
- package/src/commands/account/send.ts +0 -162
- package/src/commands/account/show.ts +0 -74
- package/src/commands/account/unlock.ts +0 -56
- package/src/commands/account/use.ts +0 -21
- package/src/commands/config/getSetReset.ts +0 -51
- package/src/commands/config/index.ts +0 -30
- package/src/commands/contracts/call.ts +0 -39
- package/src/commands/contracts/code.ts +0 -33
- package/src/commands/contracts/deploy.ts +0 -157
- package/src/commands/contracts/index.ts +0 -86
- package/src/commands/contracts/schema.ts +0 -31
- package/src/commands/contracts/write.ts +0 -49
- package/src/commands/general/index.ts +0 -45
- package/src/commands/general/init.ts +0 -179
- package/src/commands/general/start.ts +0 -116
- package/src/commands/general/stop.ts +0 -26
- package/src/commands/localnet/index.ts +0 -100
- package/src/commands/localnet/validators.ts +0 -269
- package/src/commands/network/index.ts +0 -29
- package/src/commands/network/setNetwork.ts +0 -77
- package/src/commands/scaffold/index.ts +0 -16
- package/src/commands/scaffold/new.ts +0 -34
- package/src/commands/staking/StakingAction.ts +0 -279
- package/src/commands/staking/delegatorClaim.ts +0 -41
- package/src/commands/staking/delegatorExit.ts +0 -56
- package/src/commands/staking/delegatorJoin.ts +0 -44
- package/src/commands/staking/index.ts +0 -357
- package/src/commands/staking/setIdentity.ts +0 -78
- package/src/commands/staking/setOperator.ts +0 -46
- package/src/commands/staking/stakingInfo.ts +0 -584
- package/src/commands/staking/validatorClaim.ts +0 -43
- package/src/commands/staking/validatorDeposit.ts +0 -48
- package/src/commands/staking/validatorExit.ts +0 -63
- package/src/commands/staking/validatorHistory.ts +0 -298
- package/src/commands/staking/validatorJoin.ts +0 -47
- package/src/commands/staking/validatorPrime.ts +0 -73
- package/src/commands/staking/wizard.ts +0 -809
- package/src/commands/transactions/appeal.ts +0 -39
- package/src/commands/transactions/index.ts +0 -39
- package/src/commands/transactions/receipt.ts +0 -90
- package/src/commands/update/index.ts +0 -25
- package/src/commands/update/ollama.ts +0 -103
- package/src/lib/actions/BaseAction.ts +0 -299
- package/src/lib/clients/jsonRpcClient.ts +0 -41
- package/src/lib/clients/system.ts +0 -73
- package/src/lib/config/ConfigFileManager.ts +0 -194
- package/src/lib/config/KeychainManager.ts +0 -89
- package/src/lib/config/simulator.ts +0 -68
- package/src/lib/config/text.ts +0 -2
- package/src/lib/errors/missingRequirement.ts +0 -9
- package/src/lib/errors/versionRequired.ts +0 -9
- package/src/lib/interfaces/ISimulatorService.ts +0 -37
- package/src/lib/services/simulator.ts +0 -351
- package/src/types/node-fetch.d.ts +0 -1
- package/tests/actions/appeal.test.ts +0 -99
- package/tests/actions/call.test.ts +0 -94
- package/tests/actions/code.test.ts +0 -87
- package/tests/actions/create.test.ts +0 -65
- package/tests/actions/deploy.test.ts +0 -420
- package/tests/actions/getSetReset.test.ts +0 -88
- package/tests/actions/init.test.ts +0 -467
- package/tests/actions/lock.test.ts +0 -86
- package/tests/actions/new.test.ts +0 -80
- package/tests/actions/ollama.test.ts +0 -193
- package/tests/actions/receipt.test.ts +0 -261
- package/tests/actions/schema.test.ts +0 -94
- package/tests/actions/setNetwork.test.ts +0 -160
- package/tests/actions/staking.test.ts +0 -279
- package/tests/actions/start.test.ts +0 -235
- package/tests/actions/stop.test.ts +0 -77
- package/tests/actions/unlock.test.ts +0 -139
- package/tests/actions/validators.test.ts +0 -750
- package/tests/actions/write.test.ts +0 -102
- package/tests/commands/account.test.ts +0 -146
- package/tests/commands/appeal.test.ts +0 -58
- package/tests/commands/call.test.ts +0 -78
- package/tests/commands/code.test.ts +0 -69
- package/tests/commands/config.test.ts +0 -54
- package/tests/commands/deploy.test.ts +0 -83
- package/tests/commands/init.test.ts +0 -101
- package/tests/commands/localnet.test.ts +0 -131
- package/tests/commands/network.test.ts +0 -60
- package/tests/commands/new.test.ts +0 -68
- package/tests/commands/receipt.test.ts +0 -142
- package/tests/commands/schema.test.ts +0 -67
- package/tests/commands/staking.test.ts +0 -329
- package/tests/commands/stop.test.ts +0 -27
- package/tests/commands/up.test.ts +0 -105
- package/tests/commands/update.test.ts +0 -45
- package/tests/commands/write.test.ts +0 -76
- package/tests/index.test.ts +0 -56
- package/tests/libs/baseAction.test.ts +0 -516
- package/tests/libs/configFileManager.test.ts +0 -117
- package/tests/libs/jsonRpcClient.test.ts +0 -59
- package/tests/libs/keychainManager.test.ts +0 -156
- package/tests/libs/system.test.ts +0 -148
- package/tests/services/simulator.test.ts +0 -705
- package/tests/utils.ts +0 -13
- package/tsconfig.json +0 -120
- package/vitest.config.ts +0 -12
|
@@ -1,467 +0,0 @@
|
|
|
1
|
-
import {describe, test, vi, beforeEach, afterEach, expect} from "vitest";
|
|
2
|
-
import inquirer from "inquirer";
|
|
3
|
-
import {InitAction, InitActionOptions} from "../../src/commands/general/init";
|
|
4
|
-
import {SimulatorService} from "../../src/lib/services/simulator";
|
|
5
|
-
import {OllamaAction} from "../../src/commands/update/ollama";
|
|
6
|
-
import {localnetCompatibleVersion} from "../../src/lib/config/simulator";
|
|
7
|
-
|
|
8
|
-
describe("InitAction", () => {
|
|
9
|
-
let initAction: InitAction;
|
|
10
|
-
let inquirerPromptSpy: ReturnType<any>;
|
|
11
|
-
let checkCliVersionSpy: ReturnType<typeof vi.spyOn>;
|
|
12
|
-
let checkInstallRequirementsSpy: ReturnType<typeof vi.spyOn>;
|
|
13
|
-
let checkVersionRequirementsSpy: ReturnType<typeof vi.spyOn>;
|
|
14
|
-
let resetDockerContainersSpy: ReturnType<typeof vi.spyOn>;
|
|
15
|
-
let resetDockerImagesSpy: ReturnType<typeof vi.spyOn>;
|
|
16
|
-
let resetDockerVolumesSpy: ReturnType<typeof vi.spyOn>;
|
|
17
|
-
let addConfigToEnvFileSpy: ReturnType<typeof vi.spyOn>;
|
|
18
|
-
let runSimulatorSpy: ReturnType<typeof vi.spyOn>;
|
|
19
|
-
let waitForSimulatorSpy: ReturnType<typeof vi.spyOn>;
|
|
20
|
-
let deleteAllValidatorsSpy: ReturnType<typeof vi.spyOn>;
|
|
21
|
-
let createRandomValidatorsSpy: ReturnType<typeof vi.spyOn>;
|
|
22
|
-
let cleanDatabaseSpy: ReturnType<typeof vi.spyOn>;
|
|
23
|
-
let openFrontendSpy: ReturnType<typeof vi.spyOn>;
|
|
24
|
-
let getFrontendUrlSpy: ReturnType<typeof vi.spyOn>;
|
|
25
|
-
let normalizeLocalnetVersionSpy: ReturnType<typeof vi.spyOn>;
|
|
26
|
-
|
|
27
|
-
const defaultConfig = {defaultOllamaModel: "llama3"};
|
|
28
|
-
|
|
29
|
-
const defaultOptions: InitActionOptions = {
|
|
30
|
-
numValidators: 5,
|
|
31
|
-
headless: false,
|
|
32
|
-
resetDb: false,
|
|
33
|
-
localnetVersion: localnetCompatibleVersion,
|
|
34
|
-
ollama: false
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
beforeEach(() => {
|
|
38
|
-
vi.clearAllMocks();
|
|
39
|
-
initAction = new InitAction();
|
|
40
|
-
inquirerPromptSpy = vi.spyOn(inquirer, "prompt");
|
|
41
|
-
vi.spyOn(initAction as any, "startSpinner").mockImplementation(() => {});
|
|
42
|
-
vi.spyOn(initAction as any, "setSpinnerText").mockImplementation(() => {});
|
|
43
|
-
vi.spyOn(initAction as any, "succeedSpinner").mockImplementation(() => {});
|
|
44
|
-
vi.spyOn(initAction as any, "failSpinner").mockImplementation(() => {});
|
|
45
|
-
vi.spyOn(initAction as any, "stopSpinner").mockImplementation(() => {});
|
|
46
|
-
vi.spyOn(initAction as any, "logError").mockImplementation(() => {});
|
|
47
|
-
vi.spyOn(initAction, "getConfig").mockReturnValue(defaultConfig);
|
|
48
|
-
checkCliVersionSpy = vi.spyOn(SimulatorService.prototype, "checkCliVersion").mockResolvedValue(undefined);
|
|
49
|
-
checkInstallRequirementsSpy = vi
|
|
50
|
-
.spyOn(SimulatorService.prototype, "checkInstallRequirements")
|
|
51
|
-
.mockResolvedValue({git: true, docker: true});
|
|
52
|
-
checkVersionRequirementsSpy = vi
|
|
53
|
-
.spyOn(SimulatorService.prototype, "checkVersionRequirements")
|
|
54
|
-
.mockResolvedValue({node: "", docker: ""});
|
|
55
|
-
resetDockerContainersSpy = vi
|
|
56
|
-
.spyOn(SimulatorService.prototype, "resetDockerContainers")
|
|
57
|
-
.mockResolvedValue(undefined);
|
|
58
|
-
resetDockerImagesSpy = vi
|
|
59
|
-
.spyOn(SimulatorService.prototype, "resetDockerImages")
|
|
60
|
-
.mockResolvedValue(undefined);
|
|
61
|
-
resetDockerVolumesSpy = vi
|
|
62
|
-
.spyOn(SimulatorService.prototype, "resetDockerVolumes")
|
|
63
|
-
.mockResolvedValue(undefined);
|
|
64
|
-
addConfigToEnvFileSpy = vi.spyOn(SimulatorService.prototype, "addConfigToEnvFile").mockResolvedValue();
|
|
65
|
-
runSimulatorSpy = vi
|
|
66
|
-
.spyOn(SimulatorService.prototype, "runSimulator")
|
|
67
|
-
.mockResolvedValue(undefined as any);
|
|
68
|
-
waitForSimulatorSpy = vi
|
|
69
|
-
.spyOn(SimulatorService.prototype, "waitForSimulatorToBeReady")
|
|
70
|
-
.mockResolvedValue({initialized: true}) as any;
|
|
71
|
-
deleteAllValidatorsSpy = vi
|
|
72
|
-
.spyOn(SimulatorService.prototype, "deleteAllValidators")
|
|
73
|
-
.mockResolvedValue(undefined);
|
|
74
|
-
createRandomValidatorsSpy = vi
|
|
75
|
-
.spyOn(SimulatorService.prototype, "createRandomValidators")
|
|
76
|
-
.mockResolvedValue(undefined) as any;
|
|
77
|
-
cleanDatabaseSpy = vi.spyOn(SimulatorService.prototype, "cleanDatabase").mockResolvedValue(true);
|
|
78
|
-
openFrontendSpy = vi.spyOn(SimulatorService.prototype, "openFrontend").mockResolvedValue(true);
|
|
79
|
-
getFrontendUrlSpy = vi
|
|
80
|
-
.spyOn(SimulatorService.prototype, "getFrontendUrl")
|
|
81
|
-
.mockReturnValue("http://localhost:8080");
|
|
82
|
-
normalizeLocalnetVersionSpy = vi
|
|
83
|
-
.spyOn(SimulatorService.prototype, "normalizeLocalnetVersion")
|
|
84
|
-
.mockImplementation((v: string) => v) as any;
|
|
85
|
-
vi.spyOn(SimulatorService.prototype, "isLocalnetRunning").mockResolvedValue(false);
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
afterEach(() => {
|
|
89
|
-
vi.restoreAllMocks();
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
describe("Successful Execution", () => {
|
|
93
|
-
test("should show combined confirmation message when localnet is running", async () => {
|
|
94
|
-
vi.spyOn(SimulatorService.prototype, "isLocalnetRunning").mockResolvedValue(true);
|
|
95
|
-
|
|
96
|
-
const confirmPromptSpy = vi.spyOn(initAction as any, "confirmPrompt").mockResolvedValue(undefined);
|
|
97
|
-
|
|
98
|
-
inquirerPromptSpy
|
|
99
|
-
.mockResolvedValueOnce({selectedLlmProviders: ["openai"]})
|
|
100
|
-
.mockResolvedValueOnce({openai: "API_KEY_OPENAI"});
|
|
101
|
-
|
|
102
|
-
await initAction.execute(defaultOptions);
|
|
103
|
-
|
|
104
|
-
expect(confirmPromptSpy).toHaveBeenCalledWith(
|
|
105
|
-
"GenLayer Localnet is already running and this command is going to reset GenLayer docker images, containers and volumes, providers API Keys, and GenLayer database (accounts, transactions, validators and logs). Contract code (gpy files) will be kept. Do you want to continue?",
|
|
106
|
-
);
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
test("should show standard confirmation message when localnet is not running", async () => {
|
|
110
|
-
vi.spyOn(SimulatorService.prototype, "isLocalnetRunning").mockResolvedValue(false);
|
|
111
|
-
|
|
112
|
-
const confirmPromptSpy = vi.spyOn(initAction as any, "confirmPrompt").mockResolvedValue(undefined);
|
|
113
|
-
|
|
114
|
-
inquirerPromptSpy
|
|
115
|
-
.mockResolvedValueOnce({selectedLlmProviders: ["openai"]})
|
|
116
|
-
.mockResolvedValueOnce({openai: "API_KEY_OPENAI"});
|
|
117
|
-
|
|
118
|
-
await initAction.execute(defaultOptions);
|
|
119
|
-
|
|
120
|
-
expect(confirmPromptSpy).toHaveBeenCalledWith(
|
|
121
|
-
"This command is going to reset GenLayer docker images, containers and volumes, providers API Keys, and GenLayer database (accounts, transactions, validators and logs). Contract code (gpy files) will be kept. Do you want to continue?",
|
|
122
|
-
);
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
test("executes the full flow in non-headless mode", async () => {
|
|
126
|
-
inquirerPromptSpy
|
|
127
|
-
.mockResolvedValueOnce({confirmAction: true})
|
|
128
|
-
.mockResolvedValueOnce({selectedLlmProviders: ["openai", "heuristai"]})
|
|
129
|
-
.mockResolvedValueOnce({openai: "API_KEY_OPENAI"})
|
|
130
|
-
.mockResolvedValueOnce({heuristai: "API_KEY_HEURIST"});
|
|
131
|
-
await initAction.execute(defaultOptions);
|
|
132
|
-
expect(checkCliVersionSpy).toHaveBeenCalled();
|
|
133
|
-
expect(checkInstallRequirementsSpy).toHaveBeenCalled();
|
|
134
|
-
expect(checkVersionRequirementsSpy).toHaveBeenCalled();
|
|
135
|
-
expect(resetDockerContainersSpy).toHaveBeenCalled();
|
|
136
|
-
expect(resetDockerImagesSpy).toHaveBeenCalled();
|
|
137
|
-
expect(resetDockerVolumesSpy).toHaveBeenCalled();
|
|
138
|
-
expect(addConfigToEnvFileSpy).toHaveBeenCalledWith({
|
|
139
|
-
OPENAIKEY: "API_KEY_OPENAI",
|
|
140
|
-
HEURISTAIAPIKEY: "API_KEY_HEURIST",
|
|
141
|
-
});
|
|
142
|
-
expect(addConfigToEnvFileSpy).toHaveBeenCalledWith({LOCALNETVERSION: localnetCompatibleVersion});
|
|
143
|
-
expect(runSimulatorSpy).toHaveBeenCalled();
|
|
144
|
-
expect(waitForSimulatorSpy).toHaveBeenCalled();
|
|
145
|
-
expect(deleteAllValidatorsSpy).toHaveBeenCalled();
|
|
146
|
-
expect(createRandomValidatorsSpy).toHaveBeenCalledWith(5, ["openai", "heuristai"]);
|
|
147
|
-
expect(getFrontendUrlSpy).toHaveBeenCalled();
|
|
148
|
-
expect(openFrontendSpy).toHaveBeenCalled();
|
|
149
|
-
expect((initAction as any).succeedSpinner).toHaveBeenCalledWith(
|
|
150
|
-
"GenLayer Localnet initialized successfully! Go to http://localhost:8080 in your browser to access it.",
|
|
151
|
-
);
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
test("executes correctly in headless mode with DB reset and 'ollama' selected", async () => {
|
|
155
|
-
inquirerPromptSpy
|
|
156
|
-
.mockResolvedValueOnce({confirmAction: true})
|
|
157
|
-
.mockResolvedValueOnce({selectedLlmProviders: ["openai", "ollama"]})
|
|
158
|
-
.mockResolvedValueOnce({openai: "API_KEY_OPENAI"});
|
|
159
|
-
const ollamaUpdateSpy = vi.spyOn(OllamaAction.prototype, "updateModel").mockResolvedValue(undefined);
|
|
160
|
-
const headlessOptions: InitActionOptions = {
|
|
161
|
-
numValidators: 5,
|
|
162
|
-
headless: true,
|
|
163
|
-
resetDb: true,
|
|
164
|
-
localnetVersion: localnetCompatibleVersion,
|
|
165
|
-
ollama: true
|
|
166
|
-
};
|
|
167
|
-
await initAction.execute(headlessOptions);
|
|
168
|
-
expect(cleanDatabaseSpy).toHaveBeenCalled();
|
|
169
|
-
expect(openFrontendSpy).not.toHaveBeenCalled();
|
|
170
|
-
expect((initAction as any).succeedSpinner).toHaveBeenCalledWith(
|
|
171
|
-
"GenLayer Localnet initialized successfully! ",
|
|
172
|
-
);
|
|
173
|
-
expect(ollamaUpdateSpy).toHaveBeenCalledWith("llama3");
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
test("normalizes localnetVersion if not 'latest'", async () => {
|
|
177
|
-
const customVersion = "v99";
|
|
178
|
-
normalizeLocalnetVersionSpy.mockReturnValue(customVersion);
|
|
179
|
-
inquirerPromptSpy
|
|
180
|
-
.mockResolvedValueOnce({confirmAction: true})
|
|
181
|
-
.mockResolvedValueOnce({selectedLlmProviders: ["openai"]})
|
|
182
|
-
.mockResolvedValueOnce({openai: "API_KEY_OPENAI"});
|
|
183
|
-
await initAction.execute({...defaultOptions, localnetVersion: customVersion});
|
|
184
|
-
expect(normalizeLocalnetVersionSpy).toHaveBeenCalledWith(customVersion);
|
|
185
|
-
expect(addConfigToEnvFileSpy).toHaveBeenCalledWith({LOCALNETVERSION: customVersion});
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
test("should set defaultOllamaModel to 'llama3' if not provided in config", async () => {
|
|
189
|
-
vi.spyOn(initAction, "getConfig").mockReturnValue({});
|
|
190
|
-
const writeConfigSpy = vi.spyOn(initAction, "writeConfig").mockImplementation(() => {});
|
|
191
|
-
const ollamaUpdateSpy = vi.spyOn(OllamaAction.prototype, "updateModel").mockResolvedValue(undefined);
|
|
192
|
-
inquirerPromptSpy
|
|
193
|
-
.mockResolvedValueOnce({confirmAction: true})
|
|
194
|
-
.mockResolvedValueOnce({selectedLlmProviders: ["ollama"]})
|
|
195
|
-
.mockResolvedValueOnce({ollama: "API_KEY_OLLAMA"});
|
|
196
|
-
await initAction.execute(defaultOptions);
|
|
197
|
-
expect(writeConfigSpy).toHaveBeenCalledWith("defaultOllamaModel", "llama3");
|
|
198
|
-
expect(ollamaUpdateSpy).toHaveBeenCalledWith("llama3");
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
test("validates API key input for configurable provider", async () => {
|
|
202
|
-
inquirerPromptSpy.mockResolvedValueOnce({confirmAction: true});
|
|
203
|
-
inquirerPromptSpy.mockResolvedValueOnce({selectedLlmProviders: ["openai"]});
|
|
204
|
-
let capturedQuestion: any;
|
|
205
|
-
inquirerPromptSpy.mockImplementationOnce((questions: any) => {
|
|
206
|
-
capturedQuestion = questions[0];
|
|
207
|
-
return Promise.resolve({openai: "dummy-key"});
|
|
208
|
-
});
|
|
209
|
-
await initAction.execute(defaultOptions);
|
|
210
|
-
expect(capturedQuestion).toBeDefined();
|
|
211
|
-
const expectedError = `Please enter a valid API Key for OpenAI.`;
|
|
212
|
-
expect(capturedQuestion.validate("")).toBe(expectedError);
|
|
213
|
-
expect(capturedQuestion.validate("non-empty-key")).toBe(true);
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
test("validates LLM provider selection prompt", async () => {
|
|
217
|
-
let capturedQuestion: any;
|
|
218
|
-
inquirerPromptSpy
|
|
219
|
-
.mockResolvedValueOnce({confirmAction: true})
|
|
220
|
-
.mockImplementationOnce((questions: any) => {
|
|
221
|
-
capturedQuestion = questions[0];
|
|
222
|
-
return Promise.resolve({selectedLlmProviders: ["openai"]});
|
|
223
|
-
})
|
|
224
|
-
.mockResolvedValueOnce({openai: "API_KEY_OPENAI"});
|
|
225
|
-
await initAction.execute(defaultOptions);
|
|
226
|
-
expect(capturedQuestion.validate([])).toBe("You must choose at least one option.");
|
|
227
|
-
expect(capturedQuestion.validate(["openai"])).toBe(true);
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
test("should exclude ollama from choices when ollama option is false", async () => {
|
|
231
|
-
const getAiProvidersOptionsSpy = vi.spyOn(SimulatorService.prototype, "getAiProvidersOptions");
|
|
232
|
-
inquirerPromptSpy
|
|
233
|
-
.mockResolvedValueOnce({ confirmAction: true })
|
|
234
|
-
.mockResolvedValueOnce({ selectedLlmProviders: ["openai"] })
|
|
235
|
-
.mockResolvedValueOnce({ openai: "API_KEY_OPENAI" });
|
|
236
|
-
|
|
237
|
-
await initAction.execute({ ...defaultOptions, ollama: false });
|
|
238
|
-
|
|
239
|
-
expect(getAiProvidersOptionsSpy).toHaveBeenCalledWith(true, ["ollama"]);
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
test("should include ollama in choices when ollama option is true", async () => {
|
|
243
|
-
const getAiProvidersOptionsSpy = vi.spyOn(SimulatorService.prototype, "getAiProvidersOptions");
|
|
244
|
-
inquirerPromptSpy
|
|
245
|
-
.mockResolvedValueOnce({ confirmAction: true })
|
|
246
|
-
.mockResolvedValueOnce({ selectedLlmProviders: ["openai"] })
|
|
247
|
-
.mockResolvedValueOnce({ openai: "API_KEY_OPENAI" });
|
|
248
|
-
|
|
249
|
-
await initAction.execute({ ...defaultOptions, ollama: true });
|
|
250
|
-
|
|
251
|
-
expect(getAiProvidersOptionsSpy).toHaveBeenCalledWith(true, []);
|
|
252
|
-
});
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
describe("Error Handling", () => {
|
|
256
|
-
test("fails if Docker is not installed", async () => {
|
|
257
|
-
checkInstallRequirementsSpy.mockResolvedValue({git: true, docker: false});
|
|
258
|
-
await initAction.execute(defaultOptions);
|
|
259
|
-
expect((initAction as any).failSpinner).toHaveBeenCalledWith(
|
|
260
|
-
"Docker is not installed. Please install Docker and try again.\n",
|
|
261
|
-
);
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
test("fails if localnet version is older than compatible version", async () => {
|
|
265
|
-
const olderVersion = "v0.0.1";
|
|
266
|
-
normalizeLocalnetVersionSpy.mockReturnValue(olderVersion);
|
|
267
|
-
await initAction.execute({...defaultOptions, localnetVersion: olderVersion});
|
|
268
|
-
expect((initAction as any).failSpinner).toHaveBeenCalledWith(
|
|
269
|
-
`Localnet version ${olderVersion} is not supported. Minimum required version is ${localnetCompatibleVersion}. Please use a newer version.`
|
|
270
|
-
);
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
test("should proceed when localnet version is equal to compatible version", async () => {
|
|
274
|
-
normalizeLocalnetVersionSpy.mockReturnValue(localnetCompatibleVersion);
|
|
275
|
-
inquirerPromptSpy
|
|
276
|
-
.mockResolvedValueOnce({selectedLlmProviders: ["openai"]})
|
|
277
|
-
.mockResolvedValueOnce({openai: "API_KEY_OPENAI"});
|
|
278
|
-
await initAction.execute({...defaultOptions, localnetVersion: localnetCompatibleVersion});
|
|
279
|
-
expect((initAction as any).failSpinner).not.toHaveBeenCalledWith(
|
|
280
|
-
expect.stringContaining("Localnet version")
|
|
281
|
-
);
|
|
282
|
-
});
|
|
283
|
-
|
|
284
|
-
test("should proceed when localnet version is newer than compatible version", async () => {
|
|
285
|
-
const newerVersion = "v99.99.99";
|
|
286
|
-
normalizeLocalnetVersionSpy.mockReturnValue(newerVersion);
|
|
287
|
-
inquirerPromptSpy
|
|
288
|
-
.mockResolvedValueOnce({selectedLlmProviders: ["openai"]})
|
|
289
|
-
.mockResolvedValueOnce({openai: "API_KEY_OPENAI"});
|
|
290
|
-
await initAction.execute({...defaultOptions, localnetVersion: newerVersion});
|
|
291
|
-
expect((initAction as any).failSpinner).not.toHaveBeenCalledWith(
|
|
292
|
-
expect.stringContaining("Localnet version")
|
|
293
|
-
);
|
|
294
|
-
});
|
|
295
|
-
|
|
296
|
-
test("should skip version validation when localnet version is 'latest'", async () => {
|
|
297
|
-
inquirerPromptSpy
|
|
298
|
-
.mockResolvedValueOnce({selectedLlmProviders: ["openai"]})
|
|
299
|
-
.mockResolvedValueOnce({openai: "API_KEY_OPENAI"});
|
|
300
|
-
await initAction.execute({...defaultOptions, localnetVersion: "latest"});
|
|
301
|
-
expect(normalizeLocalnetVersionSpy).not.toHaveBeenCalled();
|
|
302
|
-
expect((initAction as any).failSpinner).not.toHaveBeenCalledWith(
|
|
303
|
-
expect.stringContaining("Localnet version")
|
|
304
|
-
);
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
test("fails if checkInstallRequirements throws an error", async () => {
|
|
308
|
-
const error = new Error("Install error");
|
|
309
|
-
checkInstallRequirementsSpy.mockRejectedValue(error);
|
|
310
|
-
await initAction.execute(defaultOptions);
|
|
311
|
-
expect((initAction as any).failSpinner).toHaveBeenCalledWith(
|
|
312
|
-
"An error occurred during initialization.",
|
|
313
|
-
error,
|
|
314
|
-
);
|
|
315
|
-
});
|
|
316
|
-
|
|
317
|
-
test("fails if version requirements are not met (both docker and node)", async () => {
|
|
318
|
-
const version = "99.9.9";
|
|
319
|
-
checkVersionRequirementsSpy.mockResolvedValue({docker: version, node: version});
|
|
320
|
-
await initAction.execute(defaultOptions);
|
|
321
|
-
expect((initAction as any).failSpinner).toHaveBeenCalledWith(
|
|
322
|
-
`Docker version ${version} or higher is required. Please update Docker and try again.\nNode version ${version} or higher is required. Please update Node and try again.\n`,
|
|
323
|
-
);
|
|
324
|
-
});
|
|
325
|
-
|
|
326
|
-
test("fails if version requirement for docker is not met", async () => {
|
|
327
|
-
const version = "99.9.9";
|
|
328
|
-
checkVersionRequirementsSpy.mockResolvedValue({docker: version});
|
|
329
|
-
await initAction.execute(defaultOptions);
|
|
330
|
-
expect((initAction as any).failSpinner).toHaveBeenCalledWith(
|
|
331
|
-
`Docker version ${version} or higher is required. Please update Docker and try again.\n`,
|
|
332
|
-
);
|
|
333
|
-
});
|
|
334
|
-
|
|
335
|
-
test("fails if version requirement for node is not met", async () => {
|
|
336
|
-
const version = "99.9.9";
|
|
337
|
-
checkVersionRequirementsSpy.mockResolvedValue({node: version});
|
|
338
|
-
await initAction.execute(defaultOptions);
|
|
339
|
-
expect((initAction as any).failSpinner).toHaveBeenCalledWith(
|
|
340
|
-
`Node version ${version} or higher is required. Please update Node and try again.\n`,
|
|
341
|
-
);
|
|
342
|
-
});
|
|
343
|
-
|
|
344
|
-
test("aborts if user does not confirm reset action", async () => {
|
|
345
|
-
inquirerPromptSpy.mockResolvedValueOnce({confirmAction: false});
|
|
346
|
-
await initAction.execute(defaultOptions);
|
|
347
|
-
expect((initAction as any).logError).toHaveBeenCalledWith(`Operation aborted!`);
|
|
348
|
-
});
|
|
349
|
-
|
|
350
|
-
test("fails if resetDockerContainers throws an error", async () => {
|
|
351
|
-
inquirerPromptSpy.mockResolvedValueOnce({confirmAction: true});
|
|
352
|
-
resetDockerContainersSpy.mockRejectedValue(new Error("Container reset error"));
|
|
353
|
-
await initAction.execute(defaultOptions);
|
|
354
|
-
expect((initAction as any).failSpinner).toHaveBeenCalledWith(
|
|
355
|
-
"An error occurred during initialization.",
|
|
356
|
-
new Error("Container reset error"),
|
|
357
|
-
);
|
|
358
|
-
});
|
|
359
|
-
|
|
360
|
-
test("fails if runSimulator throws an error", async () => {
|
|
361
|
-
inquirerPromptSpy
|
|
362
|
-
.mockResolvedValueOnce({confirmAction: true})
|
|
363
|
-
.mockResolvedValueOnce({selectedLlmProviders: ["openai"]})
|
|
364
|
-
.mockResolvedValueOnce({openai: "API_KEY_OPENAI"});
|
|
365
|
-
runSimulatorSpy.mockRejectedValue(new Error("Run simulator error"));
|
|
366
|
-
await initAction.execute(defaultOptions);
|
|
367
|
-
expect((initAction as any).failSpinner).toHaveBeenCalledWith(
|
|
368
|
-
"An error occurred during initialization.",
|
|
369
|
-
new Error("Run simulator error"),
|
|
370
|
-
);
|
|
371
|
-
});
|
|
372
|
-
|
|
373
|
-
test("fails if waitForSimulatorToBeReady returns ERROR code", async () => {
|
|
374
|
-
inquirerPromptSpy
|
|
375
|
-
.mockResolvedValueOnce({confirmAction: true})
|
|
376
|
-
.mockResolvedValueOnce({selectedLlmProviders: ["openai"]})
|
|
377
|
-
.mockResolvedValueOnce({openai: "API_KEY_OPENAI"});
|
|
378
|
-
waitForSimulatorSpy.mockResolvedValue({
|
|
379
|
-
initialized: false,
|
|
380
|
-
errorCode: "ERROR",
|
|
381
|
-
errorMessage: "Initialization failed",
|
|
382
|
-
});
|
|
383
|
-
await initAction.execute(defaultOptions);
|
|
384
|
-
expect((initAction as any).failSpinner).toHaveBeenCalledWith(
|
|
385
|
-
"Unable to initialize the GenLayer Localnet: Initialization failed",
|
|
386
|
-
);
|
|
387
|
-
});
|
|
388
|
-
|
|
389
|
-
test("fails if waitForSimulatorToBeReady returns TIMEOUT code", async () => {
|
|
390
|
-
inquirerPromptSpy
|
|
391
|
-
.mockResolvedValueOnce({confirmAction: true})
|
|
392
|
-
.mockResolvedValueOnce({selectedLlmProviders: ["openai"]})
|
|
393
|
-
.mockResolvedValueOnce({openai: "API_KEY_OPENAI"});
|
|
394
|
-
waitForSimulatorSpy.mockResolvedValue({
|
|
395
|
-
initialized: false,
|
|
396
|
-
errorCode: "TIMEOUT",
|
|
397
|
-
errorMessage: "Timeout",
|
|
398
|
-
});
|
|
399
|
-
await initAction.execute(defaultOptions);
|
|
400
|
-
expect((initAction as any).failSpinner).toHaveBeenCalledWith(
|
|
401
|
-
"The localnet is taking too long to initialize. Please try again after the localnet is ready.",
|
|
402
|
-
);
|
|
403
|
-
});
|
|
404
|
-
|
|
405
|
-
test("fails if deleteAllValidators throws an error", async () => {
|
|
406
|
-
inquirerPromptSpy
|
|
407
|
-
.mockResolvedValueOnce({confirmAction: true})
|
|
408
|
-
.mockResolvedValueOnce({selectedLlmProviders: ["openai"]})
|
|
409
|
-
.mockResolvedValueOnce({openai: "API_KEY_OPENAI"});
|
|
410
|
-
deleteAllValidatorsSpy.mockRejectedValue(new Error("Validator deletion error"));
|
|
411
|
-
await initAction.execute(defaultOptions);
|
|
412
|
-
expect((initAction as any).failSpinner).toHaveBeenCalledWith(
|
|
413
|
-
"An error occurred during initialization.",
|
|
414
|
-
expect.any(Error),
|
|
415
|
-
);
|
|
416
|
-
});
|
|
417
|
-
|
|
418
|
-
test("fails if createRandomValidators throws an error", async () => {
|
|
419
|
-
inquirerPromptSpy
|
|
420
|
-
.mockResolvedValueOnce({confirmAction: true})
|
|
421
|
-
.mockResolvedValueOnce({selectedLlmProviders: ["openai"]})
|
|
422
|
-
.mockResolvedValueOnce({openai: "API_KEY_OPENAI"});
|
|
423
|
-
createRandomValidatorsSpy.mockRejectedValue(new Error("Validator creation error"));
|
|
424
|
-
await initAction.execute(defaultOptions);
|
|
425
|
-
expect((initAction as any).failSpinner).toHaveBeenCalledWith(
|
|
426
|
-
"An error occurred during initialization.",
|
|
427
|
-
Error("Validator creation error"),
|
|
428
|
-
);
|
|
429
|
-
});
|
|
430
|
-
|
|
431
|
-
test("fails if cleanDatabase throws an error when resetDb is true", async () => {
|
|
432
|
-
inquirerPromptSpy
|
|
433
|
-
.mockResolvedValueOnce({confirmAction: true})
|
|
434
|
-
.mockResolvedValueOnce({selectedLlmProviders: ["openai"]})
|
|
435
|
-
.mockResolvedValueOnce({openai: "API_KEY_OPENAI"});
|
|
436
|
-
cleanDatabaseSpy.mockRejectedValue(new Error("Database error"));
|
|
437
|
-
const optionsWithResetDb: InitActionOptions = {...defaultOptions, resetDb: true};
|
|
438
|
-
await initAction.execute(optionsWithResetDb);
|
|
439
|
-
expect((initAction as any).failSpinner).toHaveBeenCalledWith(
|
|
440
|
-
"An error occurred during initialization.",
|
|
441
|
-
new Error("Database error"),
|
|
442
|
-
);
|
|
443
|
-
});
|
|
444
|
-
|
|
445
|
-
test("fails if openFrontend throws an error", async () => {
|
|
446
|
-
inquirerPromptSpy
|
|
447
|
-
.mockResolvedValueOnce({confirmAction: true})
|
|
448
|
-
.mockResolvedValueOnce({selectedLlmProviders: ["openai"]})
|
|
449
|
-
.mockResolvedValueOnce({openai: "API_KEY_OPENAI"});
|
|
450
|
-
openFrontendSpy.mockRejectedValue(new Error("Frontend error"));
|
|
451
|
-
await initAction.execute(defaultOptions);
|
|
452
|
-
expect((initAction as any).failSpinner).toHaveBeenCalledWith(
|
|
453
|
-
"An error occurred during initialization.",
|
|
454
|
-
new Error("Frontend error"),
|
|
455
|
-
);
|
|
456
|
-
});
|
|
457
|
-
|
|
458
|
-
test("catches and logs unexpected errors", async () => {
|
|
459
|
-
inquirerPromptSpy.mockRejectedValueOnce(new Error("Unexpected prompt error"));
|
|
460
|
-
await initAction.execute(defaultOptions);
|
|
461
|
-
expect((initAction as any).failSpinner).toHaveBeenCalledWith(
|
|
462
|
-
"An error occurred during initialization.",
|
|
463
|
-
new Error("Unexpected prompt error"),
|
|
464
|
-
);
|
|
465
|
-
});
|
|
466
|
-
});
|
|
467
|
-
});
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import {describe, test, vi, beforeEach, afterEach, expect} from "vitest";
|
|
2
|
-
import {LockAccountAction} from "../../src/commands/account/lock";
|
|
3
|
-
import {readFileSync, existsSync} from "fs";
|
|
4
|
-
import os from "os";
|
|
5
|
-
|
|
6
|
-
vi.mock("fs");
|
|
7
|
-
vi.mock("os");
|
|
8
|
-
|
|
9
|
-
describe("LockAccountAction", () => {
|
|
10
|
-
let lockAction: LockAccountAction;
|
|
11
|
-
|
|
12
|
-
beforeEach(() => {
|
|
13
|
-
vi.clearAllMocks();
|
|
14
|
-
// Setup mocks before creating the action (needed for constructor)
|
|
15
|
-
vi.mocked(os.homedir).mockReturnValue("/mocked/home");
|
|
16
|
-
vi.mocked(existsSync).mockReturnValue(true);
|
|
17
|
-
vi.mocked(readFileSync).mockReturnValue(JSON.stringify({activeAccount: "default"}));
|
|
18
|
-
|
|
19
|
-
lockAction = new LockAccountAction();
|
|
20
|
-
|
|
21
|
-
// Mock the BaseAction methods
|
|
22
|
-
vi.spyOn(lockAction as any, "startSpinner").mockImplementation(() => {});
|
|
23
|
-
vi.spyOn(lockAction as any, "setSpinnerText").mockImplementation(() => {});
|
|
24
|
-
vi.spyOn(lockAction as any, "succeedSpinner").mockImplementation(() => {});
|
|
25
|
-
vi.spyOn(lockAction as any, "failSpinner").mockImplementation(() => {});
|
|
26
|
-
vi.spyOn(lockAction as any, "resolveAccountName").mockReturnValue("default");
|
|
27
|
-
|
|
28
|
-
// Mock keychainManager
|
|
29
|
-
vi.spyOn(lockAction["keychainManager"], "isKeychainAvailable").mockResolvedValue(true);
|
|
30
|
-
vi.spyOn(lockAction["keychainManager"], "getPrivateKey").mockResolvedValue("test-private-key");
|
|
31
|
-
vi.spyOn(lockAction["keychainManager"], "removePrivateKey").mockResolvedValue(true);
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
afterEach(() => {
|
|
35
|
-
vi.restoreAllMocks();
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
test("successfully locks wallet when keychain is available and key exists", async () => {
|
|
39
|
-
await lockAction.execute();
|
|
40
|
-
|
|
41
|
-
expect(lockAction["startSpinner"]).toHaveBeenCalledWith("Checking keychain availability...");
|
|
42
|
-
expect(lockAction["keychainManager"].isKeychainAvailable).toHaveBeenCalled();
|
|
43
|
-
expect(lockAction["setSpinnerText"]).toHaveBeenCalledWith("Checking for cached private key for 'default'...");
|
|
44
|
-
expect(lockAction["keychainManager"].getPrivateKey).toHaveBeenCalledWith("default");
|
|
45
|
-
expect(lockAction["setSpinnerText"]).toHaveBeenCalledWith("Removing private key for 'default' from OS keychain...");
|
|
46
|
-
expect(lockAction["keychainManager"].removePrivateKey).toHaveBeenCalledWith("default");
|
|
47
|
-
expect(lockAction["succeedSpinner"]).toHaveBeenCalledWith("Account 'default' locked! Private key removed from OS keychain.");
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
test("fails when keychain is not available", async () => {
|
|
51
|
-
vi.spyOn(lockAction["keychainManager"], "isKeychainAvailable").mockResolvedValue(false);
|
|
52
|
-
|
|
53
|
-
await lockAction.execute();
|
|
54
|
-
|
|
55
|
-
expect(lockAction["failSpinner"]).toHaveBeenCalledWith("OS keychain is not available. This command requires a supported keychain (e.g. macOS Keychain, Windows Credential Manager, or GNOME Keyring).");
|
|
56
|
-
expect(lockAction["keychainManager"].getPrivateKey).not.toHaveBeenCalled();
|
|
57
|
-
expect(lockAction["keychainManager"].removePrivateKey).not.toHaveBeenCalled();
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
test("succeeds when wallet is already locked (no cached key)", async () => {
|
|
61
|
-
vi.spyOn(lockAction["keychainManager"], "getPrivateKey").mockResolvedValue(null);
|
|
62
|
-
|
|
63
|
-
await lockAction.execute();
|
|
64
|
-
|
|
65
|
-
expect(lockAction["succeedSpinner"]).toHaveBeenCalledWith("Account 'default' is already locked.");
|
|
66
|
-
expect(lockAction["keychainManager"].removePrivateKey).not.toHaveBeenCalled();
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
test("handles error during key removal", async () => {
|
|
70
|
-
const mockError = new Error("Keychain error");
|
|
71
|
-
vi.spyOn(lockAction["keychainManager"], "removePrivateKey").mockRejectedValue(mockError);
|
|
72
|
-
|
|
73
|
-
await lockAction.execute();
|
|
74
|
-
|
|
75
|
-
expect(lockAction["failSpinner"]).toHaveBeenCalledWith("Failed to lock account.", mockError);
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
test("uses account option when provided", async () => {
|
|
79
|
-
vi.spyOn(lockAction as any, "resolveAccountName").mockReturnValue("validator");
|
|
80
|
-
|
|
81
|
-
await lockAction.execute({account: "validator"});
|
|
82
|
-
|
|
83
|
-
expect(lockAction["accountOverride"]).toBe("validator");
|
|
84
|
-
expect(lockAction["setSpinnerText"]).toHaveBeenCalledWith("Checking for cached private key for 'validator'...");
|
|
85
|
-
});
|
|
86
|
-
});
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import { describe, test, vi, beforeEach, afterEach, expect } from "vitest";
|
|
2
|
-
import fs from "fs-extra";
|
|
3
|
-
import path from "path";
|
|
4
|
-
import { NewAction } from "../../src/commands/scaffold/new";
|
|
5
|
-
|
|
6
|
-
vi.mock("fs-extra");
|
|
7
|
-
|
|
8
|
-
describe("NewAction", () => {
|
|
9
|
-
let newAction: NewAction;
|
|
10
|
-
let mockExistsSync: any;
|
|
11
|
-
let mockCopySync: any;
|
|
12
|
-
|
|
13
|
-
beforeEach(() => {
|
|
14
|
-
vi.clearAllMocks();
|
|
15
|
-
newAction = new NewAction();
|
|
16
|
-
|
|
17
|
-
mockExistsSync = vi.mocked(fs.existsSync);
|
|
18
|
-
mockCopySync = vi.mocked(fs.copySync);
|
|
19
|
-
|
|
20
|
-
vi.spyOn(newAction as any, "startSpinner").mockImplementation(() => {});
|
|
21
|
-
vi.spyOn(newAction as any, "succeedSpinner").mockImplementation(() => {});
|
|
22
|
-
vi.spyOn(newAction as any, "failSpinner").mockImplementation(() => {});
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
afterEach(() => {
|
|
26
|
-
vi.restoreAllMocks();
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
test("should successfully create a new project", async () => {
|
|
30
|
-
mockExistsSync.mockReturnValue(false);
|
|
31
|
-
mockCopySync.mockImplementation(() => {});
|
|
32
|
-
|
|
33
|
-
await newAction.createProject("myProject", { path: ".", overwrite: false });
|
|
34
|
-
|
|
35
|
-
expect(newAction["startSpinner"]).toHaveBeenCalledWith("Creating new GenLayer project: myProject");
|
|
36
|
-
expect(mockCopySync).toHaveBeenCalledWith(expect.any(String), path.resolve(".", "myProject"));
|
|
37
|
-
expect(newAction["succeedSpinner"]).toHaveBeenCalledWith(
|
|
38
|
-
`Project "myProject" created successfully at ${path.resolve(".", "myProject")}`
|
|
39
|
-
);
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
test("should fail if project directory exists and overwrite is not set", async () => {
|
|
43
|
-
mockExistsSync.mockReturnValue(true);
|
|
44
|
-
|
|
45
|
-
await newAction.createProject("existingProject", { path: ".", overwrite: false });
|
|
46
|
-
|
|
47
|
-
expect(newAction["failSpinner"]).toHaveBeenCalledWith(
|
|
48
|
-
`Project directory "${path.resolve(".", "existingProject")}" already exists. Use --overwrite to replace it.`
|
|
49
|
-
);
|
|
50
|
-
expect(mockCopySync).not.toHaveBeenCalled();
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
test("should overwrite existing project if overwrite is set", async () => {
|
|
54
|
-
mockExistsSync.mockReturnValue(true);
|
|
55
|
-
mockCopySync.mockImplementation(() => {});
|
|
56
|
-
|
|
57
|
-
await newAction.createProject("overwriteProject", { path: ".", overwrite: true });
|
|
58
|
-
|
|
59
|
-
expect(newAction["startSpinner"]).toHaveBeenCalledWith("Creating new GenLayer project: overwriteProject");
|
|
60
|
-
expect(mockCopySync).toHaveBeenCalledWith(expect.any(String), path.resolve(".", "overwriteProject"));
|
|
61
|
-
expect(newAction["succeedSpinner"]).toHaveBeenCalledWith(
|
|
62
|
-
`Project "overwriteProject" created successfully at ${path.resolve(".", "overwriteProject")}`
|
|
63
|
-
);
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
test("should fail if an error occurs while copying files", async () => {
|
|
67
|
-
mockExistsSync.mockReturnValue(false);
|
|
68
|
-
const error = new Error("Mocked file system error");
|
|
69
|
-
mockCopySync.mockImplementation(() => {
|
|
70
|
-
throw error;
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
await newAction.createProject("errorProject", { path: ".", overwrite: false });
|
|
74
|
-
|
|
75
|
-
expect(newAction["failSpinner"]).toHaveBeenCalledWith(
|
|
76
|
-
"Error creating project \"errorProject\"",
|
|
77
|
-
error
|
|
78
|
-
);
|
|
79
|
-
});
|
|
80
|
-
});
|