Skip to content

Commit fb4b3a1

Browse files
committed
fix: test the shouldUpdateDependency helper thoroughly
1 parent e5d4453 commit fb4b3a1

File tree

2 files changed

+204
-11
lines changed
  • v-next/hardhat

2 files changed

+204
-11
lines changed

v-next/hardhat/src/internal/cli/init/init.ts

+37-8
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ import type { PackageJson } from "@nomicfoundation/hardhat-utils/package";
33

44
import path from "node:path";
55

6-
import { HardhatError } from "@nomicfoundation/hardhat-errors";
6+
import {
7+
assertHardhatInvariant,
8+
HardhatError,
9+
} from "@nomicfoundation/hardhat-errors";
710
import {
811
copy,
912
ensureDir,
@@ -480,13 +483,9 @@ export async function installProjectDependencies(
480483

481484
// Finding the installed dependencies that have an incompatible version
482485
const dependenciesToUpdate = templateDependencyEntries
483-
.filter(([name, version]) => {
484-
const workspaceVersion = workspaceDependencies[name];
485-
return (
486-
workspaceVersion !== undefined &&
487-
!semver.satisfies(workspaceVersion, version) &&
488-
!semver.intersects(workspaceVersion, version)
489-
);
486+
.filter(([dependencyName, templateVersion]) => {
487+
const workspaceVersion = workspaceDependencies[dependencyName];
488+
return shouldUpdateDependency(workspaceVersion, templateVersion);
490489
})
491490
.map(([name, version]) => `${name}@${version}`);
492491

@@ -529,3 +528,33 @@ function showStarOnGitHubMessage() {
529528
console.log();
530529
console.log(chalk.cyan(" https://github.com/NomicFoundation/hardhat"));
531530
}
531+
532+
// NOTE: This function is exported for testing purposes only.
533+
export function shouldUpdateDependency(
534+
workspaceVersion: string | undefined,
535+
templateVersion: string,
536+
): boolean {
537+
// We should not update the dependency if it is not yet installed in the workspace.
538+
if (workspaceVersion === undefined) {
539+
return false;
540+
}
541+
const workspaceRange = semver.validRange(workspaceVersion, {
542+
includePrerelease: true,
543+
});
544+
const templateRange = semver.validRange(templateVersion, {
545+
includePrerelease: true,
546+
});
547+
assertHardhatInvariant(
548+
templateRange !== null,
549+
"All the versions of template dependencies should be valid",
550+
);
551+
// We should update the dependency if the workspace version could not be parsed as a range.
552+
if (workspaceRange === null) {
553+
return true;
554+
}
555+
// We should update the dependency if the workspace range (or, in particular, a specific version) is not
556+
// a strict subset of the template range/does not equal the template version.
557+
return !semver.subset(workspaceRange, templateRange, {
558+
includePrerelease: true,
559+
});
560+
}

v-next/hardhat/test/internal/cli/init/init.ts

+167-3
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import {
2929
printWelcomeMessage,
3030
relativeTemplateToWorkspacePath,
3131
relativeWorkspaceToTemplatePath,
32+
shouldUpdateDependency,
3233
} from "../../../../src/internal/cli/init/init.js";
3334
import { getTemplates } from "../../../../src/internal/cli/init/template.js";
3435

@@ -233,7 +234,7 @@ describe("copyProjectFiles", () => {
233234
describe("installProjectDependencies", async () => {
234235
useTmpDir("installProjectDependencies");
235236

236-
disableConsole();
237+
// disableConsole();
237238

238239
const templates = await getTemplates();
239240

@@ -357,7 +358,7 @@ describe("installProjectDependencies", async () => {
357358
packageJson: {
358359
name: "test",
359360
version: "0.0.1",
360-
devDependencies: { "fake-dependency": "^1.2.3" }, // <-- required version
361+
devDependencies: { "fake-dependency": ">=1.2.3" }, // <-- required version
361362
},
362363
path: process.cwd(),
363364
files: [],
@@ -367,7 +368,7 @@ describe("installProjectDependencies", async () => {
367368
"package.json",
368369
JSON.stringify({
369370
type: "module",
370-
devDependencies: { "fake-dependency": ">= 1.2.3" }, // <-- version range
371+
devDependencies: { "fake-dependency": "^1.2.3" }, // <-- version range
371372
}),
372373
);
373374
await installProjectDependencies(process.cwd(), template, false, true);
@@ -414,3 +415,166 @@ describe("initHardhat", async () => {
414415
);
415416
}
416417
});
418+
419+
describe("shouldUpdateDependency", () => {
420+
const testCases = [
421+
{
422+
workspaceVersion: "1.0.0",
423+
templateVersion: "1.0.0",
424+
expectedResult: false,
425+
},
426+
{
427+
workspaceVersion: "1.0.0",
428+
templateVersion: "1.2.3",
429+
expectedResult: true,
430+
},
431+
{
432+
workspaceVersion: "1.2.3",
433+
templateVersion: "1.0.0",
434+
expectedResult: true,
435+
},
436+
{
437+
workspaceVersion: "1.2.3",
438+
templateVersion: "^1.2.3",
439+
expectedResult: false,
440+
},
441+
{
442+
workspaceVersion: "^1.2.3",
443+
templateVersion: "1.2.3",
444+
expectedResult: true,
445+
},
446+
{
447+
workspaceVersion: ">= 1.2.3",
448+
templateVersion: "^1.2.3",
449+
expectedResult: true,
450+
},
451+
{
452+
workspaceVersion: "^1.2.3",
453+
templateVersion: ">= 1.2.3",
454+
expectedResult: false,
455+
},
456+
{
457+
workspaceVersion: "1.0.0-dev",
458+
templateVersion: "1.0.0-dev",
459+
expectedResult: false,
460+
},
461+
{
462+
workspaceVersion: "1.0.0-dev",
463+
templateVersion: "1.2.3-dev",
464+
expectedResult: true,
465+
},
466+
{
467+
workspaceVersion: "1.2.3-dev",
468+
templateVersion: "1.0.0-dev",
469+
expectedResult: true,
470+
},
471+
{
472+
workspaceVersion: "1.2.3-dev",
473+
templateVersion: "^1.2.3-dev",
474+
expectedResult: false,
475+
},
476+
{
477+
workspaceVersion: "^1.2.3-dev",
478+
templateVersion: "1.2.3-dev",
479+
expectedResult: true,
480+
},
481+
{
482+
workspaceVersion: ">= 1.2.3-dev",
483+
templateVersion: "^1.2.3-dev",
484+
expectedResult: true,
485+
},
486+
{
487+
workspaceVersion: "^1.2.3-dev",
488+
templateVersion: ">= 1.2.3-dev",
489+
expectedResult: false,
490+
},
491+
{
492+
workspaceVersion: "1.0.0",
493+
templateVersion: "1.0.0-dev",
494+
expectedResult: true,
495+
},
496+
{
497+
workspaceVersion: "1.0.0-dev",
498+
templateVersion: "1.0.0",
499+
expectedResult: true,
500+
},
501+
{
502+
workspaceVersion: "1.0.0-dev",
503+
templateVersion: "1.2.3",
504+
expectedResult: true,
505+
},
506+
{
507+
workspaceVersion: "1.0.0",
508+
templateVersion: "1.2.3-dev",
509+
expectedResult: true,
510+
},
511+
{
512+
workspaceVersion: "1.2.3",
513+
templateVersion: "1.0.0-dev",
514+
expectedResult: true,
515+
},
516+
{
517+
workspaceVersion: "1.2.3-dev",
518+
templateVersion: "1.0.0",
519+
expectedResult: true,
520+
},
521+
{
522+
workspaceVersion: "1.2.3",
523+
templateVersion: "^1.2.3-dev",
524+
expectedResult: false,
525+
},
526+
{
527+
workspaceVersion: "1.2.3-dev",
528+
templateVersion: "^1.2.3",
529+
expectedResult: true,
530+
},
531+
{
532+
workspaceVersion: "^1.2.3",
533+
templateVersion: "1.2.3-dev",
534+
expectedResult: true,
535+
},
536+
{
537+
workspaceVersion: "^1.2.3-dev",
538+
templateVersion: "1.2.3",
539+
expectedResult: true,
540+
},
541+
{
542+
workspaceVersion: ">= 1.2.3",
543+
templateVersion: "^1.2.3-dev",
544+
expectedResult: true,
545+
},
546+
{
547+
workspaceVersion: ">= 1.2.3-dev",
548+
templateVersion: "^1.2.3",
549+
expectedResult: true,
550+
},
551+
{
552+
workspaceVersion: "^1.2.3",
553+
templateVersion: ">= 1.2.3-dev",
554+
expectedResult: false,
555+
},
556+
{
557+
workspaceVersion: "^1.2.3-dev",
558+
templateVersion: ">= 1.2.3",
559+
expectedResult: true,
560+
},
561+
{
562+
workspaceVersion: "3.0.0-next.0",
563+
templateVersion: "^3.0.0-next.0",
564+
expectedResult: false,
565+
},
566+
];
567+
568+
for (const {
569+
workspaceVersion,
570+
templateVersion,
571+
expectedResult,
572+
} of testCases) {
573+
it(`should return ${expectedResult} when workspace version is ${workspaceVersion} and template version is ${templateVersion}`, () => {
574+
assert.equal(
575+
shouldUpdateDependency(workspaceVersion, templateVersion),
576+
expectedResult,
577+
);
578+
});
579+
}
580+
});

0 commit comments

Comments
 (0)