Skip to content

Commit

Permalink
refactor: cleanup package-utils
Browse files Browse the repository at this point in the history
  • Loading branch information
anshumanv committed Sep 22, 2020
1 parent 54116ae commit 60c1926
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 25 deletions.
80 changes: 80 additions & 0 deletions packages/utils/__tests__/index.test.ts
@@ -0,0 +1,80 @@
'use strict';

import { packageExists, promptInstallation, runCommand } from '../';
import ExternalCommand from '../../webpack-cli/lib/commands/ExternalCommand';

describe('@webpack-cli/utils', () => {
it('should check existence of package', () => {
// use an actual path relative to the packageUtils file
expect(packageExists('../lib/package-exists')).toBeTruthy();
expect(packageExists('./nonexistent-package')).toBeFalsy();
});

it('should not throw if the user interrupts', async () => {
(promptInstallation as jest.Mock).mockImplementation(() => {
throw new Error();
});
await expect(ExternalCommand.run('info')).resolves.not.toThrow();
});
});

describe('promptInstallation', () => {
let packageUtils;
beforeAll(() => {
packageUtils = require('../lib/');
packageUtils.getPackageManager = jest.fn();
packageUtils.packageExists = jest.fn(() => true);
});

beforeEach(() => {
(runCommand as jest.Mock).mockClear();
(prompt as jest.Mock).mockClear();
});

it('should prompt to install using npm if npm is package manager', async () => {
packageUtils.getPackageManager.mockReturnValue('npm');
(prompt as jest.Mock).mockReturnValue({
installConfirm: true,
});

const preMessage = jest.fn();
const promptResult = await packageUtils.promptInstallation('test-package', preMessage);
expect(promptResult).toBeTruthy();
expect(preMessage.mock.calls.length).toEqual(1);
expect((prompt as jest.Mock).mock.calls.length).toEqual(1);
expect((runCommand as jest.Mock).mock.calls.length).toEqual(1);
expect((prompt as jest.Mock).mock.calls[0][0][0].message).toMatch(/Would you like to install test-package\?/);
// install the package using npm
expect((runCommand as jest.Mock).mock.calls[0][0]).toEqual('npm install -D test-package');
});

it('should prompt to install using yarn if yarn is package manager', async () => {
packageUtils.getPackageManager.mockReturnValue('yarn');
(prompt as jest.Mock).mockReturnValue({
installConfirm: true,
});

const promptResult = await packageUtils.promptInstallation('test-package');
expect(promptResult).toBeTruthy();
expect((prompt as jest.Mock).mock.calls.length).toEqual(1);
expect((runCommand as jest.Mock).mock.calls.length).toEqual(1);
expect((prompt as jest.Mock).mock.calls[0][0][0].message).toMatch(/Would you like to install test-package\?/);
// install the package using yarn
expect((runCommand as jest.Mock).mock.calls[0][0]).toEqual('yarn add -D test-package');
});

it('should not install if install is not confirmed', async () => {
packageUtils.getPackageManager.mockReturnValue('npm');
(prompt as jest.Mock).mockReturnValue({
installConfirm: false,
});

const promptResult = await packageUtils.promptInstallation('test-package');
expect(promptResult).toBeUndefined();
expect((prompt as jest.Mock).mock.calls.length).toEqual(1);
// runCommand should not be called, because the installation is not confirmed
expect((runCommand as jest.Mock).mock.calls.length).toEqual(0);
expect((prompt as jest.Mock).mock.calls[0][0][0].message).toMatch(/Would you like to install test-package\?/);
expect(process.exitCode).toEqual(2);
});
});
1 change: 1 addition & 0 deletions packages/utils/src/index.ts
Expand Up @@ -13,3 +13,4 @@ export * from './global-packages-path';
export * from './get-package-manager';
export * from './package-exists';
export * from './run-command';
export * from './prompt-installation';
6 changes: 4 additions & 2 deletions packages/utils/src/prompt-installation.ts
@@ -1,6 +1,8 @@
import { prompt } from 'enquirer';
import { green } from 'colorette';
import { runCommand } from './run-command';
import { getPackageManager } from './get-package-manager';
import { packageExists } from './package-exists';

/**
*
Expand All @@ -9,7 +11,7 @@ import { runCommand } from './run-command';
*/
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
export async function promptInstallation(packageName: string, preMessage?: Function) {
const packageManager = exports.getPackageManager();
const packageManager = getPackageManager();
const options = [packageManager === 'yarn' ? 'add' : 'install', '-D', packageName];

const commandToBeRun = `${packageManager} ${options.join(' ')}`;
Expand All @@ -27,7 +29,7 @@ export async function promptInstallation(packageName: string, preMessage?: Funct
]);
if (installConfirm) {
await runCommand(commandToBeRun);
return exports.packageExists(packageName);
return packageExists(packageName);
}
// eslint-disable-next-line require-atomic-updates
process.exitCode = 2;
Expand Down
39 changes: 16 additions & 23 deletions yarn.lock
Expand Up @@ -2467,13 +2467,6 @@
resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==

"@types/cross-spawn@6.0.1":
version "6.0.1"
resolved "https://registry.yarnpkg.com/@types/cross-spawn/-/cross-spawn-6.0.1.tgz#60fa0c87046347c17d9735e5289e72b804ca9b63"
integrity sha512-MtN1pDYdI6D6QFDzy39Q+6c9rl2o/xN7aWGe6oZuzqq5N6+YuwFsWiEAv3dNzvzN9YzU+itpN8lBzFpphQKLAw==
dependencies:
"@types/node" "*"

"@types/cross-spawn@^6.0.2":
version "6.0.2"
resolved "https://registry.yarnpkg.com/@types/cross-spawn/-/cross-spawn-6.0.2.tgz#168309de311cd30a2b8ae720de6475c2fbf33ac7"
Expand Down Expand Up @@ -4688,15 +4681,6 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4:
safe-buffer "^5.0.1"
sha.js "^2.4.8"

cross-spawn@7.0.1, cross-spawn@^7.0.0:
version "7.0.1"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.1.tgz#0ab56286e0f7c24e153d04cc2aa027e43a9a5d14"
integrity sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==
dependencies:
path-key "^3.1.0"
shebang-command "^2.0.0"
which "^2.0.1"

cross-spawn@^6.0.0, cross-spawn@^6.0.5:
version "6.0.5"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
Expand All @@ -4708,6 +4692,15 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5:
shebang-command "^1.2.0"
which "^1.2.9"

cross-spawn@^7.0.0:
version "7.0.1"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.1.tgz#0ab56286e0f7c24e153d04cc2aa027e43a9a5d14"
integrity sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==
dependencies:
path-key "^3.1.0"
shebang-command "^2.0.0"
which "^2.0.1"

cross-spawn@^7.0.3:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
Expand Down Expand Up @@ -6362,13 +6355,6 @@ global-dirs@^0.1.1:
dependencies:
ini "^1.3.4"

global-modules@2.0.0, global-modules@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780"
integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==
dependencies:
global-prefix "^3.0.0"

global-modules@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea"
Expand All @@ -6378,6 +6364,13 @@ global-modules@^1.0.0:
is-windows "^1.0.1"
resolve-dir "^1.0.0"

global-modules@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780"
integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==
dependencies:
global-prefix "^3.0.0"

global-prefix@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe"
Expand Down

0 comments on commit 60c1926

Please sign in to comment.