Skip to content

Commit 4b68018

Browse files
authored
Merge pull request #5390 from NomicFoundation/global-parameters
buildGlobalParameterDefinition implementation & testing
2 parents 2a364d1 + 5fcb380 commit 4b68018

File tree

5 files changed

+155
-24
lines changed

5 files changed

+155
-24
lines changed

v-next/core/src/config.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { ParameterTypeToValueType } from "./types/common.js";
12
import type { ConfigurationVariable } from "./types/config.js";
23
import type { GlobalParameter } from "./types/global-parameters.js";
34
import type {
@@ -57,11 +58,11 @@ export function overrideTask(
5758
/**
5859
* Defines a global parameter.
5960
*/
60-
export function globalParameter(options: {
61+
export function globalParameter<T extends ParameterType>(options: {
6162
name: string;
6263
description: string;
63-
parameterType: ParameterType;
64-
defaultValue: any;
64+
parameterType?: T;
65+
defaultValue: ParameterTypeToValueType<T>;
6566
}): GlobalParameter {
6667
return buildGlobalParameterDefinition(options);
6768
}

v-next/core/src/internal/global-parameters.ts

+49-13
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,27 @@
1-
import type { ParameterType } from "../types/common.js";
1+
import type { ParameterTypeToValueType } from "../types/common.js";
22
import type {
33
GlobalArguments,
44
GlobalParameter,
55
GlobalParameterMap,
66
} from "../types/global-parameters.js";
77
import type { HardhatPlugin } from "../types/plugins.js";
88

9+
import { HardhatError } from "@nomicfoundation/hardhat-errors";
10+
11+
import { ParameterType } from "../types/common.js";
12+
13+
import {
14+
RESERVED_PARAMETER_NAMES,
15+
isParameterValueValid,
16+
isValidParamNameCasing,
17+
} from "./parameters.js";
18+
919
/**
1020
* Builds a map of the global parameters, validating them.
1121
*
1222
* Note: this function can be used before initializing the HRE, so the plugins
13-
* shouldn't be consider validated. Hence, we should validate the global
14-
* parameters.
23+
* shouldn't be consider validated. Hence, we should validate the global
24+
* parameters.
1525
*/
1626
export function buildGlobalParameterMap(
1727
resolvedPlugins: HardhatPlugin[],
@@ -48,21 +58,47 @@ export function buildGlobalParameterMap(
4858
return globalParametersIndex;
4959
}
5060

51-
export function buildGlobalParameterDefinition(options: {
61+
export function buildGlobalParameterDefinition<T extends ParameterType>({
62+
name,
63+
description,
64+
parameterType,
65+
defaultValue,
66+
}: {
5267
name: string;
5368
description: string;
54-
parameterType: ParameterType;
55-
defaultValue: any;
69+
parameterType?: T;
70+
defaultValue: ParameterTypeToValueType<T>;
5671
}): GlobalParameter {
57-
// TODO: Validate name casing
58-
// TODO: Validate default value matches with type
59-
// TODO: Validate that the name is not one of the reserved ones in parameters.ts
72+
const type = parameterType ?? ParameterType.STRING;
73+
74+
if (!isValidParamNameCasing(name)) {
75+
throw new HardhatError(HardhatError.ERRORS.ARGUMENTS.INVALID_NAME, {
76+
name,
77+
});
78+
}
79+
80+
if (RESERVED_PARAMETER_NAMES.has(name)) {
81+
throw new HardhatError(HardhatError.ERRORS.ARGUMENTS.RESERVED_NAME, {
82+
name,
83+
});
84+
}
85+
86+
if (!isParameterValueValid(type, defaultValue)) {
87+
throw new HardhatError(
88+
HardhatError.ERRORS.ARGUMENTS.INVALID_VALUE_FOR_TYPE,
89+
{
90+
value: defaultValue,
91+
name: "defaultValue",
92+
type: parameterType,
93+
},
94+
);
95+
}
6096

6197
return {
62-
name: options.name,
63-
description: options.description,
64-
parameterType: options.parameterType,
65-
defaultValue: options.defaultValue,
98+
name,
99+
description,
100+
parameterType: type,
101+
defaultValue,
66102
};
67103
}
68104

v-next/core/src/types/global-parameters.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { ParameterType } from "./common.js";
1+
import type { ParameterType, ParameterTypeToValueType } from "./common.js";
22

33
/**
44
* A global parameter with an associated value and a default if not provided by
@@ -13,11 +13,11 @@ import type { ParameterType } from "./common.js";
1313
*
1414
* If both are present, the second one takes precedence.
1515
*/
16-
export interface GlobalParameter {
16+
export interface GlobalParameter<T extends ParameterType = ParameterType> {
1717
name: string;
1818
description: string;
1919
parameterType: ParameterType;
20-
defaultValue: any;
20+
defaultValue: ParameterTypeToValueType<T>;
2121
}
2222

2323
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import assert from "node:assert/strict";
2+
import { describe, it } from "node:test";
3+
4+
import { HardhatError } from "@nomicfoundation/hardhat-errors";
5+
6+
import { ParameterType } from "../../src/config.js";
7+
import { buildGlobalParameterDefinition } from "../../src/internal/global-parameters.js";
8+
import { RESERVED_PARAMETER_NAMES } from "../../src/internal/parameters.js";
9+
10+
describe("Global Parameters", () => {
11+
describe.todo("buildGlobalParameterMap", () => {
12+
// TODO: Implement tests.
13+
});
14+
15+
describe("buildGlobalParameterDefinition", () => {
16+
it("should build a global parameter definition", () => {
17+
const options = {
18+
name: "foo",
19+
description: "Foo description",
20+
parameterType: ParameterType.BOOLEAN,
21+
defaultValue: true,
22+
};
23+
const globalParameter = buildGlobalParameterDefinition(options);
24+
25+
assert.deepEqual(globalParameter, options);
26+
});
27+
28+
it("should build a global parameter definition with a default type of STRING", () => {
29+
const options = {
30+
name: "foo",
31+
description: "Foo description",
32+
defaultValue: "bar",
33+
};
34+
const globalParameter = buildGlobalParameterDefinition(options);
35+
36+
assert.deepEqual(globalParameter, {
37+
...options,
38+
parameterType: ParameterType.STRING,
39+
});
40+
});
41+
42+
it("should throw if the parameter name is not valid", () => {
43+
assert.throws(
44+
() =>
45+
buildGlobalParameterDefinition({
46+
name: "foo bar",
47+
description: "Foo description",
48+
defaultValue: "bar",
49+
}),
50+
new HardhatError(HardhatError.ERRORS.ARGUMENTS.INVALID_NAME, {
51+
name: "foo bar",
52+
}),
53+
);
54+
});
55+
56+
it("should throw if the parameter name is reserved", () => {
57+
RESERVED_PARAMETER_NAMES.forEach((name) => {
58+
assert.throws(
59+
() =>
60+
buildGlobalParameterDefinition({
61+
name,
62+
description: "Foo description",
63+
defaultValue: "bar",
64+
}),
65+
new HardhatError(HardhatError.ERRORS.ARGUMENTS.RESERVED_NAME, {
66+
name,
67+
}),
68+
);
69+
});
70+
});
71+
72+
it("should throw if the default value does not match the type", () => {
73+
assert.throws(
74+
() =>
75+
buildGlobalParameterDefinition({
76+
name: "foo",
77+
description: "Foo description",
78+
parameterType: ParameterType.BOOLEAN,
79+
/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions --
80+
Intentionally testing an invalid type */
81+
defaultValue: "bar" as any,
82+
}),
83+
new HardhatError(HardhatError.ERRORS.ARGUMENTS.INVALID_VALUE_FOR_TYPE, {
84+
value: "bar",
85+
name: "defaultValue",
86+
type: ParameterType.BOOLEAN,
87+
}),
88+
);
89+
});
90+
});
91+
92+
describe.todo("resolveGlobalArguments", () => {
93+
// TODO: Implement tests.
94+
});
95+
});

v-next/core/test/internal/tasks/task-manager.ts

+4-5
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@ import { describe, it } from "node:test";
33

44
import { HardhatError } from "@nomicfoundation/hardhat-errors";
55

6-
import { ParameterType } from "../../../src/config.js";
6+
import { ParameterType, globalParameter } from "../../../src/config.js";
77
import { createHardhatRuntimeEnvironment } from "../../../src/index.js";
8-
import { buildGlobalParameterDefinition } from "../../../src/internal/global-parameters.js";
98
import {
109
EmptyTaskDefinitionBuilderImplementation,
1110
NewTaskDefinitionBuilderImplementation,
@@ -46,7 +45,7 @@ describe("TaskManagerImplementation", () => {
4645
.build(),
4746
],
4847
globalParameters: [
49-
buildGlobalParameterDefinition({
48+
globalParameter({
5049
name: "globalParam1",
5150
description: "",
5251
parameterType: ParameterType.STRING,
@@ -392,7 +391,7 @@ describe("TaskManagerImplementation", () => {
392391
{
393392
id: "plugin2",
394393
globalParameters: [
395-
buildGlobalParameterDefinition({
394+
globalParameter({
396395
name: "param1",
397396
description: "",
398397
parameterType: ParameterType.STRING,
@@ -430,7 +429,7 @@ describe("TaskManagerImplementation", () => {
430429
{
431430
id: "plugin2",
432431
globalParameters: [
433-
buildGlobalParameterDefinition({
432+
globalParameter({
434433
name: "param1",
435434
description: "",
436435
parameterType: ParameterType.STRING,

0 commit comments

Comments
 (0)