animate/webGl/my-threejs-test/node_modules/@parcel/package-manager/test/NodePackageManager.test.js

385 lines
10 KiB
JavaScript

// @flow strict-local
import {MemoryFS, NodeFS, OverlayFS} from '@parcel/fs';
import assert from 'assert';
import invariant from 'assert';
import path from 'path';
import sinon from 'sinon';
import ThrowableDiagnostic from '@parcel/diagnostic';
import {loadConfig} from '@parcel/utils';
import WorkerFarm from '@parcel/workers';
import {MockPackageInstaller, NodePackageManager} from '../src';
const FIXTURES_DIR = path.join(__dirname, 'fixtures');
function normalize(res) {
return {
...res,
invalidateOnFileCreate:
res?.invalidateOnFileCreate?.sort((a, b) => {
let ax =
a.filePath ??
a.glob ??
(a.aboveFilePath != null && a.fileName != null
? a.aboveFilePath + a.fileName
: '');
let bx =
b.filePath ??
b.glob ??
(b.aboveFilePath != null && b.fileName != null
? b.aboveFilePath + b.fileName
: '');
return ax < bx ? -1 : 1;
}) ?? [],
};
}
function check(resolved, expected) {
assert.deepEqual(normalize(resolved), normalize(expected));
}
describe('NodePackageManager', function () {
let fs;
let packageManager;
let packageInstaller;
let workerFarm;
// These can sometimes take a lil while
this.timeout(20000);
beforeEach(() => {
workerFarm = new WorkerFarm({
workerPath: require.resolve('@parcel/core/src/worker.js'),
});
fs = new OverlayFS(new MemoryFS(workerFarm), new NodeFS());
packageInstaller = new MockPackageInstaller();
packageManager = new NodePackageManager(fs, '/', packageInstaller);
});
afterEach(async () => {
loadConfig.clear();
await workerFarm.end();
});
it('resolves packages that exist', async () => {
check(
await packageManager.resolve(
'foo',
path.join(FIXTURES_DIR, 'has-foo/index.js'),
),
{
pkg: {
version: '1.1.0',
},
resolved: path.join(FIXTURES_DIR, 'has-foo/node_modules/foo/index.js'),
type: 1,
invalidateOnFileChange: new Set([
path.join(FIXTURES_DIR, 'has-foo/node_modules/foo/package.json'),
]),
invalidateOnFileCreate: [
{
filePath: path.join(
FIXTURES_DIR,
'has-foo/node_modules/foo/index.ts',
),
},
{
filePath: path.join(
FIXTURES_DIR,
'has-foo/node_modules/foo/index.tsx',
),
},
{
fileName: 'node_modules/foo',
aboveFilePath: path.join(FIXTURES_DIR, 'has-foo'),
},
{
fileName: 'tsconfig.json',
aboveFilePath: path.join(FIXTURES_DIR, 'has-foo'),
},
],
},
);
});
it('requires packages that exist', async () => {
assert.deepEqual(
await packageManager.require(
'foo',
path.join(FIXTURES_DIR, 'has-foo/index.js'),
),
'foobar',
);
});
it("autoinstalls packages that don't exist", async () => {
packageInstaller.register('a', fs, path.join(FIXTURES_DIR, 'packages/a'));
check(
await packageManager.resolve(
'a',
path.join(FIXTURES_DIR, 'has-foo/index.js'),
{shouldAutoInstall: true},
),
{
pkg: {
name: 'a',
},
resolved: path.join(FIXTURES_DIR, 'has-foo/node_modules/a/index.js'),
type: 1,
invalidateOnFileChange: new Set([
path.join(FIXTURES_DIR, 'has-foo/node_modules/a/package.json'),
]),
invalidateOnFileCreate: [
{
filePath: path.join(
FIXTURES_DIR,
'has-foo/node_modules/a/index.ts',
),
},
{
filePath: path.join(
FIXTURES_DIR,
'has-foo/node_modules/a/index.tsx',
),
},
{
fileName: 'node_modules/a',
aboveFilePath: path.join(FIXTURES_DIR, 'has-foo'),
},
{
fileName: 'tsconfig.json',
aboveFilePath: path.join(FIXTURES_DIR, 'has-foo'),
},
],
},
);
});
it('does not autoinstall packages that are already listed in package.json', async () => {
packageInstaller.register('a', fs, path.join(FIXTURES_DIR, 'packages/a'));
// $FlowFixMe assert.rejects is Node 10+
await assert.rejects(
() =>
packageManager.resolve(
'a',
path.join(FIXTURES_DIR, 'has-a-not-yet-installed/index.js'),
{shouldAutoInstall: true},
),
err => {
invariant(err instanceof ThrowableDiagnostic);
assert(err.message.includes('Run your package manager'));
return true;
},
);
});
it('does not autoinstall peer dependencies that are already listed in package.json', async () => {
packageInstaller.register(
'peers',
fs,
path.join(FIXTURES_DIR, 'packages/peers'),
);
let spy = sinon.spy(packageInstaller, 'install');
await packageManager.resolve(
'peers',
path.join(FIXTURES_DIR, 'has-foo/index.js'),
{shouldAutoInstall: true},
);
assert.deepEqual(spy.args, [
[
{
cwd: path.join(FIXTURES_DIR, 'has-foo'),
packagePath: path.join(FIXTURES_DIR, 'has-foo/package.json'),
fs,
saveDev: true,
modules: [{name: 'peers', range: undefined}],
},
],
]);
});
it('autoinstalls peer dependencies that are not listed in package.json', async () => {
packageInstaller.register(
'foo',
fs,
path.join(FIXTURES_DIR, 'packages/foo-2.0'),
);
packageInstaller.register(
'peers',
fs,
path.join(FIXTURES_DIR, 'packages/peers-2.0'),
);
let spy = sinon.spy(packageInstaller, 'install');
await packageManager.resolve(
'peers',
path.join(FIXTURES_DIR, 'empty/index.js'),
{shouldAutoInstall: true},
);
assert.deepEqual(spy.args, [
[
{
cwd: path.join(FIXTURES_DIR, 'empty'),
packagePath: path.join(FIXTURES_DIR, 'empty/package.json'),
fs,
saveDev: true,
modules: [{name: 'peers', range: undefined}],
},
],
[
{
cwd: path.join(FIXTURES_DIR, 'empty'),
packagePath: path.join(FIXTURES_DIR, 'empty/package.json'),
fs,
saveDev: true,
modules: [{name: 'foo', range: '^2.0.0'}],
},
],
]);
});
describe('range mismatch', () => {
it("cannot autoinstall if there's a local requirement", async () => {
packageManager.invalidate(
'foo',
path.join(FIXTURES_DIR, 'has-foo/index.js'),
);
// $FlowFixMe assert.rejects is Node 10+
await assert.rejects(
() =>
packageManager.resolve(
'foo',
path.join(FIXTURES_DIR, 'has-foo/index.js'),
{
range: '^2.0.0',
},
),
err => {
invariant(err instanceof ThrowableDiagnostic);
assert.equal(
err.message,
'Could not find module "foo" satisfying ^2.0.0.',
);
return true;
},
);
});
it("can autoinstall into local package if there isn't a local requirement", async () => {
packageInstaller.register(
'foo',
fs,
path.join(FIXTURES_DIR, 'packages/foo-2.0'),
);
let spy = sinon.spy(packageInstaller, 'install');
check(
await packageManager.resolve(
'foo',
path.join(FIXTURES_DIR, 'has-foo/subpackage/index.js'),
{
range: '^2.0.0',
shouldAutoInstall: true,
},
),
{
pkg: {
name: 'foo',
version: '2.0.0',
},
resolved: path.join(
FIXTURES_DIR,
'has-foo/subpackage/node_modules/foo/index.js',
),
type: 1,
invalidateOnFileChange: new Set([
path.join(
FIXTURES_DIR,
'has-foo/subpackage/node_modules/foo/package.json',
),
]),
invalidateOnFileCreate: [
{
filePath: path.join(
FIXTURES_DIR,
'has-foo/subpackage/node_modules/foo/index.ts',
),
},
{
filePath: path.join(
FIXTURES_DIR,
'has-foo/subpackage/node_modules/foo/index.tsx',
),
},
{
fileName: 'node_modules/foo',
aboveFilePath: path.join(FIXTURES_DIR, 'has-foo/subpackage'),
},
{
fileName: 'tsconfig.json',
aboveFilePath: path.join(FIXTURES_DIR, 'has-foo/subpackage'),
},
],
},
);
assert.deepEqual(spy.args, [
[
{
cwd: path.join(FIXTURES_DIR, 'has-foo/subpackage'),
packagePath: path.join(
FIXTURES_DIR,
'has-foo/subpackage/package.json',
),
fs,
saveDev: true,
modules: [{name: 'foo', range: '^2.0.0'}],
},
],
]);
});
it("cannot autoinstall peer dependencies if there's an incompatible local requirement", async () => {
packageManager.invalidate(
'peers',
path.join(FIXTURES_DIR, 'has-foo/index.js'),
);
packageInstaller.register(
'foo',
fs,
path.join(FIXTURES_DIR, 'packages/foo-2.0'),
);
packageInstaller.register(
'peers',
fs,
path.join(FIXTURES_DIR, 'packages/peers-2.0'),
);
// $FlowFixMe assert.rejects is Node 10+
await assert.rejects(
() =>
packageManager.resolve(
'peers',
path.join(FIXTURES_DIR, 'has-foo/index.js'),
{
range: '^2.0.0',
shouldAutoInstall: true,
},
),
err => {
assert(err instanceof ThrowableDiagnostic);
assert.equal(
err.message,
'Could not install the peer dependency "foo" for "peers", installed version 1.1.0 is incompatible with ^2.0.0',
);
return true;
},
);
});
});
});