dpdm-fast
Version:
Analyze circular dependencies in your JavaScript/TypeScript projects with Rust.
186 lines • 7.66 kB
JavaScript
/*!
* Copyright 2019 acrazing <joking.young@gmail.com>. All rights reserved.
* @since 2019-07-17 18:45:47
*/
import { __awaiter } from "tslib";
import fs from 'fs-extra';
import { dirname, join } from 'path';
import { parseCircular, simpleResolver } from './utils';
import { DependencyKind } from './consts';
describe('util', () => {
it('should resolve correctly', () => __awaiter(void 0, void 0, void 0, function* () {
const ext = ['', '.js', '.jsx', '.ts', '.tsx', '.json'];
const local = yield simpleResolver(__dirname, './bin/dpdm', ext);
const index = yield simpleResolver(__dirname, '.', ext);
yield fs.outputJSON('node_modules/dpdm-ut-parent/package.json', {
name: 'dpdm-ut-parent',
version: '1.0.0',
main: 'index.js',
dependencies: {
'dpdm-ut-deep': '^1.0.0',
},
});
yield fs.outputFile('node_modules/dpdm-ut-parent/index.js', '');
yield fs.outputJSON('node_modules/dpdm-ut-parent/node_modules/dpdm-ut-deep/package.json', {
name: 'dpdm-ut-deep',
version: '1.0.0',
main: 'index.js',
});
yield fs.outputFile('node_modules/dpdm-ut-parent/node_modules/dpdm-ut-deep/index.js', '');
yield fs.outputJSON('node_modules/dpdm-ut-deep/package.json', {
name: 'dpdm-ut-deep',
version: '2.0.0',
main: 'index.js',
});
yield fs.outputFile('node_modules/dpdm-ut-deep/index.js', '');
const pkg = yield simpleResolver(__dirname, 'dpdm-ut-parent', ext);
const deepPkg = yield simpleResolver(dirname(pkg), 'dpdm-ut-deep', ext);
const notFound = yield simpleResolver(__dirname, './utils.tsx', ext);
expect([local, index, pkg, deepPkg, notFound]).toEqual([
join(__dirname, 'bin/dpdm.ts'),
join(__dirname, 'index.ts'),
join(__dirname, '../node_modules/dpdm-ut-parent/index.js'),
join(__dirname, '../node_modules/dpdm-ut-parent/node_modules/dpdm-ut-deep/index.js'),
null,
]);
}));
describe('When parsing circular', () => {
function dependencyFactory(id) {
return {
issuer: '',
request: '',
kind: DependencyKind.StaticImport,
id,
};
}
describe('When tree is empty', () => {
const tree = {};
it('Should return empty array', () => {
const actual = parseCircular(tree);
expect(actual.length).toBe(0);
});
});
describe('When tree has just a root with no dependencies', () => {
const tree = { a: [] };
it('Should return empty array', () => {
const actual = parseCircular(tree);
expect(actual.length).toBe(0);
});
});
describe('When tree has 2 nodes, no cycle', () => {
const tree = { a: [dependencyFactory('b')], b: [] };
it('Should return empty array', () => {
const actual = parseCircular(tree);
expect(actual.length).toBe(0);
});
});
describe('When tree has 2 nodes, with cycle', () => {
const id1 = 'a';
const id2 = 'b';
const tree = {
[id1]: [dependencyFactory(id2)],
[id2]: [dependencyFactory(id1)],
};
let actual;
beforeAll(() => {
actual = parseCircular(tree);
});
it('Should return non-empty array', () => {
expect(actual.length).toBeGreaterThan(0);
});
it('Should count only one cycle', () => {
expect(actual.length).toBe(1);
});
it('Should include the ids involved in the cycle', () => {
expect(actual[0]).toMatchObject([id1, id2]);
});
});
describe('When tree has a deep cycle', () => {
const ids = ['a', 'b', 'c'];
const tree = {
[ids[0]]: [dependencyFactory(ids[1])],
[ids[1]]: [dependencyFactory(ids[2])],
[ids[2]]: [dependencyFactory(ids[0])],
};
let actual;
beforeAll(() => {
actual = parseCircular(tree);
});
it('Should return non-empty array', () => {
expect(actual.length).toBeGreaterThan(0);
});
it('Should count only one cycle', () => {
expect(actual.length).toBe(1);
});
it('Should include the ids involved in the cycle', () => {
expect(actual[0]).toMatchObject(ids);
});
});
describe('When tree has 2 cycles with no intersection', () => {
const tree = {
left1: [dependencyFactory('left2')],
left2: [dependencyFactory('left1')],
right1: [dependencyFactory('right2')],
right2: [dependencyFactory('right1')],
};
let actual;
beforeAll(() => {
actual = parseCircular(tree);
});
it('Should return non-empty array', () => {
expect(actual.length).toBeGreaterThan(0);
});
it('Should count two cycles', () => {
expect(actual.length).toBe(2);
});
it('Should include the ids involved in the cycle', () => {
expect(actual[0]).toMatchObject(['left1', 'left2']);
expect(actual[1]).toMatchObject(['right1', 'right2']);
});
});
describe('When tree has 2 cycles from common node', () => {
const tree = {
start: [dependencyFactory('left'), dependencyFactory('right')],
left: [dependencyFactory('start')],
right: [dependencyFactory('start')],
};
let actual;
beforeAll(() => {
actual = parseCircular(tree);
});
it('Should return non-empty array', () => {
expect(actual.length).toBeGreaterThan(0);
});
it('Should count two cycles', () => {
expect(actual.length).toBe(2);
});
it('Should include the ids involved in the cycle', () => {
expect(actual[0]).toMatchObject(['start', 'left']);
expect(actual[1]).toMatchObject(['start', 'right']);
});
});
describe('When tree has 2 cycles with multi-node intersection', () => {
const tree = {
start: [dependencyFactory('mid')],
mid: [dependencyFactory('left'), dependencyFactory('right')],
left: [dependencyFactory('start')],
right: [dependencyFactory('start')],
};
let actual;
beforeAll(() => {
actual = parseCircular(tree);
});
it('Should return non-empty array', () => {
expect(actual.length).toBeGreaterThan(0);
});
it('Should count two cycles', () => {
expect(actual.length).toBe(2);
});
it('Should include the ids involved in the cycle', () => {
expect(actual[0]).toMatchObject(['start', 'mid', 'left']);
expect(actual[1]).toMatchObject(['start', 'mid', 'right']);
});
});
});
});
//# sourceMappingURL=utils.spec.js.map