genlayer 0.6.0 → 0.8.0
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/.env.example +1 -0
- package/CHANGELOG.md +14 -0
- package/dist/index.js +70 -2
- package/docker-compose.yml +4 -4
- package/package.json +1 -1
- package/src/commands/config/getSetReset.ts +44 -0
- package/src/commands/config/index.ts +30 -0
- package/src/commands/general/index.ts +1 -0
- package/src/commands/general/init.ts +7 -0
- package/src/index.ts +2 -0
- package/src/lib/interfaces/ISimulatorService.ts +1 -0
- package/src/lib/services/simulator.ts +17 -0
- package/tests/actions/create.test.ts +1 -1
- package/tests/actions/getSetReset.test.ts +101 -0
- package/tests/actions/init.test.ts +3 -2
- package/tests/commands/config.test.ts +54 -0
- package/tests/commands/init.test.ts +9 -1
- package/tests/index.test.ts +4 -0
- package/tests/services/simulator.test.ts +34 -0
package/.env.example
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
+
## 0.8.0 (2024-12-11)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* implement config command ([#149](https://github.com/yeagerai/genlayer-cli/issues/149)) ([cc0f2ca](https://github.com/yeagerai/genlayer-cli/commit/cc0f2caee2c55f00efc7da0671663827a69be557))
|
|
9
|
+
|
|
10
|
+
## 0.7.0 (2024-12-09)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
* adding localnet version option on init ([#151](https://github.com/yeagerai/genlayer-cli/issues/151)) ([a7bf419](https://github.com/yeagerai/genlayer-cli/commit/a7bf41986e89e8db95003df290d381e77dad127f))
|
|
16
|
+
|
|
3
17
|
## 0.6.0 (2024-12-03)
|
|
4
18
|
|
|
5
19
|
|
package/dist/index.js
CHANGED
|
@@ -50858,7 +50858,7 @@ var {
|
|
|
50858
50858
|
} = import_index.default;
|
|
50859
50859
|
|
|
50860
50860
|
// package.json
|
|
50861
|
-
var version = "0.
|
|
50861
|
+
var version = "0.8.0";
|
|
50862
50862
|
var package_default = {
|
|
50863
50863
|
name: "genlayer",
|
|
50864
50864
|
version,
|
|
@@ -51817,6 +51817,18 @@ Run npm install -g genlayer to update
|
|
|
51817
51817
|
return true;
|
|
51818
51818
|
});
|
|
51819
51819
|
}
|
|
51820
|
+
normalizeLocalnetVersion(version3) {
|
|
51821
|
+
if (!version3.startsWith("v")) {
|
|
51822
|
+
version3 = "v" + version3;
|
|
51823
|
+
}
|
|
51824
|
+
const versionRegex = /^v(\d+)\.(\d+)\.(\d+)(-.+)?$/;
|
|
51825
|
+
const match = version3.match(versionRegex);
|
|
51826
|
+
if (!match) {
|
|
51827
|
+
console.error("Invalid version format. Expected format: v0.0.0 or v0.0.0-suffix");
|
|
51828
|
+
process.exit(1);
|
|
51829
|
+
}
|
|
51830
|
+
return version3;
|
|
51831
|
+
}
|
|
51820
51832
|
};
|
|
51821
51833
|
var simulator_default = new SimulatorService();
|
|
51822
51834
|
|
|
@@ -54427,6 +54439,10 @@ function getVersionErrorMessage({ docker, node }) {
|
|
|
54427
54439
|
function initAction(options, simulatorService) {
|
|
54428
54440
|
return __async(this, null, function* () {
|
|
54429
54441
|
simulatorService.setComposeOptions(options.headless);
|
|
54442
|
+
let localnetVersion = options.localnetVersion;
|
|
54443
|
+
if (localnetVersion !== "latest") {
|
|
54444
|
+
localnetVersion = simulatorService.normalizeLocalnetVersion(localnetVersion);
|
|
54445
|
+
}
|
|
54430
54446
|
yield simulatorService.checkCliVersion();
|
|
54431
54447
|
try {
|
|
54432
54448
|
const requirementsInstalled = yield simulatorService.checkInstallRequirements();
|
|
@@ -54512,6 +54528,7 @@ function initAction(options, simulatorService) {
|
|
|
54512
54528
|
}
|
|
54513
54529
|
console.log("Configuring GenLayer Simulator environment...");
|
|
54514
54530
|
simulatorService.addConfigToEnvFile(aiProvidersEnvVars);
|
|
54531
|
+
simulatorService.addConfigToEnvFile({ LOCALNETVERSION: localnetVersion });
|
|
54515
54532
|
console.log("Running the GenLayer Simulator...");
|
|
54516
54533
|
try {
|
|
54517
54534
|
yield simulatorService.runSimulator();
|
|
@@ -54646,7 +54663,7 @@ function startAction(options, simulatorService) {
|
|
|
54646
54663
|
|
|
54647
54664
|
// src/commands/general/index.ts
|
|
54648
54665
|
function initializeGeneralCommands(program2) {
|
|
54649
|
-
program2.command("init").description("Initialize the GenLayer Environment").option("--numValidators <numValidators>", "Number of validators", "5").option("--headless", "Headless mode", false).option("--reset-db", "Reset Database", false).action((options) => initAction(options, simulator_default));
|
|
54666
|
+
program2.command("init").description("Initialize the GenLayer Environment").option("--numValidators <numValidators>", "Number of validators", "5").option("--headless", "Headless mode", false).option("--reset-db", "Reset Database", false).option("--localnet-version <localnetVersion>", "Select a specific localnet version", "latest").action((options) => initAction(options, simulator_default));
|
|
54650
54667
|
program2.command("up").description("Starts GenLayer's simulator").option("--reset-validators", "Remove all current validators and create new random ones", false).option("--numValidators <numValidators>", "Number of validators", "5").option("--headless", "Headless mode", false).option("--reset-db", "Reset Database", false).action((options) => startAction(options, simulator_default));
|
|
54651
54668
|
return program2;
|
|
54652
54669
|
}
|
|
@@ -78269,11 +78286,62 @@ function initializeKeygenCommands(program2) {
|
|
|
78269
78286
|
return program2;
|
|
78270
78287
|
}
|
|
78271
78288
|
|
|
78289
|
+
// src/commands/config/getSetReset.ts
|
|
78290
|
+
var ConfigActions = class {
|
|
78291
|
+
constructor() {
|
|
78292
|
+
__publicField(this, "configManager");
|
|
78293
|
+
this.configManager = new ConfigFileManager();
|
|
78294
|
+
}
|
|
78295
|
+
set(keyValue) {
|
|
78296
|
+
const [key, value] = keyValue.split("=");
|
|
78297
|
+
if (!key || value === void 0) {
|
|
78298
|
+
console.error("Invalid format. Use key=value.");
|
|
78299
|
+
process.exit(1);
|
|
78300
|
+
}
|
|
78301
|
+
this.configManager.writeConfig(key, value);
|
|
78302
|
+
console.log(`Configuration updated: ${key}=${value}`);
|
|
78303
|
+
}
|
|
78304
|
+
get(key) {
|
|
78305
|
+
if (key) {
|
|
78306
|
+
const value = this.configManager.getConfigByKey(key);
|
|
78307
|
+
if (value === null) {
|
|
78308
|
+
console.log(`No value set for key: ${key}`);
|
|
78309
|
+
} else {
|
|
78310
|
+
console.log(`${key}=${value}`);
|
|
78311
|
+
}
|
|
78312
|
+
} else {
|
|
78313
|
+
const config = this.configManager.getConfig();
|
|
78314
|
+
console.log("Current configuration:", JSON.stringify(config, null, 2));
|
|
78315
|
+
}
|
|
78316
|
+
}
|
|
78317
|
+
reset(key) {
|
|
78318
|
+
const config = this.configManager.getConfig();
|
|
78319
|
+
if (config[key] === void 0) {
|
|
78320
|
+
console.log(`Key does not exist in the configuration: ${key}`);
|
|
78321
|
+
return;
|
|
78322
|
+
}
|
|
78323
|
+
delete config[key];
|
|
78324
|
+
this.configManager.writeConfig(key, void 0);
|
|
78325
|
+
console.log(`Configuration key reset: ${key}`);
|
|
78326
|
+
}
|
|
78327
|
+
};
|
|
78328
|
+
|
|
78329
|
+
// src/commands/config/index.ts
|
|
78330
|
+
function initializeConfigCommands(program2) {
|
|
78331
|
+
const configActions = new ConfigActions();
|
|
78332
|
+
const configCommand = program2.command("config").description("Manage CLI configuration, including the default network");
|
|
78333
|
+
configCommand.command("set").description("Set a configuration value").argument("<key=value>", "Configuration key-value pair to set").action((keyValue) => configActions.set(keyValue));
|
|
78334
|
+
configCommand.command("get").description("Get the current configuration").argument("[key]", "Configuration key to retrieve").action((key) => configActions.get(key));
|
|
78335
|
+
configCommand.command("reset").description("Reset a configuration value to its default").argument("<key>", "Configuration key to reset").action((key) => configActions.reset(key));
|
|
78336
|
+
return program2;
|
|
78337
|
+
}
|
|
78338
|
+
|
|
78272
78339
|
// src/index.ts
|
|
78273
78340
|
function initializeCLI() {
|
|
78274
78341
|
program.version(version).description(CLI_DESCRIPTION);
|
|
78275
78342
|
initializeGeneralCommands(program);
|
|
78276
78343
|
initializeKeygenCommands(program);
|
|
78344
|
+
initializeConfigCommands(program);
|
|
78277
78345
|
program.parse(process.argv);
|
|
78278
78346
|
}
|
|
78279
78347
|
initializeCLI();
|
package/docker-compose.yml
CHANGED
|
@@ -2,7 +2,7 @@ version: "3.8"
|
|
|
2
2
|
|
|
3
3
|
services:
|
|
4
4
|
frontend:
|
|
5
|
-
image: yeagerai/simulator-frontend
|
|
5
|
+
image: yeagerai/simulator-frontend:${LOCALNETVERSION:-latest}
|
|
6
6
|
ports:
|
|
7
7
|
- "${FRONTEND_PORT:-8080}:8080"
|
|
8
8
|
environment:
|
|
@@ -25,7 +25,7 @@ services:
|
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
jsonrpc:
|
|
28
|
-
image: yeagerai/simulator-jsonrpc
|
|
28
|
+
image: yeagerai/simulator-jsonrpc:${LOCALNETVERSION:-latest}
|
|
29
29
|
environment:
|
|
30
30
|
- FLASK_SERVER_PORT=${RPCPORT:-5000}
|
|
31
31
|
- PYTHONUNBUFFERED=1
|
|
@@ -63,7 +63,7 @@ services:
|
|
|
63
63
|
replicas: ${JSONRPC_REPLICAS:-1}
|
|
64
64
|
|
|
65
65
|
webrequest:
|
|
66
|
-
image: yeagerai/simulator-webrequest
|
|
66
|
+
image: yeagerai/simulator-webrequest:${LOCALNETVERSION:-latest}
|
|
67
67
|
shm_size: 2gb
|
|
68
68
|
environment:
|
|
69
69
|
- FLASK_SERVER_PORT=${WEBREQUESTPORT:-5002}
|
|
@@ -131,7 +131,7 @@ services:
|
|
|
131
131
|
# - "./data/postgres:/var/lib/postgresql/data"
|
|
132
132
|
|
|
133
133
|
database-migration:
|
|
134
|
-
image: yeagerai/simulator-database-migration
|
|
134
|
+
image: yeagerai/simulator-database-migration:${LOCALNETVERSION:-latest}
|
|
135
135
|
environment:
|
|
136
136
|
- DB_URL=postgresql://${DBUSER:-postgres}:${DBPASSWORD:-postgres}@postgres/${DBNAME:-simulator_db}
|
|
137
137
|
- WEBREQUESTPORT=${WEBREQUESTPORT:-5002}
|
package/package.json
CHANGED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { ConfigFileManager } from "../../lib/config/ConfigFileManager";
|
|
2
|
+
|
|
3
|
+
export class ConfigActions {
|
|
4
|
+
private configManager: ConfigFileManager;
|
|
5
|
+
|
|
6
|
+
constructor() {
|
|
7
|
+
this.configManager = new ConfigFileManager();
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
set(keyValue: string): void {
|
|
11
|
+
const [key, value] = keyValue.split("=");
|
|
12
|
+
if (!key || value === undefined) {
|
|
13
|
+
console.error("Invalid format. Use key=value.");
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
this.configManager.writeConfig(key, value);
|
|
17
|
+
console.log(`Configuration updated: ${key}=${value}`);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
get(key?: string): void {
|
|
21
|
+
if (key) {
|
|
22
|
+
const value = this.configManager.getConfigByKey(key);
|
|
23
|
+
if (value === null) {
|
|
24
|
+
console.log(`No value set for key: ${key}`);
|
|
25
|
+
} else {
|
|
26
|
+
console.log(`${key}=${value}`);
|
|
27
|
+
}
|
|
28
|
+
} else {
|
|
29
|
+
const config = this.configManager.getConfig();
|
|
30
|
+
console.log("Current configuration:", JSON.stringify(config, null, 2));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
reset(key: string): void {
|
|
35
|
+
const config = this.configManager.getConfig();
|
|
36
|
+
if (config[key] === undefined) {
|
|
37
|
+
console.log(`Key does not exist in the configuration: ${key}`);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
delete config[key];
|
|
41
|
+
this.configManager.writeConfig(key, undefined);
|
|
42
|
+
console.log(`Configuration key reset: ${key}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { ConfigActions } from "./getSetReset";
|
|
3
|
+
|
|
4
|
+
export function initializeConfigCommands(program: Command) {
|
|
5
|
+
const configActions = new ConfigActions();
|
|
6
|
+
|
|
7
|
+
const configCommand = program
|
|
8
|
+
.command("config")
|
|
9
|
+
.description("Manage CLI configuration, including the default network");
|
|
10
|
+
|
|
11
|
+
configCommand
|
|
12
|
+
.command("set")
|
|
13
|
+
.description("Set a configuration value")
|
|
14
|
+
.argument("<key=value>", "Configuration key-value pair to set")
|
|
15
|
+
.action((keyValue: string) => configActions.set(keyValue));
|
|
16
|
+
|
|
17
|
+
configCommand
|
|
18
|
+
.command("get")
|
|
19
|
+
.description("Get the current configuration")
|
|
20
|
+
.argument("[key]", "Configuration key to retrieve")
|
|
21
|
+
.action((key?: string) => configActions.get(key));
|
|
22
|
+
|
|
23
|
+
configCommand
|
|
24
|
+
.command("reset")
|
|
25
|
+
.description("Reset a configuration value to its default")
|
|
26
|
+
.argument("<key>", "Configuration key to reset")
|
|
27
|
+
.action((key: string) => configActions.reset(key));
|
|
28
|
+
|
|
29
|
+
return program;
|
|
30
|
+
}
|
|
@@ -11,6 +11,7 @@ export function initializeGeneralCommands(program: Command) {
|
|
|
11
11
|
.option("--numValidators <numValidators>", "Number of validators", "5")
|
|
12
12
|
.option("--headless", "Headless mode", false)
|
|
13
13
|
.option("--reset-db", "Reset Database", false)
|
|
14
|
+
.option("--localnet-version <localnetVersion>", "Select a specific localnet version", 'latest')
|
|
14
15
|
.action((options: InitActionOptions) => initAction(options, simulatorService));
|
|
15
16
|
|
|
16
17
|
program
|
|
@@ -6,6 +6,7 @@ export interface InitActionOptions {
|
|
|
6
6
|
numValidators: number;
|
|
7
7
|
headless: boolean;
|
|
8
8
|
resetDb: boolean;
|
|
9
|
+
localnetVersion: string;
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
function getRequirementsErrorMessage({docker}: Record<string, boolean>): string {
|
|
@@ -34,6 +35,11 @@ function getVersionErrorMessage({docker, node}: Record<string, string>): string
|
|
|
34
35
|
export async function initAction(options: InitActionOptions, simulatorService: ISimulatorService) {
|
|
35
36
|
simulatorService.setComposeOptions(options.headless);
|
|
36
37
|
|
|
38
|
+
let localnetVersion = options.localnetVersion;
|
|
39
|
+
|
|
40
|
+
if(localnetVersion !== 'latest'){
|
|
41
|
+
localnetVersion = simulatorService.normalizeLocalnetVersion(localnetVersion);
|
|
42
|
+
}
|
|
37
43
|
await simulatorService.checkCliVersion();
|
|
38
44
|
|
|
39
45
|
// Check if requirements are installed
|
|
@@ -139,6 +145,7 @@ export async function initAction(options: InitActionOptions, simulatorService: I
|
|
|
139
145
|
|
|
140
146
|
console.log("Configuring GenLayer Simulator environment...");
|
|
141
147
|
simulatorService.addConfigToEnvFile(aiProvidersEnvVars);
|
|
148
|
+
simulatorService.addConfigToEnvFile({LOCALNETVERSION: localnetVersion});
|
|
142
149
|
|
|
143
150
|
|
|
144
151
|
// Run the GenLayer Simulator
|
package/src/index.ts
CHANGED
|
@@ -4,11 +4,13 @@ import {version} from "../package.json";
|
|
|
4
4
|
import {CLI_DESCRIPTION} from "../src/lib/config/text";
|
|
5
5
|
import { initializeGeneralCommands } from "../src/commands/general";
|
|
6
6
|
import { initializeKeygenCommands } from "../src/commands/keygen";
|
|
7
|
+
import { initializeConfigCommands } from "../src/commands/config";
|
|
7
8
|
|
|
8
9
|
export function initializeCLI() {
|
|
9
10
|
program.version(version).description(CLI_DESCRIPTION);
|
|
10
11
|
initializeGeneralCommands(program);
|
|
11
12
|
initializeKeygenCommands(program);
|
|
13
|
+
initializeConfigCommands(program);
|
|
12
14
|
program.parse(process.argv);
|
|
13
15
|
}
|
|
14
16
|
|
|
@@ -295,6 +295,23 @@ export class SimulatorService implements ISimulatorService {
|
|
|
295
295
|
return true;
|
|
296
296
|
}
|
|
297
297
|
|
|
298
|
+
public normalizeLocalnetVersion(version: string) {
|
|
299
|
+
|
|
300
|
+
if (!version.startsWith('v')) {
|
|
301
|
+
version = 'v' + version;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const versionRegex = /^v(\d+)\.(\d+)\.(\d+)(-.+)?$/;
|
|
305
|
+
const match = version.match(versionRegex);
|
|
306
|
+
|
|
307
|
+
if (!match) {
|
|
308
|
+
console.error('Invalid version format. Expected format: v0.0.0 or v0.0.0-suffix');
|
|
309
|
+
process.exit(1);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
return version
|
|
313
|
+
}
|
|
314
|
+
|
|
298
315
|
}
|
|
299
316
|
|
|
300
317
|
export default new SimulatorService();
|
|
@@ -89,7 +89,7 @@ describe("KeypairCreator", () => {
|
|
|
89
89
|
|
|
90
90
|
test("overwrites the file if overwrite is true", () => {
|
|
91
91
|
const consoleLogSpy = vi.spyOn(console, "log");
|
|
92
|
-
vi.mocked(existsSync).mockReturnValue(true);
|
|
92
|
+
vi.mocked(existsSync).mockReturnValue(true);
|
|
93
93
|
const options = { output: "keypair.json", overwrite: true };
|
|
94
94
|
|
|
95
95
|
keypairCreator.createKeypairAction(options);
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { describe, test, vi, beforeEach, afterEach, expect } from "vitest";
|
|
2
|
+
import { ConfigActions } from "../../src/commands/config/getSetReset";
|
|
3
|
+
import { ConfigFileManager } from "../../src/lib/config/ConfigFileManager";
|
|
4
|
+
|
|
5
|
+
vi.mock("../../src/lib/config/ConfigFileManager");
|
|
6
|
+
|
|
7
|
+
describe("ConfigActions", () => {
|
|
8
|
+
let configActions: ConfigActions;
|
|
9
|
+
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
configActions = new ConfigActions();
|
|
12
|
+
vi.clearAllMocks();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
new ConfigFileManager();
|
|
16
|
+
|
|
17
|
+
afterEach(() => {
|
|
18
|
+
vi.restoreAllMocks();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test("set method writes key-value pair to the configuration", () => {
|
|
22
|
+
const consoleLogSpy = vi.spyOn(console, "log");
|
|
23
|
+
|
|
24
|
+
configActions.set("defaultNetwork=testnet");
|
|
25
|
+
|
|
26
|
+
expect(configActions["configManager"].writeConfig).toHaveBeenCalledWith("defaultNetwork", "testnet");
|
|
27
|
+
expect(consoleLogSpy).toHaveBeenCalledWith("Configuration updated: defaultNetwork=testnet");
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test("set method throws error for invalid format", () => {
|
|
31
|
+
const consoleErrorSpy = vi.spyOn(console, "error");
|
|
32
|
+
const processExitSpy = vi.spyOn(process, "exit").mockImplementation(() => {
|
|
33
|
+
throw new Error("process.exit");
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
expect(() => configActions.set("invalidFormat")).toThrowError("process.exit");
|
|
37
|
+
|
|
38
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith("Invalid format. Use key=value.");
|
|
39
|
+
expect(processExitSpy).toHaveBeenCalledWith(1);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test("get method retrieves value for a specific key", () => {
|
|
43
|
+
vi.mocked(ConfigFileManager.prototype.getConfigByKey).mockReturnValue("testnet");
|
|
44
|
+
|
|
45
|
+
const consoleLogSpy = vi.spyOn(console, "log");
|
|
46
|
+
|
|
47
|
+
configActions.get("defaultNetwork");
|
|
48
|
+
|
|
49
|
+
expect(configActions["configManager"].getConfigByKey).toHaveBeenCalledWith("defaultNetwork");
|
|
50
|
+
expect(consoleLogSpy).toHaveBeenCalledWith("defaultNetwork=testnet");
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test("get method prints message when key has no value", () => {
|
|
54
|
+
vi.mocked(ConfigFileManager.prototype.getConfigByKey).mockReturnValue(null);
|
|
55
|
+
|
|
56
|
+
const consoleLogSpy = vi.spyOn(console, "log");
|
|
57
|
+
|
|
58
|
+
configActions.get("nonexistentKey");
|
|
59
|
+
|
|
60
|
+
expect(configActions["configManager"].getConfigByKey).toHaveBeenCalledWith("nonexistentKey");
|
|
61
|
+
expect(consoleLogSpy).toHaveBeenCalledWith("No value set for key: nonexistentKey");
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test("get method retrieves the entire configuration when no key is provided", () => {
|
|
65
|
+
const mockConfig = { defaultNetwork: "testnet" };
|
|
66
|
+
vi.mocked(ConfigFileManager.prototype.getConfig).mockReturnValue(mockConfig);
|
|
67
|
+
|
|
68
|
+
const consoleLogSpy = vi.spyOn(console, "log");
|
|
69
|
+
|
|
70
|
+
configActions.get();
|
|
71
|
+
|
|
72
|
+
expect(configActions["configManager"].getConfig).toHaveBeenCalledTimes(1);
|
|
73
|
+
expect(consoleLogSpy).toHaveBeenCalledWith("Current configuration:", JSON.stringify(mockConfig, null, 2));
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test("reset method removes key from configuration", () => {
|
|
77
|
+
const mockConfig = { defaultNetwork: "testnet" };
|
|
78
|
+
vi.mocked(ConfigFileManager.prototype.getConfig).mockReturnValue(mockConfig);
|
|
79
|
+
|
|
80
|
+
const consoleLogSpy = vi.spyOn(console, "log");
|
|
81
|
+
|
|
82
|
+
configActions.reset("defaultNetwork");
|
|
83
|
+
|
|
84
|
+
expect(configActions["configManager"].getConfig).toHaveBeenCalledTimes(1);
|
|
85
|
+
expect(configActions["configManager"].writeConfig).toHaveBeenCalledWith("defaultNetwork", undefined);
|
|
86
|
+
expect(consoleLogSpy).toHaveBeenCalledWith("Configuration key reset: defaultNetwork");
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test("reset method prints message when key does not exist", () => {
|
|
90
|
+
const mockConfig = {};
|
|
91
|
+
vi.mocked(ConfigFileManager.prototype.getConfig).mockReturnValue(mockConfig);
|
|
92
|
+
|
|
93
|
+
const consoleLogSpy = vi.spyOn(console, "log");
|
|
94
|
+
|
|
95
|
+
configActions.reset("nonexistentKey");
|
|
96
|
+
|
|
97
|
+
expect(configActions["configManager"].getConfig).toHaveBeenCalledTimes(1);
|
|
98
|
+
expect(configActions["configManager"].writeConfig).not.toHaveBeenCalled();
|
|
99
|
+
expect(consoleLogSpy).toHaveBeenCalledWith("Key does not exist in the configuration: nonexistentKey");
|
|
100
|
+
});
|
|
101
|
+
});
|
|
@@ -14,7 +14,7 @@ vi.mock("dotenv");
|
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
const tempDir = mkdtempSync(join(tmpdir(), "test-initAction-"));
|
|
17
|
-
const defaultActionOptions = { numValidators: 5, branch: "main", location: tempDir, headless: false, resetDb: false };
|
|
17
|
+
const defaultActionOptions = { numValidators: 5, branch: "main", location: tempDir, headless: false, resetDb: false, localnetVersion: 'latest' };
|
|
18
18
|
|
|
19
19
|
describe("init action", () => {
|
|
20
20
|
let error: ReturnType<any>;
|
|
@@ -201,7 +201,7 @@ describe("init action", () => {
|
|
|
201
201
|
simServResetDockerContainers.mockResolvedValue(true);
|
|
202
202
|
simServResetDockerImages.mockResolvedValue(true);
|
|
203
203
|
|
|
204
|
-
await initAction({...defaultActionOptions, headless: true, resetDb: true}, simulatorService);
|
|
204
|
+
await initAction({...defaultActionOptions, headless: true, resetDb: true, localnetVersion: "v1.0.0"}, simulatorService);
|
|
205
205
|
|
|
206
206
|
expect(log).toHaveBeenCalledWith(
|
|
207
207
|
`GenLayer simulator initialized successfully! `
|
|
@@ -441,4 +441,5 @@ describe("init action", () => {
|
|
|
441
441
|
|
|
442
442
|
expect(error).toHaveBeenCalledWith(errorMsg);
|
|
443
443
|
});
|
|
444
|
+
|
|
444
445
|
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { vi, describe, beforeEach, afterEach, test, expect } from "vitest";
|
|
3
|
+
import { initializeConfigCommands } from "../../src/commands/config";
|
|
4
|
+
import { ConfigActions } from "../../src/commands/config/getSetReset";
|
|
5
|
+
|
|
6
|
+
vi.mock("../../src/commands/config/getSetReset");
|
|
7
|
+
|
|
8
|
+
describe("config commands", () => {
|
|
9
|
+
let program: Command;
|
|
10
|
+
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
program = new Command();
|
|
13
|
+
initializeConfigCommands(program);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
afterEach(() => {
|
|
17
|
+
vi.restoreAllMocks();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test("ConfigActions.set is called with the correct key-value pair", async () => {
|
|
21
|
+
program.parse(["node", "test", "config", "set", "defaultNetwork=testnet"]);
|
|
22
|
+
expect(ConfigActions).toHaveBeenCalledTimes(1);
|
|
23
|
+
expect(ConfigActions.prototype.set).toHaveBeenCalledWith("defaultNetwork=testnet");
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test("ConfigActions.get is called with a specific key", async () => {
|
|
27
|
+
program.parse(["node", "test", "config", "get", "defaultNetwork"]);
|
|
28
|
+
expect(ConfigActions).toHaveBeenCalledTimes(1);
|
|
29
|
+
expect(ConfigActions.prototype.get).toHaveBeenCalledWith("defaultNetwork");
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test("ConfigActions.get is called without a key", async () => {
|
|
33
|
+
program.parse(["node", "test", "config", "get"]);
|
|
34
|
+
expect(ConfigActions).toHaveBeenCalledTimes(1);
|
|
35
|
+
expect(ConfigActions.prototype.get).toHaveBeenCalledWith(undefined);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test("ConfigActions.reset is called with the correct key", async () => {
|
|
39
|
+
program.parse(["node", "test", "config", "reset", "defaultNetwork"]);
|
|
40
|
+
expect(ConfigActions).toHaveBeenCalledTimes(1);
|
|
41
|
+
expect(ConfigActions.prototype.reset).toHaveBeenCalledWith("defaultNetwork");
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test("ConfigActions is instantiated when the command is executed", async () => {
|
|
45
|
+
program.parse(["node", "test", "config", "set", "defaultNetwork=testnet"]);
|
|
46
|
+
expect(ConfigActions).toHaveBeenCalledTimes(1);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test("ConfigActions.set is called without throwing errors for valid input", async () => {
|
|
50
|
+
program.parse(["node", "test", "config", "set", "defaultNetwork=testnet"]);
|
|
51
|
+
vi.mocked(ConfigActions.prototype.set).mockReturnValue();
|
|
52
|
+
expect(() => program.parse(["node", "test", "config", "set", "defaultNetwork=testnet"])).not.toThrow();
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -8,7 +8,8 @@ const openFrontendSpy = vi.spyOn(simulatorService, "openFrontend");
|
|
|
8
8
|
const defaultOptions = {
|
|
9
9
|
numValidators: "5",
|
|
10
10
|
headless: false,
|
|
11
|
-
resetDb: false
|
|
11
|
+
resetDb: false,
|
|
12
|
+
localnetVersion: 'latest'
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
vi.mock("inquirer", () => ({
|
|
@@ -73,4 +74,11 @@ describe("init command", () => {
|
|
|
73
74
|
expect(action).toHaveBeenCalledWith({...defaultOptions, headless: true});
|
|
74
75
|
expect(openFrontendSpy).not.toHaveBeenCalled();
|
|
75
76
|
});
|
|
77
|
+
|
|
78
|
+
test("option --localnet-version is accepted", async () => {
|
|
79
|
+
program.parse(["node", "test", "init", "--localnet-version", "v1.0.0"]);
|
|
80
|
+
expect(action).toHaveBeenCalledTimes(1);
|
|
81
|
+
expect(action).toHaveBeenCalledWith({...defaultOptions, localnetVersion: "v1.0.0"});
|
|
82
|
+
expect(openFrontendSpy).not.toHaveBeenCalled();
|
|
83
|
+
});
|
|
76
84
|
});
|
package/tests/index.test.ts
CHANGED
|
@@ -17,6 +17,10 @@ vi.mock("../src/commands/keygen", () => ({
|
|
|
17
17
|
initializeKeygenCommands: vi.fn(),
|
|
18
18
|
}));
|
|
19
19
|
|
|
20
|
+
vi.mock("../src/commands/config", () => ({
|
|
21
|
+
initializeConfigCommands: vi.fn(),
|
|
22
|
+
}));
|
|
23
|
+
|
|
20
24
|
|
|
21
25
|
describe("CLI", () => {
|
|
22
26
|
it("should initialize CLI", () => {
|
|
@@ -505,3 +505,37 @@ describe("SimulatorService - Docker Tests", () => {
|
|
|
505
505
|
consoleWarnSpy.mockRestore();
|
|
506
506
|
});
|
|
507
507
|
});
|
|
508
|
+
|
|
509
|
+
describe('normalizeLocalnetVersion', () => {
|
|
510
|
+
test('should add "v" if not present', () => {
|
|
511
|
+
expect(simulatorService.normalizeLocalnetVersion("0.26.0")).toBe("v0.26.0");
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
test('should preserve "v" if already present', () => {
|
|
515
|
+
expect(simulatorService.normalizeLocalnetVersion("v0.26.0")).toBe("v0.26.0");
|
|
516
|
+
});
|
|
517
|
+
|
|
518
|
+
test('should retain suffixes like "-test000"', () => {
|
|
519
|
+
expect(simulatorService.normalizeLocalnetVersion("0.25.0-test000")).toBe("v0.25.0-test000");
|
|
520
|
+
expect(simulatorService.normalizeLocalnetVersion("v1.0.0-alpha")).toBe("v1.0.0-alpha");
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
test('should handle versions with numbers only', () => {
|
|
524
|
+
expect(simulatorService.normalizeLocalnetVersion("1.0.0")).toBe("v1.0.0");
|
|
525
|
+
});
|
|
526
|
+
|
|
527
|
+
test('should throw an error and exit for invalid versions', () => {
|
|
528
|
+
const mockExit = vi.spyOn(process, 'exit').mockImplementation(() => { return undefined as never});
|
|
529
|
+
const mockConsoleError = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
530
|
+
|
|
531
|
+
simulatorService.normalizeLocalnetVersion("invalid-version");
|
|
532
|
+
|
|
533
|
+
expect(mockConsoleError).toHaveBeenCalledWith(
|
|
534
|
+
'Invalid version format. Expected format: v0.0.0 or v0.0.0-suffix'
|
|
535
|
+
);
|
|
536
|
+
expect(mockExit).toHaveBeenCalledWith(1);
|
|
537
|
+
|
|
538
|
+
mockExit.mockRestore();
|
|
539
|
+
mockConsoleError.mockRestore();
|
|
540
|
+
});
|
|
541
|
+
});
|