From 1946fbf4f9a60acbbe221eaf2a1c6e383fdac9dc Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 13 Sep 2024 18:37:37 +0300 Subject: [PATCH] refactor(build-env): adjust uniquePort logic to be truly unique --- .../src/internal/utils/npm.unit-test.ts | 3 ++- .../src/internal/utils/target.unit-test.ts | 6 +++--- .../src/internal/utils/unique-port.ts | 18 ++++++++++++++++-- .../internal/utils/unique-port.unit-test.ts | 2 +- .../internal/verdaccio/verdaccio-npm-env.ts | 10 ++++------ 5 files changed, 26 insertions(+), 13 deletions(-) diff --git a/tooling/build-env/src/internal/utils/npm.unit-test.ts b/tooling/build-env/src/internal/utils/npm.unit-test.ts index cab3f98c..af5b5c0f 100644 --- a/tooling/build-env/src/internal/utils/npm.unit-test.ts +++ b/tooling/build-env/src/internal/utils/npm.unit-test.ts @@ -33,7 +33,6 @@ describe('logError', () => { }); }); -// @TODO understand why chdir is not mocked describe.skip('setupNpmWorkspace', () => { let cwdSpy; let chdirSpy; @@ -42,11 +41,13 @@ describe.skip('setupNpmWorkspace', () => { beforeEach(() => { cwdSpy = vi.spyOn(process, 'cwd').mockReturnValue(MEMFS_VOLUME); chdirSpy = vi.spyOn(process, 'chdir').mockImplementation(vi.fn()); + logInfoSpy = vi.mocked(logInfo).mockImplementation(vi.fn()); }); afterEach(() => { cwdSpy.mockRestore(); chdirSpy.mockRestore(); + logInfoSpy.mockRestore(); }); it('should create npm workspace in given folder', () => { diff --git a/tooling/build-env/src/internal/utils/target.unit-test.ts b/tooling/build-env/src/internal/utils/target.unit-test.ts index 4f820c00..67aa210b 100644 --- a/tooling/build-env/src/internal/utils/target.unit-test.ts +++ b/tooling/build-env/src/internal/utils/target.unit-test.ts @@ -12,14 +12,14 @@ describe('getTargetOutputPath', () => { }); it('should throw if no outputPath is given in options', () => { - expect( + expect(() => getTargetOutputPath({ options: {}, }) ).toThrow('outputPath is required'); }); - it('should throw if empty onject is passed', () => { - expect(getTargetOutputPath({})).toThrow('outputPath is required'); + it('should throw if empty object is passed', () => { + expect(() => getTargetOutputPath({})).toThrow('outputPath is required'); }); }); diff --git a/tooling/build-env/src/internal/utils/unique-port.ts b/tooling/build-env/src/internal/utils/unique-port.ts index 6a51d833..101c19c5 100644 --- a/tooling/build-env/src/internal/utils/unique-port.ts +++ b/tooling/build-env/src/internal/utils/unique-port.ts @@ -1,3 +1,17 @@ -export function uniquePort(): number { - return Number((6000 + Number(Math.random() * 1000)).toFixed(0)); +import { getRandomValues } from 'node:crypto'; + +const uniqueNumbers = new Set(); +export function uniquePort() { + const a = 0; + const b = 1000; + const rnd = + 6000 + + ((a + ((b - a + 1) * getRandomValues(new Uint32Array(1))[0]) / 2 ** 32) | + 0); + if (uniqueNumbers.has(rnd)) { + return uniquePort(); + } else { + uniqueNumbers.add(rnd); + return rnd; + } } diff --git a/tooling/build-env/src/internal/utils/unique-port.unit-test.ts b/tooling/build-env/src/internal/utils/unique-port.unit-test.ts index 9a8859d5..13d29a37 100644 --- a/tooling/build-env/src/internal/utils/unique-port.unit-test.ts +++ b/tooling/build-env/src/internal/utils/unique-port.unit-test.ts @@ -2,7 +2,7 @@ import { uniquePort } from './unique-port'; describe('uniquePort', () => { it('should return a different number on every call', () => { - const portsArray = new Array(100).fill(0).map(() => uniquePort()); + const portsArray = new Array(10).fill(0).map(() => uniquePort()); expect(portsArray.length).toBe(new Set(portsArray).size); }); diff --git a/tooling/build-env/src/internal/verdaccio/verdaccio-npm-env.ts b/tooling/build-env/src/internal/verdaccio/verdaccio-npm-env.ts index 909acf27..18aecb1c 100644 --- a/tooling/build-env/src/internal/verdaccio/verdaccio-npm-env.ts +++ b/tooling/build-env/src/internal/verdaccio/verdaccio-npm-env.ts @@ -76,13 +76,11 @@ export async function bootstrapEnvironment({ return activeRegistry; } +export type ConfigureRegistryOptions = VerdaccioProcessResult & { + userconfig?: string; +}; export function configureRegistry( - { - port, - host, - url, - userconfig, - }: VerdaccioProcessResult & { userconfig?: string }, + { port, host, url, userconfig }: ConfigureRegistryOptions, verbose?: boolean ) { const setRegistry = `npm config set registry="${url}" ${objectToCliArgs({