Son CV dans un terminal web en Javascript!
https://terminal-cv.gregandev.fr
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
930 lines
26 KiB
930 lines
26 KiB
2 years ago
|
// @flow
|
||
|
import assert from 'assert';
|
||
|
import nullthrows from 'nullthrows';
|
||
|
import path from 'path';
|
||
|
import ParcelConfig from '../src/ParcelConfig';
|
||
|
import {
|
||
|
validateConfigFile,
|
||
|
mergePipelines,
|
||
|
mergeMaps,
|
||
|
mergeConfigs,
|
||
|
resolveExtends,
|
||
|
parseAndProcessConfig,
|
||
|
resolveParcelConfig,
|
||
|
processConfig,
|
||
|
} from '../src/requests/ParcelConfigRequest';
|
||
|
import {validatePackageName} from '../src/ParcelConfig.schema';
|
||
|
import {DEFAULT_OPTIONS, relative} from './test-utils';
|
||
|
import {toProjectPath} from '../src/projectPath';
|
||
|
|
||
|
describe('ParcelConfigRequest', () => {
|
||
|
describe('validatePackageName', () => {
|
||
|
it('should error on an invalid official package', () => {
|
||
|
assert.throws(() => {
|
||
|
validatePackageName('@parcel/foo-bar', 'transform', 'transformers');
|
||
|
}, /Official parcel transform packages must be named according to "@parcel\/transform-{name}"/);
|
||
|
|
||
|
assert.throws(() => {
|
||
|
validatePackageName('@parcel/transformer', 'transform', 'transformers');
|
||
|
}, /Official parcel transform packages must be named according to "@parcel\/transform-{name}"/);
|
||
|
});
|
||
|
|
||
|
it('should succeed on a valid official package', () => {
|
||
|
validatePackageName('@parcel/transform-bar', 'transform', 'transformers');
|
||
|
});
|
||
|
|
||
|
it('should error on an invalid community package', () => {
|
||
|
assert.throws(() => {
|
||
|
validatePackageName('foo-bar', 'transform', 'transformers');
|
||
|
}, /Parcel transform packages must be named according to "parcel-transform-{name}"/);
|
||
|
|
||
|
assert.throws(() => {
|
||
|
validatePackageName('parcel-foo-bar', 'transform', 'transformers');
|
||
|
}, /Parcel transform packages must be named according to "parcel-transform-{name}"/);
|
||
|
|
||
|
assert.throws(() => {
|
||
|
validatePackageName('parcel-transform', 'transform', 'transformers');
|
||
|
}, /Parcel transform packages must be named according to "parcel-transform-{name}"/);
|
||
|
});
|
||
|
|
||
|
it('should succeed on a valid community package', () => {
|
||
|
validatePackageName('parcel-transform-bar', 'transform', 'transformers');
|
||
|
});
|
||
|
|
||
|
it('should error on an invalid scoped package', () => {
|
||
|
assert.throws(() => {
|
||
|
validatePackageName('@test/foo-bar', 'transform', 'transformers');
|
||
|
}, /Scoped parcel transform packages must be named according to "@test\/parcel-transform\[-{name}\]"/);
|
||
|
|
||
|
assert.throws(() => {
|
||
|
validatePackageName(
|
||
|
'@test/parcel-foo-bar',
|
||
|
'transform',
|
||
|
'transformers',
|
||
|
);
|
||
|
}, /Scoped parcel transform packages must be named according to "@test\/parcel-transform\[-{name}\]"/);
|
||
|
});
|
||
|
|
||
|
it('should succeed on a valid scoped package', () => {
|
||
|
validatePackageName(
|
||
|
'@test/parcel-transform-bar',
|
||
|
'transform',
|
||
|
'transformers',
|
||
|
);
|
||
|
|
||
|
validatePackageName(
|
||
|
'@test/parcel-transform',
|
||
|
'transform',
|
||
|
'transformers',
|
||
|
);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('validateConfigFile', () => {
|
||
|
it('should throw on invalid config', () => {
|
||
|
assert.throws(() => {
|
||
|
validateConfigFile(
|
||
|
{
|
||
|
filePath: '.parcelrc',
|
||
|
extends: 'parcel-config-foo',
|
||
|
transformers: {
|
||
|
'*.js': ['parcel-invalid-plugin'],
|
||
|
},
|
||
|
},
|
||
|
'.parcelrc',
|
||
|
);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should require pipeline to be an array', () => {
|
||
|
assert.throws(() => {
|
||
|
validateConfigFile(
|
||
|
// $FlowExpectedError[incompatible-call]
|
||
|
{
|
||
|
filePath: '.parcelrc',
|
||
|
resolvers: '123',
|
||
|
},
|
||
|
'.parcelrc',
|
||
|
);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should require pipeline elements to be strings', () => {
|
||
|
assert.throws(() => {
|
||
|
validateConfigFile(
|
||
|
{
|
||
|
filePath: '.parcelrc',
|
||
|
// $FlowExpectedError[incompatible-call]
|
||
|
resolvers: [1, '123', 5],
|
||
|
},
|
||
|
'.parcelrc',
|
||
|
);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should require package names to be valid', () => {
|
||
|
assert.throws(() => {
|
||
|
validateConfigFile(
|
||
|
{
|
||
|
filePath: '.parcelrc',
|
||
|
resolvers: ['parcel-foo-bar'],
|
||
|
},
|
||
|
'.parcelrc',
|
||
|
);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should succeed with an array of valid package names', () => {
|
||
|
validateConfigFile(
|
||
|
{
|
||
|
filePath: '.parcelrc',
|
||
|
resolvers: ['parcel-resolver-test'],
|
||
|
},
|
||
|
'.parcelrc',
|
||
|
);
|
||
|
});
|
||
|
|
||
|
it('should support spread elements', () => {
|
||
|
validateConfigFile(
|
||
|
{
|
||
|
filePath: '.parcelrc',
|
||
|
resolvers: ['parcel-resolver-test', '...'],
|
||
|
},
|
||
|
'.parcelrc',
|
||
|
);
|
||
|
});
|
||
|
|
||
|
it('should require glob map to be an object', () => {
|
||
|
assert.throws(() => {
|
||
|
validateConfigFile(
|
||
|
{
|
||
|
filePath: '.parcelrc',
|
||
|
// $FlowExpectedError[incompatible-call]
|
||
|
transformers: ['parcel-transformer-test', '...'],
|
||
|
},
|
||
|
'.parcelrc',
|
||
|
);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should trigger the validator function for each key', () => {
|
||
|
assert.throws(() => {
|
||
|
validateConfigFile(
|
||
|
{
|
||
|
filePath: '.parcelrc',
|
||
|
transformers: {
|
||
|
'types:*.{ts,tsx}': ['@parcel/transformer-typescript-types'],
|
||
|
'bundle-text:*': ['-inline-string', '...'],
|
||
|
},
|
||
|
},
|
||
|
'.parcelrc',
|
||
|
);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should require extends to be a string or array of strings', () => {
|
||
|
assert.throws(() => {
|
||
|
validateConfigFile(
|
||
|
// $FlowExpectedError[incompatible-call]
|
||
|
{
|
||
|
filePath: '.parcelrc',
|
||
|
extends: 2,
|
||
|
},
|
||
|
'.parcelrc',
|
||
|
);
|
||
|
});
|
||
|
|
||
|
assert.throws(() => {
|
||
|
validateConfigFile(
|
||
|
{
|
||
|
filePath: '.parcelrc',
|
||
|
// $FlowExpectedError[incompatible-call]
|
||
|
extends: [2, 7],
|
||
|
},
|
||
|
'.parcelrc',
|
||
|
);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should support relative paths', () => {
|
||
|
validateConfigFile(
|
||
|
{
|
||
|
filePath: '.parcelrc',
|
||
|
extends: './foo',
|
||
|
},
|
||
|
'.parcelrc',
|
||
|
);
|
||
|
|
||
|
validateConfigFile(
|
||
|
{
|
||
|
filePath: '.parcelrc',
|
||
|
extends: ['./foo', './bar'],
|
||
|
},
|
||
|
'.parcelrc',
|
||
|
);
|
||
|
});
|
||
|
|
||
|
it('should validate package names', () => {
|
||
|
assert.throws(() => {
|
||
|
validateConfigFile(
|
||
|
{
|
||
|
filePath: '.parcelrc',
|
||
|
extends: 'foo',
|
||
|
},
|
||
|
'.parcelrc',
|
||
|
);
|
||
|
});
|
||
|
|
||
|
assert.throws(() => {
|
||
|
validateConfigFile(
|
||
|
{
|
||
|
filePath: '.parcelrc',
|
||
|
extends: ['foo', 'bar'],
|
||
|
},
|
||
|
'.parcelrc',
|
||
|
);
|
||
|
});
|
||
|
|
||
|
validateConfigFile(
|
||
|
{
|
||
|
filePath: '.parcelrc',
|
||
|
extends: 'parcel-config-foo',
|
||
|
},
|
||
|
'.parcelrc',
|
||
|
);
|
||
|
|
||
|
validateConfigFile(
|
||
|
{
|
||
|
filePath: '.parcelrc',
|
||
|
extends: ['parcel-config-foo', 'parcel-config-bar'],
|
||
|
},
|
||
|
'.parcelrc',
|
||
|
);
|
||
|
});
|
||
|
|
||
|
it('should throw for invalid top level keys', () => {
|
||
|
assert.throws(
|
||
|
() => {
|
||
|
validateConfigFile(
|
||
|
// $FlowExpectedError
|
||
|
{
|
||
|
extends: '@parcel/config-default',
|
||
|
'@parcel/transformer-js': {
|
||
|
inlineEnvironment: false,
|
||
|
},
|
||
|
},
|
||
|
'.parcelrc',
|
||
|
);
|
||
|
},
|
||
|
e => {
|
||
|
assert.strictEqual(
|
||
|
e.diagnostics[0].codeFrames[0].codeHighlights[0].message,
|
||
|
`Did you mean "transformers"?`,
|
||
|
);
|
||
|
return true;
|
||
|
},
|
||
|
);
|
||
|
});
|
||
|
|
||
|
it('should succeed on valid config', () => {
|
||
|
validateConfigFile(
|
||
|
{
|
||
|
filePath: '.parcelrc',
|
||
|
extends: 'parcel-config-foo',
|
||
|
transformers: {
|
||
|
'*.js': ['parcel-transformer-foo'],
|
||
|
},
|
||
|
},
|
||
|
'.parcelrc',
|
||
|
);
|
||
|
});
|
||
|
|
||
|
it('should throw error on empty config file', () => {
|
||
|
assert.throws(() => {
|
||
|
validateConfigFile({}, '.parcelrc');
|
||
|
}, /.parcelrc can't be empty/);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('mergePipelines', () => {
|
||
|
it('should return an empty array if base and extension are null', () => {
|
||
|
assert.deepEqual(mergePipelines(null, null), []);
|
||
|
});
|
||
|
|
||
|
it('should return base if extension is null', () => {
|
||
|
assert.deepEqual(
|
||
|
mergePipelines(
|
||
|
[
|
||
|
{
|
||
|
packageName: 'parcel-transform-foo',
|
||
|
resolveFrom: toProjectPath('/', '/.parcelrc'),
|
||
|
keyPath: '/transformers/*.js/0',
|
||
|
},
|
||
|
],
|
||
|
null,
|
||
|
),
|
||
|
[
|
||
|
{
|
||
|
packageName: 'parcel-transform-foo',
|
||
|
resolveFrom: '.parcelrc',
|
||
|
keyPath: '/transformers/*.js/0',
|
||
|
},
|
||
|
],
|
||
|
);
|
||
|
});
|
||
|
|
||
|
it('should return extension if base is null', () => {
|
||
|
assert.deepEqual(
|
||
|
mergePipelines(null, [
|
||
|
{
|
||
|
packageName: 'parcel-transform-bar',
|
||
|
resolveFrom: toProjectPath('/', '/.parcelrc'),
|
||
|
keyPath: '/transformers/*.js/0',
|
||
|
},
|
||
|
]),
|
||
|
[
|
||
|
{
|
||
|
packageName: 'parcel-transform-bar',
|
||
|
resolveFrom: '.parcelrc',
|
||
|
keyPath: '/transformers/*.js/0',
|
||
|
},
|
||
|
],
|
||
|
);
|
||
|
});
|
||
|
|
||
|
it('should return extension if there are no spread elements', () => {
|
||
|
assert.deepEqual(
|
||
|
mergePipelines(
|
||
|
[
|
||
|
{
|
||
|
packageName: 'parcel-transform-foo',
|
||
|
resolveFrom: toProjectPath('/', '/.parcelrc'),
|
||
|
keyPath: '/transformers/*.js/0',
|
||
|
},
|
||
|
],
|
||
|
[
|
||
|
{
|
||
|
packageName: 'parcel-transform-bar',
|
||
|
resolveFrom: toProjectPath('/', '/.parcelrc'),
|
||
|
keyPath: '/transformers/*.js/0',
|
||
|
},
|
||
|
],
|
||
|
),
|
||
|
[
|
||
|
{
|
||
|
packageName: 'parcel-transform-bar',
|
||
|
resolveFrom: '.parcelrc',
|
||
|
keyPath: '/transformers/*.js/0',
|
||
|
},
|
||
|
],
|
||
|
);
|
||
|
});
|
||
|
|
||
|
it('should return merge base into extension if there are spread elements', () => {
|
||
|
assert.deepEqual(
|
||
|
mergePipelines(
|
||
|
[
|
||
|
{
|
||
|
packageName: 'parcel-transform-foo',
|
||
|
resolveFrom: toProjectPath('/', '/.parcelrc'),
|
||
|
keyPath: '/transformers/*.js/0',
|
||
|
},
|
||
|
],
|
||
|
[
|
||
|
{
|
||
|
packageName: 'parcel-transform-bar',
|
||
|
resolveFrom: toProjectPath('/', '/.parcelrc'),
|
||
|
keyPath: '/transformers/*.js/0',
|
||
|
},
|
||
|
'...',
|
||
|
{
|
||
|
packageName: 'parcel-transform-baz',
|
||
|
resolveFrom: toProjectPath('/', '/.parcelrc'),
|
||
|
keyPath: '/transformers/*.js/2',
|
||
|
},
|
||
|
],
|
||
|
),
|
||
|
[
|
||
|
{
|
||
|
packageName: 'parcel-transform-bar',
|
||
|
resolveFrom: '.parcelrc',
|
||
|
keyPath: '/transformers/*.js/0',
|
||
|
},
|
||
|
{
|
||
|
packageName: 'parcel-transform-foo',
|
||
|
resolveFrom: '.parcelrc',
|
||
|
keyPath: '/transformers/*.js/0',
|
||
|
},
|
||
|
{
|
||
|
packageName: 'parcel-transform-baz',
|
||
|
resolveFrom: '.parcelrc',
|
||
|
keyPath: '/transformers/*.js/2',
|
||
|
},
|
||
|
],
|
||
|
);
|
||
|
});
|
||
|
|
||
|
it('should throw if more than one spread element is in a pipeline', () => {
|
||
|
assert.throws(() => {
|
||
|
mergePipelines(
|
||
|
[
|
||
|
{
|
||
|
packageName: 'parcel-transform-foo',
|
||
|
resolveFrom: toProjectPath('/', '/.parcelrc'),
|
||
|
keyPath: '/transformers/*.js/0',
|
||
|
},
|
||
|
],
|
||
|
[
|
||
|
{
|
||
|
packageName: 'parcel-transform-bar',
|
||
|
resolveFrom: toProjectPath('/', '/.parcelrc'),
|
||
|
keyPath: '/transformers/*.js/0',
|
||
|
},
|
||
|
'...',
|
||
|
{
|
||
|
packageName: 'parcel-transform-baz',
|
||
|
resolveFrom: toProjectPath('/', '/.parcelrc'),
|
||
|
keyPath: '/transformers/*.js/2',
|
||
|
},
|
||
|
'...',
|
||
|
],
|
||
|
);
|
||
|
}, /Only one spread element can be included in a config pipeline/);
|
||
|
});
|
||
|
|
||
|
it('should remove spread element even without a base map', () => {
|
||
|
assert.deepEqual(
|
||
|
mergePipelines(null, [
|
||
|
{
|
||
|
packageName: 'parcel-transform-bar',
|
||
|
resolveFrom: toProjectPath('/', '/.parcelrc'),
|
||
|
keyPath: '/transformers/*.js/0',
|
||
|
},
|
||
|
'...',
|
||
|
{
|
||
|
packageName: 'parcel-transform-baz',
|
||
|
resolveFrom: toProjectPath('/', '/.parcelrc'),
|
||
|
keyPath: '/transformers/*.js/2',
|
||
|
},
|
||
|
]),
|
||
|
[
|
||
|
{
|
||
|
packageName: 'parcel-transform-bar',
|
||
|
resolveFrom: '.parcelrc',
|
||
|
keyPath: '/transformers/*.js/0',
|
||
|
},
|
||
|
{
|
||
|
packageName: 'parcel-transform-baz',
|
||
|
resolveFrom: '.parcelrc',
|
||
|
keyPath: '/transformers/*.js/2',
|
||
|
},
|
||
|
],
|
||
|
);
|
||
|
});
|
||
|
|
||
|
it('should throw if more than one spread element is in a pipeline even without a base map', () => {
|
||
|
assert.throws(() => {
|
||
|
mergePipelines(null, [
|
||
|
{
|
||
|
packageName: 'parcel-transform-bar',
|
||
|
resolveFrom: toProjectPath('/', '/.parcelrc'),
|
||
|
keyPath: '/transformers/*.js/0',
|
||
|
},
|
||
|
'...',
|
||
|
{
|
||
|
packageName: 'parcel-transform-baz',
|
||
|
resolveFrom: toProjectPath('/', '/.parcelrc'),
|
||
|
keyPath: '/transformers/*.js/2',
|
||
|
},
|
||
|
'...',
|
||
|
]);
|
||
|
}, /Only one spread element can be included in a config pipeline/);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('mergeMaps', () => {
|
||
|
it('should return an empty object if base and extension are null', () => {
|
||
|
assert.deepEqual(mergeMaps(null, null), {});
|
||
|
});
|
||
|
|
||
|
it('should return base if extension is null', () => {
|
||
|
assert.deepEqual(mergeMaps({'*.js': 'foo'}, null), {
|
||
|
'*.js': 'foo',
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should return extension if base is null', () => {
|
||
|
assert.deepEqual(mergeMaps(null, {'*.js': 'foo'}), {
|
||
|
'*.js': 'foo',
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should merge the objects', () => {
|
||
|
assert.deepEqual(
|
||
|
mergeMaps({'*.css': 'css', '*.js': 'base-js'}, {'*.js': 'ext-js'}),
|
||
|
{'*.js': 'ext-js', '*.css': 'css'},
|
||
|
);
|
||
|
});
|
||
|
|
||
|
it('should ensure that extension properties have a higher precedence than base properties', () => {
|
||
|
let merged = mergeMaps({'*.{js,jsx}': 'base-js'}, {'*.js': 'ext-js'});
|
||
|
assert.deepEqual(merged, {'*.js': 'ext-js', '*.{js,jsx}': 'base-js'});
|
||
|
assert.deepEqual(Object.keys(merged), ['*.js', '*.{js,jsx}']);
|
||
|
});
|
||
|
|
||
|
it('should call a merger function if provided', () => {
|
||
|
let merger = (a, b) => [a, b];
|
||
|
assert.deepEqual(
|
||
|
mergeMaps({'*.js': 'base-js'}, {'*.js': 'ext-js'}, merger),
|
||
|
{'*.js': ['base-js', 'ext-js']},
|
||
|
);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('mergeConfigs', () => {
|
||
|
it('should merge configs', () => {
|
||
|
let base = new ParcelConfig(
|
||
|
{
|
||
|
filePath: toProjectPath('/', '/.parcelrc'),
|
||
|
resolvers: [
|
||
|
{
|
||
|
packageName: 'parcel-resolver-base',
|
||
|
resolveFrom: toProjectPath('/', '/.parcelrc'),
|
||
|
keyPath: '/resolvers/0',
|
||
|
},
|
||
|
],
|
||
|
transformers: {
|
||
|
'*.js': [
|
||
|
{
|
||
|
packageName: 'parcel-transform-base',
|
||
|
resolveFrom: toProjectPath('/', '/.parcelrc'),
|
||
|
keyPath: '/transformers/*.js/0',
|
||
|
},
|
||
|
],
|
||
|
'*.css': [
|
||
|
{
|
||
|
packageName: 'parcel-transform-css',
|
||
|
resolveFrom: toProjectPath('/', '/.parcelrc'),
|
||
|
keyPath: '/transformers/*.css/0',
|
||
|
},
|
||
|
],
|
||
|
},
|
||
|
bundler: {
|
||
|
packageName: 'parcel-bundler-base',
|
||
|
resolveFrom: toProjectPath('/', '/.parcelrc'),
|
||
|
keyPath: '/bundler',
|
||
|
},
|
||
|
},
|
||
|
DEFAULT_OPTIONS,
|
||
|
);
|
||
|
|
||
|
let ext = {
|
||
|
filePath: '.parcelrc',
|
||
|
resolvers: [
|
||
|
{
|
||
|
packageName: 'parcel-resolver-ext',
|
||
|
resolveFrom: '.parcelrc',
|
||
|
keyPath: '/resolvers/0',
|
||
|
},
|
||
|
'...',
|
||
|
],
|
||
|
transformers: {
|
||
|
'*.js': [
|
||
|
{
|
||
|
packageName: 'parcel-transform-ext',
|
||
|
resolveFrom: '.parcelrc',
|
||
|
keyPath: '/transformers/*.js/0',
|
||
|
},
|
||
|
'...',
|
||
|
],
|
||
|
},
|
||
|
};
|
||
|
|
||
|
let merged = {
|
||
|
filePath: '.parcelrc',
|
||
|
resolvers: [
|
||
|
{
|
||
|
packageName: 'parcel-resolver-ext',
|
||
|
resolveFrom: '.parcelrc',
|
||
|
keyPath: '/resolvers/0',
|
||
|
},
|
||
|
{
|
||
|
packageName: 'parcel-resolver-base',
|
||
|
resolveFrom: '.parcelrc',
|
||
|
keyPath: '/resolvers/0',
|
||
|
},
|
||
|
],
|
||
|
transformers: {
|
||
|
'*.js': [
|
||
|
{
|
||
|
packageName: 'parcel-transform-ext',
|
||
|
resolveFrom: '.parcelrc',
|
||
|
keyPath: '/transformers/*.js/0',
|
||
|
},
|
||
|
{
|
||
|
packageName: 'parcel-transform-base',
|
||
|
resolveFrom: '.parcelrc',
|
||
|
keyPath: '/transformers/*.js/0',
|
||
|
},
|
||
|
],
|
||
|
'*.css': [
|
||
|
{
|
||
|
packageName: 'parcel-transform-css',
|
||
|
resolveFrom: '.parcelrc',
|
||
|
keyPath: '/transformers/*.css/0',
|
||
|
},
|
||
|
],
|
||
|
},
|
||
|
bundler: {
|
||
|
packageName: 'parcel-bundler-base',
|
||
|
resolveFrom: '.parcelrc',
|
||
|
keyPath: '/bundler',
|
||
|
},
|
||
|
runtimes: [],
|
||
|
namers: [],
|
||
|
optimizers: {},
|
||
|
compressors: {},
|
||
|
packagers: {},
|
||
|
reporters: [],
|
||
|
validators: {},
|
||
|
};
|
||
|
|
||
|
// $FlowFixMe
|
||
|
assert.deepEqual(mergeConfigs(base, ext), merged);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('resolveExtends', () => {
|
||
|
it('should resolve a relative path', async () => {
|
||
|
let resolved = await resolveExtends(
|
||
|
'../.parcelrc',
|
||
|
path.join(__dirname, 'fixtures', 'config', 'subfolder', '.parcelrc'),
|
||
|
'/extends',
|
||
|
DEFAULT_OPTIONS,
|
||
|
);
|
||
|
assert.equal(
|
||
|
resolved,
|
||
|
path.join(__dirname, 'fixtures', 'config', '.parcelrc'),
|
||
|
);
|
||
|
});
|
||
|
|
||
|
it('should resolve a package name', async () => {
|
||
|
let resolved = await resolveExtends(
|
||
|
'@parcel/config-default',
|
||
|
path.join(__dirname, 'fixtures', 'config', 'subfolder', '.parcelrc'),
|
||
|
'/extends',
|
||
|
DEFAULT_OPTIONS,
|
||
|
);
|
||
|
assert.equal(resolved, require.resolve('@parcel/config-default'));
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('parseAndProcessConfig', () => {
|
||
|
it('should load and merge configs', async () => {
|
||
|
let defaultConfigPath = require.resolve('@parcel/config-default');
|
||
|
let defaultConfig = await processConfig(
|
||
|
{
|
||
|
...require('@parcel/config-default'),
|
||
|
filePath: defaultConfigPath,
|
||
|
},
|
||
|
DEFAULT_OPTIONS,
|
||
|
);
|
||
|
let configFilePath = path.join(
|
||
|
__dirname,
|
||
|
'fixtures',
|
||
|
'config',
|
||
|
'.parcelrc',
|
||
|
);
|
||
|
let subConfigFilePath = path.join(
|
||
|
__dirname,
|
||
|
'fixtures',
|
||
|
'config',
|
||
|
'subfolder',
|
||
|
'.parcelrc',
|
||
|
);
|
||
|
let {config} = await parseAndProcessConfig(
|
||
|
subConfigFilePath,
|
||
|
DEFAULT_OPTIONS.inputFS.readFileSync(subConfigFilePath, 'utf8'),
|
||
|
DEFAULT_OPTIONS,
|
||
|
);
|
||
|
|
||
|
let transformers = nullthrows(config.transformers);
|
||
|
assert.deepEqual(transformers['*.js'], [
|
||
|
{
|
||
|
packageName: 'parcel-transformer-sub',
|
||
|
resolveFrom: relative(subConfigFilePath),
|
||
|
keyPath: '/transformers/*.js/0',
|
||
|
},
|
||
|
{
|
||
|
packageName: 'parcel-transformer-base',
|
||
|
resolveFrom: relative(configFilePath),
|
||
|
keyPath: '/transformers/*.js/0',
|
||
|
},
|
||
|
'...',
|
||
|
]);
|
||
|
assert(Object.keys(transformers).length > 1);
|
||
|
assert.deepEqual(config.resolvers, defaultConfig.resolvers);
|
||
|
assert.deepEqual(config.bundler, defaultConfig.bundler);
|
||
|
assert.deepEqual(config.namers, defaultConfig.namers || []);
|
||
|
assert.deepEqual(config.packagers, defaultConfig.packagers || {});
|
||
|
assert.deepEqual(config.optimizers, defaultConfig.optimizers || {});
|
||
|
assert.deepEqual(config.reporters, defaultConfig.reporters || []);
|
||
|
});
|
||
|
|
||
|
it('should emit a codeframe.codeHighlights when a malformed .parcelrc was found', async () => {
|
||
|
let configFilePath = path.join(
|
||
|
__dirname,
|
||
|
'fixtures',
|
||
|
'config-malformed',
|
||
|
'.parcelrc',
|
||
|
);
|
||
|
let code = await DEFAULT_OPTIONS.inputFS.readFile(configFilePath, 'utf8');
|
||
|
|
||
|
let pos = {
|
||
|
line: 2,
|
||
|
column: 14,
|
||
|
};
|
||
|
|
||
|
// $FlowFixMe[prop-missing]
|
||
|
await assert.rejects(
|
||
|
() => parseAndProcessConfig(configFilePath, code, DEFAULT_OPTIONS),
|
||
|
{
|
||
|
name: 'Error',
|
||
|
diagnostics: [
|
||
|
{
|
||
|
message: 'Failed to parse .parcelrc',
|
||
|
origin: '@parcel/core',
|
||
|
codeFrames: [
|
||
|
{
|
||
|
filePath: configFilePath,
|
||
|
language: 'json5',
|
||
|
code,
|
||
|
codeHighlights: [
|
||
|
{
|
||
|
message: "JSON5: invalid character 'b' at 2:14",
|
||
|
start: pos,
|
||
|
end: pos,
|
||
|
},
|
||
|
],
|
||
|
},
|
||
|
],
|
||
|
},
|
||
|
],
|
||
|
},
|
||
|
);
|
||
|
});
|
||
|
|
||
|
it('should emit a codeframe when an extended parcel config file is not found', async () => {
|
||
|
let configFilePath = path.join(
|
||
|
__dirname,
|
||
|
'fixtures',
|
||
|
'config-extends-not-found',
|
||
|
'.parcelrc',
|
||
|
);
|
||
|
let code = await DEFAULT_OPTIONS.inputFS.readFile(configFilePath, 'utf8');
|
||
|
|
||
|
// $FlowFixMe[prop-missing]
|
||
|
await assert.rejects(
|
||
|
() => parseAndProcessConfig(configFilePath, code, DEFAULT_OPTIONS),
|
||
|
{
|
||
|
name: 'Error',
|
||
|
diagnostics: [
|
||
|
{
|
||
|
message: 'Cannot find extended parcel config',
|
||
|
origin: '@parcel/core',
|
||
|
codeFrames: [
|
||
|
{
|
||
|
filePath: configFilePath,
|
||
|
language: 'json5',
|
||
|
code,
|
||
|
codeHighlights: [
|
||
|
{
|
||
|
message:
|
||
|
'"./.parclrc-node-modules" does not exist, did you mean "./.parcelrc-node-modules"?',
|
||
|
start: {line: 2, column: 14},
|
||
|
end: {line: 2, column: 38},
|
||
|
},
|
||
|
],
|
||
|
},
|
||
|
],
|
||
|
},
|
||
|
],
|
||
|
},
|
||
|
);
|
||
|
});
|
||
|
|
||
|
it('should emit a codeframe when an extended parcel config node module is not found', async () => {
|
||
|
let configFilePath = path.join(
|
||
|
__dirname,
|
||
|
'fixtures',
|
||
|
'config-extends-not-found',
|
||
|
'.parcelrc-node-modules',
|
||
|
);
|
||
|
let code = await DEFAULT_OPTIONS.inputFS.readFile(configFilePath, 'utf8');
|
||
|
|
||
|
// $FlowFixMe[prop-missing]
|
||
|
await assert.rejects(
|
||
|
() => parseAndProcessConfig(configFilePath, code, DEFAULT_OPTIONS),
|
||
|
{
|
||
|
name: 'Error',
|
||
|
diagnostics: [
|
||
|
{
|
||
|
message: 'Cannot find extended parcel config',
|
||
|
origin: '@parcel/core',
|
||
|
codeFrames: [
|
||
|
{
|
||
|
filePath: configFilePath,
|
||
|
language: 'json5',
|
||
|
code,
|
||
|
codeHighlights: [
|
||
|
{
|
||
|
message:
|
||
|
'Cannot find module "@parcel/config-deflt", did you mean "@parcel/config-default"?',
|
||
|
start: {line: 2, column: 14},
|
||
|
end: {line: 2, column: 35},
|
||
|
},
|
||
|
],
|
||
|
},
|
||
|
],
|
||
|
},
|
||
|
],
|
||
|
},
|
||
|
);
|
||
|
});
|
||
|
|
||
|
it('should emit multiple codeframes when multiple extended configs are not found', async () => {
|
||
|
let configFilePath = path.join(
|
||
|
__dirname,
|
||
|
'fixtures',
|
||
|
'config-extends-not-found',
|
||
|
'.parcelrc-multiple',
|
||
|
);
|
||
|
let code = await DEFAULT_OPTIONS.inputFS.readFile(configFilePath, 'utf8');
|
||
|
|
||
|
// $FlowFixMe[prop-missing]
|
||
|
await assert.rejects(
|
||
|
() => parseAndProcessConfig(configFilePath, code, DEFAULT_OPTIONS),
|
||
|
{
|
||
|
name: 'Error',
|
||
|
diagnostics: [
|
||
|
{
|
||
|
message: 'Cannot find extended parcel config',
|
||
|
origin: '@parcel/core',
|
||
|
codeFrames: [
|
||
|
{
|
||
|
filePath: configFilePath,
|
||
|
language: 'json5',
|
||
|
code,
|
||
|
codeHighlights: [
|
||
|
{
|
||
|
message:
|
||
|
'Cannot find module "@parcel/config-deflt", did you mean "@parcel/config-default"?',
|
||
|
start: {line: 2, column: 15},
|
||
|
end: {line: 2, column: 36},
|
||
|
},
|
||
|
],
|
||
|
},
|
||
|
],
|
||
|
},
|
||
|
{
|
||
|
message: 'Cannot find extended parcel config',
|
||
|
origin: '@parcel/core',
|
||
|
codeFrames: [
|
||
|
{
|
||
|
filePath: configFilePath,
|
||
|
language: 'json5',
|
||
|
code,
|
||
|
codeHighlights: [
|
||
|
{
|
||
|
message:
|
||
|
'"./.parclrc" does not exist, did you mean "./.parcelrc"?',
|
||
|
start: {line: 2, column: 39},
|
||
|
end: {line: 2, column: 50},
|
||
|
},
|
||
|
],
|
||
|
},
|
||
|
],
|
||
|
},
|
||
|
],
|
||
|
},
|
||
|
);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('resolve', () => {
|
||
|
it('should return null if there is no .parcelrc file found', async () => {
|
||
|
let resolved = await resolveParcelConfig(DEFAULT_OPTIONS);
|
||
|
assert.equal(resolved, null);
|
||
|
});
|
||
|
|
||
|
it('should resolve a config if a .parcelrc file is found', async () => {
|
||
|
let resolved = await resolveParcelConfig({
|
||
|
...DEFAULT_OPTIONS,
|
||
|
projectRoot: path.join(__dirname, 'fixtures', 'config', 'subfolder'),
|
||
|
});
|
||
|
|
||
|
assert(resolved !== null);
|
||
|
});
|
||
|
});
|
||
|
});
|