genlayer 0.1.2 → 0.1.4
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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
+
## 0.1.4 (2024-11-12)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* changing linux command to fix display issue and fixing waiting simulator issue ([#127](https://github.com/yeagerai/genlayer-cli/issues/127)) ([721eebf](https://github.com/yeagerai/genlayer-cli/commit/721eebfea758a0897f23afd60b5767c59d593eb1))
|
|
9
|
+
|
|
10
|
+
## 0.1.3 (2024-11-08)
|
|
11
|
+
|
|
3
12
|
## 0.1.2 (2024-11-08)
|
|
4
13
|
|
|
5
14
|
## 0.1.1 (2024-11-08)
|
package/dist/index.js
CHANGED
|
@@ -39699,7 +39699,7 @@ var {
|
|
|
39699
39699
|
} = import_index.default;
|
|
39700
39700
|
|
|
39701
39701
|
// package.json
|
|
39702
|
-
var version = "0.1.
|
|
39702
|
+
var version = "0.1.4";
|
|
39703
39703
|
|
|
39704
39704
|
// src/lib/config/text.ts
|
|
39705
39705
|
var CLI_DESCRIPTION = "GenLayer CLI is a development environment for the GenLayer ecosystem. It allows developers to interact with the protocol by creating accounts, sending transactions, and working with Intelligent Contracts by testing, debugging, and deploying them.";
|
|
@@ -39767,7 +39767,7 @@ var DOCKER_IMAGES_AND_CONTAINERS_NAME_PREFIX = "genlayer-simulator-";
|
|
|
39767
39767
|
var DEFAULT_RUN_SIMULATOR_COMMAND = (simulatorLocation) => ({
|
|
39768
39768
|
darwin: `osascript -e 'tell application "Terminal" to do script "cd ${simulatorLocation} && docker compose build && docker compose up"'`,
|
|
39769
39769
|
win32: `start cmd.exe /c "cd /d ${simulatorLocation} && docker compose build && docker compose up && pause"`,
|
|
39770
|
-
linux: `
|
|
39770
|
+
linux: `nohup bash -c 'cd ${simulatorLocation} && docker compose build && docker compose up -d'`
|
|
39771
39771
|
});
|
|
39772
39772
|
var DEFAULT_PULL_OLLAMA_COMMAND = (simulatorLocation) => ({
|
|
39773
39773
|
darwin: `cd ${simulatorLocation} && docker exec ollama ollama pull llama3`,
|
|
@@ -40568,10 +40568,11 @@ var SimulatorService = class {
|
|
|
40568
40568
|
}
|
|
40569
40569
|
waitForSimulatorToBeReady() {
|
|
40570
40570
|
return __async(this, arguments, function* (retries = STARTING_TIMEOUT_ATTEMPTS) {
|
|
40571
|
+
var _a, _b, _c;
|
|
40571
40572
|
console.log("Waiting for the simulator to start up...");
|
|
40572
40573
|
try {
|
|
40573
40574
|
const response = yield rpcClient.request({ method: "ping", params: [] });
|
|
40574
|
-
if (response
|
|
40575
|
+
if ((response == null ? void 0 : response.result) === "OK" || ((_a = response == null ? void 0 : response.result) == null ? void 0 : _a.status) === "OK" || ((_c = (_b = response == null ? void 0 : response.result) == null ? void 0 : _b.data) == null ? void 0 : _c.status) === "OK") {
|
|
40575
40576
|
return { initialized: true };
|
|
40576
40577
|
}
|
|
40577
40578
|
if (retries > 0) {
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@ export const DOCKER_IMAGES_AND_CONTAINERS_NAME_PREFIX = "genlayer-simulator-";
|
|
|
4
4
|
export const DEFAULT_RUN_SIMULATOR_COMMAND = (simulatorLocation: string) => ({
|
|
5
5
|
darwin: `osascript -e 'tell application "Terminal" to do script "cd ${simulatorLocation} && docker compose build && docker compose up"'`,
|
|
6
6
|
win32: `start cmd.exe /c "cd /d ${simulatorLocation} && docker compose build && docker compose up && pause"`,
|
|
7
|
-
linux: `
|
|
7
|
+
linux: `nohup bash -c 'cd ${simulatorLocation} && docker compose build && docker compose up -d'`,
|
|
8
8
|
});
|
|
9
9
|
export const DEFAULT_PULL_OLLAMA_COMMAND = (simulatorLocation: string) => ({
|
|
10
10
|
darwin: `cd ${simulatorLocation} && docker exec ollama ollama pull llama3`,
|
|
@@ -221,8 +221,8 @@ export class SimulatorService implements ISimulatorService {
|
|
|
221
221
|
const response = await rpcClient.request({method: "ping", params: []});
|
|
222
222
|
|
|
223
223
|
//Compatibility with current simulator version
|
|
224
|
-
if (response
|
|
225
|
-
return {initialized: true};
|
|
224
|
+
if (response?.result === "OK" || response?.result?.status === "OK" || response?.result?.data?.status === "OK") {
|
|
225
|
+
return { initialized: true };
|
|
226
226
|
}
|
|
227
227
|
if (retries > 0) {
|
|
228
228
|
await sleep(STARTING_TIMEOUT_WAIT_CYLCE);
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
import { describe, beforeEach, test, expect, vi, Mock } from "vitest";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import * as fs from "fs";
|
|
4
|
+
import * as dotenv from "dotenv";
|
|
5
|
+
import simulatorService from "../../src/lib/services/simulator";
|
|
6
|
+
import {
|
|
7
|
+
getVersion,
|
|
8
|
+
executeCommand,
|
|
9
|
+
openUrl,
|
|
10
|
+
checkCommand,
|
|
11
|
+
stopDockerContainer,
|
|
12
|
+
removeDockerContainer, listDockerContainers,
|
|
13
|
+
} from "../../src/lib/clients/system";
|
|
14
|
+
import {
|
|
15
|
+
DOCKER_IMAGES_AND_CONTAINERS_NAME_PREFIX,
|
|
16
|
+
VERSION_REQUIREMENTS,
|
|
17
|
+
} from "../../src/lib/config/simulator";
|
|
18
|
+
import {
|
|
19
|
+
STARTING_TIMEOUT_ATTEMPTS,
|
|
20
|
+
DEFAULT_RUN_SIMULATOR_COMMAND,
|
|
21
|
+
DEFAULT_RUN_DOCKER_COMMAND,
|
|
22
|
+
DEFAULT_PULL_OLLAMA_COMMAND
|
|
23
|
+
} from "../../src/lib/config/simulator";
|
|
24
|
+
import { rpcClient } from "../../src/lib/clients/jsonRpcClient";
|
|
25
|
+
import * as semver from "semver";
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
vi.mock("fs");
|
|
29
|
+
vi.mock("path");
|
|
30
|
+
vi.mock("dotenv");
|
|
31
|
+
vi.mock("semver", () => ({
|
|
32
|
+
satisfies: vi.fn(),
|
|
33
|
+
}));
|
|
34
|
+
vi.mock("../../src/lib/clients/system", () => ({
|
|
35
|
+
checkCommand: vi.fn(),
|
|
36
|
+
getVersion: vi.fn(),
|
|
37
|
+
executeCommand: vi.fn(),
|
|
38
|
+
openUrl: vi.fn(),
|
|
39
|
+
listDockerContainers: vi.fn(),
|
|
40
|
+
stopDockerContainer: vi.fn(),
|
|
41
|
+
removeDockerContainer: vi.fn(),
|
|
42
|
+
}));
|
|
43
|
+
|
|
44
|
+
vi.mock("../../src/lib/clients/jsonRpcClient", () => ({
|
|
45
|
+
rpcClient: {
|
|
46
|
+
request: vi.fn(),
|
|
47
|
+
},
|
|
48
|
+
}));
|
|
49
|
+
|
|
50
|
+
describe("SimulatorService - Basic Tests", () => {
|
|
51
|
+
beforeEach(() => {
|
|
52
|
+
vi.clearAllMocks();
|
|
53
|
+
vi.mocked(path.join).mockImplementation((...args) => args.join("/"));
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test("should return the correct simulator location path", () => {
|
|
57
|
+
const expectedPath = "/mock/home/genlayer-simulator";
|
|
58
|
+
simulatorService.setSimulatorLocation("/mock/home/genlayer-simulator");
|
|
59
|
+
const simulatorLocation = simulatorService.getSimulatorLocation();
|
|
60
|
+
expect(simulatorLocation).toBe(expectedPath);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test("should read the correct frontend URL from .env config", () => {
|
|
64
|
+
const mockEnvFilePath = "/mock/home/genlayer-simulator/.env";
|
|
65
|
+
const mockEnvContent = "FRONTEND_PORT=8080";
|
|
66
|
+
const mockEnvConfig = { FRONTEND_PORT: "8080" };
|
|
67
|
+
vi.mocked(fs.readFileSync).mockReturnValue(mockEnvContent);
|
|
68
|
+
vi.mocked(dotenv.parse).mockReturnValue(mockEnvConfig);
|
|
69
|
+
simulatorService.setSimulatorLocation("/mock/home/genlayer-simulator");
|
|
70
|
+
const frontendUrl = simulatorService.getFrontendUrl();
|
|
71
|
+
expect(frontendUrl).toBe("http://localhost:8080");
|
|
72
|
+
expect(fs.readFileSync).toHaveBeenCalledWith(mockEnvFilePath, "utf8");
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test("should check version requirements and return missing versions", async () => {
|
|
76
|
+
vi.mocked(getVersion).mockResolvedValueOnce("12.0.0").mockResolvedValueOnce("18.0.0");
|
|
77
|
+
vi.mocked(semver.satisfies).mockImplementation((version, range) => {
|
|
78
|
+
if (range === VERSION_REQUIREMENTS.node) return version === "18.0.0";
|
|
79
|
+
return false;
|
|
80
|
+
});
|
|
81
|
+
const missingVersions = await simulatorService.checkVersionRequirements();
|
|
82
|
+
expect(missingVersions.node).toBe(VERSION_REQUIREMENTS.node);
|
|
83
|
+
expect(missingVersions.docker).toBe(VERSION_REQUIREMENTS.docker);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test("should handle error when checkVersion throws VersionRequiredError", async () => {
|
|
87
|
+
vi.mocked(getVersion).mockResolvedValueOnce("10.0.0");
|
|
88
|
+
vi.mocked(semver.satisfies).mockReturnValue(false);
|
|
89
|
+
await expect(simulatorService.checkVersion("14.0.0", "node")).rejects.toThrow();
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
test("should download simulator if not already installed", async () => {
|
|
93
|
+
const result = await simulatorService.downloadSimulator();
|
|
94
|
+
expect(result.wasInstalled).toBe(false);
|
|
95
|
+
expect(executeCommand).toHaveBeenCalled();
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
test("should skip download if simulator is already installed", async () => {
|
|
99
|
+
vi.mocked(executeCommand).mockRejectedValueOnce(new Error("Mocked command error"));
|
|
100
|
+
vi.spyOn(fs, "existsSync").mockReturnValue(true);
|
|
101
|
+
const result = await simulatorService.downloadSimulator();
|
|
102
|
+
expect(result.wasInstalled).toBe(true);
|
|
103
|
+
expect(executeCommand).toHaveBeenCalled();
|
|
104
|
+
expect(fs.existsSync).toHaveBeenCalled();
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
test("should return initialized true when simulator responds with OK (result.status = OK)", async () => {
|
|
108
|
+
vi.mocked(rpcClient.request).mockResolvedValueOnce({ result: {status: 'OK'} });
|
|
109
|
+
const result = await simulatorService.waitForSimulatorToBeReady(STARTING_TIMEOUT_ATTEMPTS);
|
|
110
|
+
expect(result).toEqual({ initialized: true });
|
|
111
|
+
expect(rpcClient.request).toHaveBeenCalledWith({ method: "ping", params: [] });
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test("should return initialized true when simulator responds with OK (result.data.status = OK)", async () => {
|
|
115
|
+
vi.mocked(rpcClient.request).mockResolvedValueOnce({ result: {data: {status: 'OK'}} });
|
|
116
|
+
const result = await simulatorService.waitForSimulatorToBeReady(STARTING_TIMEOUT_ATTEMPTS);
|
|
117
|
+
expect(result).toEqual({ initialized: true });
|
|
118
|
+
expect(rpcClient.request).toHaveBeenCalledWith({ method: "ping", params: [] });
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
test("should return initialized true when simulator responds with OK (result = OK)", async () => {
|
|
122
|
+
vi.mocked(rpcClient.request).mockResolvedValueOnce({ result: 'OK' });
|
|
123
|
+
const result = await simulatorService.waitForSimulatorToBeReady(STARTING_TIMEOUT_ATTEMPTS);
|
|
124
|
+
expect(result).toEqual({ initialized: true });
|
|
125
|
+
expect(rpcClient.request).toHaveBeenCalledWith({ method: "ping", params: [] });
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
test("should return initialized false with errorCode TIMEOUT after retries", async () => {
|
|
129
|
+
vi.mocked(rpcClient.request).mockResolvedValue(undefined);
|
|
130
|
+
const result = await simulatorService.waitForSimulatorToBeReady(1);
|
|
131
|
+
expect(result).toEqual({ initialized: false, errorCode: "TIMEOUT" });
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
test("should return initialized false with errorCode ERROR on non-retryable error", async () => {
|
|
135
|
+
const nonRetryableError = new Error("Unexpected error");
|
|
136
|
+
vi.mocked(rpcClient.request).mockRejectedValue(nonRetryableError);
|
|
137
|
+
const result = await simulatorService.waitForSimulatorToBeReady(STARTING_TIMEOUT_ATTEMPTS);
|
|
138
|
+
expect(result).toEqual({ initialized: false, errorCode: "ERROR", errorMessage: nonRetryableError.message });
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
test("should execute the correct pull command based on simulator location", async () => {
|
|
142
|
+
const expectedCommand = DEFAULT_PULL_OLLAMA_COMMAND("/mock/home/genlayer-simulator");
|
|
143
|
+
vi.mocked(executeCommand).mockResolvedValueOnce({
|
|
144
|
+
stdout: "success",
|
|
145
|
+
stderr: "",
|
|
146
|
+
});
|
|
147
|
+
const result = await simulatorService.pullOllamaModel();
|
|
148
|
+
expect(result).toBe(true);
|
|
149
|
+
expect(executeCommand).toHaveBeenCalledWith(expectedCommand);
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
test("should execute the correct run simulator command based on simulator location", async () => {
|
|
153
|
+
(executeCommand as Mock).mockResolvedValue({
|
|
154
|
+
stdout: "Simulator started",
|
|
155
|
+
stderr: "",
|
|
156
|
+
});
|
|
157
|
+
const result = await simulatorService.runSimulator();
|
|
158
|
+
const expectedCommand = DEFAULT_RUN_SIMULATOR_COMMAND("/mock/home/genlayer-simulator");
|
|
159
|
+
expect(executeCommand).toHaveBeenCalledWith(expectedCommand);
|
|
160
|
+
expect(result).toEqual({ stdout: "Simulator started", stderr: "" });
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
test("should open the frontend URL and return true", async () => {
|
|
164
|
+
vi.spyOn(simulatorService, "getFrontendUrl").mockReturnValue("http://localhost:8080");
|
|
165
|
+
const result = await simulatorService.openFrontend();
|
|
166
|
+
expect(simulatorService.getFrontendUrl).toHaveBeenCalled();
|
|
167
|
+
expect(openUrl).toHaveBeenCalledWith("http://localhost:8080");
|
|
168
|
+
expect(result).toBe(true);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
test("should call rpcClient.request with correct parameters and return the response", async () => {
|
|
172
|
+
const mockResponse = { success: true };
|
|
173
|
+
vi.mocked(rpcClient.request).mockResolvedValue(mockResponse);
|
|
174
|
+
const result = await simulatorService.deleteAllValidators();
|
|
175
|
+
expect(rpcClient.request).toHaveBeenCalledWith({ method: "delete_all_validators", params: [] });
|
|
176
|
+
expect(result).toBe(mockResponse);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
test("should throw an unexpected error when checking node version requirements", async () => {
|
|
180
|
+
const unexpectedError = new Error("Unexpected error (node)");
|
|
181
|
+
vi.spyOn(simulatorService, "checkVersion").mockRejectedValueOnce(unexpectedError);
|
|
182
|
+
await expect(simulatorService.checkVersionRequirements()).rejects.toThrow("Unexpected error (node)");
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
test("should throw an unexpected error when checking docker version requirements", async () => {
|
|
186
|
+
vi.spyOn(simulatorService, "checkVersion")
|
|
187
|
+
.mockResolvedValueOnce(undefined)
|
|
188
|
+
.mockRejectedValueOnce(new Error("Unexpected error (docker)"));
|
|
189
|
+
await expect(simulatorService.checkVersionRequirements()).rejects.toThrow("Unexpected error (docker)");
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
test("should throw an unexpected error when checking git installation requirement", async () => {
|
|
193
|
+
vi.mocked(checkCommand).mockRejectedValueOnce(new Error("Unexpected git error"));
|
|
194
|
+
await expect(simulatorService.checkInstallRequirements()).rejects.toThrow("Unexpected git error");
|
|
195
|
+
const requirementsInstalled = { git: false, docker: false };
|
|
196
|
+
expect(requirementsInstalled.git).toBe(false);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
test("should throw an unexpected error when checking docker installation requirement", async () => {
|
|
200
|
+
vi.mocked(checkCommand)
|
|
201
|
+
.mockResolvedValueOnce(undefined)
|
|
202
|
+
.mockRejectedValueOnce(new Error("Unexpected docker error"));
|
|
203
|
+
await expect(simulatorService.checkInstallRequirements()).rejects.toThrow("Unexpected docker error");
|
|
204
|
+
const requirementsInstalled = { git: false, docker: false };
|
|
205
|
+
expect(requirementsInstalled.docker).toBe(false);
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
test("should stop and remove Docker containers with the specified prefix", async () => {
|
|
209
|
+
const mockContainers = [
|
|
210
|
+
DOCKER_IMAGES_AND_CONTAINERS_NAME_PREFIX + "1",
|
|
211
|
+
DOCKER_IMAGES_AND_CONTAINERS_NAME_PREFIX + "2"
|
|
212
|
+
];
|
|
213
|
+
vi.mocked(listDockerContainers).mockResolvedValue(mockContainers);
|
|
214
|
+
vi.mocked(stopDockerContainer).mockResolvedValue(undefined);
|
|
215
|
+
vi.mocked(removeDockerContainer).mockResolvedValue(undefined);
|
|
216
|
+
const result = await simulatorService.resetDockerContainers();
|
|
217
|
+
expect(result).toBe(true);
|
|
218
|
+
expect(stopDockerContainer).toHaveBeenCalledWith(DOCKER_IMAGES_AND_CONTAINERS_NAME_PREFIX + "1");
|
|
219
|
+
expect(stopDockerContainer).toHaveBeenCalledWith(DOCKER_IMAGES_AND_CONTAINERS_NAME_PREFIX + "2");
|
|
220
|
+
expect(removeDockerContainer).toHaveBeenCalledWith(DOCKER_IMAGES_AND_CONTAINERS_NAME_PREFIX + "1");
|
|
221
|
+
expect(removeDockerContainer).toHaveBeenCalledWith(DOCKER_IMAGES_AND_CONTAINERS_NAME_PREFIX + "2");
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
test("should retry when response is not 'OK' and reach sleep path", async () => {
|
|
225
|
+
vi.mocked(rpcClient.request).mockResolvedValue({ result: { status: "NOT_OK" } });
|
|
226
|
+
const result = await simulatorService.waitForSimulatorToBeReady(1);
|
|
227
|
+
expect(result).toEqual({ initialized: false, errorCode: "TIMEOUT" });
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
test("should retry on fetch error and reach sleep path", async () => {
|
|
231
|
+
const fetchError = new Error("Fetch Error");
|
|
232
|
+
fetchError.name = "FetchError";
|
|
233
|
+
vi.mocked(rpcClient.request).mockRejectedValue(fetchError);
|
|
234
|
+
const result = await simulatorService.waitForSimulatorToBeReady(1);
|
|
235
|
+
expect(result).toEqual({ initialized: false, errorCode: "ERROR", errorMessage: fetchError.message });
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
test("should throw an error if executeCommand fails and simulator location does not exist", async () => {
|
|
239
|
+
const mockError = new Error("git clone failed");
|
|
240
|
+
vi.mocked(executeCommand).mockRejectedValueOnce(mockError);
|
|
241
|
+
vi.mocked(fs.existsSync).mockReturnValue(false);
|
|
242
|
+
await expect(simulatorService.downloadSimulator()).rejects.toThrow("git clone failed");
|
|
243
|
+
expect(executeCommand).toHaveBeenCalled();
|
|
244
|
+
expect(fs.existsSync).toHaveBeenCalledWith("/mock/home/genlayer-simulator");
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
test("should call executeCommand if docker ps command fails", async () => {
|
|
248
|
+
vi.mocked(checkCommand)
|
|
249
|
+
.mockResolvedValueOnce(undefined)
|
|
250
|
+
.mockResolvedValueOnce(undefined)
|
|
251
|
+
.mockRejectedValueOnce(new Error("docker ps failed"));
|
|
252
|
+
vi.mocked(executeCommand).mockResolvedValueOnce({
|
|
253
|
+
stdout: '',
|
|
254
|
+
stderr: ''
|
|
255
|
+
});
|
|
256
|
+
const result = await simulatorService.checkInstallRequirements();
|
|
257
|
+
expect(executeCommand).toHaveBeenCalledWith(DEFAULT_RUN_DOCKER_COMMAND);
|
|
258
|
+
expect(result.docker).toBe(true);
|
|
259
|
+
expect(result.git).toBe(true);
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
test("should update envConfig with newConfig values", () => {
|
|
263
|
+
const envFilePath = path.join("/mock/home/genlayer-simulator", ".env");
|
|
264
|
+
const originalEnvContent = "KEY1=value1\nKEY2=value2";
|
|
265
|
+
const envConfig = { KEY1: "value1", KEY2: "value2" };
|
|
266
|
+
const newConfig = { KEY2: "new_value2", KEY3: "value3" };
|
|
267
|
+
vi.mocked(fs.readFileSync)
|
|
268
|
+
.mockReturnValueOnce(originalEnvContent)
|
|
269
|
+
.mockReturnValueOnce(originalEnvContent);
|
|
270
|
+
vi.mocked(dotenv.parse).mockReturnValue(envConfig);
|
|
271
|
+
const writeFileSyncSpy = vi.spyOn(fs, "writeFileSync");
|
|
272
|
+
simulatorService["addConfigToEnvFile"](newConfig);
|
|
273
|
+
expect(envConfig).toEqual({
|
|
274
|
+
KEY1: "value1",
|
|
275
|
+
KEY2: "new_value2",
|
|
276
|
+
KEY3: "value3",
|
|
277
|
+
});
|
|
278
|
+
expect(writeFileSyncSpy).toHaveBeenCalledWith(`${envFilePath}.bak`, originalEnvContent);
|
|
279
|
+
expect(writeFileSyncSpy).toHaveBeenCalledWith(
|
|
280
|
+
envFilePath,
|
|
281
|
+
"KEY1=value1\nKEY2=new_value2\nKEY3=value3"
|
|
282
|
+
);
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
test("should return providers without errors", () => {
|
|
286
|
+
expect(simulatorService.getAiProvidersOptions(true)).toEqual(expect.any(Array));
|
|
287
|
+
expect(simulatorService.getAiProvidersOptions(false)).toEqual(expect.any(Array));
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
});
|