fix: consume optimised-glob and fs-adapter internally; optimize code; optimize dependencies
This commit is contained in:
parent
c0cf85de70
commit
f6693b3bc4
50 changed files with 688 additions and 904 deletions
|
|
@ -34,36 +34,29 @@
|
||||||
"prepublishOnly": "npm run publish-docs",
|
"prepublishOnly": "npm run publish-docs",
|
||||||
"test:node": "npm run test:node:unit && npm run test:node:e2e",
|
"test:node": "npm run test:node:unit && npm run test:node:e2e",
|
||||||
"test:node:e2e": "mocha './test-node/**/*.e2e.js' --timeout 60000",
|
"test:node:e2e": "mocha './test-node/**/*.e2e.js' --timeout 60000",
|
||||||
"test:node:unit": "mocha './test-node/**/*.test.js'"
|
"test:node:unit": "mocha './{test-node,src}/**/*.test.js'"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/core": "^7.21.4",
|
"@babel/parser": "^7.24.5",
|
||||||
"@babel/parser": "^7.21.4",
|
"@babel/plugin-syntax-import-assertions": "^7.24.1",
|
||||||
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
"@babel/traverse": "^7.24.5",
|
||||||
"@babel/plugin-syntax-export-default-from": "^7.18.6",
|
"@babel/types": "^7.24.5",
|
||||||
"@babel/plugin-syntax-import-assertions": "^7.20.0",
|
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||||
"@babel/register": "^7.21.0",
|
"@swc/core": "^1.5.5",
|
||||||
"@babel/traverse": "^7.21.4",
|
"@web/dev-server": "^0.4.4",
|
||||||
"@babel/types": "^7.21.4",
|
|
||||||
"@rollup/plugin-node-resolve": "^15.0.2",
|
|
||||||
"@swc/core": "^1.3.46",
|
|
||||||
"@web/dev-server": "^0.4.2",
|
|
||||||
"anymatch": "^3.1.3",
|
|
||||||
"commander": "^2.20.3",
|
"commander": "^2.20.3",
|
||||||
"glob": "^8.1.0",
|
"inquirer": "^9.2.20",
|
||||||
"inquirer": "^9.1.5",
|
"lit-element": "^4.0.5",
|
||||||
"is-negated-glob": "^1.0.0",
|
|
||||||
"lit-element": "~3.3.1",
|
|
||||||
"parse5": "^7.1.2",
|
"parse5": "^7.1.2",
|
||||||
"read-package-tree": "5.3.1",
|
"semver": "^7.6.1",
|
||||||
"semver": "^7.3.8",
|
|
||||||
"swc-to-babel": "^1.26.0"
|
"swc-to-babel": "^1.26.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/chai": "^4.3.4",
|
"@types/chai": "^4.3.16",
|
||||||
"@types/inquirer": "^9.0.3",
|
"@types/inquirer": "^9.0.7",
|
||||||
"@types/mocha": "^10.0.1",
|
"@types/mocha": "^10.0.6",
|
||||||
"@web/dev-server-core": "^0.4.0",
|
"@web/dev-server-core": "^0.7.1",
|
||||||
|
"globby": "^14.0.1",
|
||||||
"mock-fs": "^5.2.0",
|
"mock-fs": "^5.2.0",
|
||||||
"mock-require": "^3.0.3"
|
"mock-require": "^3.0.3"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
diff --git a/node_modules/@web/dev-server-core/test-helpers.mjs b/node_modules/@web/dev-server-core/test-helpers.mjs
|
|
||||||
index 1a4d604..9c0d714 100644
|
|
||||||
--- a/node_modules/@web/dev-server-core/test-helpers.mjs
|
|
||||||
+++ b/node_modules/@web/dev-server-core/test-helpers.mjs
|
|
||||||
@@ -1,5 +1,5 @@
|
|
||||||
// this file is autogenerated with the generate-mjs-dts-entrypoints script
|
|
||||||
-import cjsEntrypoint from './dist/index.js';
|
|
||||||
+import cjsEntrypoint from './dist/test-helpers.js';
|
|
||||||
|
|
||||||
const {
|
|
||||||
virtualFilesPlugin,
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
/* eslint-disable no-shadow */
|
/* eslint-disable no-shadow */
|
||||||
import pathLib from 'path';
|
import path from 'path';
|
||||||
import child_process from 'child_process'; // eslint-disable-line camelcase
|
import child_process from 'child_process'; // eslint-disable-line camelcase
|
||||||
import glob from 'glob';
|
import { globbySync } from 'globby'; // eslint-disable-line import/no-extraneous-dependencies
|
||||||
import readPackageTree from '../program/utils/read-package-tree-with-bower-support.js';
|
import { optimisedGlob } from '../program/utils/optimised-glob.js';
|
||||||
import { LogService } from '../program/core/LogService.js';
|
import { LogService } from '../program/core/LogService.js';
|
||||||
import { toPosixPath } from '../program/utils/to-posix-path.js';
|
import { toPosixPath } from '../program/utils/to-posix-path.js';
|
||||||
|
import { fsAdapter } from '../program/utils/fs-adapter.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {any[]} arr
|
* @param {any[]} arr
|
||||||
|
|
@ -59,13 +60,9 @@ export function pathsArrayFromCs(t, cwd = process.cwd()) {
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
if (t.includes('*')) {
|
if (t.includes('*')) {
|
||||||
if (!t.endsWith('/')) {
|
return globbySync(t, { cwd, absolute: true, onlyFiles: false }).map(toPosixPath);
|
||||||
// eslint-disable-next-line no-param-reassign
|
|
||||||
t = `${t}/`;
|
|
||||||
}
|
}
|
||||||
return glob.sync(t, { cwd, absolute: true }).map(toPosixPath);
|
return toPosixPath(path.resolve(cwd, t.trim()));
|
||||||
}
|
|
||||||
return toPosixPath(pathLib.resolve(cwd, t.trim()));
|
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -132,6 +129,48 @@ export function targetDefault(cwd) {
|
||||||
return [toPosixPath(cwd)];
|
return [toPosixPath(cwd)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} targetPath
|
||||||
|
* @param {((s:string) => boolean)|null} matcher
|
||||||
|
* @param {'npm'|'bower'} [mode]
|
||||||
|
*/
|
||||||
|
async function readPackageTree(targetPath, matcher, mode) {
|
||||||
|
const folderName = mode === 'npm' ? 'node_modules' : 'bower_components';
|
||||||
|
const potentialPaths = await optimisedGlob(`${folderName}/**/*`, {
|
||||||
|
onlyDirectories: true,
|
||||||
|
cwd: targetPath,
|
||||||
|
absolute: true,
|
||||||
|
fs: fsAdapter.fs,
|
||||||
|
});
|
||||||
|
const matchingPaths = potentialPaths.filter(potentialPath => {
|
||||||
|
// only dirs that are direct children of node_modules. So '**/node_modules/a' will match, but '**/node_modules/a/b' won't
|
||||||
|
const [, projectName] = potentialPath.match(new RegExp(`^.*/${folderName}/([^/]*)$`)) || [];
|
||||||
|
return matcher ? matcher(projectName) : true;
|
||||||
|
});
|
||||||
|
return matchingPaths;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string|undefined} matchPattern
|
||||||
|
*/
|
||||||
|
function getMatcher(matchPattern) {
|
||||||
|
if (!matchPattern) return null;
|
||||||
|
|
||||||
|
const isValidMatchPattern = matchPattern.startsWith('/') && matchPattern.endsWith('/');
|
||||||
|
if (!isValidMatchPattern) {
|
||||||
|
LogService.error(
|
||||||
|
`[appendProjectDependencyPaths] Please provide a matchPattern enclosed by '/'. Found: ${matchPattern}`,
|
||||||
|
);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (/** @type {string} */ d) => {
|
||||||
|
const reString = matchPattern.slice(1, -1);
|
||||||
|
const result = new RegExp(reString).test(d);
|
||||||
|
LogService.debug(`[appendProjectDependencyPaths]: /${reString}/.test(${d} => ${result})`);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Returns all sub projects matching condition supplied in matchFn
|
* Returns all sub projects matching condition supplied in matchFn
|
||||||
* @param {string[]} rootPaths all search-target project paths
|
* @param {string[]} rootPaths all search-target project paths
|
||||||
|
|
@ -143,44 +182,15 @@ export async function appendProjectDependencyPaths(
|
||||||
matchPattern,
|
matchPattern,
|
||||||
modes = ['npm', 'bower'],
|
modes = ['npm', 'bower'],
|
||||||
) {
|
) {
|
||||||
let matchFn;
|
const matcher = getMatcher(matchPattern);
|
||||||
if (matchPattern) {
|
|
||||||
if (matchPattern.startsWith('/') && matchPattern.endsWith('/')) {
|
|
||||||
matchFn = (/** @type {any} */ _, /** @type {string} */ d) => {
|
|
||||||
const reString = matchPattern.slice(1, -1);
|
|
||||||
const result = new RegExp(reString).test(d);
|
|
||||||
LogService.debug(`[appendProjectDependencyPaths]: /${reString}/.test(${d} => ${result})`);
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
LogService.error(
|
|
||||||
`[appendProjectDependencyPaths] Please provide a matchPattern enclosed by '/'. Found: ${matchPattern}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/** @type {string[]} */
|
/** @type {string[]} */
|
||||||
const depProjectPaths = [];
|
const depProjectPaths = [];
|
||||||
for (const targetPath of rootPaths) {
|
for (const targetPath of rootPaths) {
|
||||||
for (const mode of modes) {
|
for (const mode of modes) {
|
||||||
await readPackageTree(
|
depProjectPaths.push(...(await readPackageTree(targetPath, matcher, mode)));
|
||||||
targetPath,
|
|
||||||
matchFn,
|
|
||||||
(/** @type {string | undefined} */ err, /** @type {{ children: any[]; }} */ tree) => {
|
|
||||||
if (err) {
|
|
||||||
throw new Error(err);
|
|
||||||
}
|
|
||||||
const paths = tree.children.map(child => child.realpath);
|
|
||||||
depProjectPaths.push(...paths);
|
|
||||||
},
|
|
||||||
mode,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Write all data to {outputPath}/projectDeps.json
|
|
||||||
// const projectDeps = {};
|
|
||||||
// rootPaths.forEach(rootP => {
|
|
||||||
// depProjectPaths.filter(depP => depP.startsWith(rootP)).;
|
|
||||||
// });
|
|
||||||
|
|
||||||
return depProjectPaths.concat(rootPaths).map(toPosixPath);
|
return depProjectPaths.concat(rootPaths).map(toPosixPath);
|
||||||
}
|
}
|
||||||
|
|
@ -192,7 +202,7 @@ export async function appendProjectDependencyPaths(
|
||||||
*/
|
*/
|
||||||
export async function installDeps(searchTargetPaths) {
|
export async function installDeps(searchTargetPaths) {
|
||||||
for (const targetPath of searchTargetPaths) {
|
for (const targetPath of searchTargetPaths) {
|
||||||
LogService.info(`Installing npm dependencies for ${pathLib.basename(targetPath)}`);
|
LogService.info(`Installing npm dependencies for ${path.basename(targetPath)}`);
|
||||||
try {
|
try {
|
||||||
await spawnProcess('npm i --no-progress', { cwd: targetPath });
|
await spawnProcess('npm i --no-progress', { cwd: targetPath });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -200,7 +210,7 @@ export async function installDeps(searchTargetPaths) {
|
||||||
LogService.error(e);
|
LogService.error(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogService.info(`Installing bower dependencies for ${pathLib.basename(targetPath)}`);
|
LogService.info(`Installing bower dependencies for ${path.basename(targetPath)}`);
|
||||||
try {
|
try {
|
||||||
await spawnProcess(`bower i --production --force-latest`, { cwd: targetPath });
|
await spawnProcess(`bower i --production --force-latest`, { cwd: targetPath });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -211,14 +221,14 @@ export async function installDeps(searchTargetPaths) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const _cliHelpersModule = {
|
export const _cliHelpersModule = {
|
||||||
csToArray,
|
|
||||||
extensionsFromCs,
|
|
||||||
setQueryMethod,
|
|
||||||
pathsArrayFromCs,
|
|
||||||
targetDefault,
|
|
||||||
appendProjectDependencyPaths,
|
appendProjectDependencyPaths,
|
||||||
|
pathsArrayFromCollectionName,
|
||||||
|
extensionsFromCs,
|
||||||
|
pathsArrayFromCs,
|
||||||
|
setQueryMethod,
|
||||||
|
targetDefault,
|
||||||
spawnProcess,
|
spawnProcess,
|
||||||
installDeps,
|
installDeps,
|
||||||
pathsArrayFromCollectionName,
|
csToArray,
|
||||||
flatten,
|
flatten,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import child_process from 'child_process'; // eslint-disable-line camelcase
|
import child_process from 'child_process'; // eslint-disable-line camelcase
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import fs from 'fs';
|
|
||||||
import commander from 'commander';
|
import commander from 'commander';
|
||||||
|
|
||||||
import { LogService } from '../program/core/LogService.js';
|
import { LogService } from '../program/core/LogService.js';
|
||||||
import { QueryService } from '../program/core/QueryService.js';
|
import { QueryService } from '../program/core/QueryService.js';
|
||||||
import { InputDataService } from '../program/core/InputDataService.js';
|
import { InputDataService } from '../program/core/InputDataService.js';
|
||||||
|
|
@ -12,6 +13,7 @@ import { _providenceModule } from '../program/providence.js';
|
||||||
import { _cliHelpersModule } from './cli-helpers.js';
|
import { _cliHelpersModule } from './cli-helpers.js';
|
||||||
import { _extendDocsModule } from './launch-providence-with-extend-docs.js';
|
import { _extendDocsModule } from './launch-providence-with-extend-docs.js';
|
||||||
import { _promptAnalyzerMenuModule } from './prompt-analyzer-menu.js';
|
import { _promptAnalyzerMenuModule } from './prompt-analyzer-menu.js';
|
||||||
|
import { fsAdapter } from '../program/utils/fs-adapter.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {import('../../types/index.js').AnalyzerName} AnalyzerName
|
* @typedef {import('../../types/index.js').AnalyzerName} AnalyzerName
|
||||||
|
|
@ -19,7 +21,10 @@ import { _promptAnalyzerMenuModule } from './prompt-analyzer-menu.js';
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { version } = JSON.parse(
|
const { version } = JSON.parse(
|
||||||
fs.readFileSync(path.resolve(getCurrentDir(import.meta.url), '../../package.json'), 'utf8'),
|
fsAdapter.fs.readFileSync(
|
||||||
|
path.resolve(getCurrentDir(import.meta.url), '../../package.json'),
|
||||||
|
'utf8',
|
||||||
|
),
|
||||||
);
|
);
|
||||||
const { extensionsFromCs, setQueryMethod, targetDefault, installDeps } = _cliHelpersModule;
|
const { extensionsFromCs, setQueryMethod, targetDefault, installDeps } = _cliHelpersModule;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
/* eslint-disable import/no-extraneous-dependencies */
|
/* eslint-disable import/no-extraneous-dependencies */
|
||||||
import fs from 'fs';
|
import path from 'path';
|
||||||
import pathLib from 'path';
|
|
||||||
import { performance } from 'perf_hooks';
|
import { performance } from 'perf_hooks';
|
||||||
import { _providenceModule } from '../program/providence.js';
|
import { _providenceModule } from '../program/providence.js';
|
||||||
import { QueryService } from '../program/core/QueryService.js';
|
import { QueryService } from '../program/core/QueryService.js';
|
||||||
|
|
@ -8,6 +7,7 @@ import { InputDataService } from '../program/core/InputDataService.js';
|
||||||
import { LogService } from '../program/core/LogService.js';
|
import { LogService } from '../program/core/LogService.js';
|
||||||
import { flatten } from './cli-helpers.js';
|
import { flatten } from './cli-helpers.js';
|
||||||
import MatchPathsAnalyzer from '../program/analyzers/match-paths.js';
|
import MatchPathsAnalyzer from '../program/analyzers/match-paths.js';
|
||||||
|
import { fsAdapter } from '../program/utils/fs-adapter.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {import('../../types/index.js').PathFromSystemRoot} PathFromSystemRoot
|
* @typedef {import('../../types/index.js').PathFromSystemRoot} PathFromSystemRoot
|
||||||
|
|
@ -33,7 +33,7 @@ export async function getExtendDocsResults({
|
||||||
allowlistReference,
|
allowlistReference,
|
||||||
cwd,
|
cwd,
|
||||||
}) {
|
}) {
|
||||||
const monoPkgs = InputDataService.getMonoRepoPackages(cwd);
|
const monoPkgs = await InputDataService.getMonoRepoPackages(cwd);
|
||||||
|
|
||||||
const results = await _providenceModule.providence(
|
const results = await _providenceModule.providence(
|
||||||
await QueryService.getQueryConfigFromAnalyzer(MatchPathsAnalyzer, { prefix: prefixCfg }),
|
await QueryService.getQueryConfigFromAnalyzer(MatchPathsAnalyzer, { prefix: prefixCfg }),
|
||||||
|
|
@ -71,7 +71,7 @@ export async function getExtendDocsResults({
|
||||||
const normalizedP = `./${p}`;
|
const normalizedP = `./${p}`;
|
||||||
if (pathStr.startsWith(normalizedP)) {
|
if (pathStr.startsWith(normalizedP)) {
|
||||||
const localPath = pathStr.replace(normalizedP, ''); // 'lea-tabs.js'
|
const localPath = pathStr.replace(normalizedP, ''); // 'lea-tabs.js'
|
||||||
result = `${name}/${localPath}`; // 'lea-tabs/lea-tabs.js'
|
result = path.join(name, localPath); // 'lea-tabs/lea-tabs.js'
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -124,12 +124,12 @@ export async function launchProvidenceWithExtendDocs({
|
||||||
});
|
});
|
||||||
|
|
||||||
// Write results
|
// Write results
|
||||||
const outputFilePath = pathLib.join(outputFolder, 'providence-extend-docs-data.json');
|
const outputFilePath = path.join(outputFolder, 'providence-extend-docs-data.json');
|
||||||
|
|
||||||
if (fs.existsSync(outputFilePath)) {
|
if (fsAdapter.fs.existsSync(outputFilePath)) {
|
||||||
fs.unlinkSync(outputFilePath);
|
fsAdapter.fs.unlinkSync(outputFilePath);
|
||||||
}
|
}
|
||||||
fs.writeFile(outputFilePath, JSON.stringify(queryOutputs, null, 2), err => {
|
fsAdapter.fs.writeFile(outputFilePath, JSON.stringify(queryOutputs, null, 2), err => {
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import fs from 'fs';
|
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import inquirer from 'inquirer';
|
import inquirer from 'inquirer';
|
||||||
import traverse from '@babel/traverse';
|
import traverse from '@babel/traverse';
|
||||||
|
|
@ -7,6 +6,7 @@ import { AstService } from '../program/core/AstService.js';
|
||||||
import { LogService } from '../program/core/LogService.js';
|
import { LogService } from '../program/core/LogService.js';
|
||||||
import JsdocCommentParser from '../program/utils/jsdoc-comment-parser.js';
|
import JsdocCommentParser from '../program/utils/jsdoc-comment-parser.js';
|
||||||
import { getCurrentDir } from '../program/utils/get-current-dir.js';
|
import { getCurrentDir } from '../program/utils/get-current-dir.js';
|
||||||
|
import { fsAdapter } from '../program/utils/fs-adapter.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {import('../../types/index.js').TargetDepsObj} TargetDepsObj
|
* @typedef {import('../../types/index.js').TargetDepsObj} TargetDepsObj
|
||||||
|
|
@ -42,7 +42,7 @@ function getPropsFromParsedJsDoc(jsdoc) {
|
||||||
* @param {PathFromSystemRoot} file
|
* @param {PathFromSystemRoot} file
|
||||||
*/
|
*/
|
||||||
function getAnalyzerOptions(file) {
|
function getAnalyzerOptions(file) {
|
||||||
const code = fs.readFileSync(file, 'utf8');
|
const code = fsAdapter.fs.readFileSync(file, 'utf8');
|
||||||
const babelAst = AstService.getAst(code, 'swc-to-babel', { filePath: file });
|
const babelAst = AstService.getAst(code, 'swc-to-babel', { filePath: file });
|
||||||
|
|
||||||
let commentNode;
|
let commentNode;
|
||||||
|
|
@ -74,7 +74,7 @@ function getAnalyzerOptions(file) {
|
||||||
* @param {PathFromSystemRoot} dir
|
* @param {PathFromSystemRoot} dir
|
||||||
* @param {boolean} [shouldGetOptions]
|
* @param {boolean} [shouldGetOptions]
|
||||||
*/
|
*/
|
||||||
function gatherAnalyzers(dir, shouldGetOptions) {
|
async function gatherAnalyzers(dir, shouldGetOptions) {
|
||||||
return InputDataService.gatherFilesFromDir(dir, { depth: 0 }).map(file => {
|
return InputDataService.gatherFilesFromDir(dir, { depth: 0 }).map(file => {
|
||||||
const analyzerObj = { file, name: path.basename(file, '.js') };
|
const analyzerObj = { file, name: path.basename(file, '.js') };
|
||||||
if (shouldGetOptions) {
|
if (shouldGetOptions) {
|
||||||
|
|
@ -98,7 +98,7 @@ export async function promptAnalyzerConfigMenu(
|
||||||
path.resolve(getCurrentDir(import.meta.url), '../program/analyzers')
|
path.resolve(getCurrentDir(import.meta.url), '../program/analyzers')
|
||||||
),
|
),
|
||||||
) {
|
) {
|
||||||
const menuOptions = gatherAnalyzers(dir, true);
|
const menuOptions = await gatherAnalyzers(dir, true);
|
||||||
const analyzer = menuOptions.find(o => o.name === analyzerName);
|
const analyzer = menuOptions.find(o => o.name === analyzerName);
|
||||||
if (!analyzer) {
|
if (!analyzer) {
|
||||||
LogService.error(`[promptAnalyzerConfigMenu] analyzer "${analyzerName}" not found.`);
|
LogService.error(`[promptAnalyzerConfigMenu] analyzer "${analyzerName}" not found.`);
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import fs from 'fs';
|
import path from 'path';
|
||||||
import pathLib from 'path';
|
|
||||||
import { startDevServer } from '@web/dev-server';
|
import { startDevServer } from '@web/dev-server';
|
||||||
import { ReportService } from '../program/core/ReportService.js';
|
import { ReportService } from '../program/core/ReportService.js';
|
||||||
import { providenceConfUtil } from '../program/utils/providence-conf-util.js';
|
import { providenceConfUtil } from '../program/utils/providence-conf-util.js';
|
||||||
import { getCurrentDir } from '../program/utils/get-current-dir.js';
|
import { getCurrentDir } from '../program/utils/get-current-dir.js';
|
||||||
|
import { fsAdapter } from '../program/utils/fs-adapter.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {import('../../types/index.js').PathFromSystemRoot} PathFromSystemRoot
|
* @typedef {import('../../types/index.js').PathFromSystemRoot} PathFromSystemRoot
|
||||||
|
|
@ -25,7 +25,7 @@ async function getCachedProvidenceResults({
|
||||||
*/
|
*/
|
||||||
let outputFilePaths;
|
let outputFilePaths;
|
||||||
try {
|
try {
|
||||||
outputFilePaths = fs.readdirSync(resultsPath);
|
outputFilePaths = fsAdapter.fs.readdirSync(resultsPath);
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
throw new Error(`Please make sure providence results can be found in ${resultsPath}`);
|
throw new Error(`Please make sure providence results can be found in ${resultsPath}`);
|
||||||
}
|
}
|
||||||
|
|
@ -33,7 +33,9 @@ async function getCachedProvidenceResults({
|
||||||
const resultFiles = {};
|
const resultFiles = {};
|
||||||
let searchTargetDeps;
|
let searchTargetDeps;
|
||||||
outputFilePaths.forEach(fileName => {
|
outputFilePaths.forEach(fileName => {
|
||||||
const content = JSON.parse(fs.readFileSync(pathLib.join(resultsPath, fileName), 'utf-8'));
|
const content = JSON.parse(
|
||||||
|
fsAdapter.fs.readFileSync(path.join(resultsPath, fileName), 'utf-8'),
|
||||||
|
);
|
||||||
if (fileName === 'search-target-deps-file.json') {
|
if (fileName === 'search-target-deps-file.json') {
|
||||||
searchTargetDeps = content;
|
searchTargetDeps = content;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -62,8 +64,8 @@ function createMiddleWares({ providenceConf, providenceConfRaw, searchTargetDeps
|
||||||
*/
|
*/
|
||||||
function getPackageJson(projectPath) {
|
function getPackageJson(projectPath) {
|
||||||
try {
|
try {
|
||||||
const file = pathLib.resolve(projectPath, 'package.json');
|
const file = path.resolve(projectPath, 'package.json');
|
||||||
return JSON.parse(fs.readFileSync(file, 'utf8'));
|
return JSON.parse(fsAdapter.fs.readFileSync(file, 'utf8'));
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -85,7 +87,7 @@ function createMiddleWares({ providenceConf, providenceConfRaw, searchTargetDeps
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
const pathFromServerRootToHere = `/${pathLib.relative(
|
const pathFromServerRootToHere = `/${path.relative(
|
||||||
process.cwd(),
|
process.cwd(),
|
||||||
getCurrentDir(import.meta.url),
|
getCurrentDir(import.meta.url),
|
||||||
)}`;
|
)}`;
|
||||||
|
|
@ -148,13 +150,13 @@ export async function createDashboardServerConfig() {
|
||||||
// Needed for dev purposes (we call it from ./packages-node/providence-analytics/ instead of ./)
|
// Needed for dev purposes (we call it from ./packages-node/providence-analytics/ instead of ./)
|
||||||
// Allows es-dev-server to find the right moduleDirs
|
// Allows es-dev-server to find the right moduleDirs
|
||||||
const fromPackageRoot = process.argv.includes('--serve-from-package-root');
|
const fromPackageRoot = process.argv.includes('--serve-from-package-root');
|
||||||
const moduleRoot = fromPackageRoot ? pathLib.resolve(process.cwd(), '../../') : process.cwd();
|
const moduleRoot = fromPackageRoot ? path.resolve(process.cwd(), '../../') : process.cwd();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
appIndex: pathLib.resolve(getCurrentDir(import.meta.url), 'index.html'),
|
appIndex: path.resolve(getCurrentDir(import.meta.url), 'index.html'),
|
||||||
rootDir: moduleRoot,
|
rootDir: moduleRoot,
|
||||||
nodeResolve: true,
|
nodeResolve: true,
|
||||||
moduleDirs: pathLib.resolve(moduleRoot, 'node_modules'),
|
moduleDirs: path.resolve(moduleRoot, 'node_modules'),
|
||||||
watch: false,
|
watch: false,
|
||||||
open: true,
|
open: true,
|
||||||
middleware: createMiddleWares({
|
middleware: createMiddleWares({
|
||||||
|
|
|
||||||
|
|
@ -241,7 +241,7 @@ export default class FindClassesAnalyzer extends Analyzer {
|
||||||
/**
|
/**
|
||||||
* Prepare
|
* Prepare
|
||||||
*/
|
*/
|
||||||
const analyzerResult = this._prepare(cfg);
|
const analyzerResult = await this._prepare(cfg);
|
||||||
if (analyzerResult) {
|
if (analyzerResult) {
|
||||||
return analyzerResult;
|
return analyzerResult;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ export default class FindCustomelementsAnalyzer extends Analyzer {
|
||||||
/**
|
/**
|
||||||
* Prepare
|
* Prepare
|
||||||
*/
|
*/
|
||||||
const cachedAnalyzerResult = this._prepare(cfg);
|
const cachedAnalyzerResult = await this._prepare(cfg);
|
||||||
if (cachedAnalyzerResult) {
|
if (cachedAnalyzerResult) {
|
||||||
return cachedAnalyzerResult;
|
return cachedAnalyzerResult;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -124,7 +124,7 @@ export default class FindImportsSwcAnalyzer extends Analyzer {
|
||||||
/**
|
/**
|
||||||
* Prepare
|
* Prepare
|
||||||
*/
|
*/
|
||||||
const cachedAnalyzerResult = this._prepare(cfg);
|
const cachedAnalyzerResult = await this._prepare(cfg);
|
||||||
if (cachedAnalyzerResult) {
|
if (cachedAnalyzerResult) {
|
||||||
return cachedAnalyzerResult;
|
return cachedAnalyzerResult;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
/* eslint-disable no-shadow */
|
/* eslint-disable no-shadow */
|
||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import fs from 'fs';
|
|
||||||
import pathLib from 'path';
|
import pathLib from 'path';
|
||||||
import babelTraverse from '@babel/traverse';
|
import babelTraverse from '@babel/traverse';
|
||||||
import { isRelativeSourcePath, toRelativeSourcePath } from '../../utils/relative-source-path.js';
|
import { isRelativeSourcePath, toRelativeSourcePath } from '../../utils/relative-source-path.js';
|
||||||
|
|
@ -9,6 +8,7 @@ import { resolveImportPath } from '../../utils/resolve-import-path.js';
|
||||||
import { AstService } from '../../core/AstService.js';
|
import { AstService } from '../../core/AstService.js';
|
||||||
import { LogService } from '../../core/LogService.js';
|
import { LogService } from '../../core/LogService.js';
|
||||||
import { memoize } from '../../utils/memoize.js';
|
import { memoize } from '../../utils/memoize.js';
|
||||||
|
import { fsAdapter } from '../../utils/fs-adapter.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {import('../../../../types/index.js').RootFile} RootFile
|
* @typedef {import('../../../../types/index.js').RootFile} RootFile
|
||||||
|
|
@ -23,7 +23,7 @@ import { memoize } from '../../utils/memoize.js';
|
||||||
* @param {string} projectName
|
* @param {string} projectName
|
||||||
*/
|
*/
|
||||||
function isSelfReferencingProject(source, projectName) {
|
function isSelfReferencingProject(source, projectName) {
|
||||||
return source.startsWith(`${projectName}`);
|
return source.split('/')[0] === projectName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -184,7 +184,7 @@ async function trackDownIdentifierFn(
|
||||||
specifier: '[default]',
|
specifier: '[default]',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const code = fs.readFileSync(resolvedSourcePath, 'utf8');
|
const code = fsAdapter.fs.readFileSync(resolvedSourcePath, 'utf8');
|
||||||
const babelAst = AstService.getAst(code, 'swc-to-babel', { filePath: resolvedSourcePath });
|
const babelAst = AstService.getAst(code, 'swc-to-babel', { filePath: resolvedSourcePath });
|
||||||
|
|
||||||
const shouldLookForDefaultExport = identifierName === '[default]';
|
const shouldLookForDefaultExport = identifierName === '[default]';
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import fs from 'fs';
|
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { swcTraverse } from '../../utils/swc-traverse.js';
|
import { swcTraverse } from '../../utils/swc-traverse.js';
|
||||||
import { isRelativeSourcePath, toRelativeSourcePath } from '../../utils/relative-source-path.js';
|
import { isRelativeSourcePath, toRelativeSourcePath } from '../../utils/relative-source-path.js';
|
||||||
|
|
@ -6,12 +5,13 @@ import { InputDataService } from '../../core/InputDataService.js';
|
||||||
import { resolveImportPath } from '../../utils/resolve-import-path.js';
|
import { resolveImportPath } from '../../utils/resolve-import-path.js';
|
||||||
import { AstService } from '../../core/AstService.js';
|
import { AstService } from '../../core/AstService.js';
|
||||||
import { memoize } from '../../utils/memoize.js';
|
import { memoize } from '../../utils/memoize.js';
|
||||||
|
import { fsAdapter } from '../../utils/fs-adapter.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {import('../../../../types/index.js').RootFile} RootFile
|
* @typedef {import('../../../../types/index.js').PathFromSystemRoot} PathFromSystemRoot
|
||||||
* @typedef {import('../../../../types/index.js').SpecifierSource} SpecifierSource
|
* @typedef {import('../../../../types/index.js').SpecifierSource} SpecifierSource
|
||||||
* @typedef {import('../../../../types/index.js').IdentifierName} IdentifierName
|
* @typedef {import('../../../../types/index.js').IdentifierName} IdentifierName
|
||||||
* @typedef {import('../../../../types/index.js').PathFromSystemRoot} PathFromSystemRoot
|
* @typedef {import('../../../../types/index.js').RootFile} RootFile
|
||||||
* @typedef {import('../../../../types/index.js').SwcPath} SwcPath
|
* @typedef {import('../../../../types/index.js').SwcPath} SwcPath
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -20,7 +20,7 @@ import { memoize } from '../../utils/memoize.js';
|
||||||
* @param {string} projectName
|
* @param {string} projectName
|
||||||
*/
|
*/
|
||||||
function isSelfReferencingProject(source, projectName) {
|
function isSelfReferencingProject(source, projectName) {
|
||||||
return source.startsWith(`${projectName}`);
|
return source.split('/')[0] === projectName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -193,7 +193,7 @@ async function trackDownIdentifierFn(
|
||||||
specifier: '[default]',
|
specifier: '[default]',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const code = fs.readFileSync(/** @type {string} */ (resolvedSourcePath), 'utf8');
|
const code = fsAdapter.fs.readFileSync(/** @type {string} */ (resolvedSourcePath), 'utf8');
|
||||||
const swcAst = AstService._getSwcAst(code);
|
const swcAst = AstService._getSwcAst(code);
|
||||||
|
|
||||||
const shouldLookForDefaultExport = identifierName === '[default]';
|
const shouldLookForDefaultExport = identifierName === '[default]';
|
||||||
|
|
|
||||||
|
|
@ -192,14 +192,11 @@ export default class MatchImportsAnalyzer extends Analyzer {
|
||||||
/**
|
/**
|
||||||
* Prepare
|
* Prepare
|
||||||
*/
|
*/
|
||||||
const cachedAnalyzerResult = this._prepare(cfg);
|
const cachedAnalyzerResult = await this._prepare(cfg);
|
||||||
if (cachedAnalyzerResult) {
|
if (cachedAnalyzerResult) {
|
||||||
return cachedAnalyzerResult;
|
return cachedAnalyzerResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Traverse
|
|
||||||
*/
|
|
||||||
let { referenceProjectResult } = cfg;
|
let { referenceProjectResult } = cfg;
|
||||||
if (!referenceProjectResult) {
|
if (!referenceProjectResult) {
|
||||||
const findExportsAnalyzer = new FindExportsAnalyzer();
|
const findExportsAnalyzer = new FindExportsAnalyzer();
|
||||||
|
|
@ -222,6 +219,9 @@ export default class MatchImportsAnalyzer extends Analyzer {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Traverse
|
||||||
|
*/
|
||||||
const queryOutput = await matchImportsPostprocess(
|
const queryOutput = await matchImportsPostprocess(
|
||||||
referenceProjectResult,
|
referenceProjectResult,
|
||||||
targetProjectResult,
|
targetProjectResult,
|
||||||
|
|
|
||||||
|
|
@ -198,7 +198,6 @@ function getVariablePaths(
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param {FindCustomelementsAnalyzerResult} targetFindCustomelementsResult
|
* @param {FindCustomelementsAnalyzerResult} targetFindCustomelementsResult
|
||||||
* @param {FindCustomelementsAnalyzerResult} refFindCustomelementsResult
|
* @param {FindCustomelementsAnalyzerResult} refFindCustomelementsResult
|
||||||
* @param {FindExportsAnalyzerResult} refFindExportsResult
|
* @param {FindExportsAnalyzerResult} refFindExportsResult
|
||||||
|
|
@ -240,8 +239,10 @@ function getTagPaths(
|
||||||
if (!matchSubclassSpecifierRootFile) {
|
if (!matchSubclassSpecifierRootFile) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const sameRoot = entry.rootFile.file === matchSubclassSpecifierRootFile.file;
|
const sameRoot = entry.rootFile.file === matchSubclassSpecifierRootFile.file;
|
||||||
const sameIdentifier = entry.rootFile.specifier === matchSubclassEntry.exportSpecifier.name;
|
const sameIdentifier = entry.rootFile.specifier === matchSubclassEntry.exportSpecifier.name;
|
||||||
|
|
||||||
return sameRoot && sameIdentifier;
|
return sameRoot && sameIdentifier;
|
||||||
});
|
});
|
||||||
if (refPathMatch) {
|
if (refPathMatch) {
|
||||||
|
|
@ -274,11 +275,11 @@ function matchPathsPostprocess(
|
||||||
/** @type {AnalyzerQueryResult} */
|
/** @type {AnalyzerQueryResult} */
|
||||||
const resultsArray = [];
|
const resultsArray = [];
|
||||||
|
|
||||||
targetMatchSubclassesResult.queryOutput.forEach(matchSubclassEntry => {
|
for (const matchSubclassEntry of targetMatchSubclassesResult.queryOutput) {
|
||||||
const fromClass = matchSubclassEntry.exportSpecifier.name;
|
const fromClass = matchSubclassEntry.exportSpecifier.name;
|
||||||
|
|
||||||
matchSubclassEntry.matchesPerProject.forEach(projectMatch => {
|
for (const projectMatch of matchSubclassEntry.matchesPerProject) {
|
||||||
projectMatch.files.forEach(({ identifier: toClass, file: targetMatchedFile }) => {
|
for (const { identifier: toClass, file: targetMatchedFile } of projectMatch.files) {
|
||||||
const resultEntry = {
|
const resultEntry = {
|
||||||
name: fromClass,
|
name: fromClass,
|
||||||
};
|
};
|
||||||
|
|
@ -293,7 +294,7 @@ function matchPathsPostprocess(
|
||||||
refProjectName,
|
refProjectName,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (paths && paths.length) {
|
if (paths?.length) {
|
||||||
resultEntry.variable = {
|
resultEntry.variable = {
|
||||||
from: fromClass,
|
from: fromClass,
|
||||||
to: toClass,
|
to: toClass,
|
||||||
|
|
@ -324,9 +325,9 @@ function matchPathsPostprocess(
|
||||||
if (resultEntry.variable || resultEntry.tag) {
|
if (resultEntry.variable || resultEntry.tag) {
|
||||||
resultsArray.push(resultEntry);
|
resultsArray.push(resultEntry);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
});
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
return resultsArray;
|
return resultsArray;
|
||||||
}
|
}
|
||||||
|
|
@ -394,7 +395,7 @@ export default class MatchPathsAnalyzer extends Analyzer {
|
||||||
/**
|
/**
|
||||||
* Prepare
|
* Prepare
|
||||||
*/
|
*/
|
||||||
const analyzerResult = this._prepare(cfg);
|
const analyzerResult = await this._prepare(cfg);
|
||||||
if (analyzerResult) {
|
if (analyzerResult) {
|
||||||
return analyzerResult;
|
return analyzerResult;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -312,7 +312,7 @@ export default class MatchSubclassesAnalyzer extends Analyzer {
|
||||||
/**
|
/**
|
||||||
* Prepare
|
* Prepare
|
||||||
*/
|
*/
|
||||||
const analyzerResult = this._prepare(cfg);
|
const analyzerResult = await this._prepare(cfg);
|
||||||
if (analyzerResult) {
|
if (analyzerResult) {
|
||||||
return analyzerResult;
|
return analyzerResult;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,9 +54,8 @@ async function analyzePerAstFile(projectData, astAnalysis, analyzerCfg) {
|
||||||
* @param {object[]|object} data
|
* @param {object[]|object} data
|
||||||
*/
|
*/
|
||||||
function posixify(data) {
|
function posixify(data) {
|
||||||
if (!data) {
|
if (!data) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (Array.isArray(data)) {
|
if (Array.isArray(data)) {
|
||||||
data.forEach(posixify);
|
data.forEach(posixify);
|
||||||
} else if (typeof data === 'object') {
|
} else if (typeof data === 'object') {
|
||||||
|
|
@ -212,7 +211,7 @@ export class Analyzer {
|
||||||
* @param {AnalyzerConfig} cfg
|
* @param {AnalyzerConfig} cfg
|
||||||
* @returns {CachedAnalyzerResult|undefined}
|
* @returns {CachedAnalyzerResult|undefined}
|
||||||
*/
|
*/
|
||||||
_prepare(cfg) {
|
async _prepare(cfg) {
|
||||||
LogService.debug(`Analyzer "${this.name}": started _prepare method`);
|
LogService.debug(`Analyzer "${this.name}": started _prepare method`);
|
||||||
/** @type {typeof Analyzer} */ (this.constructor).__unwindProvidedResults(cfg);
|
/** @type {typeof Analyzer} */ (this.constructor).__unwindProvidedResults(cfg);
|
||||||
|
|
||||||
|
|
@ -281,14 +280,14 @@ export class Analyzer {
|
||||||
* Get reference and search-target data
|
* Get reference and search-target data
|
||||||
*/
|
*/
|
||||||
if (!cfg.targetProjectResult) {
|
if (!cfg.targetProjectResult) {
|
||||||
this.targetData = InputDataService.createDataObject(
|
this.targetData = await InputDataService.createDataObject(
|
||||||
[cfg.targetProjectPath],
|
[cfg.targetProjectPath],
|
||||||
cfg.gatherFilesConfig,
|
cfg.gatherFilesConfig,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cfg.referenceProjectPath) {
|
if (cfg.referenceProjectPath) {
|
||||||
this.referenceData = InputDataService.createDataObject(
|
this.referenceData = await InputDataService.createDataObject(
|
||||||
[cfg.referenceProjectPath],
|
[cfg.referenceProjectPath],
|
||||||
cfg.gatherFilesConfigReference || cfg.gatherFilesConfig,
|
cfg.gatherFilesConfigReference || cfg.gatherFilesConfig,
|
||||||
);
|
);
|
||||||
|
|
@ -333,7 +332,7 @@ export class Analyzer {
|
||||||
if (!projectPath) {
|
if (!projectPath) {
|
||||||
LogService.error(`[Analyzer._traverse]: you must provide a projectPath`);
|
LogService.error(`[Analyzer._traverse]: you must provide a projectPath`);
|
||||||
}
|
}
|
||||||
finalTargetData = InputDataService.createDataObject([
|
finalTargetData = await InputDataService.createDataObject([
|
||||||
{
|
{
|
||||||
project: {
|
project: {
|
||||||
name: projectName || '[n/a]',
|
name: projectName || '[n/a]',
|
||||||
|
|
@ -366,7 +365,7 @@ export class Analyzer {
|
||||||
/**
|
/**
|
||||||
* Prepare
|
* Prepare
|
||||||
*/
|
*/
|
||||||
const cachedAnalyzerResult = this._prepare(cfg);
|
const cachedAnalyzerResult = await this._prepare(cfg);
|
||||||
if (cachedAnalyzerResult) {
|
if (cachedAnalyzerResult) {
|
||||||
return cachedAnalyzerResult;
|
return cachedAnalyzerResult;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,42 +1,37 @@
|
||||||
/* eslint-disable no-param-reassign */
|
|
||||||
import fs from 'fs';
|
|
||||||
import pathLib from 'path';
|
|
||||||
import child_process from 'child_process'; // eslint-disable-line camelcase
|
import child_process from 'child_process'; // eslint-disable-line camelcase
|
||||||
import glob from 'glob';
|
import path from 'path';
|
||||||
import anymatch from 'anymatch';
|
|
||||||
// @ts-expect-error
|
import { getFilePathRelativeFromRoot } from '../utils/get-file-path-relative-from-root.js';
|
||||||
import isNegatedGlob from 'is-negated-glob';
|
import { optimisedGlob } from '../utils/optimised-glob.js';
|
||||||
|
import { toPosixPath } from '../utils/to-posix-path.js';
|
||||||
|
import { fsAdapter } from '../utils/fs-adapter.js';
|
||||||
|
import { memoize } from '../utils/memoize.js';
|
||||||
import { LogService } from './LogService.js';
|
import { LogService } from './LogService.js';
|
||||||
import { AstService } from './AstService.js';
|
import { AstService } from './AstService.js';
|
||||||
import { getFilePathRelativeFromRoot } from '../utils/get-file-path-relative-from-root.js';
|
|
||||||
import { toPosixPath } from '../utils/to-posix-path.js';
|
|
||||||
import { memoize } from '../utils/memoize.js';
|
|
||||||
|
|
||||||
// const memoize = fn => fn;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @typedef {import('../../../types/index.js').PathRelativeFromProjectRoot} PathRelativeFromProjectRoot
|
||||||
* @typedef {import('../../../types/index.js').FindImportsAnalyzerResult} FindImportsAnalyzerResult
|
* @typedef {import('../../../types/index.js').FindImportsAnalyzerResult} FindImportsAnalyzerResult
|
||||||
* @typedef {import('../../../types/index.js').FindImportsAnalyzerEntry} FindImportsAnalyzerEntry
|
* @typedef {import('../../../types/index.js').FindImportsAnalyzerEntry} FindImportsAnalyzerEntry
|
||||||
* @typedef {import('../../../types/index.js').PathRelativeFromProjectRoot} PathRelativeFromProjectRoot
|
* @typedef {import('../../../types/index.js').ProjectInputDataWithMeta} ProjectInputDataWithMeta
|
||||||
|
* @typedef {import('../../../types/index.js').AnalyzerQueryResult} AnalyzerQueryResult
|
||||||
|
* @typedef {import('../../../types/index.js').AnalyzerQueryConfig} AnalyzerQueryConfig
|
||||||
|
* @typedef {import('../../../types/index.js').FeatureQueryConfig} FeatureQueryConfig
|
||||||
|
* @typedef {import('../../../types/index.js').PathFromSystemRoot} PathFromSystemRoot
|
||||||
|
* @typedef {import('../../../types/index.js').SearchQueryConfig} SearchQueryConfig
|
||||||
|
* @typedef {import('../../../types/index.js').GatherFilesConfig} GatherFilesConfig
|
||||||
|
* @typedef {import('../../../types/index.js').ProjectInputData} ProjectInputData
|
||||||
|
* @typedef {import('../../../types/index.js').AnalyzerConfig} AnalyzerConfig
|
||||||
|
* @typedef {{path:PathFromSystemRoot; name:ProjectName}} ProjectNameAndPath
|
||||||
* @typedef {import('../../../types/index.js').PathRelative} PathRelative
|
* @typedef {import('../../../types/index.js').PathRelative} PathRelative
|
||||||
|
* @typedef {import('../../../types/index.js').AnalyzerName} AnalyzerName
|
||||||
* @typedef {import('../../../types/index.js').QueryConfig} QueryConfig
|
* @typedef {import('../../../types/index.js').QueryConfig} QueryConfig
|
||||||
* @typedef {import('../../../types/index.js').QueryResult} QueryResult
|
* @typedef {import('../../../types/index.js').QueryResult} QueryResult
|
||||||
* @typedef {import('../../../types/index.js').FeatureQueryConfig} FeatureQueryConfig
|
|
||||||
* @typedef {import('../../../types/index.js').SearchQueryConfig} SearchQueryConfig
|
|
||||||
* @typedef {import('../../../types/index.js').AnalyzerQueryConfig} AnalyzerQueryConfig
|
|
||||||
* @typedef {import('../../../types/index.js').Feature} Feature
|
|
||||||
* @typedef {import('../../../types/index.js').AnalyzerConfig} AnalyzerConfig
|
|
||||||
* @typedef {import('../../../types/index.js').Analyzer} Analyzer
|
|
||||||
* @typedef {import('../../../types/index.js').AnalyzerName} AnalyzerName
|
|
||||||
* @typedef {import('../../../types/index.js').PathFromSystemRoot} PathFromSystemRoot
|
|
||||||
* @typedef {import('../../../types/index.js').GatherFilesConfig} GatherFilesConfig
|
|
||||||
* @typedef {import('../../../types/index.js').AnalyzerQueryResult} AnalyzerQueryResult
|
|
||||||
* @typedef {import('../../../types/index.js').ProjectInputData} ProjectInputData
|
|
||||||
* @typedef {import('../../../types/index.js').ProjectInputDataWithMeta} ProjectInputDataWithMeta
|
|
||||||
* @typedef {import('../../../types/index.js').Project} Project
|
|
||||||
* @typedef {import('../../../types/index.js').ProjectName} ProjectName
|
* @typedef {import('../../../types/index.js').ProjectName} ProjectName
|
||||||
* @typedef {import('../../../types/index.js').PackageJson} PackageJson
|
* @typedef {import('../../../types/index.js').PackageJson} PackageJson
|
||||||
* @typedef {{path:PathFromSystemRoot; name:ProjectName}} ProjectNameAndPath
|
* @typedef {import('../../../types/index.js').Analyzer} Analyzer
|
||||||
|
* @typedef {import('../../../types/index.js').Project} Project
|
||||||
|
* @typedef {import('../../../types/index.js').Feature} Feature
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -45,13 +40,13 @@ import { memoize } from '../utils/memoize.js';
|
||||||
*/
|
*/
|
||||||
const getPackageJson = memoize((/** @type {PathFromSystemRoot} */ rootPath) => {
|
const getPackageJson = memoize((/** @type {PathFromSystemRoot} */ rootPath) => {
|
||||||
try {
|
try {
|
||||||
const fileContent = fs.readFileSync(`${rootPath}/package.json`, 'utf8');
|
const fileContent = fsAdapter.fs.readFileSync(`${rootPath}/package.json`, 'utf8');
|
||||||
return JSON.parse(fileContent);
|
return JSON.parse(fileContent);
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
try {
|
try {
|
||||||
// For testing purposes, we allow to have a package.mock.json that contains 'fictional'
|
// For testing purposes, we allow to have a package.mock.json that contains 'fictional'
|
||||||
// packages (like 'exporting-ref-project') not on npm registry
|
// packages (like 'exporting-ref-project') not on npm registry
|
||||||
const fileContent = fs.readFileSync(`${rootPath}/package.mock.json`, 'utf8');
|
const fileContent = fsAdapter.fs.readFileSync(`${rootPath}/package.mock.json`, 'utf8');
|
||||||
return JSON.parse(fileContent);
|
return JSON.parse(fileContent);
|
||||||
} catch (__) {
|
} catch (__) {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|
@ -65,7 +60,7 @@ const getPackageJson = memoize((/** @type {PathFromSystemRoot} */ rootPath) => {
|
||||||
*/
|
*/
|
||||||
const getLernaJson = memoize((/** @type {PathFromSystemRoot} */ rootPath) => {
|
const getLernaJson = memoize((/** @type {PathFromSystemRoot} */ rootPath) => {
|
||||||
try {
|
try {
|
||||||
const fileContent = fs.readFileSync(`${rootPath}/lerna.json`, 'utf8');
|
const fileContent = fsAdapter.fs.readFileSync(`${rootPath}/lerna.json`, 'utf8');
|
||||||
return JSON.parse(fileContent);
|
return JSON.parse(fileContent);
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|
@ -73,34 +68,31 @@ const getLernaJson = memoize((/** @type {PathFromSystemRoot} */ rootPath) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {(list:PathFromSystemRoot[]|string[], rootPath:PathFromSystemRoot) => ProjectNameAndPath[]} GetPathsFromGlobListFn
|
* @typedef {(list:PathFromSystemRoot[]|string[], rootPath:PathFromSystemRoot) => Promise<ProjectNameAndPath[]>} GetPathsFromGlobListFn
|
||||||
* @type {GetPathsFromGlobListFn}
|
* @type {GetPathsFromGlobListFn}
|
||||||
*/
|
*/
|
||||||
const getPathsFromGlobList = memoize(
|
const getPathsFromGlobList = memoize(
|
||||||
(
|
async (
|
||||||
/** @type {PathFromSystemRoot[]|string[]} */ list,
|
/** @type {PathFromSystemRoot[]|string[]} */ list,
|
||||||
/** @type {PathFromSystemRoot} */ rootPath,
|
/** @type {PathFromSystemRoot} */ rootPath,
|
||||||
) => {
|
) => {
|
||||||
/** @type {string[]} */
|
/** @type {string[]} */
|
||||||
const results = [];
|
const results = [];
|
||||||
list.forEach(pathOrGlob => {
|
for (const pathOrGlob of list) {
|
||||||
if (!pathOrGlob.endsWith('/')) {
|
|
||||||
// eslint-disable-next-line no-param-reassign
|
|
||||||
pathOrGlob = `${pathOrGlob}/`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pathOrGlob.includes('*')) {
|
if (pathOrGlob.includes('*')) {
|
||||||
const globResults = glob.sync(pathOrGlob, { cwd: rootPath, absolute: false });
|
const globResults = await optimisedGlob(pathOrGlob, {
|
||||||
globResults.forEach(r => {
|
cwd: rootPath,
|
||||||
results.push(r);
|
absolute: false,
|
||||||
|
onlyFiles: false,
|
||||||
});
|
});
|
||||||
|
results.push(...globResults);
|
||||||
} else {
|
} else {
|
||||||
results.push(pathOrGlob);
|
results.push(pathOrGlob);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
return results.map(pkgPath => {
|
return results.map(pkgPath => {
|
||||||
const packageRoot = pathLib.resolve(rootPath, pkgPath);
|
const packageRoot = path.resolve(rootPath, pkgPath);
|
||||||
const basename = pathLib.basename(pkgPath);
|
const basename = path.basename(pkgPath);
|
||||||
const pkgJson = getPackageJson(/** @type {PathFromSystemRoot} */ (packageRoot));
|
const pkgJson = getPackageJson(/** @type {PathFromSystemRoot} */ (packageRoot));
|
||||||
const name = /** @type {ProjectName} */ ((pkgJson && pkgJson.name) || basename);
|
const name = /** @type {ProjectName} */ ((pkgJson && pkgJson.name) || basename);
|
||||||
return { name, path: /** @type {PathFromSystemRoot} */ (pkgPath) };
|
return { name, path: /** @type {PathFromSystemRoot} */ (pkgPath) };
|
||||||
|
|
@ -114,7 +106,7 @@ const getPathsFromGlobList = memoize(
|
||||||
*/
|
*/
|
||||||
const getGitignoreFile = memoize((/** @type {PathFromSystemRoot} */ rootPath) => {
|
const getGitignoreFile = memoize((/** @type {PathFromSystemRoot} */ rootPath) => {
|
||||||
try {
|
try {
|
||||||
return fs.readFileSync(`${rootPath}/.gitignore`, 'utf8');
|
return fsAdapter.fs.readFileSync(`${rootPath}/.gitignore`, 'utf8');
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
@ -131,6 +123,7 @@ const getGitIgnorePaths = memoize((/** @type {PathFromSystemRoot} */ rootPath) =
|
||||||
}
|
}
|
||||||
|
|
||||||
const entries = fileContent.split('\n').filter(entry => {
|
const entries = fileContent.split('\n').filter(entry => {
|
||||||
|
// eslint-disable-next-line no-param-reassign
|
||||||
entry = entry.trim();
|
entry = entry.trim();
|
||||||
if (entry.startsWith('#')) {
|
if (entry.startsWith('#')) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -143,15 +136,19 @@ const getGitIgnorePaths = memoize((/** @type {PathFromSystemRoot} */ rootPath) =
|
||||||
|
|
||||||
// normalize entries to be compatible with anymatch
|
// normalize entries to be compatible with anymatch
|
||||||
const normalizedEntries = entries.map(entry => {
|
const normalizedEntries = entries.map(entry => {
|
||||||
|
// eslint-disable-next-line no-param-reassign
|
||||||
entry = toPosixPath(entry);
|
entry = toPosixPath(entry);
|
||||||
|
|
||||||
if (entry.startsWith('/')) {
|
if (entry.startsWith('/')) {
|
||||||
|
// eslint-disable-next-line no-param-reassign
|
||||||
entry = entry.slice(1);
|
entry = entry.slice(1);
|
||||||
}
|
}
|
||||||
const isFile = entry.indexOf('.') > 0; // index of 0 means hidden file.
|
const isFile = entry.indexOf('.') > 0; // index of 0 means hidden file.
|
||||||
if (entry.endsWith('/')) {
|
if (entry.endsWith('/')) {
|
||||||
|
// eslint-disable-next-line no-param-reassign
|
||||||
entry += '**';
|
entry += '**';
|
||||||
} else if (!isFile) {
|
} else if (!isFile) {
|
||||||
|
// eslint-disable-next-line no-param-reassign
|
||||||
entry += '/**';
|
entry += '/**';
|
||||||
}
|
}
|
||||||
return entry;
|
return entry;
|
||||||
|
|
@ -189,30 +186,6 @@ function ensureArray(v) {
|
||||||
return Array.isArray(v) ? v : [v];
|
return Array.isArray(v) ? v : [v];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string|string[]} patterns
|
|
||||||
* @param {Partial<{keepDirs:boolean;root:string}>} [options]
|
|
||||||
*
|
|
||||||
* @typedef {(patterns:string|string[], opts: {keepDirs?:boolean;root:string}) => string[]} MultiGlobSyncFn
|
|
||||||
* @type {MultiGlobSyncFn}
|
|
||||||
*/
|
|
||||||
const multiGlobSync = memoize(
|
|
||||||
(/** @type {string|string[]} */ patterns, { keepDirs = false, root } = {}) => {
|
|
||||||
patterns = ensureArray(patterns);
|
|
||||||
const res = new Set();
|
|
||||||
patterns.forEach(pattern => {
|
|
||||||
const files = glob.sync(pattern, { root });
|
|
||||||
files.forEach(filePath => {
|
|
||||||
if (fs.lstatSync(filePath).isDirectory() && !keepDirs) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
res.add(filePath);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return Array.from(res);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} localPathWithDotSlash
|
* @param {string} localPathWithDotSlash
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
|
|
@ -261,26 +234,28 @@ export class InputDataService {
|
||||||
* @param {Partial<GatherFilesConfig>} gatherFilesConfig
|
* @param {Partial<GatherFilesConfig>} gatherFilesConfig
|
||||||
* @returns {ProjectInputDataWithMeta[]}
|
* @returns {ProjectInputDataWithMeta[]}
|
||||||
*/
|
*/
|
||||||
static createDataObject(projectPaths, gatherFilesConfig = {}) {
|
static async createDataObject(projectPaths, gatherFilesConfig = {}) {
|
||||||
/** @type {ProjectInputData[]} */
|
/** @type {ProjectInputData[]} */
|
||||||
const inputData = projectPaths.map(projectPathOrObj => {
|
const inputData = [];
|
||||||
|
for (const projectPathOrObj of projectPaths) {
|
||||||
if (typeof projectPathOrObj === 'object') {
|
if (typeof projectPathOrObj === 'object') {
|
||||||
// ProjectInputData was provided already manually
|
// ProjectInputData was provided already manually
|
||||||
return projectPathOrObj;
|
inputData.push(projectPathOrObj);
|
||||||
|
continue; // eslint-disable-line no-continue
|
||||||
}
|
}
|
||||||
|
|
||||||
const projectPath = projectPathOrObj;
|
const projectPath = projectPathOrObj;
|
||||||
return {
|
inputData.push({
|
||||||
project: /** @type {Project} */ ({
|
project: /** @type {Project} */ ({
|
||||||
name: pathLib.basename(projectPath),
|
name: path.basename(projectPath),
|
||||||
path: projectPath,
|
path: projectPath,
|
||||||
}),
|
}),
|
||||||
entries: this.gatherFilesFromDir(projectPath, {
|
entries: await this.gatherFilesFromDir(projectPath, {
|
||||||
...this.defaultGatherFilesConfig,
|
...this.defaultGatherFilesConfig,
|
||||||
...gatherFilesConfig,
|
...gatherFilesConfig,
|
||||||
}),
|
}),
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return this._addMetaToProjectsData(inputData);
|
return this._addMetaToProjectsData(inputData);
|
||||||
}
|
}
|
||||||
|
|
@ -333,7 +308,7 @@ export class InputDataService {
|
||||||
let commitHash;
|
let commitHash;
|
||||||
let isGitRepo;
|
let isGitRepo;
|
||||||
try {
|
try {
|
||||||
isGitRepo = fs.lstatSync(pathLib.resolve(projectPath, '.git')).isDirectory();
|
isGitRepo = fsAdapter.fs.lstatSync(path.resolve(projectPath, '.git')).isDirectory();
|
||||||
// eslint-disable-next-line no-empty
|
// eslint-disable-next-line no-empty
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
|
|
||||||
|
|
@ -372,7 +347,7 @@ export class InputDataService {
|
||||||
projectObj.entries.forEach(entry => {
|
projectObj.entries.forEach(entry => {
|
||||||
let code;
|
let code;
|
||||||
try {
|
try {
|
||||||
code = fs.readFileSync(entry, 'utf8');
|
code = fsAdapter.fs.readFileSync(entry, 'utf8');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
LogService.error(`Could not find "${entry}"`);
|
LogService.error(`Could not find "${entry}"`);
|
||||||
}
|
}
|
||||||
|
|
@ -380,7 +355,7 @@ export class InputDataService {
|
||||||
toPosixPath(entry),
|
toPosixPath(entry),
|
||||||
toPosixPath(projectObj.project.path),
|
toPosixPath(projectObj.project.path),
|
||||||
);
|
);
|
||||||
if (pathLib.extname(file) === '.html') {
|
if (path.extname(file) === '.html') {
|
||||||
const extractedScripts = AstService.getScriptsFromHtml(/** @type {string} */ (code));
|
const extractedScripts = AstService.getScriptsFromHtml(/** @type {string} */ (code));
|
||||||
// eslint-disable-next-line no-shadow
|
// eslint-disable-next-line no-shadow
|
||||||
extractedScripts.forEach((code, i) => {
|
extractedScripts.forEach((code, i) => {
|
||||||
|
|
@ -409,19 +384,16 @@ export class InputDataService {
|
||||||
if (this.__targetProjectPaths) {
|
if (this.__targetProjectPaths) {
|
||||||
return this.__targetProjectPaths;
|
return this.__targetProjectPaths;
|
||||||
}
|
}
|
||||||
const submoduleDir = pathLib.resolve(
|
const submoduleDir = path.resolve(__dirname, '../../../providence-input-data/search-targets');
|
||||||
__dirname,
|
|
||||||
'../../../providence-input-data/search-targets',
|
|
||||||
);
|
|
||||||
let dirs;
|
let dirs;
|
||||||
try {
|
try {
|
||||||
dirs = fs.readdirSync(submoduleDir);
|
dirs = fsAdapter.fs.readdirSync(submoduleDir);
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
return dirs
|
return dirs
|
||||||
.map(dir => /** @type {PathFromSystemRoot} */ (pathLib.join(submoduleDir, dir)))
|
.map(dir => /** @type {PathFromSystemRoot} */ (path.join(submoduleDir, dir)))
|
||||||
.filter(dirPath => fs.lstatSync(dirPath).isDirectory());
|
.filter(dirPath => fsAdapter.fs.lstatSync(dirPath).isDirectory());
|
||||||
}
|
}
|
||||||
|
|
||||||
static set targetProjectPaths(v) {
|
static set targetProjectPaths(v) {
|
||||||
|
|
@ -438,11 +410,11 @@ export class InputDataService {
|
||||||
|
|
||||||
let dirs;
|
let dirs;
|
||||||
try {
|
try {
|
||||||
const referencesDir = pathLib.resolve(__dirname, '../../../providence-input-data/references');
|
const referencesDir = path.resolve(__dirname, '../../../providence-input-data/references');
|
||||||
dirs = fs.readdirSync(referencesDir);
|
dirs = fsAdapter.fs.readdirSync(referencesDir);
|
||||||
dirs = dirs
|
dirs = dirs
|
||||||
.map(dir => pathLib.join(referencesDir, dir))
|
.map(dir => path.join(referencesDir, dir))
|
||||||
.filter(dirPath => fs.lstatSync(dirPath).isDirectory());
|
.filter(dirPath => fsAdapter.fs.lstatSync(dirPath).isDirectory());
|
||||||
// eslint-disable-next-line no-empty
|
// eslint-disable-next-line no-empty
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
return /** @type {PathFromSystemRoot[]} */ (dirs);
|
return /** @type {PathFromSystemRoot[]} */ (dirs);
|
||||||
|
|
@ -457,31 +429,31 @@ export class InputDataService {
|
||||||
*/
|
*/
|
||||||
static get defaultGatherFilesConfig() {
|
static get defaultGatherFilesConfig() {
|
||||||
return {
|
return {
|
||||||
extensions: ['.js'],
|
|
||||||
allowlist: ['!node_modules/**', '!bower_components/**', '!**/*.conf.js', '!**/*.config.js'],
|
allowlist: ['!node_modules/**', '!bower_components/**', '!**/*.conf.js', '!**/*.config.js'],
|
||||||
|
extensions: ['.js'],
|
||||||
depth: Infinity,
|
depth: Infinity,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {PathFromSystemRoot} startPath
|
* @protected
|
||||||
* @param {GatherFilesConfig} cfg
|
* @param {number} depth
|
||||||
* @param {boolean} withoutDepth
|
* @param {string[]} extensions
|
||||||
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
static getGlobPattern(startPath, cfg, withoutDepth = false) {
|
static _getDefaultGlobDepthPattern(depth = Infinity, extensions = ['.js']) {
|
||||||
// if startPath ends with '/', remove
|
// `.{${cfg.extensions.map(e => e.slice(1)).join(',')},}`;
|
||||||
let globPattern = startPath.replace(/\/$/, '');
|
const extensionsGlobPart = `.{${extensions.map(extension => extension.slice(1)).join(',')},}`;
|
||||||
if (process.platform === 'win32') {
|
if (depth === Infinity) {
|
||||||
globPattern = globPattern.replace(/^.:/, '').replace(/\\/g, '/');
|
return `**/*${extensionsGlobPart}`;
|
||||||
}
|
}
|
||||||
if (!withoutDepth) {
|
if (depth > 1) {
|
||||||
if (typeof cfg.depth === 'number' && cfg.depth !== Infinity) {
|
return `${`/*`.repeat(depth + 1)}${extensionsGlobPart}`;
|
||||||
globPattern += `/*`.repeat(cfg.depth + 1);
|
|
||||||
} else {
|
|
||||||
globPattern += `/**/*`;
|
|
||||||
}
|
}
|
||||||
|
if (depth === 0) {
|
||||||
|
return `*${extensionsGlobPart}`;
|
||||||
}
|
}
|
||||||
return { globPattern };
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -498,9 +470,9 @@ export class InputDataService {
|
||||||
* Gets an array of files for given extension
|
* Gets an array of files for given extension
|
||||||
* @param {PathFromSystemRoot} startPath - local filesystem path
|
* @param {PathFromSystemRoot} startPath - local filesystem path
|
||||||
* @param {Partial<GatherFilesConfig>} customConfig - configuration object
|
* @param {Partial<GatherFilesConfig>} customConfig - configuration object
|
||||||
* @returns {PathFromSystemRoot[]} result list of file paths
|
* @returns {Promise<PathFromSystemRoot[]>} result list of file paths
|
||||||
*/
|
*/
|
||||||
static gatherFilesFromDir(startPath, customConfig = {}) {
|
static async gatherFilesFromDir(startPath, customConfig = {}) {
|
||||||
const cfg = {
|
const cfg = {
|
||||||
...this.defaultGatherFilesConfig,
|
...this.defaultGatherFilesConfig,
|
||||||
...customConfig,
|
...customConfig,
|
||||||
|
|
@ -523,84 +495,79 @@ export class InputDataService {
|
||||||
|
|
||||||
if (cfg.allowlistMode === 'export-map') {
|
if (cfg.allowlistMode === 'export-map') {
|
||||||
const pkgJson = getPackageJson(startPath);
|
const pkgJson = getPackageJson(startPath);
|
||||||
if (!pkgJson.exports) {
|
if (!pkgJson?.exports) {
|
||||||
LogService.error(`No exports found in package.json of ${startPath}`);
|
LogService.error(`No exports found in package.json of ${startPath}`);
|
||||||
}
|
}
|
||||||
const exposedAndInternalPaths = this.getPathsFromExportMap(pkgJson.exports, {
|
const exposedAndInternalPaths = await this.getPathsFromExportMap(pkgJson?.exports, {
|
||||||
packageRootPath: startPath,
|
packageRootPath: startPath,
|
||||||
});
|
});
|
||||||
return exposedAndInternalPaths
|
return exposedAndInternalPaths
|
||||||
.map(p => p.internal)
|
.map(p => p.internal)
|
||||||
.filter(p => cfg.extensions.includes(`${pathLib.extname(p)}`));
|
.filter(p => cfg.extensions.includes(`${path.extname(p)}`));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @type {string[]} */
|
/** @type {string[]} */
|
||||||
let gitIgnorePaths = [];
|
const negativeGitGlobs = [];
|
||||||
/** @type {string[]} */
|
/** @type {string[]} */
|
||||||
let npmPackagePaths = [];
|
const npmGlobs = [];
|
||||||
const allowlistMode = cfg.allowlistMode || this._determineAllowListMode(startPath);
|
const allowlistMode = cfg.allowlistMode || this._determineAllowListMode(startPath);
|
||||||
|
|
||||||
if (allowlistMode === 'git') {
|
if (allowlistMode === 'git') {
|
||||||
gitIgnorePaths = getGitIgnorePaths(startPath);
|
negativeGitGlobs.push(
|
||||||
|
...getGitIgnorePaths(startPath).map(gitIgnorePath => `!${gitIgnorePath}`),
|
||||||
|
);
|
||||||
} else if (allowlistMode === 'npm') {
|
} else if (allowlistMode === 'npm') {
|
||||||
npmPackagePaths = getNpmPackagePaths(startPath);
|
npmGlobs.push(...getNpmPackagePaths(startPath));
|
||||||
}
|
|
||||||
const removeFilter = gitIgnorePaths;
|
|
||||||
const keepFilter = npmPackagePaths;
|
|
||||||
|
|
||||||
cfg.allowlist.forEach(allowEntry => {
|
|
||||||
const { negated, pattern } = isNegatedGlob(allowEntry);
|
|
||||||
if (negated) {
|
|
||||||
removeFilter.push(pattern);
|
|
||||||
} else {
|
|
||||||
keepFilter.push(allowEntry);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let { globPattern } = this.getGlobPattern(startPath, cfg);
|
|
||||||
globPattern += `.{${cfg.extensions.map(e => e.slice(1)).join(',')},}`;
|
|
||||||
const globRes = multiGlobSync(globPattern);
|
|
||||||
|
|
||||||
let filteredGlobRes;
|
|
||||||
if (removeFilter.length || keepFilter.length) {
|
|
||||||
filteredGlobRes = globRes.filter(filePath => {
|
|
||||||
const localFilePath = toPosixPath(filePath).replace(`${toPosixPath(startPath)}/`, '');
|
|
||||||
// @ts-expect-error
|
|
||||||
let shouldRemove = removeFilter.length && anymatch(removeFilter, localFilePath);
|
|
||||||
// @ts-expect-error
|
|
||||||
let shouldKeep = keepFilter.length && anymatch(keepFilter, localFilePath);
|
|
||||||
|
|
||||||
if (shouldRemove && shouldKeep) {
|
|
||||||
// Contradicting configs: the one defined by end user takes highest precedence
|
|
||||||
// If the match came from allowListMode, it loses.
|
|
||||||
// @ts-expect-error
|
|
||||||
if (allowlistMode === 'git' && anymatch(gitIgnorePaths, localFilePath)) {
|
|
||||||
// shouldRemove was caused by .gitignore, shouldKeep by custom allowlist
|
|
||||||
shouldRemove = false;
|
|
||||||
// @ts-expect-error
|
|
||||||
} else if (allowlistMode === 'npm' && anymatch(npmPackagePaths, localFilePath)) {
|
|
||||||
// shouldKeep was caused by npm "files", shouldRemove by custom allowlist
|
|
||||||
shouldKeep = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (removeFilter.length && shouldRemove) {
|
const combinedGlobs = [...cfg.allowlist, ...npmGlobs, ...negativeGitGlobs];
|
||||||
return false;
|
const hasProvidedPositiveGlob = cfg.allowlist.some(glob => !glob.startsWith('!'));
|
||||||
}
|
|
||||||
if (!keepFilter.length) {
|
// We need to expand
|
||||||
return true;
|
const shouldLookForAllFilesInProject =
|
||||||
}
|
allowlistMode === 'all' || (!npmGlobs.length && !hasProvidedPositiveGlob);
|
||||||
return shouldKeep;
|
if (shouldLookForAllFilesInProject) {
|
||||||
});
|
combinedGlobs.push(this._getDefaultGlobDepthPattern(cfg.depth, cfg.extensions));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!filteredGlobRes || !filteredGlobRes.length) {
|
const globbyCfg = {
|
||||||
|
expandDirectories: false,
|
||||||
|
onlyFiles: true,
|
||||||
|
absolute: true,
|
||||||
|
cwd: startPath,
|
||||||
|
};
|
||||||
|
let filteredGlobRes = await optimisedGlob(combinedGlobs, globbyCfg);
|
||||||
|
|
||||||
|
// Unfortunatly, globby does not correctly remove the negated globs,
|
||||||
|
// so we have to do it manually
|
||||||
|
const negatedGlobs = combinedGlobs.filter(p => p.startsWith('!'));
|
||||||
|
if (negatedGlobs.length) {
|
||||||
|
const subtract = await optimisedGlob(
|
||||||
|
negatedGlobs.map(p => p.slice(1)),
|
||||||
|
globbyCfg,
|
||||||
|
);
|
||||||
|
// eslint-disable-next-line no-shadow
|
||||||
|
filteredGlobRes = filteredGlobRes.filter(file => !subtract.includes(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure we don't delete to much by giving customConfig.allowlist priority
|
||||||
|
if (customConfig.allowlist?.length) {
|
||||||
|
const customResults = await optimisedGlob(customConfig.allowlist, globbyCfg);
|
||||||
|
filteredGlobRes = Array.from(new Set([...filteredGlobRes, ...customResults]));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter by extension (in the future: use globs exclusively for this?)
|
||||||
|
if (cfg.extensions.length) {
|
||||||
|
filteredGlobRes = filteredGlobRes.filter(glob =>
|
||||||
|
cfg.extensions.some(ext => glob.endsWith(ext)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!filteredGlobRes?.length) {
|
||||||
LogService.warn(`No files found for path '${startPath}'`);
|
LogService.warn(`No files found for path '${startPath}'`);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
// reappend startPath
|
|
||||||
// const res = filteredGlobRes.map(f => pathLib.resolve(startPath, f));
|
|
||||||
return /** @type {PathFromSystemRoot[]} */ (filteredGlobRes.map(toPosixPath));
|
return /** @type {PathFromSystemRoot[]} */ (filteredGlobRes.map(toPosixPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -617,9 +584,9 @@ export class InputDataService {
|
||||||
/**
|
/**
|
||||||
* Gives back all monorepo package paths
|
* Gives back all monorepo package paths
|
||||||
* @param {PathFromSystemRoot} rootPath
|
* @param {PathFromSystemRoot} rootPath
|
||||||
* @returns {ProjectNameAndPath[]|undefined}
|
* @ returns {ProjectNameAndPath[]|undefined}
|
||||||
*/
|
*/
|
||||||
static getMonoRepoPackages(rootPath) {
|
static async getMonoRepoPackages(rootPath) {
|
||||||
// [1] Look for npm/yarn workspaces
|
// [1] Look for npm/yarn workspaces
|
||||||
const pkgJson = getPackageJson(rootPath);
|
const pkgJson = getPackageJson(rootPath);
|
||||||
if (pkgJson?.workspaces) {
|
if (pkgJson?.workspaces) {
|
||||||
|
|
@ -641,7 +608,7 @@ export class InputDataService {
|
||||||
* @param {string} opts.packageRootPath
|
* @param {string} opts.packageRootPath
|
||||||
* @returns {Promise<{internalExportMapPaths:string[]; exposedExportMapPaths:string[]}>}
|
* @returns {Promise<{internalExportMapPaths:string[]; exposedExportMapPaths:string[]}>}
|
||||||
*/
|
*/
|
||||||
static getPathsFromExportMap(exports, { nodeResolveMode = 'default', packageRootPath }) {
|
static async getPathsFromExportMap(exports, { nodeResolveMode = 'default', packageRootPath }) {
|
||||||
const exportMapPaths = [];
|
const exportMapPaths = [];
|
||||||
|
|
||||||
for (const [key, valObjOrStr] of Object.entries(exports)) {
|
for (const [key, valObjOrStr] of Object.entries(exports)) {
|
||||||
|
|
@ -672,25 +639,24 @@ export class InputDataService {
|
||||||
const valueToUseForGlob = stripDotSlashFromLocalPath(resolvedVal).replace('*', '**/*');
|
const valueToUseForGlob = stripDotSlashFromLocalPath(resolvedVal).replace('*', '**/*');
|
||||||
|
|
||||||
// Generate all possible entries via glob, first strip './'
|
// Generate all possible entries via glob, first strip './'
|
||||||
const internalExportMapPathsForKeyRaw = glob.sync(valueToUseForGlob, {
|
const internalExportMapPathsForKeyRaw = await optimisedGlob(valueToUseForGlob, {
|
||||||
cwd: packageRootPath,
|
cwd: packageRootPath,
|
||||||
nodir: true,
|
onlyFiles: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const exposedExportMapPathsForKeyRaw = internalExportMapPathsForKeyRaw.map(pathInside => {
|
const exposedExportMapPathsForKeyRaw = internalExportMapPathsForKeyRaw.map(pathInside => {
|
||||||
// Say we have "exports": { "./*.js": "./src/*.js" }
|
// Say we have "exports": { "./*.js": "./src/*.js" }
|
||||||
// => internalExportMapPathsForKey: ['./src/a.js', './src/b.js']
|
// => internalExportMapPathsForKey: ['./src/a.js', './src/b.js']
|
||||||
// => exposedExportMapPathsForKey: ['./a.js', './b.js']
|
// => exposedExportMapPathsForKey: ['./a.js', './b.js']
|
||||||
const [, variablePart] = pathInside.match(
|
const [, variablePart] =
|
||||||
new RegExp(valueToUseForGlob.replace('*', '(.*)')),
|
pathInside.match(new RegExp(valueToUseForGlob.replace('*', '(.*)'))) || [];
|
||||||
);
|
|
||||||
return resolvedKey.replace('*', variablePart);
|
return resolvedKey.replace('*', variablePart);
|
||||||
});
|
});
|
||||||
const internalExportMapPathsForKey = internalExportMapPathsForKeyRaw.map(filePath =>
|
const internalExportMapPathsForKey = internalExportMapPathsForKeyRaw.map(
|
||||||
normalizeLocalPathWithDotSlash(filePath),
|
normalizeLocalPathWithDotSlash,
|
||||||
);
|
);
|
||||||
const exposedExportMapPathsForKey = exposedExportMapPathsForKeyRaw.map(filePath =>
|
const exposedExportMapPathsForKey = exposedExportMapPathsForKeyRaw.map(
|
||||||
normalizeLocalPathWithDotSlash(filePath),
|
normalizeLocalPathWithDotSlash,
|
||||||
);
|
);
|
||||||
|
|
||||||
exportMapPaths.push(
|
exportMapPaths.push(
|
||||||
|
|
@ -704,9 +670,6 @@ export class InputDataService {
|
||||||
return exportMapPaths;
|
return exportMapPaths;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: Remove memoizeConfig.isCacheDisabled this once whole providence uses cacheConfig instead of
|
|
||||||
// memoizeConfig.isCacheDisabled
|
|
||||||
// InputDataService.cacheDisabled = memoizeConfig.isCacheDisabled;
|
|
||||||
|
|
||||||
InputDataService.getProjectMeta = memoize(InputDataService.getProjectMeta);
|
InputDataService.getProjectMeta = memoize(InputDataService.getProjectMeta);
|
||||||
InputDataService.gatherFilesFromDir = memoize(InputDataService.gatherFilesFromDir);
|
InputDataService.gatherFilesFromDir = memoize(InputDataService.gatherFilesFromDir);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import pathLib from 'path';
|
import path from 'path';
|
||||||
import fs from 'fs';
|
import { fsAdapter } from '../utils/fs-adapter.js';
|
||||||
|
|
||||||
const { log } = console;
|
const { log } = console;
|
||||||
|
|
||||||
|
|
@ -111,14 +111,14 @@ export class LogService {
|
||||||
}
|
}
|
||||||
|
|
||||||
static writeLogFile() {
|
static writeLogFile() {
|
||||||
const filePath = pathLib.join(process.cwd(), 'providence.log');
|
const filePath = path.join(process.cwd(), 'providence.log');
|
||||||
let file = `[log ${new Date()}]\n`;
|
let file = `[log ${new Date()}]\n`;
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
this._logHistory.forEach(l => {
|
this._logHistory.forEach(l => {
|
||||||
file += `${l}\n`;
|
file += `${l}\n`;
|
||||||
});
|
});
|
||||||
file += `[/log ${new Date()}]\n\n`;
|
file += `[/log ${new Date()}]\n\n`;
|
||||||
fs.writeFileSync(filePath, file, { flag: 'a' });
|
fsAdapter.fs.writeFileSync(filePath, file, { flag: 'a' });
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
this._logHistory = [];
|
this._logHistory = [];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,18 @@
|
||||||
import fs from 'fs';
|
import path from 'path';
|
||||||
import pathLib from 'path';
|
|
||||||
import { getHash } from '../utils/get-hash.js';
|
import { getHash } from '../utils/get-hash.js';
|
||||||
// import { memoize } from '../utils/memoize.js';
|
import { fsAdapter } from '../utils/fs-adapter.js';
|
||||||
const memoize = fn => fn;
|
|
||||||
|
import { memoize } from '../utils/memoize.js';
|
||||||
|
// const memoize = fn => fn;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {import('../../../types/index.js').Project} Project
|
|
||||||
* @typedef {import('../../../types/index.js').ProjectName} ProjectName
|
|
||||||
* @typedef {import('../../../types/index.js').AnalyzerQueryResult} AnalyzerQueryResult
|
* @typedef {import('../../../types/index.js').AnalyzerQueryResult} AnalyzerQueryResult
|
||||||
|
* @typedef {import('../../../types/index.js').PathFromSystemRoot} PathFromSystemRoot
|
||||||
* @typedef {import('../../../types/index.js').AnalyzerConfig} AnalyzerConfig
|
* @typedef {import('../../../types/index.js').AnalyzerConfig} AnalyzerConfig
|
||||||
* @typedef {import('../../../types/index.js').AnalyzerName} AnalyzerName
|
* @typedef {import('../../../types/index.js').AnalyzerName} AnalyzerName
|
||||||
|
* @typedef {import('../../../types/index.js').ProjectName} ProjectName
|
||||||
* @typedef {import('../../../types/index.js').QueryResult} QueryResult
|
* @typedef {import('../../../types/index.js').QueryResult} QueryResult
|
||||||
* @typedef {import('../../../types/index.js').PathFromSystemRoot} PathFromSystemRoot
|
* @typedef {import('../../../types/index.js').Project} Project
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -57,20 +58,20 @@ export class ReportService {
|
||||||
outputPath = this.outputPath,
|
outputPath = this.outputPath,
|
||||||
) {
|
) {
|
||||||
const output = JSON.stringify(queryResult, null, 2);
|
const output = JSON.stringify(queryResult, null, 2);
|
||||||
if (!fs.existsSync(outputPath)) {
|
if (!fsAdapter.fs.existsSync(outputPath)) {
|
||||||
fs.mkdirSync(outputPath);
|
fsAdapter.fs.mkdirSync(outputPath);
|
||||||
}
|
}
|
||||||
const { name } = queryResult.meta.analyzerMeta;
|
const { name } = queryResult.meta.analyzerMeta;
|
||||||
const filePath = this._getResultFileNameAndPath(name, identifier);
|
const filePath = this._getResultFileNameAndPath(name, identifier);
|
||||||
|
|
||||||
fs.writeFileSync(filePath, output, { flag: 'w' });
|
fsAdapter.fs.writeFileSync(filePath, output, { flag: 'w' });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
static get outputPath() {
|
static get outputPath() {
|
||||||
return this.__outputPath || pathLib.join(process.cwd(), '/providence-output');
|
return this.__outputPath || path.join(process.cwd(), '/providence-output');
|
||||||
}
|
}
|
||||||
|
|
||||||
static set outputPath(p) {
|
static set outputPath(p) {
|
||||||
|
|
@ -93,7 +94,10 @@ export class ReportService {
|
||||||
let cachedResult;
|
let cachedResult;
|
||||||
try {
|
try {
|
||||||
cachedResult = JSON.parse(
|
cachedResult = JSON.parse(
|
||||||
fs.readFileSync(this._getResultFileNameAndPath(analyzerName, identifier), 'utf-8'),
|
fsAdapter.fs.readFileSync(
|
||||||
|
this._getResultFileNameAndPath(analyzerName, identifier),
|
||||||
|
'utf-8',
|
||||||
|
),
|
||||||
);
|
);
|
||||||
// eslint-disable-next-line no-empty
|
// eslint-disable-next-line no-empty
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
|
|
@ -107,7 +111,7 @@ export class ReportService {
|
||||||
*/
|
*/
|
||||||
static _getResultFileNameAndPath(name, identifier) {
|
static _getResultFileNameAndPath(name, identifier) {
|
||||||
return /** @type {PathFromSystemRoot} */ (
|
return /** @type {PathFromSystemRoot} */ (
|
||||||
pathLib.join(this.outputPath, `${name || 'query'}_-_${identifier}.json`)
|
path.join(this.outputPath, `${name || 'query'}_-_${identifier}.json`)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -117,15 +121,15 @@ export class ReportService {
|
||||||
*/
|
*/
|
||||||
static writeEntryToSearchTargetDepsFile(depProj, rootProjectMeta) {
|
static writeEntryToSearchTargetDepsFile(depProj, rootProjectMeta) {
|
||||||
const rootProj = `${rootProjectMeta.name}#${rootProjectMeta.version}`;
|
const rootProj = `${rootProjectMeta.name}#${rootProjectMeta.version}`;
|
||||||
const filePath = pathLib.join(this.outputPath, 'search-target-deps-file.json');
|
const filePath = path.join(this.outputPath, 'search-target-deps-file.json');
|
||||||
let file = {};
|
let file = {};
|
||||||
try {
|
try {
|
||||||
file = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
file = JSON.parse(fsAdapter.fs.readFileSync(filePath, 'utf-8'));
|
||||||
// eslint-disable-next-line no-empty
|
// eslint-disable-next-line no-empty
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
const deps = [...(file[rootProj] || []), depProj];
|
const deps = [...(file[rootProj] || []), depProj];
|
||||||
file[rootProj] = [...new Set(deps)];
|
file[rootProj] = [...new Set(deps)];
|
||||||
fs.writeFileSync(filePath, JSON.stringify(file, null, 2), { flag: 'w' });
|
fsAdapter.fs.writeFileSync(filePath, JSON.stringify(file, null, 2), { flag: 'w' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ReportService.createIdentifier = memoize(ReportService.createIdentifier);
|
ReportService.createIdentifier = memoize(ReportService.createIdentifier);
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
import { performance } from 'perf_hooks';
|
import { performance } from 'perf_hooks';
|
||||||
import { ReportService } from './core/ReportService.js';
|
import nodeFs from 'fs';
|
||||||
|
|
||||||
import { InputDataService } from './core/InputDataService.js';
|
import { InputDataService } from './core/InputDataService.js';
|
||||||
import { LogService } from './core/LogService.js';
|
import { ReportService } from './core/ReportService.js';
|
||||||
import { QueryService } from './core/QueryService.js';
|
import { QueryService } from './core/QueryService.js';
|
||||||
|
import { fsAdapter } from './utils/fs-adapter.js';
|
||||||
|
import { LogService } from './core/LogService.js';
|
||||||
import { AstService } from './core/AstService.js';
|
import { AstService } from './core/AstService.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -196,9 +199,15 @@ export async function providence(queryConfig, customConfig) {
|
||||||
/** Allows to navigate to source file in code editor */
|
/** Allows to navigate to source file in code editor */
|
||||||
addSystemPathsInResult: false,
|
addSystemPathsInResult: false,
|
||||||
fallbackToBabel: false,
|
fallbackToBabel: false,
|
||||||
|
fs: nodeFs,
|
||||||
...customConfig,
|
...customConfig,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (cfg.fs) {
|
||||||
|
// Allow to mock fs for testing
|
||||||
|
fsAdapter.setFs(cfg.fs);
|
||||||
|
}
|
||||||
|
|
||||||
if (cfg.debugEnabled) {
|
if (cfg.debugEnabled) {
|
||||||
LogService.debugEnabled = true;
|
LogService.debugEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
@ -215,7 +224,7 @@ export async function providence(queryConfig, customConfig) {
|
||||||
if (queryConfig.type === 'ast-analyzer') {
|
if (queryConfig.type === 'ast-analyzer') {
|
||||||
queryResults = await handleAnalyzer(queryConfig, cfg);
|
queryResults = await handleAnalyzer(queryConfig, cfg);
|
||||||
} else {
|
} else {
|
||||||
const inputData = InputDataService.createDataObject(
|
const inputData = await InputDataService.createDataObject(
|
||||||
cfg.targetProjectPaths,
|
cfg.targetProjectPaths,
|
||||||
cfg.gatherFilesConfig,
|
cfg.gatherFilesConfig,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import fs from 'fs';
|
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import babelTraversePkg from '@babel/traverse';
|
import babelTraversePkg from '@babel/traverse';
|
||||||
import { AstService } from '../core/AstService.js';
|
import { AstService } from '../core/AstService.js';
|
||||||
import { trackDownIdentifier } from '../analyzers/helpers/track-down-identifier.js';
|
import { trackDownIdentifier } from '../analyzers/helpers/track-down-identifier.js';
|
||||||
import { toPosixPath } from './to-posix-path.js';
|
import { toPosixPath } from './to-posix-path.js';
|
||||||
|
import { fsAdapter } from './fs-adapter.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {import('@babel/types').Node} Node
|
* @typedef {import('@babel/types').Node} Node
|
||||||
|
|
@ -82,7 +82,7 @@ export async function getSourceCodeFragmentOfDeclaration({
|
||||||
exportedIdentifier,
|
exportedIdentifier,
|
||||||
projectRootPath,
|
projectRootPath,
|
||||||
}) {
|
}) {
|
||||||
const code = fs.readFileSync(filePath, 'utf8');
|
const code = fsAdapter.fs.readFileSync(filePath, 'utf8');
|
||||||
// TODO: fix swc-to-babel lib to make this compatible with 'swc-to-babel' mode of getAst
|
// TODO: fix swc-to-babel lib to make this compatible with 'swc-to-babel' mode of getAst
|
||||||
const babelAst = AstService.getAst(code, 'babel', { filePath });
|
const babelAst = AstService.getAst(code, 'babel', { filePath });
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import fs from 'fs';
|
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { swcTraverse, getPathFromNode } from './swc-traverse.js';
|
import { swcTraverse, getPathFromNode } from './swc-traverse.js';
|
||||||
import { AstService } from '../core/AstService.js';
|
import { AstService } from '../core/AstService.js';
|
||||||
import { trackDownIdentifier } from '../analyzers/helpers/track-down-identifier.js';
|
import { trackDownIdentifier } from '../analyzers/helpers/track-down-identifier.js';
|
||||||
import { toPosixPath } from './to-posix-path.js';
|
import { toPosixPath } from './to-posix-path.js';
|
||||||
|
import { fsAdapter } from './fs-adapter.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {import('@swc/core').Node} SwcNode
|
* @typedef {import('@swc/core').Node} SwcNode
|
||||||
|
|
@ -84,7 +84,7 @@ export async function getSourceCodeFragmentOfDeclaration({
|
||||||
exportedIdentifier,
|
exportedIdentifier,
|
||||||
projectRootPath,
|
projectRootPath,
|
||||||
}) {
|
}) {
|
||||||
const code = fs.readFileSync(filePath, 'utf8');
|
const code = fsAdapter.fs.readFileSync(filePath, 'utf8');
|
||||||
|
|
||||||
// compensate for swc span bug: https://github.com/swc-project/swc/issues/1366#issuecomment-1516539812
|
// compensate for swc span bug: https://github.com/swc-project/swc/issues/1366#issuecomment-1516539812
|
||||||
const offset = AstService._getSwcOffset();
|
const offset = AstService._getSwcOffset();
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import pathLib from 'path';
|
import path from 'path';
|
||||||
import fs from 'fs';
|
|
||||||
import { pathToFileURL } from 'url';
|
import { pathToFileURL } from 'url';
|
||||||
|
import { fsAdapter } from './fs-adapter.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {import('../../../types/index.js').ProvidenceCliConf} ProvidenceCliConf
|
* @typedef {import('../../../types/index.js').ProvidenceCliConf} ProvidenceCliConf
|
||||||
|
|
@ -10,12 +10,12 @@ import { pathToFileURL } from 'url';
|
||||||
* @returns {Promise<{providenceConf:Partial<ProvidenceCliConf>;providenceConfRaw:string}|null>}
|
* @returns {Promise<{providenceConf:Partial<ProvidenceCliConf>;providenceConfRaw:string}|null>}
|
||||||
*/
|
*/
|
||||||
async function getConf() {
|
async function getConf() {
|
||||||
const confPathWithoutExtension = `${pathLib.join(process.cwd(), 'providence.conf')}`;
|
const confPathWithoutExtension = `${path.join(process.cwd(), 'providence.conf')}`;
|
||||||
let confPathFound;
|
let confPathFound;
|
||||||
try {
|
try {
|
||||||
if (fs.existsSync(`${confPathWithoutExtension}.js`)) {
|
if (fsAdapter.fs.existsSync(`${confPathWithoutExtension}.js`)) {
|
||||||
confPathFound = `${confPathWithoutExtension}.js`;
|
confPathFound = `${confPathWithoutExtension}.js`;
|
||||||
} else if (fs.existsSync(`${confPathWithoutExtension}.mjs`)) {
|
} else if (fsAdapter.fs.existsSync(`${confPathWithoutExtension}.mjs`)) {
|
||||||
confPathFound = `${confPathWithoutExtension}.mjs`;
|
confPathFound = `${confPathWithoutExtension}.mjs`;
|
||||||
}
|
}
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
|
|
@ -36,7 +36,7 @@ async function getConf() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const providenceConfRaw = fs.readFileSync(confPathFound, 'utf8');
|
const providenceConfRaw = fsAdapter.fs.readFileSync(confPathFound, 'utf8');
|
||||||
return { providenceConf, providenceConfRaw };
|
return { providenceConf, providenceConfRaw };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,227 +0,0 @@
|
||||||
// @ts-nocheck
|
|
||||||
/* eslint-disable */
|
|
||||||
/**
|
|
||||||
* This is a modified version of https://github.com/npm/read-package-tree/blob/master/rpt.js
|
|
||||||
* The original is meant for npm dependencies only. In our (rare) case, we have a hybrid landscape
|
|
||||||
* where we also want to look for npm dependencies inside bower dependencies (bower_components folder).
|
|
||||||
*
|
|
||||||
* Original: https://github.com/npm/read-package-tree
|
|
||||||
*
|
|
||||||
* The ISC License
|
|
||||||
*
|
|
||||||
* Copyright (c) Isaac Z. Schlueter and Contributors
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
|
||||||
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import fs from 'fs';
|
|
||||||
/* istanbul ignore next */
|
|
||||||
import { promisify } from 'util';
|
|
||||||
import { basename, dirname, join } from 'path';
|
|
||||||
import rpjSync from 'read-package-json';
|
|
||||||
import readdirSync from 'readdir-scoped-modules';
|
|
||||||
import realpath from 'read-package-tree/realpath.js';
|
|
||||||
|
|
||||||
const rpj = promisify(rpjSync);
|
|
||||||
const readdir = promisify(readdirSync);
|
|
||||||
|
|
||||||
let ID = 0;
|
|
||||||
class Node {
|
|
||||||
constructor(pkg, logical, physical, er, cache) {
|
|
||||||
// should be impossible.
|
|
||||||
const cached = cache.get(physical);
|
|
||||||
/* istanbul ignore next */
|
|
||||||
if (cached && !cached.then) throw new Error('re-creating already instantiated node');
|
|
||||||
|
|
||||||
cache.set(physical, this);
|
|
||||||
|
|
||||||
const parent = basename(dirname(logical));
|
|
||||||
if (parent.charAt(0) === '@') this.name = `${parent}/${basename(logical)}`;
|
|
||||||
else this.name = basename(logical);
|
|
||||||
this.path = logical;
|
|
||||||
this.realpath = physical;
|
|
||||||
this.error = er;
|
|
||||||
this.id = ID++;
|
|
||||||
this.package = pkg || {};
|
|
||||||
this.parent = null;
|
|
||||||
this.isLink = false;
|
|
||||||
this.children = [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Link extends Node {
|
|
||||||
constructor(pkg, logical, physical, realpath, er, cache) {
|
|
||||||
super(pkg, logical, physical, er, cache);
|
|
||||||
|
|
||||||
// if the target has started, but not completed, then
|
|
||||||
// a Promise will be in the cache to indicate this.
|
|
||||||
const cachedTarget = cache.get(realpath);
|
|
||||||
if (cachedTarget && cachedTarget.then)
|
|
||||||
cachedTarget.then(node => {
|
|
||||||
this.target = node;
|
|
||||||
this.children = node.children;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.target = cachedTarget || new Node(pkg, logical, realpath, er, cache);
|
|
||||||
this.realpath = realpath;
|
|
||||||
this.isLink = true;
|
|
||||||
this.error = er;
|
|
||||||
this.children = this.target.children;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is the way it is to expose a timing issue which is difficult to
|
|
||||||
// test otherwise. The creation of a Node may take slightly longer than
|
|
||||||
// the creation of a Link that targets it. If the Node has _begun_ its
|
|
||||||
// creation phase (and put a Promise in the cache) then the Link will
|
|
||||||
// get a Promise as its cachedTarget instead of an actual Node object.
|
|
||||||
// This is not a problem, because it gets resolved prior to returning
|
|
||||||
// the tree or attempting to load children. However, it IS remarkably
|
|
||||||
// difficult to get to happen in a test environment to verify reliably.
|
|
||||||
// Hence this kludge.
|
|
||||||
const newNode = (pkg, logical, physical, er, cache) =>
|
|
||||||
process.env._TEST_RPT_SLOW_LINK_TARGET_ === '1'
|
|
||||||
? new Promise(res => setTimeout(() => res(new Node(pkg, logical, physical, er, cache)), 10))
|
|
||||||
: new Node(pkg, logical, physical, er, cache);
|
|
||||||
|
|
||||||
const loadNode = (logical, physical, cache, rpcache, stcache) => {
|
|
||||||
// cache temporarily holds a promise placeholder so we
|
|
||||||
// don't try to create the same node multiple times.
|
|
||||||
// this is very rare to encounter, given the aggressive
|
|
||||||
// caching on fs.realpath and fs.lstat calls, but
|
|
||||||
// it can happen in theory.
|
|
||||||
const cached = cache.get(physical);
|
|
||||||
/* istanbul ignore next */
|
|
||||||
if (cached) return Promise.resolve(cached);
|
|
||||||
|
|
||||||
const p = realpath(physical, rpcache, stcache, 0).then(
|
|
||||||
real =>
|
|
||||||
rpj(join(real, 'package.json'))
|
|
||||||
.then(
|
|
||||||
pkg => [pkg, null],
|
|
||||||
er => [null, er],
|
|
||||||
)
|
|
||||||
.then(([pkg, er]) =>
|
|
||||||
physical === real
|
|
||||||
? newNode(pkg, logical, physical, er, cache)
|
|
||||||
: new Link(pkg, logical, physical, real, er, cache),
|
|
||||||
),
|
|
||||||
// if the realpath fails, don't bother with the rest
|
|
||||||
er => new Node(null, logical, physical, er, cache),
|
|
||||||
);
|
|
||||||
|
|
||||||
cache.set(physical, p);
|
|
||||||
return p;
|
|
||||||
};
|
|
||||||
|
|
||||||
const loadChildren = (node, cache, filterWith, rpcache, stcache, mode) => {
|
|
||||||
// if a Link target has started, but not completed, then
|
|
||||||
// a Promise will be in the cache to indicate this.
|
|
||||||
//
|
|
||||||
// XXX When we can one day loadChildren on the link *target* instead of
|
|
||||||
// the link itself, to match real dep resolution, then we may end up with
|
|
||||||
// a node target in the cache that isn't yet done resolving when we get
|
|
||||||
// here. For now, though, this line will never be reached, so it's hidden
|
|
||||||
//
|
|
||||||
// if (node.then)
|
|
||||||
// return node.then(node => loadChildren(node, cache, filterWith, rpcache, stcache))
|
|
||||||
|
|
||||||
let depFolder = 'node_modules';
|
|
||||||
if (mode === 'bower') {
|
|
||||||
// TODO: if people rename their bower_components folder to smth like "lib", please handle
|
|
||||||
depFolder = 'bower_components';
|
|
||||||
try {
|
|
||||||
const bowerrc = JSON.parse(fs.readFileSync(join(node.path, '.bowerrc')));
|
|
||||||
if (bowerrc && bowerrc.directory) {
|
|
||||||
depFolder = bowerrc.directory;
|
|
||||||
}
|
|
||||||
} catch (_) {}
|
|
||||||
}
|
|
||||||
const nm = join(node.path, depFolder);
|
|
||||||
// const nm = join(node.path, 'bower_components')
|
|
||||||
return realpath(nm, rpcache, stcache, 0)
|
|
||||||
.then(rm => readdir(rm).then(kids => [rm, kids]))
|
|
||||||
.then(([rm, kids]) =>
|
|
||||||
Promise.all(
|
|
||||||
kids
|
|
||||||
.filter(kid => kid.charAt(0) !== '.' && (!filterWith || filterWith(node, kid)))
|
|
||||||
.map(kid => loadNode(join(nm, kid), join(rm, kid), cache, rpcache, stcache)),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.then(kidNodes => {
|
|
||||||
kidNodes.forEach(k => (k.parent = node));
|
|
||||||
node.children.push.apply(
|
|
||||||
node.children,
|
|
||||||
kidNodes.sort((a, b) =>
|
|
||||||
(a.package.name ? a.package.name.toLowerCase() : a.path).localeCompare(
|
|
||||||
b.package.name ? b.package.name.toLowerCase() : b.path,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
return node;
|
|
||||||
})
|
|
||||||
.catch(() => node);
|
|
||||||
};
|
|
||||||
|
|
||||||
const loadTree = (node, did, cache, filterWith, rpcache, stcache, mode) => {
|
|
||||||
// impossible except in pathological ELOOP cases
|
|
||||||
/* istanbul ignore next */
|
|
||||||
if (did.has(node.realpath)) return Promise.resolve(node);
|
|
||||||
|
|
||||||
did.add(node.realpath);
|
|
||||||
|
|
||||||
// load children on the target, not the link
|
|
||||||
return loadChildren(node, cache, filterWith, rpcache, stcache, mode)
|
|
||||||
.then(node =>
|
|
||||||
Promise.all(
|
|
||||||
node.children
|
|
||||||
.filter(kid => !did.has(kid.realpath))
|
|
||||||
.map(kid => loadTree(kid, did, cache, filterWith, rpcache, stcache, mode)),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.then(() => node);
|
|
||||||
};
|
|
||||||
|
|
||||||
// XXX Drop filterWith and/or cb in next semver major bump
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {*} root
|
|
||||||
* @param {*} filterWith
|
|
||||||
* @param {*} cb
|
|
||||||
* @param {'npm'|'bower'} [mode='npm'] if mode is 'bower', will look in 'bower_components' instead
|
|
||||||
* of 'node_modules'
|
|
||||||
*/
|
|
||||||
const rpt = (root, filterWith, cb, mode = 'npm') => {
|
|
||||||
if (!cb && typeof filterWith === 'function') {
|
|
||||||
cb = filterWith;
|
|
||||||
filterWith = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const cache = new Map();
|
|
||||||
// we can assume that the cwd is real enough
|
|
||||||
const cwd = process.cwd();
|
|
||||||
const rpcache = new Map([[cwd, cwd]]);
|
|
||||||
const stcache = new Map();
|
|
||||||
const p = realpath(root, rpcache, stcache, 0)
|
|
||||||
.then(realRoot => loadNode(root, realRoot, cache, rpcache, stcache))
|
|
||||||
.then(node => loadTree(node, new Set(), cache, filterWith, rpcache, stcache, mode));
|
|
||||||
|
|
||||||
if (typeof cb === 'function') p.then(tree => cb(null, tree), cb);
|
|
||||||
|
|
||||||
return p;
|
|
||||||
};
|
|
||||||
|
|
||||||
rpt.Node = Node;
|
|
||||||
rpt.Link = Link;
|
|
||||||
|
|
||||||
export default rpt;
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
import { builtinModules } from 'module';
|
import { builtinModules } from 'module';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
import { nodeResolve } from '@rollup/plugin-node-resolve';
|
import { nodeResolve } from '@rollup/plugin-node-resolve';
|
||||||
import { LogService } from '../core/LogService.js';
|
|
||||||
import { memoize } from './memoize.js';
|
|
||||||
import { toPosixPath } from './to-posix-path.js';
|
|
||||||
import { isRelativeSourcePath } from './relative-source-path.js';
|
import { isRelativeSourcePath } from './relative-source-path.js';
|
||||||
|
import { LogService } from '../core/LogService.js';
|
||||||
|
import { toPosixPath } from './to-posix-path.js';
|
||||||
|
import { memoize } from './memoize.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {import('../../../types/index.js').PathRelativeFromProjectRoot} PathRelativeFromProjectRoot
|
* @typedef {import('../../../types/index.js').PathRelativeFromProjectRoot} PathRelativeFromProjectRoot
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import {
|
||||||
suppressNonCriticalLogs,
|
suppressNonCriticalLogs,
|
||||||
restoreSuppressNonCriticalLogs,
|
restoreSuppressNonCriticalLogs,
|
||||||
} from './mock-log-service-helpers.js';
|
} from './mock-log-service-helpers.js';
|
||||||
import { memoizeConfig } from '../src/program/utils/memoize.js';
|
import { memoize } from '../src/program/utils/memoize.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {import('../types/index.js').QueryResult} QueryResult
|
* @typedef {import('../types/index.js').QueryResult} QueryResult
|
||||||
|
|
@ -20,17 +20,17 @@ export function setupAnalyzerTest() {
|
||||||
|
|
||||||
const originalReferenceProjectPaths = InputDataService.referenceProjectPaths;
|
const originalReferenceProjectPaths = InputDataService.referenceProjectPaths;
|
||||||
const cacheDisabledQInitialValue = QueryService.cacheDisabled;
|
const cacheDisabledQInitialValue = QueryService.cacheDisabled;
|
||||||
const cacheDisabledIInitialValue = memoizeConfig.isCacheDisabled;
|
const cacheEnabledIInitialValue = memoize.isCacheEnabled;
|
||||||
|
|
||||||
before(() => {
|
before(() => {
|
||||||
QueryService.cacheDisabled = true;
|
QueryService.cacheDisabled = true;
|
||||||
memoizeConfig.isCacheDisabled = true;
|
memoize.disableCaching();
|
||||||
suppressNonCriticalLogs();
|
suppressNonCriticalLogs();
|
||||||
});
|
});
|
||||||
|
|
||||||
after(() => {
|
after(() => {
|
||||||
QueryService.cacheDisabled = cacheDisabledQInitialValue;
|
QueryService.cacheDisabled = cacheDisabledQInitialValue;
|
||||||
memoizeConfig.isCacheDisabled = cacheDisabledIInitialValue;
|
memoize.restoreCaching(cacheEnabledIInitialValue);
|
||||||
restoreSuppressNonCriticalLogs();
|
restoreSuppressNonCriticalLogs();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ export class DummyAnalyzer extends Analyzer {
|
||||||
/**
|
/**
|
||||||
* Prepare
|
* Prepare
|
||||||
*/
|
*/
|
||||||
const analyzerResult = this._prepare(cfg);
|
const analyzerResult = await this._prepare(cfg);
|
||||||
if (analyzerResult) {
|
if (analyzerResult) {
|
||||||
return analyzerResult;
|
return analyzerResult;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,24 @@
|
||||||
/* eslint-disable no-unused-expressions */
|
/* eslint-disable no-unused-expressions */
|
||||||
/* eslint-disable import/no-extraneous-dependencies */
|
/* eslint-disable import/no-extraneous-dependencies */
|
||||||
import sinon from 'sinon';
|
|
||||||
import pathLib from 'path';
|
|
||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
|
import pathLib from 'path';
|
||||||
|
|
||||||
import { expect } from 'chai';
|
import { expect } from 'chai';
|
||||||
|
import sinon from 'sinon';
|
||||||
import { it } from 'mocha';
|
import { it } from 'mocha';
|
||||||
import {
|
|
||||||
mockProject,
|
|
||||||
restoreMockedProjects,
|
|
||||||
mockTargetAndReferenceProject,
|
|
||||||
} from '../../test-helpers/mock-project-helpers.js';
|
|
||||||
import { _providenceModule } from '../../src/program/providence.js';
|
|
||||||
import { _cliHelpersModule } from '../../src/cli/cli-helpers.js';
|
|
||||||
import { toPosixPath } from '../../src/program/utils/to-posix-path.js';
|
|
||||||
import { memoizeConfig } from '../../src/program/utils/memoize.js';
|
|
||||||
import { getExtendDocsResults } from '../../src/cli/launch-providence-with-extend-docs.js';
|
import { getExtendDocsResults } from '../../src/cli/launch-providence-with-extend-docs.js';
|
||||||
import { AstService } from '../../src/index.js';
|
|
||||||
import { setupAnalyzerTest } from '../../test-helpers/setup-analyzer-test.js';
|
import { setupAnalyzerTest } from '../../test-helpers/setup-analyzer-test.js';
|
||||||
|
import { toPosixPath } from '../../src/program/utils/to-posix-path.js';
|
||||||
|
import { _providenceModule } from '../../src/program/providence.js';
|
||||||
|
import { memoize } from '../../src/program/utils/memoize.js';
|
||||||
|
import { _cliHelpersModule } from '../../src/cli/cli-helpers.js';
|
||||||
|
import {
|
||||||
|
mockTargetAndReferenceProject,
|
||||||
|
restoreMockedProjects,
|
||||||
|
mockProject,
|
||||||
|
} from '../../test-helpers/mock-project-helpers.js';
|
||||||
|
import { AstService } from '../../src/index.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {import('../../types/index.js').QueryResult} QueryResult
|
* @typedef {import('../../types/index.js').QueryResult} QueryResult
|
||||||
|
|
@ -50,7 +52,7 @@ describe('CLI helpers', () => {
|
||||||
|
|
||||||
describe('pathsArrayFromCs', () => {
|
describe('pathsArrayFromCs', () => {
|
||||||
it('allows absolute paths', async () => {
|
it('allows absolute paths', async () => {
|
||||||
expect(pathsArrayFromCs('/mocked/path/example-project', rootDir)).to.eql([
|
expect(pathsArrayFromCs('/mocked/path/example-project', rootDir)).to.deep.equal([
|
||||||
'/mocked/path/example-project',
|
'/mocked/path/example-project',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
@ -58,14 +60,14 @@ describe('CLI helpers', () => {
|
||||||
it('allows relative paths', async () => {
|
it('allows relative paths', async () => {
|
||||||
expect(
|
expect(
|
||||||
pathsArrayFromCs('./test-helpers/project-mocks/importing-target-project', rootDir),
|
pathsArrayFromCs('./test-helpers/project-mocks/importing-target-project', rootDir),
|
||||||
).to.eql([`${rootDir}/test-helpers/project-mocks/importing-target-project`]);
|
).to.deep.equal([`${rootDir}/test-helpers/project-mocks/importing-target-project`]);
|
||||||
expect(
|
expect(
|
||||||
pathsArrayFromCs('test-helpers/project-mocks/importing-target-project', rootDir),
|
pathsArrayFromCs('test-helpers/project-mocks/importing-target-project', rootDir),
|
||||||
).to.eql([`${rootDir}/test-helpers/project-mocks/importing-target-project`]);
|
).to.deep.equal([`${rootDir}/test-helpers/project-mocks/importing-target-project`]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('allows globs', async () => {
|
it('allows globs', async () => {
|
||||||
expect(pathsArrayFromCs('test-helpers/project-mocks*', rootDir)).to.eql([
|
expect(pathsArrayFromCs('test-helpers/project-mocks*', rootDir)).to.deep.equal([
|
||||||
`${rootDir}/test-helpers/project-mocks`,
|
`${rootDir}/test-helpers/project-mocks`,
|
||||||
`${rootDir}/test-helpers/project-mocks-analyzer-outputs`,
|
`${rootDir}/test-helpers/project-mocks-analyzer-outputs`,
|
||||||
]);
|
]);
|
||||||
|
|
@ -74,7 +76,7 @@ describe('CLI helpers', () => {
|
||||||
it('allows multiple comma separated paths', async () => {
|
it('allows multiple comma separated paths', async () => {
|
||||||
const paths =
|
const paths =
|
||||||
'test-helpers/project-mocks*, ./test-helpers/project-mocks/importing-target-project,/mocked/path/example-project';
|
'test-helpers/project-mocks*, ./test-helpers/project-mocks/importing-target-project,/mocked/path/example-project';
|
||||||
expect(pathsArrayFromCs(paths, rootDir)).to.eql([
|
expect(pathsArrayFromCs(paths, rootDir)).to.deep.equal([
|
||||||
`${rootDir}/test-helpers/project-mocks`,
|
`${rootDir}/test-helpers/project-mocks`,
|
||||||
`${rootDir}/test-helpers/project-mocks-analyzer-outputs`,
|
`${rootDir}/test-helpers/project-mocks-analyzer-outputs`,
|
||||||
`${rootDir}/test-helpers/project-mocks/importing-target-project`,
|
`${rootDir}/test-helpers/project-mocks/importing-target-project`,
|
||||||
|
|
@ -87,7 +89,7 @@ describe('CLI helpers', () => {
|
||||||
it('gets collections from external target config', async () => {
|
it('gets collections from external target config', async () => {
|
||||||
expect(
|
expect(
|
||||||
pathsArrayFromCollectionName('lion-collection', 'search-target', externalCfgMock, rootDir),
|
pathsArrayFromCollectionName('lion-collection', 'search-target', externalCfgMock, rootDir),
|
||||||
).to.eql(
|
).to.deep.equal(
|
||||||
externalCfgMock.searchTargetCollections['lion-collection'].map(p =>
|
externalCfgMock.searchTargetCollections['lion-collection'].map(p =>
|
||||||
toPosixPath(pathLib.join(rootDir, p)),
|
toPosixPath(pathLib.join(rootDir, p)),
|
||||||
),
|
),
|
||||||
|
|
@ -102,7 +104,7 @@ describe('CLI helpers', () => {
|
||||||
externalCfgMock,
|
externalCfgMock,
|
||||||
rootDir,
|
rootDir,
|
||||||
),
|
),
|
||||||
).to.eql(
|
).to.deep.equal(
|
||||||
externalCfgMock.referenceCollections['lion-based-ui-collection'].map(p =>
|
externalCfgMock.referenceCollections['lion-based-ui-collection'].map(p =>
|
||||||
toPosixPath(pathLib.join(rootDir, p)),
|
toPosixPath(pathLib.join(rootDir, p)),
|
||||||
),
|
),
|
||||||
|
|
@ -130,7 +132,7 @@ describe('CLI helpers', () => {
|
||||||
|
|
||||||
it('adds bower and node dependencies', async () => {
|
it('adds bower and node dependencies', async () => {
|
||||||
const result = await appendProjectDependencyPaths(['/mocked/path/example-project']);
|
const result = await appendProjectDependencyPaths(['/mocked/path/example-project']);
|
||||||
expect(result).to.eql([
|
expect(result).to.deep.equal([
|
||||||
'/mocked/path/example-project/node_modules/dependency-a',
|
'/mocked/path/example-project/node_modules/dependency-a',
|
||||||
'/mocked/path/example-project/node_modules/my-dependency',
|
'/mocked/path/example-project/node_modules/my-dependency',
|
||||||
'/mocked/path/example-project/bower_components/dependency-b',
|
'/mocked/path/example-project/bower_components/dependency-b',
|
||||||
|
|
@ -143,7 +145,7 @@ describe('CLI helpers', () => {
|
||||||
['/mocked/path/example-project'],
|
['/mocked/path/example-project'],
|
||||||
'/^dependency-/',
|
'/^dependency-/',
|
||||||
);
|
);
|
||||||
expect(result).to.eql([
|
expect(result).to.deep.equal([
|
||||||
'/mocked/path/example-project/node_modules/dependency-a',
|
'/mocked/path/example-project/node_modules/dependency-a',
|
||||||
// in windows, it should not add '/mocked/path/example-project/node_modules/my-dependency',
|
// in windows, it should not add '/mocked/path/example-project/node_modules/my-dependency',
|
||||||
'/mocked/path/example-project/bower_components/dependency-b',
|
'/mocked/path/example-project/bower_components/dependency-b',
|
||||||
|
|
@ -151,7 +153,7 @@ describe('CLI helpers', () => {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const result2 = await appendProjectDependencyPaths(['/mocked/path/example-project'], '/b$/');
|
const result2 = await appendProjectDependencyPaths(['/mocked/path/example-project'], '/b$/');
|
||||||
expect(result2).to.eql([
|
expect(result2).to.deep.equal([
|
||||||
'/mocked/path/example-project/bower_components/dependency-b',
|
'/mocked/path/example-project/bower_components/dependency-b',
|
||||||
'/mocked/path/example-project',
|
'/mocked/path/example-project',
|
||||||
]);
|
]);
|
||||||
|
|
@ -163,7 +165,7 @@ describe('CLI helpers', () => {
|
||||||
undefined,
|
undefined,
|
||||||
['npm'],
|
['npm'],
|
||||||
);
|
);
|
||||||
expect(result).to.eql([
|
expect(result).to.deep.equal([
|
||||||
'/mocked/path/example-project/node_modules/dependency-a',
|
'/mocked/path/example-project/node_modules/dependency-a',
|
||||||
'/mocked/path/example-project/node_modules/my-dependency',
|
'/mocked/path/example-project/node_modules/my-dependency',
|
||||||
'/mocked/path/example-project',
|
'/mocked/path/example-project',
|
||||||
|
|
@ -174,7 +176,7 @@ describe('CLI helpers', () => {
|
||||||
undefined,
|
undefined,
|
||||||
['bower'],
|
['bower'],
|
||||||
);
|
);
|
||||||
expect(result2).to.eql([
|
expect(result2).to.deep.equal([
|
||||||
'/mocked/path/example-project/bower_components/dependency-b',
|
'/mocked/path/example-project/bower_components/dependency-b',
|
||||||
'/mocked/path/example-project',
|
'/mocked/path/example-project',
|
||||||
]);
|
]);
|
||||||
|
|
@ -189,7 +191,7 @@ describe('CLI helpers', () => {
|
||||||
it('rewrites monorepo package paths when analysis is run from monorepo root', async () => {
|
it('rewrites monorepo package paths when analysis is run from monorepo root', async () => {
|
||||||
// This fails after InputDataService.addAstToProjectsData is memoized
|
// This fails after InputDataService.addAstToProjectsData is memoized
|
||||||
// (it does pass when run in isolation however, as a quick fix we disable memoization cache here...)
|
// (it does pass when run in isolation however, as a quick fix we disable memoization cache here...)
|
||||||
memoizeConfig.isCacheDisabled = true;
|
memoize.disableCaching();
|
||||||
// Since we use the print method here, we need to force Babel, bc swc-to-babel output is not compatible
|
// Since we use the print method here, we need to force Babel, bc swc-to-babel output is not compatible
|
||||||
// with @babel/generate
|
// with @babel/generate
|
||||||
const initialAstServiceFallbackToBabel = AstService.fallbackToBabel;
|
const initialAstServiceFallbackToBabel = AstService.fallbackToBabel;
|
||||||
|
|
@ -268,7 +270,7 @@ describe('CLI helpers', () => {
|
||||||
cwd: '/my-components',
|
cwd: '/my-components',
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(result).to.eql([
|
expect(result).to.deep.equal([
|
||||||
{
|
{
|
||||||
name: 'TheirButton',
|
name: 'TheirButton',
|
||||||
variable: {
|
variable: {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/* eslint-disable import/no-extraneous-dependencies */
|
/* eslint-disable import/no-extraneous-dependencies */
|
||||||
import pathLib from 'path';
|
import path from 'path';
|
||||||
import { expect } from 'chai';
|
import { expect } from 'chai';
|
||||||
import { it } from 'mocha';
|
import { it } from 'mocha';
|
||||||
import { appendProjectDependencyPaths } from '../../src/cli/cli-helpers.js';
|
import { appendProjectDependencyPaths } from '../../src/cli/cli-helpers.js';
|
||||||
|
|
@ -15,13 +15,13 @@ describe('CLI helpers against filesystem', () => {
|
||||||
describe('appendProjectDependencyPaths', () => {
|
describe('appendProjectDependencyPaths', () => {
|
||||||
it('allows a regex filter', async () => {
|
it('allows a regex filter', async () => {
|
||||||
const targetFilePath = toPosixPath(
|
const targetFilePath = toPosixPath(
|
||||||
pathLib.resolve(
|
path.resolve(
|
||||||
getCurrentDir(import.meta.url),
|
getCurrentDir(import.meta.url),
|
||||||
'../../test-helpers/project-mocks/importing-target-project',
|
'../../test-helpers/project-mocks/importing-target-project',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
const result = await appendProjectDependencyPaths([targetFilePath], '/^dep-/');
|
const result = await appendProjectDependencyPaths([targetFilePath], '/^dep-/');
|
||||||
expect(result).to.eql([
|
expect(result).to.deep.equal([
|
||||||
`${targetFilePath}/node_modules/dep-a`,
|
`${targetFilePath}/node_modules/dep-a`,
|
||||||
// in windows, it should not add `${targetFilePath}/node_modules/my-dep-b`,
|
// in windows, it should not add `${targetFilePath}/node_modules/my-dep-b`,
|
||||||
targetFilePath,
|
targetFilePath,
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import { _providenceModule } from '../../src/program/providence.js';
|
||||||
import { _cliHelpersModule } from '../../src/cli/cli-helpers.js';
|
import { _cliHelpersModule } from '../../src/cli/cli-helpers.js';
|
||||||
import { cli } from '../../src/cli/cli.js';
|
import { cli } from '../../src/cli/cli.js';
|
||||||
import { _promptAnalyzerMenuModule } from '../../src/cli/prompt-analyzer-menu.js';
|
import { _promptAnalyzerMenuModule } from '../../src/cli/prompt-analyzer-menu.js';
|
||||||
import { memoizeConfig } from '../../src/program/utils/memoize.js';
|
import { memoize } from '../../src/program/utils/memoize.js';
|
||||||
import { _extendDocsModule } from '../../src/cli/launch-providence-with-extend-docs.js';
|
import { _extendDocsModule } from '../../src/cli/launch-providence-with-extend-docs.js';
|
||||||
import { dashboardServer } from '../../src/dashboard/server.js';
|
import { dashboardServer } from '../../src/dashboard/server.js';
|
||||||
import { setupAnalyzerTest } from '../../test-helpers/setup-analyzer-test.js';
|
import { setupAnalyzerTest } from '../../test-helpers/setup-analyzer-test.js';
|
||||||
|
|
@ -120,7 +120,8 @@ describe('Providence CLI', () => {
|
||||||
projectPath: '/mocked/path/example-project',
|
projectPath: '/mocked/path/example-project',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
memoizeConfig.isCacheDisabled = true;
|
// memoizeConfig.isCacheDisabled = true;
|
||||||
|
memoize.disableCaching();
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
|
@ -186,18 +187,26 @@ describe('Providence CLI', () => {
|
||||||
|
|
||||||
it('"-e --extensions"', async () => {
|
it('"-e --extensions"', async () => {
|
||||||
await runCli(`${anyCmdThatAcceptsGlobalOpts} -e bla,blu`, rootDir);
|
await runCli(`${anyCmdThatAcceptsGlobalOpts} -e bla,blu`, rootDir);
|
||||||
expect(providenceStub.args[0][1].gatherFilesConfig.extensions).to.eql(['.bla', '.blu']);
|
expect(providenceStub.args[0][1].gatherFilesConfig.extensions).to.deep.equal([
|
||||||
|
'.bla',
|
||||||
|
'.blu',
|
||||||
|
]);
|
||||||
|
|
||||||
providenceStub.resetHistory();
|
providenceStub.resetHistory();
|
||||||
|
|
||||||
await runCli(`${anyCmdThatAcceptsGlobalOpts} --extensions bla,blu`, rootDir);
|
await runCli(`${anyCmdThatAcceptsGlobalOpts} --extensions bla,blu`, rootDir);
|
||||||
expect(providenceStub.args[0][1].gatherFilesConfig.extensions).to.eql(['.bla', '.blu']);
|
expect(providenceStub.args[0][1].gatherFilesConfig.extensions).to.deep.equal([
|
||||||
|
'.bla',
|
||||||
|
'.blu',
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('"-t --search-target-paths"', async () => {
|
it('"-t --search-target-paths"', async () => {
|
||||||
await runCli(`${anyCmdThatAcceptsGlobalOpts} -t /mocked/path/example-project`, rootDir);
|
await runCli(`${anyCmdThatAcceptsGlobalOpts} -t /mocked/path/example-project`, rootDir);
|
||||||
expect(pathsArrayFromCsStub.args[0][0]).to.equal('/mocked/path/example-project');
|
expect(pathsArrayFromCsStub.args[0][0]).to.equal('/mocked/path/example-project');
|
||||||
expect(providenceStub.args[0][1].targetProjectPaths).to.eql(['/mocked/path/example-project']);
|
expect(providenceStub.args[0][1].targetProjectPaths).to.deep.equal([
|
||||||
|
'/mocked/path/example-project',
|
||||||
|
]);
|
||||||
|
|
||||||
pathsArrayFromCsStub.resetHistory();
|
pathsArrayFromCsStub.resetHistory();
|
||||||
providenceStub.resetHistory();
|
providenceStub.resetHistory();
|
||||||
|
|
@ -207,13 +216,15 @@ describe('Providence CLI', () => {
|
||||||
rootDir,
|
rootDir,
|
||||||
);
|
);
|
||||||
expect(pathsArrayFromCsStub.args[0][0]).to.equal('/mocked/path/example-project');
|
expect(pathsArrayFromCsStub.args[0][0]).to.equal('/mocked/path/example-project');
|
||||||
expect(providenceStub.args[0][1].targetProjectPaths).to.eql(['/mocked/path/example-project']);
|
expect(providenceStub.args[0][1].targetProjectPaths).to.deep.equal([
|
||||||
|
'/mocked/path/example-project',
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('"-r --reference-paths"', async () => {
|
it('"-r --reference-paths"', async () => {
|
||||||
await runCli(`${anyCmdThatAcceptsGlobalOpts} -r /mocked/path/example-project`, rootDir);
|
await runCli(`${anyCmdThatAcceptsGlobalOpts} -r /mocked/path/example-project`, rootDir);
|
||||||
expect(pathsArrayFromCsStub.args[0][0]).to.equal('/mocked/path/example-project');
|
expect(pathsArrayFromCsStub.args[0][0]).to.equal('/mocked/path/example-project');
|
||||||
expect(providenceStub.args[0][1].referenceProjectPaths).to.eql([
|
expect(providenceStub.args[0][1].referenceProjectPaths).to.deep.equal([
|
||||||
'/mocked/path/example-project',
|
'/mocked/path/example-project',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
@ -225,7 +236,7 @@ describe('Providence CLI', () => {
|
||||||
rootDir,
|
rootDir,
|
||||||
);
|
);
|
||||||
expect(pathsArrayFromCsStub.args[0][0]).to.equal('/mocked/path/example-project');
|
expect(pathsArrayFromCsStub.args[0][0]).to.equal('/mocked/path/example-project');
|
||||||
expect(providenceStub.args[0][1].referenceProjectPaths).to.eql([
|
expect(providenceStub.args[0][1].referenceProjectPaths).to.deep.equal([
|
||||||
'/mocked/path/example-project',
|
'/mocked/path/example-project',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
@ -236,7 +247,9 @@ describe('Providence CLI', () => {
|
||||||
rootDir,
|
rootDir,
|
||||||
);
|
);
|
||||||
expect(pathsArrayFromCollectionStub.args[0][0]).to.equal('lion-collection');
|
expect(pathsArrayFromCollectionStub.args[0][0]).to.equal('lion-collection');
|
||||||
expect(providenceStub.args[0][1].targetProjectPaths).to.eql(['/mocked/path/example-project']);
|
expect(providenceStub.args[0][1].targetProjectPaths).to.deep.equal([
|
||||||
|
'/mocked/path/example-project',
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('"--reference-collection"', async () => {
|
it('"--reference-collection"', async () => {
|
||||||
|
|
@ -245,14 +258,14 @@ describe('Providence CLI', () => {
|
||||||
rootDir,
|
rootDir,
|
||||||
);
|
);
|
||||||
expect(pathsArrayFromCollectionStub.args[0][0]).to.equal('lion-based-ui-collection');
|
expect(pathsArrayFromCollectionStub.args[0][0]).to.equal('lion-based-ui-collection');
|
||||||
expect(providenceStub.args[0][1].referenceProjectPaths).to.eql([
|
expect(providenceStub.args[0][1].referenceProjectPaths).to.deep.equal([
|
||||||
'/mocked/path/example-project',
|
'/mocked/path/example-project',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('"-a --allowlist"', async () => {
|
it('"-a --allowlist"', async () => {
|
||||||
await runCli(`${anyCmdThatAcceptsGlobalOpts} -a mocked/**/*,rocked/*`, rootDir);
|
await runCli(`${anyCmdThatAcceptsGlobalOpts} -a mocked/**/*,rocked/*`, rootDir);
|
||||||
expect(providenceStub.args[0][1].gatherFilesConfig.allowlist).to.eql([
|
expect(providenceStub.args[0][1].gatherFilesConfig.allowlist).to.deep.equal([
|
||||||
'mocked/**/*',
|
'mocked/**/*',
|
||||||
'rocked/*',
|
'rocked/*',
|
||||||
]);
|
]);
|
||||||
|
|
@ -260,7 +273,7 @@ describe('Providence CLI', () => {
|
||||||
providenceStub.resetHistory();
|
providenceStub.resetHistory();
|
||||||
|
|
||||||
await runCli(`${anyCmdThatAcceptsGlobalOpts} --allowlist mocked/**/*,rocked/*`, rootDir);
|
await runCli(`${anyCmdThatAcceptsGlobalOpts} --allowlist mocked/**/*,rocked/*`, rootDir);
|
||||||
expect(providenceStub.args[0][1].gatherFilesConfig.allowlist).to.eql([
|
expect(providenceStub.args[0][1].gatherFilesConfig.allowlist).to.deep.equal([
|
||||||
'mocked/**/*',
|
'mocked/**/*',
|
||||||
'rocked/*',
|
'rocked/*',
|
||||||
]);
|
]);
|
||||||
|
|
@ -271,7 +284,7 @@ describe('Providence CLI', () => {
|
||||||
`${anyCmdThatAcceptsGlobalOpts} --allowlist-reference mocked/**/*,rocked/*`,
|
`${anyCmdThatAcceptsGlobalOpts} --allowlist-reference mocked/**/*,rocked/*`,
|
||||||
rootDir,
|
rootDir,
|
||||||
);
|
);
|
||||||
expect(providenceStub.args[0][1].gatherFilesConfigReference.allowlist).to.eql([
|
expect(providenceStub.args[0][1].gatherFilesConfigReference.allowlist).to.deep.equal([
|
||||||
'mocked/**/*',
|
'mocked/**/*',
|
||||||
'rocked/*',
|
'rocked/*',
|
||||||
]);
|
]);
|
||||||
|
|
@ -311,7 +324,7 @@ describe('Providence CLI', () => {
|
||||||
|
|
||||||
await runCli(`${anyCmdThatAcceptsGlobalOpts} --target-dependencies`, rootDir);
|
await runCli(`${anyCmdThatAcceptsGlobalOpts} --target-dependencies`, rootDir);
|
||||||
expect(appendProjectDependencyPathsStub.called).to.be.true;
|
expect(appendProjectDependencyPathsStub.called).to.be.true;
|
||||||
expect(providenceStub.args[0][1].targetProjectPaths).to.eql([
|
expect(providenceStub.args[0][1].targetProjectPaths).to.deep.equal([
|
||||||
'/mocked/path/example-project',
|
'/mocked/path/example-project',
|
||||||
'/mocked/path/example-project/node_modules/mock-dep-a',
|
'/mocked/path/example-project/node_modules/mock-dep-a',
|
||||||
'/mocked/path/example-project/bower_components/mock-dep-b',
|
'/mocked/path/example-project/bower_components/mock-dep-b',
|
||||||
|
|
@ -355,13 +368,13 @@ describe('Providence CLI', () => {
|
||||||
it('"-c --config"', async () => {
|
it('"-c --config"', async () => {
|
||||||
await runCli(`analyze match-analyzer-mock -c {"a":"2"}`, rootDir);
|
await runCli(`analyze match-analyzer-mock -c {"a":"2"}`, rootDir);
|
||||||
expect(qConfStub.args[0][0]).to.equal('match-analyzer-mock');
|
expect(qConfStub.args[0][0]).to.equal('match-analyzer-mock');
|
||||||
expect(qConfStub.args[0][1]).to.eql({ a: '2', metaConfig: {} });
|
expect(qConfStub.args[0][1]).to.deep.equal({ a: '2', metaConfig: {} });
|
||||||
|
|
||||||
qConfStub.resetHistory();
|
qConfStub.resetHistory();
|
||||||
|
|
||||||
await runCli(`analyze match-analyzer-mock --config {"a":"2"}`, rootDir);
|
await runCli(`analyze match-analyzer-mock --config {"a":"2"}`, rootDir);
|
||||||
expect(qConfStub.args[0][0]).to.equal('match-analyzer-mock');
|
expect(qConfStub.args[0][0]).to.equal('match-analyzer-mock');
|
||||||
expect(qConfStub.args[0][1]).to.eql({ a: '2', metaConfig: {} });
|
expect(qConfStub.args[0][1]).to.deep.equal({ a: '2', metaConfig: {} });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('calls "promptAnalyzerConfigMenu" without config given', async () => {
|
it('calls "promptAnalyzerConfigMenu" without config given', async () => {
|
||||||
|
|
@ -417,7 +430,7 @@ describe('Providence CLI', () => {
|
||||||
rootDir,
|
rootDir,
|
||||||
);
|
);
|
||||||
expect(extendDocsStub.called).to.be.true;
|
expect(extendDocsStub.called).to.be.true;
|
||||||
expect(extendDocsStub.args[0][0]).to.eql({
|
expect(extendDocsStub.args[0][0]).to.deep.equal({
|
||||||
referenceProjectPaths: ['/xyz/x'],
|
referenceProjectPaths: ['/xyz/x'],
|
||||||
prefixCfg: {
|
prefixCfg: {
|
||||||
from: 'pfrom',
|
from: 'pfrom',
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,16 @@
|
||||||
/* eslint-disable import/no-extraneous-dependencies */
|
/* eslint-disable import/no-extraneous-dependencies */
|
||||||
import fs from 'fs';
|
import { fileURLToPath, pathToFileURL } from 'url';
|
||||||
import pathLib from 'path';
|
import pathLib from 'path';
|
||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
import { fileURLToPath, pathToFileURL } from 'url';
|
|
||||||
|
import { createTestServer } from '@web/dev-server-core/test-helpers';
|
||||||
import { expect } from 'chai';
|
import { expect } from 'chai';
|
||||||
import { it } from 'mocha';
|
import { it } from 'mocha';
|
||||||
import fetch from 'node-fetch';
|
|
||||||
import { createTestServer } from '@web/dev-server-core/test-helpers';
|
import { providenceConfUtil } from '../../src/program/utils/providence-conf-util.js';
|
||||||
import { createDashboardServerConfig } from '../../src/dashboard/server.js';
|
import { createDashboardServerConfig } from '../../src/dashboard/server.js';
|
||||||
import { ReportService } from '../../src/program/core/ReportService.js';
|
import { ReportService } from '../../src/program/core/ReportService.js';
|
||||||
import { providenceConfUtil } from '../../src/program/utils/providence-conf-util.js';
|
import { fsAdapter } from '../../src/program/utils/fs-adapter.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {import('@web/dev-server-core').DevServer} DevServer
|
* @typedef {import('@web/dev-server-core').DevServer} DevServer
|
||||||
|
|
@ -27,7 +28,7 @@ const mockedOutputPath = pathLib.join(__dirname, 'fixtures/providence-output');
|
||||||
async function getConf(url) {
|
async function getConf(url) {
|
||||||
const { href } = pathToFileURL(url);
|
const { href } = pathToFileURL(url);
|
||||||
const { default: providenceConf } = await import(href);
|
const { default: providenceConf } = await import(href);
|
||||||
const providenceConfRaw = fs.readFileSync(url, 'utf8');
|
const providenceConfRaw = fsAdapter.fs.readFileSync(url, 'utf8');
|
||||||
return { providenceConf, providenceConfRaw };
|
return { providenceConf, providenceConfRaw };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -40,7 +41,7 @@ describe('Dashboard Server', () => {
|
||||||
let providenceConfStub;
|
let providenceConfStub;
|
||||||
|
|
||||||
before(() => {
|
before(() => {
|
||||||
// N.B. don't use mock-fs, since it doesn't correctly handle dynamic imports and fs.promises
|
// N.B. don't use mock-fs, since it doesn't correctly handle dynamic imports and fsAdapter.fs.promises
|
||||||
ReportService.outputPath = mockedOutputPath;
|
ReportService.outputPath = mockedOutputPath;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -81,8 +82,11 @@ describe('Dashboard Server', () => {
|
||||||
const response = await fetch(`${host}/menu-data.json`);
|
const response = await fetch(`${host}/menu-data.json`);
|
||||||
expect(response.status).to.equal(200);
|
expect(response.status).to.equal(200);
|
||||||
const responseJSON = await response.json();
|
const responseJSON = await response.json();
|
||||||
const expectedResult = fs.readFileSync(`${mockedResponsesPath}/menu-data.json`, 'utf8');
|
const expectedResult = fsAdapter.fs.readFileSync(
|
||||||
expect(responseJSON).to.eql(JSON.parse(expectedResult));
|
`${mockedResponsesPath}/menu-data.json`,
|
||||||
|
'utf8',
|
||||||
|
);
|
||||||
|
expect(responseJSON).to.deep.equal(JSON.parse(expectedResult));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -91,8 +95,11 @@ describe('Dashboard Server', () => {
|
||||||
const response = await fetch(`${host}/results.json`);
|
const response = await fetch(`${host}/results.json`);
|
||||||
expect(response.status).to.equal(200);
|
expect(response.status).to.equal(200);
|
||||||
const responseJson = await response.json();
|
const responseJson = await response.json();
|
||||||
const expectedResult = fs.readFileSync(`${mockedResponsesPath}/results.json`, 'utf8');
|
const expectedResult = fsAdapter.fs.readFileSync(
|
||||||
expect(responseJson).to.eql(JSON.parse(expectedResult));
|
`${mockedResponsesPath}/results.json`,
|
||||||
|
'utf8',
|
||||||
|
);
|
||||||
|
expect(responseJson).to.deep.equal(JSON.parse(expectedResult));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,12 @@
|
||||||
/* eslint-disable import/no-extraneous-dependencies */
|
/* eslint-disable import/no-extraneous-dependencies */
|
||||||
import pathLib, { dirname } from 'path';
|
import pathLib, { dirname } from 'path';
|
||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
import fs from 'fs';
|
|
||||||
import { expect } from 'chai';
|
import { expect } from 'chai';
|
||||||
import { it } from 'mocha';
|
import { it } from 'mocha';
|
||||||
import { providence } from '../../../../src/program/providence.js';
|
import { providence } from '../../../../src/program/providence.js';
|
||||||
import { QueryService } from '../../../../src/program/core/QueryService.js';
|
import { QueryService } from '../../../../src/program/core/QueryService.js';
|
||||||
import { ReportService } from '../../../../src/program/core/ReportService.js';
|
import { ReportService } from '../../../../src/program/core/ReportService.js';
|
||||||
import { memoizeConfig } from '../../../../src/program/utils/memoize.js';
|
import { memoize } from '../../../../src/program/utils/memoize.js';
|
||||||
import { setupAnalyzerTest } from '../../../../test-helpers/setup-analyzer-test.js';
|
import { setupAnalyzerTest } from '../../../../test-helpers/setup-analyzer-test.js';
|
||||||
import {
|
import {
|
||||||
FindExportsAnalyzer,
|
FindExportsAnalyzer,
|
||||||
|
|
@ -18,6 +17,7 @@ import MatchSubclassesAnalyzer from '../../../../src/program/analyzers/match-sub
|
||||||
import MatchPathsAnalyzer from '../../../../src/program/analyzers/match-paths.js';
|
import MatchPathsAnalyzer from '../../../../src/program/analyzers/match-paths.js';
|
||||||
import FindCustomelementsAnalyzer from '../../../../src/program/analyzers/find-customelements.js';
|
import FindCustomelementsAnalyzer from '../../../../src/program/analyzers/find-customelements.js';
|
||||||
import FindClassesAnalyzer from '../../../../src/program/analyzers/find-classes.js';
|
import FindClassesAnalyzer from '../../../../src/program/analyzers/find-classes.js';
|
||||||
|
import { fsAdapter } from '../../../../src/program/utils/fs-adapter.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {import('../../../../types/index.js').ProvidenceConfig} ProvidenceConfig
|
* @typedef {import('../../../../types/index.js').ProvidenceConfig} ProvidenceConfig
|
||||||
|
|
@ -48,13 +48,13 @@ describe('Analyzers file-system integration', () => {
|
||||||
const originalGetResultFileNameAndPath = ReportService._getResultFileNameAndPath;
|
const originalGetResultFileNameAndPath = ReportService._getResultFileNameAndPath;
|
||||||
const originalOutputPath = ReportService.outputPath;
|
const originalOutputPath = ReportService.outputPath;
|
||||||
|
|
||||||
const memoizeCacheDisabledInitial = memoizeConfig.isCacheDisabled;
|
const memoizeCacheEnabledInitial = memoize.isCacheEnabled;
|
||||||
memoizeConfig.isCacheDisabled = true;
|
memoize.disableCaching();
|
||||||
|
|
||||||
after(() => {
|
after(() => {
|
||||||
ReportService._getResultFileNameAndPath = originalGetResultFileNameAndPath;
|
ReportService._getResultFileNameAndPath = originalGetResultFileNameAndPath;
|
||||||
ReportService.outputPath = originalOutputPath;
|
ReportService.outputPath = originalOutputPath;
|
||||||
memoizeConfig.isCacheDisabled = memoizeCacheDisabledInitial;
|
memoize.restoreCaching(memoizeCacheEnabledInitial);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (generateE2eMode) {
|
if (generateE2eMode) {
|
||||||
|
|
@ -132,7 +132,7 @@ describe('Analyzers file-system integration', () => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const expectedOutput = JSON.parse(
|
const expectedOutput = JSON.parse(
|
||||||
fs.readFileSync(
|
fsAdapter.fs.readFileSync(
|
||||||
pathLib.resolve(
|
pathLib.resolve(
|
||||||
__dirname,
|
__dirname,
|
||||||
`../../../../test-helpers/project-mocks-analyzer-outputs/${ctor.analyzerName}.json`,
|
`../../../../test-helpers/project-mocks-analyzer-outputs/${ctor.analyzerName}.json`,
|
||||||
|
|
@ -141,8 +141,8 @@ describe('Analyzers file-system integration', () => {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
const { queryOutput } = JSON.parse(JSON.stringify(queryResults[0]));
|
const { queryOutput } = JSON.parse(JSON.stringify(queryResults[0]));
|
||||||
expect(queryOutput).not.to.eql([]);
|
expect(queryOutput).not.to.deep.equal([]);
|
||||||
expect(queryOutput).to.eql(expectedOutput.queryOutput);
|
expect(queryOutput).to.deep.equal(expectedOutput.queryOutput);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ describe('Analyzer "find-classes"', async () => {
|
||||||
mockProject([`class EmptyClass {}`]);
|
mockProject([`class EmptyClass {}`]);
|
||||||
const queryResults = await providence(findClassesQueryConfig, _providenceCfg);
|
const queryResults = await providence(findClassesQueryConfig, _providenceCfg);
|
||||||
const firstEntry = getEntry(queryResults[0]);
|
const firstEntry = getEntry(queryResults[0]);
|
||||||
expect(firstEntry.result).to.eql([
|
expect(firstEntry.result).to.deep.equal([
|
||||||
{
|
{
|
||||||
name: 'EmptyClass',
|
name: 'EmptyClass',
|
||||||
isMixin: false,
|
isMixin: false,
|
||||||
|
|
@ -41,7 +41,7 @@ describe('Analyzer "find-classes"', async () => {
|
||||||
mockProject([`const m = superclass => class MyMixin extends superclass {}`]);
|
mockProject([`const m = superclass => class MyMixin extends superclass {}`]);
|
||||||
const queryResults = await providence(findClassesQueryConfig, _providenceCfg);
|
const queryResults = await providence(findClassesQueryConfig, _providenceCfg);
|
||||||
const firstEntry = getEntry(queryResults[0]);
|
const firstEntry = getEntry(queryResults[0]);
|
||||||
expect(firstEntry.result).to.eql([
|
expect(firstEntry.result).to.deep.equal([
|
||||||
{
|
{
|
||||||
name: 'MyMixin',
|
name: 'MyMixin',
|
||||||
superClasses: [
|
superClasses: [
|
||||||
|
|
@ -72,7 +72,7 @@ describe('Analyzer "find-classes"', async () => {
|
||||||
});
|
});
|
||||||
const queryResults = await providence(findClassesQueryConfig, _providenceCfg);
|
const queryResults = await providence(findClassesQueryConfig, _providenceCfg);
|
||||||
const firstEntry = getEntry(queryResults[0]);
|
const firstEntry = getEntry(queryResults[0]);
|
||||||
expect(firstEntry.result[1].superClasses).to.eql([
|
expect(firstEntry.result[1].superClasses).to.deep.equal([
|
||||||
{
|
{
|
||||||
isMixin: true,
|
isMixin: true,
|
||||||
name: 'Mixin',
|
name: 'Mixin',
|
||||||
|
|
@ -109,7 +109,7 @@ describe('Analyzer "find-classes"', async () => {
|
||||||
]);
|
]);
|
||||||
const queryResults = await providence(findClassesQueryConfig, _providenceCfg);
|
const queryResults = await providence(findClassesQueryConfig, _providenceCfg);
|
||||||
const firstEntry = getEntry(queryResults[0]);
|
const firstEntry = getEntry(queryResults[0]);
|
||||||
expect(firstEntry.result[0].members.methods).to.eql([
|
expect(firstEntry.result[0].members.methods).to.deep.equal([
|
||||||
{
|
{
|
||||||
accessType: 'public',
|
accessType: 'public',
|
||||||
name: 'method',
|
name: 'method',
|
||||||
|
|
@ -145,7 +145,7 @@ describe('Analyzer "find-classes"', async () => {
|
||||||
]);
|
]);
|
||||||
const queryResults = await providence(findClassesQueryConfig, _providenceCfg);
|
const queryResults = await providence(findClassesQueryConfig, _providenceCfg);
|
||||||
const firstEntry = getEntry(queryResults[0]);
|
const firstEntry = getEntry(queryResults[0]);
|
||||||
expect(firstEntry.result[0].members.props).to.eql([
|
expect(firstEntry.result[0].members.props).to.deep.equal([
|
||||||
{
|
{
|
||||||
accessType: 'public',
|
accessType: 'public',
|
||||||
kind: ['get', 'set'],
|
kind: ['get', 'set'],
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ describe('Analyzer "find-customelements"', async () => {
|
||||||
const queryResults = await providence(findCustomelementsQueryConfig, _providenceCfg);
|
const queryResults = await providence(findCustomelementsQueryConfig, _providenceCfg);
|
||||||
const queryResult = queryResults[0];
|
const queryResult = queryResults[0];
|
||||||
const firstEntry = getEntry(queryResult);
|
const firstEntry = getEntry(queryResult);
|
||||||
expect(firstEntry.result[0].rootFile).to.eql({
|
expect(firstEntry.result[0].rootFile).to.deep.equal({
|
||||||
file: './src/CustomEl.js',
|
file: './src/CustomEl.js',
|
||||||
specifier: 'CustomEl',
|
specifier: 'CustomEl',
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ describe('Analyzer "find-exports"', async () => {
|
||||||
const queryResults = await providence(findExportsQueryConfig, _providenceCfg);
|
const queryResults = await providence(findExportsQueryConfig, _providenceCfg);
|
||||||
const firstResult = getEntry(queryResults[0]).result[0];
|
const firstResult = getEntry(queryResults[0]).result[0];
|
||||||
|
|
||||||
expect(firstResult.exportSpecifiers).to.eql(['x']);
|
expect(firstResult.exportSpecifiers).to.deep.equal(['x']);
|
||||||
expect(firstResult.source).to.be.undefined;
|
expect(firstResult.source).to.be.undefined;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -34,7 +34,7 @@ describe('Analyzer "find-exports"', async () => {
|
||||||
mockProject([`export default class X {}`]);
|
mockProject([`export default class X {}`]);
|
||||||
const queryResults = await providence(findExportsQueryConfig, _providenceCfg);
|
const queryResults = await providence(findExportsQueryConfig, _providenceCfg);
|
||||||
const firstResult = getEntry(queryResults[0]).result[0];
|
const firstResult = getEntry(queryResults[0]).result[0];
|
||||||
expect(firstResult.exportSpecifiers).to.eql(['[default]']);
|
expect(firstResult.exportSpecifiers).to.deep.equal(['[default]']);
|
||||||
expect(firstResult.source).to.be.undefined;
|
expect(firstResult.source).to.be.undefined;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -43,7 +43,7 @@ describe('Analyzer "find-exports"', async () => {
|
||||||
const queryResults = await providence(findExportsQueryConfig, _providenceCfg);
|
const queryResults = await providence(findExportsQueryConfig, _providenceCfg);
|
||||||
const firstResult = getEntry(queryResults[0]).result[0];
|
const firstResult = getEntry(queryResults[0]).result[0];
|
||||||
|
|
||||||
expect(firstResult.exportSpecifiers).to.eql(['[default]']);
|
expect(firstResult.exportSpecifiers).to.deep.equal(['[default]']);
|
||||||
expect(firstResult.source).to.be.undefined;
|
expect(firstResult.source).to.be.undefined;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -56,7 +56,7 @@ describe('Analyzer "find-exports"', async () => {
|
||||||
|
|
||||||
const queryResults = await providence(findExportsQueryConfig, _providenceCfg);
|
const queryResults = await providence(findExportsQueryConfig, _providenceCfg);
|
||||||
const firstResult = getEntry(queryResults[0]).result[0];
|
const firstResult = getEntry(queryResults[0]).result[0];
|
||||||
expect(firstResult).to.eql({
|
expect(firstResult).to.deep.equal({
|
||||||
exportSpecifiers: ['[default]'],
|
exportSpecifiers: ['[default]'],
|
||||||
source: undefined,
|
source: undefined,
|
||||||
rootFileMap: [
|
rootFileMap: [
|
||||||
|
|
@ -68,7 +68,7 @@ describe('Analyzer "find-exports"', async () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const secondEntry = getEntry(queryResults[0], 1);
|
const secondEntry = getEntry(queryResults[0], 1);
|
||||||
expect(secondEntry.result[0]).to.eql({
|
expect(secondEntry.result[0]).to.deep.equal({
|
||||||
exportSpecifiers: ['namedExport'],
|
exportSpecifiers: ['namedExport'],
|
||||||
source: './file-with-default-export.js',
|
source: './file-with-default-export.js',
|
||||||
localMap: [{ exported: 'namedExport', local: '[default]' }],
|
localMap: [{ exported: 'namedExport', local: '[default]' }],
|
||||||
|
|
@ -128,7 +128,7 @@ describe('Analyzer "find-exports"', async () => {
|
||||||
expect(firstEntry.result[0].exportSpecifiers.length).to.equal(1);
|
expect(firstEntry.result[0].exportSpecifiers.length).to.equal(1);
|
||||||
expect(firstEntry.result[0].exportSpecifiers[0]).to.equal('[default]');
|
expect(firstEntry.result[0].exportSpecifiers[0]).to.equal('[default]');
|
||||||
expect(firstEntry.result[0].source).to.equal('./styles.css');
|
expect(firstEntry.result[0].source).to.equal('./styles.css');
|
||||||
expect(firstEntry.result[0].rootFileMap[0]).to.eql({
|
expect(firstEntry.result[0].rootFileMap[0]).to.deep.equal({
|
||||||
currentFileSpecifier: '[default]',
|
currentFileSpecifier: '[default]',
|
||||||
rootFile: {
|
rootFile: {
|
||||||
file: './styles.css',
|
file: './styles.css',
|
||||||
|
|
@ -147,7 +147,7 @@ describe('Analyzer "find-exports"', async () => {
|
||||||
expect(firstEntry.result[0].exportSpecifiers.length).to.equal(1);
|
expect(firstEntry.result[0].exportSpecifiers.length).to.equal(1);
|
||||||
expect(firstEntry.result[0].exportSpecifiers[0]).to.equal('[default]');
|
expect(firstEntry.result[0].exportSpecifiers[0]).to.equal('[default]');
|
||||||
expect(firstEntry.result[0].source).to.equal('./styles.css');
|
expect(firstEntry.result[0].source).to.equal('./styles.css');
|
||||||
expect(firstEntry.result[0].rootFileMap[0]).to.eql({
|
expect(firstEntry.result[0].rootFileMap[0]).to.deep.equal({
|
||||||
currentFileSpecifier: '[default]',
|
currentFileSpecifier: '[default]',
|
||||||
rootFile: {
|
rootFile: {
|
||||||
file: './styles.css',
|
file: './styles.css',
|
||||||
|
|
@ -161,7 +161,7 @@ describe('Analyzer "find-exports"', async () => {
|
||||||
const queryResults = await providence(findExportsQueryConfig, _providenceCfg);
|
const queryResults = await providence(findExportsQueryConfig, _providenceCfg);
|
||||||
const firstEntry = getEntry(queryResults[0]);
|
const firstEntry = getEntry(queryResults[0]);
|
||||||
// This info will be relevant later to identify 'transitive' relations
|
// This info will be relevant later to identify 'transitive' relations
|
||||||
expect(firstEntry.result[0].localMap).to.eql([
|
expect(firstEntry.result[0].localMap).to.deep.equal([
|
||||||
{
|
{
|
||||||
local: 'x',
|
local: 'x',
|
||||||
exported: 'y',
|
exported: 'y',
|
||||||
|
|
@ -174,7 +174,7 @@ describe('Analyzer "find-exports"', async () => {
|
||||||
const queryResults = await providence(findExportsQueryConfig, _providenceCfg);
|
const queryResults = await providence(findExportsQueryConfig, _providenceCfg);
|
||||||
const firstEntry = getEntry(queryResults[0]);
|
const firstEntry = getEntry(queryResults[0]);
|
||||||
expect(firstEntry.result[0].exportSpecifiers.length).to.equal(2);
|
expect(firstEntry.result[0].exportSpecifiers.length).to.equal(2);
|
||||||
expect(firstEntry.result[0].exportSpecifiers).to.eql(['x', 'y']);
|
expect(firstEntry.result[0].exportSpecifiers).to.deep.equal(['x', 'y']);
|
||||||
expect(firstEntry.result[0].source).to.equal('my/source');
|
expect(firstEntry.result[0].source).to.equal('my/source');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -190,7 +190,7 @@ describe('Analyzer "find-exports"', async () => {
|
||||||
const secondEntry = getEntry(queryResults[0], 1);
|
const secondEntry = getEntry(queryResults[0], 1);
|
||||||
const thirdEntry = getEntry(queryResults[0], 2);
|
const thirdEntry = getEntry(queryResults[0], 2);
|
||||||
|
|
||||||
expect(firstEntry.result[0].rootFileMap).to.eql([
|
expect(firstEntry.result[0].rootFileMap).to.deep.equal([
|
||||||
{
|
{
|
||||||
currentFileSpecifier: 'MyComp', // this is the local name in the file we track from
|
currentFileSpecifier: 'MyComp', // this is the local name in the file we track from
|
||||||
rootFile: {
|
rootFile: {
|
||||||
|
|
@ -199,16 +199,7 @@ describe('Analyzer "find-exports"', async () => {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
expect(secondEntry.result[0].rootFileMap).to.eql([
|
expect(secondEntry.result[0].rootFileMap).to.deep.equal([
|
||||||
{
|
|
||||||
currentFileSpecifier: 'InBetweenComp',
|
|
||||||
rootFile: {
|
|
||||||
file: './src/OriginalComp.js',
|
|
||||||
specifier: 'OriginalComp',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
expect(thirdEntry.result[0].rootFileMap).to.eql([
|
|
||||||
{
|
{
|
||||||
currentFileSpecifier: 'OriginalComp',
|
currentFileSpecifier: 'OriginalComp',
|
||||||
rootFile: {
|
rootFile: {
|
||||||
|
|
@ -217,6 +208,15 @@ describe('Analyzer "find-exports"', async () => {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
expect(thirdEntry.result[0].rootFileMap).to.deep.equal([
|
||||||
|
{
|
||||||
|
currentFileSpecifier: 'InBetweenComp',
|
||||||
|
rootFile: {
|
||||||
|
file: './src/OriginalComp.js',
|
||||||
|
specifier: 'OriginalComp',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`stores rootFileMap of an exported Identifier`, async () => {
|
it(`stores rootFileMap of an exported Identifier`, async () => {
|
||||||
|
|
@ -236,7 +236,7 @@ describe('Analyzer "find-exports"', async () => {
|
||||||
const queryResults = await providence(findExportsQueryConfig, _providenceCfg);
|
const queryResults = await providence(findExportsQueryConfig, _providenceCfg);
|
||||||
const firstEntry = getEntry(queryResults[0]);
|
const firstEntry = getEntry(queryResults[0]);
|
||||||
|
|
||||||
expect(firstEntry.result[0].rootFileMap).to.eql([
|
expect(firstEntry.result[0].rootFileMap).to.deep.equal([
|
||||||
{
|
{
|
||||||
currentFileSpecifier: '[default]',
|
currentFileSpecifier: '[default]',
|
||||||
rootFile: {
|
rootFile: {
|
||||||
|
|
@ -252,7 +252,7 @@ describe('Analyzer "find-exports"', async () => {
|
||||||
mockProject([`// some comment here...`]);
|
mockProject([`// some comment here...`]);
|
||||||
const queryResults = await providence(findExportsQueryConfig, _providenceCfg);
|
const queryResults = await providence(findExportsQueryConfig, _providenceCfg);
|
||||||
const firstEntry = getEntry(queryResults[0]);
|
const firstEntry = getEntry(queryResults[0]);
|
||||||
expect(firstEntry.result[0].exportSpecifiers).to.eql(['[file]']);
|
expect(firstEntry.result[0].exportSpecifiers).to.deep.equal(['[file]']);
|
||||||
expect(firstEntry.result[0].source).to.equal(undefined);
|
expect(firstEntry.result[0].source).to.equal(undefined);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -322,10 +322,10 @@ describe('Analyzer "find-exports"', async () => {
|
||||||
const queryResults = await providence(findExportsQueryConfig, _providenceCfg);
|
const queryResults = await providence(findExportsQueryConfig, _providenceCfg);
|
||||||
const queryResult = queryResults[0];
|
const queryResult = queryResults[0];
|
||||||
const [firstEntry, secondEntry, thirdEntry] = getEntries(queryResult);
|
const [firstEntry, secondEntry, thirdEntry] = getEntries(queryResult);
|
||||||
expect(firstEntry.meta.categories).to.eql(['fooCategory']);
|
expect(firstEntry.meta.categories).to.deep.equal(['fooCategory']);
|
||||||
// not mutually exclusive...
|
// not mutually exclusive...
|
||||||
expect(secondEntry.meta.categories).to.eql(['barCategory', 'testCategory']);
|
expect(secondEntry.meta.categories).to.deep.equal(['barCategory', 'testCategory']);
|
||||||
expect(thirdEntry.meta.categories).to.eql([]);
|
expect(thirdEntry.meta.categories).to.deep.equal([]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ describe('Analyzer "find-imports"', async () => {
|
||||||
const queryResults = await providence(findImportsQueryConfig, _providenceCfg);
|
const queryResults = await providence(findImportsQueryConfig, _providenceCfg);
|
||||||
const queryResult = queryResults[0];
|
const queryResult = queryResults[0];
|
||||||
const firstEntry = getEntry(queryResult);
|
const firstEntry = getEntry(queryResult);
|
||||||
expect(firstEntry.result[0].importSpecifiers).to.eql(['[file]']);
|
expect(firstEntry.result[0].importSpecifiers).to.deep.equal(['[file]']);
|
||||||
expect(firstEntry.result[0].source).to.equal('imported/source');
|
expect(firstEntry.result[0].source).to.equal('imported/source');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -128,7 +128,7 @@ describe('Analyzer "find-imports"', async () => {
|
||||||
const queryResult = queryResults[0];
|
const queryResult = queryResults[0];
|
||||||
const firstEntry = getEntry(queryResult);
|
const firstEntry = getEntry(queryResult);
|
||||||
// This info will be relevant later to identify transitive relations
|
// This info will be relevant later to identify transitive relations
|
||||||
expect(firstEntry.result[0].localMap[0]).to.eql({
|
expect(firstEntry.result[0].localMap[0]).to.deep.equal({
|
||||||
local: 'y',
|
local: 'y',
|
||||||
imported: 'x',
|
imported: 'x',
|
||||||
});
|
});
|
||||||
|
|
@ -332,7 +332,7 @@ describe('Analyzer "find-imports"', async () => {
|
||||||
// Should be normalized source...?
|
// Should be normalized source...?
|
||||||
expect(queryResult.queryOutput[0].source).to.equal('@external/source.js');
|
expect(queryResult.queryOutput[0].source).to.equal('@external/source.js');
|
||||||
expect(queryResult.queryOutput[0].id).to.equal('x::@external/source.js');
|
expect(queryResult.queryOutput[0].id).to.equal('x::@external/source.js');
|
||||||
expect(queryResult.queryOutput[0].dependents).to.eql([
|
expect(queryResult.queryOutput[0].dependents).to.deep.equal([
|
||||||
'fictional-project/file1.js',
|
'fictional-project/file1.js',
|
||||||
'fictional-project/file2.js',
|
'fictional-project/file2.js',
|
||||||
]);
|
]);
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ describe('trackdownIdentifier', () => {
|
||||||
const rootPath = '/my/project';
|
const rootPath = '/my/project';
|
||||||
|
|
||||||
const rootFile = await trackDownIdentifier(source, identifierName, currentFilePath, rootPath);
|
const rootFile = await trackDownIdentifier(source, identifierName, currentFilePath, rootPath);
|
||||||
expect(rootFile).to.eql({
|
expect(rootFile).to.deep.equal({
|
||||||
file: './src/declarationOfMyClass.js',
|
file: './src/declarationOfMyClass.js',
|
||||||
specifier: 'MyClass',
|
specifier: 'MyClass',
|
||||||
});
|
});
|
||||||
|
|
@ -71,7 +71,7 @@ describe('trackdownIdentifier', () => {
|
||||||
const rootPath = '/my/project';
|
const rootPath = '/my/project';
|
||||||
|
|
||||||
const rootFile = await trackDownIdentifier(source, identifierName, currentFilePath, rootPath);
|
const rootFile = await trackDownIdentifier(source, identifierName, currentFilePath, rootPath);
|
||||||
expect(rootFile).to.eql({
|
expect(rootFile).to.deep.equal({
|
||||||
file: './src/declarationOfMyClass.js',
|
file: './src/declarationOfMyClass.js',
|
||||||
specifier: 'MyClass',
|
specifier: 'MyClass',
|
||||||
});
|
});
|
||||||
|
|
@ -105,7 +105,7 @@ describe('trackdownIdentifier', () => {
|
||||||
const rootPath = '/my/project';
|
const rootPath = '/my/project';
|
||||||
|
|
||||||
const rootFile = await trackDownIdentifier(source, identifierName, currentFilePath, rootPath);
|
const rootFile = await trackDownIdentifier(source, identifierName, currentFilePath, rootPath);
|
||||||
expect(rootFile).to.eql({
|
expect(rootFile).to.deep.equal({
|
||||||
file: './src/declarationOfMyClass.js',
|
file: './src/declarationOfMyClass.js',
|
||||||
specifier: '[default]',
|
specifier: '[default]',
|
||||||
});
|
});
|
||||||
|
|
@ -131,7 +131,7 @@ describe('trackdownIdentifier', () => {
|
||||||
const rootPath = '/my/project';
|
const rootPath = '/my/project';
|
||||||
|
|
||||||
const rootFile = await trackDownIdentifier(source, identifierName, currentFilePath, rootPath);
|
const rootFile = await trackDownIdentifier(source, identifierName, currentFilePath, rootPath);
|
||||||
expect(rootFile).to.eql({
|
expect(rootFile).to.deep.equal({
|
||||||
file: '@external/source',
|
file: '@external/source',
|
||||||
specifier: '[default]',
|
specifier: '[default]',
|
||||||
});
|
});
|
||||||
|
|
@ -162,7 +162,7 @@ describe('trackdownIdentifier', () => {
|
||||||
const rootPath = '/my/project';
|
const rootPath = '/my/project';
|
||||||
|
|
||||||
const rootFile = await trackDownIdentifier(source, identifierName, currentFilePath, rootPath);
|
const rootFile = await trackDownIdentifier(source, identifierName, currentFilePath, rootPath);
|
||||||
expect(rootFile).to.eql({
|
expect(rootFile).to.deep.equal({
|
||||||
file: './MyClass.js',
|
file: './MyClass.js',
|
||||||
specifier: '[default]',
|
specifier: '[default]',
|
||||||
});
|
});
|
||||||
|
|
@ -201,7 +201,7 @@ describe('trackdownIdentifier', () => {
|
||||||
rootPath,
|
rootPath,
|
||||||
projectName,
|
projectName,
|
||||||
);
|
);
|
||||||
expect(rootFile).to.eql({
|
expect(rootFile).to.deep.equal({
|
||||||
file: './MyClass.js',
|
file: './MyClass.js',
|
||||||
specifier: '[default]',
|
specifier: '[default]',
|
||||||
});
|
});
|
||||||
|
|
@ -232,7 +232,7 @@ describe('trackdownIdentifier', () => {
|
||||||
const rootPath = '/my/project';
|
const rootPath = '/my/project';
|
||||||
|
|
||||||
const rootFile = await trackDownIdentifier(source, identifierName, currentFilePath, rootPath);
|
const rootFile = await trackDownIdentifier(source, identifierName, currentFilePath, rootPath);
|
||||||
expect(rootFile).to.eql({
|
expect(rootFile).to.deep.equal({
|
||||||
file: './src/declarationOfMyNumber.js',
|
file: './src/declarationOfMyNumber.js',
|
||||||
specifier: 'myNumber',
|
specifier: 'myNumber',
|
||||||
});
|
});
|
||||||
|
|
@ -260,7 +260,7 @@ describe('trackdownIdentifier', () => {
|
||||||
const rootPath = '/my/project';
|
const rootPath = '/my/project';
|
||||||
|
|
||||||
const rootFile = await trackDownIdentifier(source, identifierName, currentFilePath, rootPath);
|
const rootFile = await trackDownIdentifier(source, identifierName, currentFilePath, rootPath);
|
||||||
expect(rootFile).to.eql({
|
expect(rootFile).to.deep.equal({
|
||||||
file: './packages/accordion/IngAccordionContent.js',
|
file: './packages/accordion/IngAccordionContent.js',
|
||||||
specifier: 'IngAccordionContent',
|
specifier: 'IngAccordionContent',
|
||||||
});
|
});
|
||||||
|
|
@ -277,7 +277,7 @@ describe('trackdownIdentifier', () => {
|
||||||
currentFilePath2,
|
currentFilePath2,
|
||||||
rootPath2,
|
rootPath2,
|
||||||
);
|
);
|
||||||
expect(rootFile2).to.eql({
|
expect(rootFile2).to.deep.equal({
|
||||||
file: './packages/accordion/IngAccordionInvokerButton.js',
|
file: './packages/accordion/IngAccordionInvokerButton.js',
|
||||||
specifier: 'IngAccordionInvokerButton',
|
specifier: 'IngAccordionInvokerButton',
|
||||||
});
|
});
|
||||||
|
|
@ -321,7 +321,7 @@ describe('trackDownIdentifierFromScope', () => {
|
||||||
fullCurrentFilePath,
|
fullCurrentFilePath,
|
||||||
projectPath,
|
projectPath,
|
||||||
);
|
);
|
||||||
expect(rootFile).to.eql({
|
expect(rootFile).to.deep.equal({
|
||||||
file: '[current]',
|
file: '[current]',
|
||||||
specifier: 'MyClass',
|
specifier: 'MyClass',
|
||||||
});
|
});
|
||||||
|
|
@ -372,7 +372,7 @@ describe('trackDownIdentifierFromScope', () => {
|
||||||
fullCurrentFilePath,
|
fullCurrentFilePath,
|
||||||
projectPath,
|
projectPath,
|
||||||
);
|
);
|
||||||
expect(rootFile).to.eql({
|
expect(rootFile).to.deep.equal({
|
||||||
file: './src/declarationOfMyClass.js',
|
file: './src/declarationOfMyClass.js',
|
||||||
specifier: 'MyClass',
|
specifier: 'MyClass',
|
||||||
});
|
});
|
||||||
|
|
@ -420,7 +420,7 @@ describe('trackDownIdentifierFromScope', () => {
|
||||||
fullCurrentFilePath,
|
fullCurrentFilePath,
|
||||||
projectPath,
|
projectPath,
|
||||||
);
|
);
|
||||||
expect(rootFile).to.eql({
|
expect(rootFile).to.deep.equal({
|
||||||
file: './src/classes.js',
|
file: './src/classes.js',
|
||||||
specifier: 'El1',
|
specifier: 'El1',
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -215,14 +215,14 @@ describe('Analyzer "match-imports"', async () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
const [name, filePath, project] = targetExportedId.split('::');
|
const [name, filePath, project] = targetExportedId.split('::');
|
||||||
expect(matchedEntry.exportSpecifier).to.eql({
|
expect(matchedEntry.exportSpecifier).to.deep.equal({
|
||||||
name,
|
name,
|
||||||
filePath,
|
filePath,
|
||||||
project,
|
project,
|
||||||
id: targetExportedId,
|
id: targetExportedId,
|
||||||
});
|
});
|
||||||
expect(matchedEntry.matchesPerProject[0].project).to.equal('importing-target-project');
|
expect(matchedEntry.matchesPerProject[0].project).to.equal('importing-target-project');
|
||||||
expect(matchedEntry.matchesPerProject[0].files).to.eql(importedByFiles);
|
expect(matchedEntry.matchesPerProject[0].files).to.deep.equal(importedByFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('Extracting exports', () => {
|
describe('Extracting exports', () => {
|
||||||
|
|
@ -435,7 +435,7 @@ describe('Analyzer "match-imports"', async () => {
|
||||||
});
|
});
|
||||||
const queryResult = queryResults[0];
|
const queryResult = queryResults[0];
|
||||||
expect(queryResult.queryOutput[0].exportSpecifier.name).to.equal('[default]');
|
expect(queryResult.queryOutput[0].exportSpecifier.name).to.equal('[default]');
|
||||||
expect(queryResult.queryOutput[0].matchesPerProject).to.eql([
|
expect(queryResult.queryOutput[0].matchesPerProject).to.deep.equal([
|
||||||
{ files: ['./importDefault1.js', './importDefault2.js'], project: 'target' },
|
{ files: ['./importDefault1.js', './importDefault2.js'], project: 'target' },
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
@ -476,11 +476,11 @@ describe('Analyzer "match-imports"', async () => {
|
||||||
});
|
});
|
||||||
const queryResult = queryResults[0];
|
const queryResult = queryResults[0];
|
||||||
expect(queryResult.queryOutput[0].exportSpecifier.name).to.equal('[default]');
|
expect(queryResult.queryOutput[0].exportSpecifier.name).to.equal('[default]');
|
||||||
expect(queryResult.queryOutput[0].matchesPerProject).to.eql([
|
expect(queryResult.queryOutput[0].matchesPerProject).to.deep.equal([
|
||||||
{ files: ['./deep-imports.js'], project: 'target' },
|
{ files: ['./deep-imports.js'], project: 'target' },
|
||||||
]);
|
]);
|
||||||
expect(queryResult.queryOutput[1].exportSpecifier.name).to.equal('RefClass');
|
expect(queryResult.queryOutput[1].exportSpecifier.name).to.equal('RefClass');
|
||||||
expect(queryResult.queryOutput[1].matchesPerProject).to.eql([
|
expect(queryResult.queryOutput[1].matchesPerProject).to.deep.equal([
|
||||||
{ files: ['./deep-imports.js'], project: 'target' },
|
{ files: ['./deep-imports.js'], project: 'target' },
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -188,7 +188,7 @@ describe('Analyzer "match-paths"', async () => {
|
||||||
mockTargetAndReferenceProject(searchTargetProject, referenceProject);
|
mockTargetAndReferenceProject(searchTargetProject, referenceProject);
|
||||||
const queryResults = await providence(matchPathsQueryConfig, _providenceCfg);
|
const queryResults = await providence(matchPathsQueryConfig, _providenceCfg);
|
||||||
const queryResult = queryResults[0];
|
const queryResult = queryResults[0];
|
||||||
expect(queryResult.queryOutput).to.eql(expectedMatches);
|
expect(queryResult.queryOutput).to.deep.equal(expectedMatches);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Features', () => {
|
describe('Features', () => {
|
||||||
|
|
@ -239,7 +239,7 @@ describe('Analyzer "match-paths"', async () => {
|
||||||
mockTargetAndReferenceProject(targetProj, refProj);
|
mockTargetAndReferenceProject(targetProj, refProj);
|
||||||
const queryResults = await providence(matchPathsQueryConfig, _providenceCfg);
|
const queryResults = await providence(matchPathsQueryConfig, _providenceCfg);
|
||||||
const queryResult = queryResults[0];
|
const queryResult = queryResults[0];
|
||||||
expect(queryResult.queryOutput[0].variable.paths[0]).to.eql({
|
expect(queryResult.queryOutput[0].variable.paths[0]).to.deep.equal({
|
||||||
from: './index.js',
|
from: './index.js',
|
||||||
to: './target-src/TargetClass.js',
|
to: './target-src/TargetClass.js',
|
||||||
});
|
});
|
||||||
|
|
@ -263,7 +263,7 @@ describe('Analyzer "match-paths"', async () => {
|
||||||
mockTargetAndReferenceProject(targetProjWithMultipleExports, refProj);
|
mockTargetAndReferenceProject(targetProjWithMultipleExports, refProj);
|
||||||
const queryResults = await providence(matchPathsQueryConfig, _providenceCfg);
|
const queryResults = await providence(matchPathsQueryConfig, _providenceCfg);
|
||||||
const queryResult = queryResults[0];
|
const queryResult = queryResults[0];
|
||||||
expect(queryResult.queryOutput[0].variable.paths[0]).to.eql({
|
expect(queryResult.queryOutput[0].variable.paths[0]).to.deep.equal({
|
||||||
from: './index.js',
|
from: './index.js',
|
||||||
to: './reexportFromRoot.js',
|
to: './reexportFromRoot.js',
|
||||||
});
|
});
|
||||||
|
|
@ -296,7 +296,7 @@ describe('Analyzer "match-paths"', async () => {
|
||||||
mockTargetAndReferenceProject(targetProjWithMultipleExportsAndMainEntry, refProj);
|
mockTargetAndReferenceProject(targetProjWithMultipleExportsAndMainEntry, refProj);
|
||||||
const queryResults = await providence(matchPathsQueryConfig, _providenceCfg);
|
const queryResults = await providence(matchPathsQueryConfig, _providenceCfg);
|
||||||
const queryResult = queryResults[0];
|
const queryResult = queryResults[0];
|
||||||
expect(queryResult.queryOutput[0].variable.paths[0]).to.eql({
|
expect(queryResult.queryOutput[0].variable.paths[0]).to.deep.equal({
|
||||||
from: './index.js',
|
from: './index.js',
|
||||||
to: './target-src/mainEntry.js',
|
to: './target-src/mainEntry.js',
|
||||||
});
|
});
|
||||||
|
|
@ -308,8 +308,11 @@ describe('Analyzer "match-paths"', async () => {
|
||||||
const queryResults = await providence(matchPathsQueryConfig, _providenceCfg);
|
const queryResults = await providence(matchPathsQueryConfig, _providenceCfg);
|
||||||
const queryResult = queryResults[0];
|
const queryResult = queryResults[0];
|
||||||
const unprefixedPaths = queryResult.queryOutput[0].variable.paths[0];
|
const unprefixedPaths = queryResult.queryOutput[0].variable.paths[0];
|
||||||
expect(unprefixedPaths).to.eql({ from: './index.js', to: './target-src/TargetClass.js' });
|
expect(unprefixedPaths).to.deep.equal({
|
||||||
expect(queryResult.queryOutput[0].variable.paths[1]).to.eql({
|
from: './index.js',
|
||||||
|
to: './target-src/TargetClass.js',
|
||||||
|
});
|
||||||
|
expect(queryResult.queryOutput[0].variable.paths[1]).to.deep.equal({
|
||||||
from: `${refProj.name}/${unprefixedPaths.from.slice(2)}`,
|
from: `${refProj.name}/${unprefixedPaths.from.slice(2)}`,
|
||||||
to: unprefixedPaths.to,
|
to: unprefixedPaths.to,
|
||||||
});
|
});
|
||||||
|
|
@ -336,11 +339,11 @@ describe('Analyzer "match-paths"', async () => {
|
||||||
mockTargetAndReferenceProject(targetProjMultipleTargetExtensions, refProj);
|
mockTargetAndReferenceProject(targetProjMultipleTargetExtensions, refProj);
|
||||||
const queryResults = await providence(matchPathsQueryConfig, _providenceCfg);
|
const queryResults = await providence(matchPathsQueryConfig, _providenceCfg);
|
||||||
const queryResult = queryResults[0];
|
const queryResult = queryResults[0];
|
||||||
expect(queryResult.queryOutput[0].variable.paths[0]).to.eql({
|
expect(queryResult.queryOutput[0].variable.paths[0]).to.deep.equal({
|
||||||
from: './index.js',
|
from: './index.js',
|
||||||
to: './target-src/TargetClass.js',
|
to: './target-src/TargetClass.js',
|
||||||
});
|
});
|
||||||
expect(queryResult.queryOutput[1].variable.paths[0]).to.eql({
|
expect(queryResult.queryOutput[1].variable.paths[0]).to.deep.equal({
|
||||||
from: './index.js',
|
from: './index.js',
|
||||||
to: './target-src/TargetSomething.js',
|
to: './target-src/TargetSomething.js',
|
||||||
});
|
});
|
||||||
|
|
@ -410,7 +413,7 @@ describe('Analyzer "match-paths"', async () => {
|
||||||
);
|
);
|
||||||
const queryResults = await providence(matchPathsQueryConfigFilter, _providenceCfg);
|
const queryResults = await providence(matchPathsQueryConfigFilter, _providenceCfg);
|
||||||
const queryResult = queryResults[0];
|
const queryResult = queryResults[0];
|
||||||
expect(queryResult.queryOutput[0].variable.paths[0]).to.eql({
|
expect(queryResult.queryOutput[0].variable.paths[0]).to.deep.equal({
|
||||||
from: './index.js',
|
from: './index.js',
|
||||||
to: './target-src/TargetClass.js',
|
to: './target-src/TargetClass.js',
|
||||||
});
|
});
|
||||||
|
|
@ -515,8 +518,8 @@ describe('Analyzer "match-paths"', async () => {
|
||||||
mockTargetAndReferenceProject(searchTargetProject, referenceProject);
|
mockTargetAndReferenceProject(searchTargetProject, referenceProject);
|
||||||
const queryResults = await providence(matchPathsQueryConfig, _providenceCfg);
|
const queryResults = await providence(matchPathsQueryConfig, _providenceCfg);
|
||||||
const queryResult = queryResults[0];
|
const queryResult = queryResults[0];
|
||||||
expect(queryResult.queryOutput[0].tag).to.eql(expectedMatches[0]);
|
expect(queryResult.queryOutput[0].tag).to.deep.equal(expectedMatches[0]);
|
||||||
expect(queryResult.queryOutput[1].tag).to.eql(expectedMatches[1]);
|
expect(queryResult.queryOutput[1].tag).to.deep.equal(expectedMatches[1]);
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: test works in isolation, but some side effects occur when run in suite
|
// TODO: test works in isolation, but some side effects occur when run in suite
|
||||||
|
|
@ -578,7 +581,7 @@ describe('Analyzer "match-paths"', async () => {
|
||||||
providenceCfg,
|
providenceCfg,
|
||||||
);
|
);
|
||||||
const queryResult = queryResults[0];
|
const queryResult = queryResults[0];
|
||||||
expect(queryResult.queryOutput[0].tag).to.eql({
|
expect(queryResult.queryOutput[0].tag).to.deep.equal({
|
||||||
from: 'their-button',
|
from: 'their-button',
|
||||||
to: 'my-button',
|
to: 'my-button',
|
||||||
paths: [
|
paths: [
|
||||||
|
|
@ -607,7 +610,7 @@ describe('Analyzer "match-paths"', async () => {
|
||||||
mockTargetAndReferenceProject(searchTargetProject, referenceProject);
|
mockTargetAndReferenceProject(searchTargetProject, referenceProject);
|
||||||
const queryResults = await providence(matchPathsQueryConfig, _providenceCfg);
|
const queryResults = await providence(matchPathsQueryConfig, _providenceCfg);
|
||||||
const queryResult = queryResults[0];
|
const queryResult = queryResults[0];
|
||||||
expect(queryResult.queryOutput[0].tag.paths[0]).to.eql({
|
expect(queryResult.queryOutput[0].tag.paths[0]).to.deep.equal({
|
||||||
from: './customelementDefinitions.js',
|
from: './customelementDefinitions.js',
|
||||||
to: './extendedCustomelementDefinitions.js',
|
to: './extendedCustomelementDefinitions.js',
|
||||||
});
|
});
|
||||||
|
|
@ -617,7 +620,7 @@ describe('Analyzer "match-paths"', async () => {
|
||||||
mockTargetAndReferenceProject(searchTargetProject, referenceProject);
|
mockTargetAndReferenceProject(searchTargetProject, referenceProject);
|
||||||
const queryResults = await providence(matchPathsQueryConfig, _providenceCfg);
|
const queryResults = await providence(matchPathsQueryConfig, _providenceCfg);
|
||||||
const queryResult = queryResults[0];
|
const queryResult = queryResults[0];
|
||||||
expect(queryResult.queryOutput[0].tag.paths[1]).to.eql({
|
expect(queryResult.queryOutput[0].tag.paths[1]).to.deep.equal({
|
||||||
from: 'reference-project/customelementDefinitions.js',
|
from: 'reference-project/customelementDefinitions.js',
|
||||||
to: './extendedCustomelementDefinitions.js',
|
to: './extendedCustomelementDefinitions.js',
|
||||||
});
|
});
|
||||||
|
|
@ -736,7 +739,7 @@ describe('Analyzer "match-paths"', async () => {
|
||||||
mockTargetAndReferenceProject(searchTargetProjectFull, referenceProjectFull);
|
mockTargetAndReferenceProject(searchTargetProjectFull, referenceProjectFull);
|
||||||
const queryResults = await providence(matchPathsQueryConfig, _providenceCfg);
|
const queryResults = await providence(matchPathsQueryConfig, _providenceCfg);
|
||||||
const queryResult = queryResults[0];
|
const queryResult = queryResults[0];
|
||||||
expect(queryResult.queryOutput).to.eql(expectedMatchesFull);
|
expect(queryResult.queryOutput).to.deep.equal(expectedMatchesFull);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -332,14 +332,14 @@ describe('Analyzer "match-subclasses"', async () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
const [name, filePath, project] = targetExportedId.split('::');
|
const [name, filePath, project] = targetExportedId.split('::');
|
||||||
expect(matchedEntry.exportSpecifier).to.eql({
|
expect(matchedEntry.exportSpecifier).to.deep.equal({
|
||||||
name,
|
name,
|
||||||
filePath,
|
filePath,
|
||||||
project,
|
project,
|
||||||
id: targetExportedId,
|
id: targetExportedId,
|
||||||
});
|
});
|
||||||
expect(matchedEntry.matchesPerProject[0].project).to.equal('importing-target-project');
|
expect(matchedEntry.matchesPerProject[0].project).to.equal('importing-target-project');
|
||||||
expect(matchedEntry.matchesPerProject[0].files).to.eql(importedByFiles);
|
expect(matchedEntry.matchesPerProject[0].files).to.deep.equal(importedByFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
mockTargetAndReferenceProject(searchTargetProject, referenceProject);
|
mockTargetAndReferenceProject(searchTargetProject, referenceProject);
|
||||||
|
|
|
||||||
|
|
@ -81,19 +81,19 @@ describe('Analyzer', async () => {
|
||||||
const queryResult = queryResults[0];
|
const queryResult = queryResults[0];
|
||||||
const { queryOutput, meta } = queryResult;
|
const { queryOutput, meta } = queryResult;
|
||||||
|
|
||||||
expect(queryOutput[0]).to.eql({
|
expect(queryOutput[0]).to.deep.equal({
|
||||||
file: './test-file-0.js',
|
file: './test-file-0.js',
|
||||||
meta: {},
|
meta: {},
|
||||||
result: [{ matched: 'entry' }],
|
result: [{ matched: 'entry' }],
|
||||||
});
|
});
|
||||||
expect(queryOutput[1]).to.eql({
|
expect(queryOutput[1]).to.deep.equal({
|
||||||
file: './test-file2.js',
|
file: './test-file2.js',
|
||||||
meta: {},
|
meta: {},
|
||||||
result: [{ matched: 'entry' }],
|
result: [{ matched: 'entry' }],
|
||||||
});
|
});
|
||||||
// Local machine info needs to be deleted, so that results are always 'machine agnostic'
|
// Local machine info needs to be deleted, so that results are always 'machine agnostic'
|
||||||
// (which is needed to share cached json results via git)
|
// (which is needed to share cached json results via git)
|
||||||
expect(meta).to.eql({
|
expect(meta).to.deep.equal({
|
||||||
searchType: 'ast-analyzer',
|
searchType: 'ast-analyzer',
|
||||||
analyzerMeta: {
|
analyzerMeta: {
|
||||||
name: 'my-analyzer',
|
name: 'my-analyzer',
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
import { expect } from 'chai';
|
import { expect } from 'chai';
|
||||||
import { it } from 'mocha';
|
import { it } from 'mocha';
|
||||||
import pathLib from 'path';
|
|
||||||
import { InputDataService } from '../../../src/program/core/InputDataService.js';
|
import { InputDataService } from '../../../src/program/core/InputDataService.js';
|
||||||
import { memoizeConfig } from '../../../src/program/utils/memoize.js';
|
import { memoize } from '../../../src/program/utils/memoize.js';
|
||||||
import { getCurrentDir } from '../../../src/program/utils/get-current-dir.js';
|
|
||||||
import {
|
import {
|
||||||
restoreMockedProjects,
|
restoreMockedProjects,
|
||||||
mockProject,
|
mockProject,
|
||||||
|
|
@ -24,13 +22,13 @@ describe('InputDataService', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
memoizeConfig.isCacheDisabled = true;
|
memoize.disableCaching();
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
restoreOriginalInputDataPaths();
|
restoreOriginalInputDataPaths();
|
||||||
restoreMockedProjects();
|
restoreMockedProjects();
|
||||||
memoizeConfig.isCacheDisabled = false;
|
memoize.restoreCaching();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Configuration', () => {
|
describe('Configuration', () => {
|
||||||
|
|
@ -50,36 +48,43 @@ describe('InputDataService', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Methods', () => {
|
describe('Methods', () => {
|
||||||
// TODO: mock file system...
|
|
||||||
it('"createDataObject"', async () => {
|
it('"createDataObject"', async () => {
|
||||||
/** @type {* & PathFromSystemRoot} */
|
mockProject({
|
||||||
const projectPath = pathLib.resolve(
|
'./package.json': JSON.stringify({
|
||||||
getCurrentDir(import.meta.url),
|
name: 'fictional-project',
|
||||||
'../../../test-helpers/project-mocks/importing-target-project',
|
main: 'my/index.js',
|
||||||
);
|
version: '1.0.0',
|
||||||
|
}),
|
||||||
|
'./src/file.js': '// bla',
|
||||||
|
'./src/file2.js': '// bla',
|
||||||
|
});
|
||||||
|
|
||||||
const inputDataPerProject = InputDataService.createDataObject([projectPath]);
|
const inputDataPerProject = await InputDataService.createDataObject(['/fictional/project']);
|
||||||
expect(Object.keys(inputDataPerProject[0].project)).to.eql([
|
expect(inputDataPerProject).to.deep.equal([
|
||||||
'path',
|
{
|
||||||
'mainEntry',
|
project: {
|
||||||
'name',
|
path: '/fictional/project',
|
||||||
'version',
|
mainEntry: './my/index.js',
|
||||||
'commitHash',
|
name: 'fictional-project',
|
||||||
|
version: '1.0.0',
|
||||||
|
commitHash: '[not-a-git-root]',
|
||||||
|
},
|
||||||
|
entries: [
|
||||||
|
{
|
||||||
|
file: './src/file.js',
|
||||||
|
context: {
|
||||||
|
code: '// bla',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
file: './src/file2.js',
|
||||||
|
context: {
|
||||||
|
code: '// bla',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
expect(inputDataPerProject[0].project.name).to.equal('importing-target-project');
|
|
||||||
expect(inputDataPerProject[0].project.mainEntry).to.equal(
|
|
||||||
'./target-src/match-imports/root-level-imports.js',
|
|
||||||
);
|
|
||||||
expect(
|
|
||||||
inputDataPerProject[0].project.path.endsWith(
|
|
||||||
'/test-helpers/project-mocks/importing-target-project',
|
|
||||||
),
|
|
||||||
).to.equal(true);
|
|
||||||
expect(inputDataPerProject[0].entries.length).to.equal(6);
|
|
||||||
expect(inputDataPerProject[0].entries[0].context.code).to.not.be.undefined;
|
|
||||||
expect(inputDataPerProject[0].entries[0].file).to.equal(
|
|
||||||
'./target-src/find-customelements/multiple.js',
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('"targetProjectPaths"', async () => {});
|
it('"targetProjectPaths"', async () => {});
|
||||||
|
|
@ -99,11 +104,11 @@ describe('InputDataService', () => {
|
||||||
'{ "name": "@another-scope/another-package" }',
|
'{ "name": "@another-scope/another-package" }',
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(InputDataService.getMonoRepoPackages('/fictional/project')).to.eql([
|
expect(await InputDataService.getMonoRepoPackages('/fictional/project')).to.deep.equal([
|
||||||
{ path: 'packages/pkg1/', name: 'package1' },
|
{ path: 'packages/pkg1', name: 'package1' },
|
||||||
{ path: 'packages/pkg2/', name: 'pkg2' }, // fallback when no package.json
|
{ path: 'packages/pkg2', name: 'pkg2' }, // fallback when no package.json
|
||||||
{ path: 'packages/pkg3/', name: '@scope/pkg3' },
|
{ path: 'packages/pkg3', name: '@scope/pkg3' },
|
||||||
{ path: 'another-folder/another-package/', name: '@another-scope/another-package' },
|
{ path: 'another-folder/another-package', name: '@another-scope/another-package' },
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -120,11 +125,11 @@ describe('InputDataService', () => {
|
||||||
'{ "name": "@another-scope/another-package" }',
|
'{ "name": "@another-scope/another-package" }',
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(InputDataService.getMonoRepoPackages('/fictional/project')).to.eql([
|
expect(await InputDataService.getMonoRepoPackages('/fictional/project')).to.deep.equal([
|
||||||
{ path: 'packages/pkg1/', name: 'package1' },
|
{ path: 'packages/pkg1', name: 'package1' },
|
||||||
{ path: 'packages/pkg2/', name: 'pkg2' }, // fallback when no package.json
|
{ path: 'packages/pkg2', name: 'pkg2' }, // fallback when no package.json
|
||||||
{ path: 'packages/pkg3/', name: '@scope/pkg3' },
|
{ path: 'packages/pkg3', name: '@scope/pkg3' },
|
||||||
{ path: 'another-folder/another-package/', name: '@another-scope/another-package' },
|
{ path: 'another-folder/another-package', name: '@another-scope/another-package' },
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -143,19 +148,21 @@ describe('InputDataService', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('gathers a list of files', async () => {
|
it('gathers a list of files', async () => {
|
||||||
const globOutput = InputDataService.gatherFilesFromDir('/fictional/project');
|
const globOutput = await InputDataService.gatherFilesFromDir('/fictional/project');
|
||||||
expect(globOutput).to.eql([
|
expect(globOutput).to.deep.equal([
|
||||||
'/fictional/project/index.js',
|
'/fictional/project/index.js',
|
||||||
'/fictional/project/internal.js',
|
'/fictional/project/internal.js',
|
||||||
|
'/fictional/project/something.test.js',
|
||||||
'/fictional/project/nested/index.js',
|
'/fictional/project/nested/index.js',
|
||||||
'/fictional/project/nested/nested-two/index.test.js',
|
'/fictional/project/nested/nested-two/index.test.js',
|
||||||
'/fictional/project/something.test.js',
|
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('allows passing a depth which stops at nested depth', async () => {
|
it('allows passing a depth which stops at nested depth', async () => {
|
||||||
const globOutput = InputDataService.gatherFilesFromDir('/fictional/project', { depth: 0 });
|
const globOutput = await InputDataService.gatherFilesFromDir('/fictional/project', {
|
||||||
expect(globOutput).to.eql([
|
depth: 0,
|
||||||
|
});
|
||||||
|
expect(globOutput).to.deep.equal([
|
||||||
'/fictional/project/index.js',
|
'/fictional/project/index.js',
|
||||||
'/fictional/project/internal.js',
|
'/fictional/project/internal.js',
|
||||||
'/fictional/project/something.test.js',
|
'/fictional/project/something.test.js',
|
||||||
|
|
@ -163,26 +170,26 @@ describe('InputDataService', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('allows passing extensions', async () => {
|
it('allows passing extensions', async () => {
|
||||||
const globOutput = InputDataService.gatherFilesFromDir('/fictional/project', {
|
const globOutput = await InputDataService.gatherFilesFromDir('/fictional/project', {
|
||||||
extensions: ['.html', '.js'],
|
extensions: ['.html', '.js'],
|
||||||
});
|
});
|
||||||
expect(globOutput).to.eql([
|
expect(globOutput).to.deep.equal([
|
||||||
'/fictional/project/index.html',
|
'/fictional/project/index.html',
|
||||||
'/fictional/project/index.js',
|
'/fictional/project/index.js',
|
||||||
'/fictional/project/internal.js',
|
'/fictional/project/internal.js',
|
||||||
'/fictional/project/nested/index.js',
|
|
||||||
'/fictional/project/nested/nested-two/index.test.js',
|
|
||||||
'/fictional/project/something.test.html',
|
'/fictional/project/something.test.html',
|
||||||
'/fictional/project/something.test.js',
|
'/fictional/project/something.test.js',
|
||||||
|
'/fictional/project/nested/index.js',
|
||||||
|
'/fictional/project/nested/nested-two/index.test.js',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('allows passing excluded folders', async () => {
|
it('allows passing excluded folders', async () => {
|
||||||
const globOutput = InputDataService.gatherFilesFromDir('/fictional/project', {
|
const globOutput = await InputDataService.gatherFilesFromDir('/fictional/project', {
|
||||||
extensions: ['.html', '.js'],
|
extensions: ['.html', '.js'],
|
||||||
allowlist: ['!nested/**'],
|
allowlist: ['!nested/**'],
|
||||||
});
|
});
|
||||||
expect(globOutput).to.eql([
|
expect(globOutput).to.deep.equal([
|
||||||
'/fictional/project/index.html',
|
'/fictional/project/index.html',
|
||||||
'/fictional/project/index.js',
|
'/fictional/project/index.js',
|
||||||
'/fictional/project/internal.js',
|
'/fictional/project/internal.js',
|
||||||
|
|
@ -192,25 +199,25 @@ describe('InputDataService', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('allows passing excluded files', async () => {
|
it('allows passing excluded files', async () => {
|
||||||
const globOutput = InputDataService.gatherFilesFromDir('/fictional/project', {
|
const globOutput = await InputDataService.gatherFilesFromDir('/fictional/project', {
|
||||||
extensions: ['.html', '.js'],
|
extensions: ['.html', '.js'],
|
||||||
allowlist: ['!index.js', '!**/*/index.js'],
|
allowlist: ['!index.js', '!**/*/index.js'],
|
||||||
});
|
});
|
||||||
expect(globOutput).to.eql([
|
expect(globOutput).to.deep.equal([
|
||||||
'/fictional/project/index.html',
|
'/fictional/project/index.html',
|
||||||
'/fictional/project/internal.js',
|
'/fictional/project/internal.js',
|
||||||
'/fictional/project/nested/nested-two/index.test.js',
|
|
||||||
'/fictional/project/something.test.html',
|
'/fictional/project/something.test.html',
|
||||||
'/fictional/project/something.test.js',
|
'/fictional/project/something.test.js',
|
||||||
|
'/fictional/project/nested/nested-two/index.test.js',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('allows passing exclude globs', async () => {
|
it('allows passing exclude globs', async () => {
|
||||||
const globOutput = InputDataService.gatherFilesFromDir('/fictional/project', {
|
const globOutput = await InputDataService.gatherFilesFromDir('/fictional/project', {
|
||||||
extensions: ['.html', '.js'],
|
extensions: ['.html', '.js'],
|
||||||
allowlist: ['!**/*.test.{html,js}'],
|
allowlist: ['!**/*.test.{html,js}'],
|
||||||
});
|
});
|
||||||
expect(globOutput).to.eql([
|
expect(globOutput).to.deep.equal([
|
||||||
'/fictional/project/index.html',
|
'/fictional/project/index.html',
|
||||||
'/fictional/project/index.js',
|
'/fictional/project/index.js',
|
||||||
'/fictional/project/internal.js',
|
'/fictional/project/internal.js',
|
||||||
|
|
@ -219,11 +226,11 @@ describe('InputDataService', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not support non globs in "allowlist"', async () => {
|
it('does not support non globs in "allowlist"', async () => {
|
||||||
const globOutput = InputDataService.gatherFilesFromDir('/fictional/project', {
|
const globOutput = await InputDataService.gatherFilesFromDir('/fictional/project', {
|
||||||
extensions: ['.html', '.js'],
|
extensions: ['.html', '.js'],
|
||||||
allowlist: ['nested'],
|
allowlist: ['nested'],
|
||||||
});
|
});
|
||||||
expect(globOutput).to.eql([]);
|
expect(globOutput).to.deep.equal([]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('omits node_modules and bower_components at root level by default', async () => {
|
it('omits node_modules and bower_components at root level by default', async () => {
|
||||||
|
|
@ -235,11 +242,11 @@ describe('InputDataService', () => {
|
||||||
'./nested/bower_components/pkg/y.js': '',
|
'./nested/bower_components/pkg/y.js': '',
|
||||||
});
|
});
|
||||||
|
|
||||||
const globOutput = InputDataService.gatherFilesFromDir('/fictional/project');
|
const globOutput = await InputDataService.gatherFilesFromDir('/fictional/project');
|
||||||
expect(globOutput).to.eql([
|
expect(globOutput).to.deep.equal([
|
||||||
'/fictional/project/index.js',
|
'/fictional/project/index.js',
|
||||||
'/fictional/project/nested/bower_components/pkg/y.js',
|
|
||||||
'/fictional/project/nested/node_modules/pkg/x.js',
|
'/fictional/project/nested/node_modules/pkg/x.js',
|
||||||
|
'/fictional/project/nested/bower_components/pkg/y.js',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -249,12 +256,12 @@ describe('InputDataService', () => {
|
||||||
'./omitted/file.js': '',
|
'./omitted/file.js': '',
|
||||||
'./added/file.js': '',
|
'./added/file.js': '',
|
||||||
});
|
});
|
||||||
const globOutput = InputDataService.gatherFilesFromDir('/fictional/project', {
|
const globOutput = await InputDataService.gatherFilesFromDir('/fictional/project', {
|
||||||
allowlist: ['*', 'added/**/*'],
|
allowlist: ['*', 'added/**/*'],
|
||||||
});
|
});
|
||||||
expect(globOutput).to.eql([
|
expect(globOutput).to.deep.equal([
|
||||||
'/fictional/project/added/file.js',
|
|
||||||
'/fictional/project/root-lvl.js',
|
'/fictional/project/root-lvl.js',
|
||||||
|
'/fictional/project/added/file.js',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -265,10 +272,10 @@ describe('InputDataService', () => {
|
||||||
'./deeper/glob/file.js': '',
|
'./deeper/glob/file.js': '',
|
||||||
'./deeper/file.js': '',
|
'./deeper/file.js': '',
|
||||||
});
|
});
|
||||||
const globOutput = InputDataService.gatherFilesFromDir('/fictional/project', {
|
const globOutput = await InputDataService.gatherFilesFromDir('/fictional/project', {
|
||||||
allowlist: ['deeper/**/*'],
|
allowlist: ['deeper/**/*'],
|
||||||
});
|
});
|
||||||
expect(globOutput).to.eql([
|
expect(globOutput).to.deep.equal([
|
||||||
'/fictional/project/deeper/file.js',
|
'/fictional/project/deeper/file.js',
|
||||||
'/fictional/project/deeper/glob/file.js',
|
'/fictional/project/deeper/glob/file.js',
|
||||||
'/fictional/project/deeper/glob/structure/file.js',
|
'/fictional/project/deeper/glob/structure/file.js',
|
||||||
|
|
@ -285,8 +292,8 @@ describe('InputDataService', () => {
|
||||||
'./some-other-pkg/commitlint.conf.js': '',
|
'./some-other-pkg/commitlint.conf.js': '',
|
||||||
});
|
});
|
||||||
|
|
||||||
const globOutput = InputDataService.gatherFilesFromDir('/fictional/project');
|
const globOutput = await InputDataService.gatherFilesFromDir('/fictional/project');
|
||||||
expect(globOutput).to.eql(['/fictional/project/index.js']);
|
expect(globOutput).to.deep.equal(['/fictional/project/index.js']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('omits hidden files by default', async () => {
|
it('omits hidden files by default', async () => {
|
||||||
|
|
@ -295,8 +302,8 @@ describe('InputDataService', () => {
|
||||||
'./index.js': '',
|
'./index.js': '',
|
||||||
});
|
});
|
||||||
|
|
||||||
const globOutput = InputDataService.gatherFilesFromDir('/fictional/project');
|
const globOutput = await InputDataService.gatherFilesFromDir('/fictional/project');
|
||||||
expect(globOutput).to.eql(['/fictional/project/index.js']);
|
expect(globOutput).to.deep.equal(['/fictional/project/index.js']);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('AllowlistMode', () => {
|
describe('AllowlistMode', () => {
|
||||||
|
|
@ -308,8 +315,8 @@ describe('InputDataService', () => {
|
||||||
}),
|
}),
|
||||||
'.gitignore': '/dist',
|
'.gitignore': '/dist',
|
||||||
});
|
});
|
||||||
const globOutput = InputDataService.gatherFilesFromDir('/fictional/project');
|
const globOutput = await InputDataService.gatherFilesFromDir('/fictional/project');
|
||||||
expect(globOutput).to.eql([
|
expect(globOutput).to.deep.equal([
|
||||||
// This means allowlistMode is 'git'
|
// This means allowlistMode is 'git'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
@ -322,8 +329,8 @@ describe('InputDataService', () => {
|
||||||
files: ['dist'],
|
files: ['dist'],
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
const globOutput2 = InputDataService.gatherFilesFromDir('/fictional/project');
|
const globOutput2 = await InputDataService.gatherFilesFromDir('/fictional/project');
|
||||||
expect(globOutput2).to.eql([
|
expect(globOutput2).to.deep.equal([
|
||||||
// This means allowlistMode is 'npm'
|
// This means allowlistMode is 'npm'
|
||||||
'/fictional/project/dist/bundle.js',
|
'/fictional/project/dist/bundle.js',
|
||||||
]);
|
]);
|
||||||
|
|
@ -335,10 +342,10 @@ describe('InputDataService', () => {
|
||||||
projectPath: '/inside/proj/with/node_modules/detect-as-npm',
|
projectPath: '/inside/proj/with/node_modules/detect-as-npm',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
const globOutput3 = InputDataService.gatherFilesFromDir(
|
const globOutput3 = await InputDataService.gatherFilesFromDir(
|
||||||
'/inside/proj/with/node_modules/detect-as-npm',
|
'/inside/proj/with/node_modules/detect-as-npm',
|
||||||
);
|
);
|
||||||
expect(globOutput3).to.eql([
|
expect(globOutput3).to.deep.equal([
|
||||||
// This means allowlistMode is 'npm' (even though we found .gitignore)
|
// This means allowlistMode is 'npm' (even though we found .gitignore)
|
||||||
'/inside/proj/with/node_modules/detect-as-npm/dist/bundle.js',
|
'/inside/proj/with/node_modules/detect-as-npm/dist/bundle.js',
|
||||||
]);
|
]);
|
||||||
|
|
@ -350,10 +357,10 @@ describe('InputDataService', () => {
|
||||||
projectPath: '/inside/proj/with/node_modules/@scoped/detect-as-npm',
|
projectPath: '/inside/proj/with/node_modules/@scoped/detect-as-npm',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
const globOutput4 = InputDataService.gatherFilesFromDir(
|
const globOutput4 = await InputDataService.gatherFilesFromDir(
|
||||||
'/inside/proj/with/node_modules/@scoped/detect-as-npm',
|
'/inside/proj/with/node_modules/@scoped/detect-as-npm',
|
||||||
);
|
);
|
||||||
expect(globOutput4).to.eql([
|
expect(globOutput4).to.deep.equal([
|
||||||
// This means allowlistMode is 'npm' (even though we found .gitignore)
|
// This means allowlistMode is 'npm' (even though we found .gitignore)
|
||||||
'/inside/proj/with/node_modules/@scoped/detect-as-npm/dist/bundle.js',
|
'/inside/proj/with/node_modules/@scoped/detect-as-npm/dist/bundle.js',
|
||||||
]);
|
]);
|
||||||
|
|
@ -369,13 +376,13 @@ describe('InputDataService', () => {
|
||||||
files: ['*.add.js', 'docs', 'src'],
|
files: ['*.add.js', 'docs', 'src'],
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
const globOutput = InputDataService.gatherFilesFromDir('/fictional/project', {
|
const globOutput = await InputDataService.gatherFilesFromDir('/fictional/project', {
|
||||||
allowlistMode: 'npm',
|
allowlistMode: 'npm',
|
||||||
});
|
});
|
||||||
expect(globOutput).to.eql([
|
expect(globOutput).to.deep.equal([
|
||||||
'/fictional/project/docs/x.js',
|
|
||||||
'/fictional/project/file.add.js',
|
'/fictional/project/file.add.js',
|
||||||
'/fictional/project/src/y.js',
|
'/fictional/project/src/y.js',
|
||||||
|
'/fictional/project/docs/x.js',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -395,12 +402,12 @@ build/
|
||||||
!keep/
|
!keep/
|
||||||
`,
|
`,
|
||||||
});
|
});
|
||||||
const globOutput = InputDataService.gatherFilesFromDir('/fictional/project', {
|
const globOutput = await InputDataService.gatherFilesFromDir('/fictional/project', {
|
||||||
allowlistMode: 'git',
|
allowlistMode: 'git',
|
||||||
});
|
});
|
||||||
expect(globOutput).to.eql([
|
expect(globOutput).to.deep.equal([
|
||||||
'/fictional/project/keep/it.js',
|
|
||||||
'/fictional/project/shall/pass.js',
|
'/fictional/project/shall/pass.js',
|
||||||
|
'/fictional/project/keep/it.js',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -415,12 +422,12 @@ build/
|
||||||
/dist
|
/dist
|
||||||
`,
|
`,
|
||||||
});
|
});
|
||||||
const globOutput = InputDataService.gatherFilesFromDir('/fictional/project', {
|
const globOutput = await InputDataService.gatherFilesFromDir('/fictional/project', {
|
||||||
allowlistMode: 'all',
|
allowlistMode: 'all',
|
||||||
});
|
});
|
||||||
expect(globOutput).to.eql([
|
expect(globOutput).to.deep.equal([
|
||||||
'/fictional/project/dist/bundle.js',
|
|
||||||
'/fictional/project/src/file.js',
|
'/fictional/project/src/file.js',
|
||||||
|
'/fictional/project/dist/bundle.js',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -434,10 +441,10 @@ build/
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
const globOutput = InputDataService.gatherFilesFromDir('/fictional/project', {
|
const globOutput = await InputDataService.gatherFilesFromDir('/fictional/project', {
|
||||||
allowlistMode: 'export-map',
|
allowlistMode: 'export-map',
|
||||||
});
|
});
|
||||||
expect(globOutput).to.eql(['./internal/file.js']);
|
expect(globOutput).to.deep.equal(['./internal/file.js']);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -451,11 +458,11 @@ build/
|
||||||
files: ['dist'], // This will not be considered by default, unless explicitly configured in allowlist
|
files: ['dist'], // This will not be considered by default, unless explicitly configured in allowlist
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
const globOutput = InputDataService.gatherFilesFromDir('/fictional/project', {
|
const globOutput = await InputDataService.gatherFilesFromDir('/fictional/project', {
|
||||||
allowlist: ['dist/**'],
|
allowlist: ['dist/**'],
|
||||||
allowlistMode: 'git', // for clarity, (would also be autodetected if not provided)
|
allowlistMode: 'git', // for clarity, (would also be autodetected if not provided)
|
||||||
});
|
});
|
||||||
expect(globOutput).to.eql(['/fictional/project/dist/bundle.js']);
|
expect(globOutput).to.deep.equal(['/fictional/project/dist/bundle.js']);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Default allowlist', () => {
|
describe('Default allowlist', () => {
|
||||||
|
|
@ -466,10 +473,10 @@ build/
|
||||||
'./added.js': '',
|
'./added.js': '',
|
||||||
'./omit.js': '',
|
'./omit.js': '',
|
||||||
});
|
});
|
||||||
const globOutput = InputDataService.gatherFilesFromDir('/fictional/project', {
|
const globOutput = await InputDataService.gatherFilesFromDir('/fictional/project', {
|
||||||
allowlist: ['added*'],
|
allowlist: ['added*'],
|
||||||
});
|
});
|
||||||
expect(globOutput).to.eql(['/fictional/project/added.js']);
|
expect(globOutput).to.deep.equal(['/fictional/project/added.js']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('allows to omit default config filter', async () => {
|
it('allows to omit default config filter', async () => {
|
||||||
|
|
@ -481,16 +488,16 @@ build/
|
||||||
'./added.js': '',
|
'./added.js': '',
|
||||||
'./omit.js': '',
|
'./omit.js': '',
|
||||||
});
|
});
|
||||||
const globOutput = InputDataService.gatherFilesFromDir('/fictional/project', {
|
const globOutput = await InputDataService.gatherFilesFromDir('/fictional/project', {
|
||||||
allowlist: ['!omit*'],
|
allowlist: ['!omit*'],
|
||||||
omitDefaultAllowlist: true,
|
omitDefaultAllowlist: true,
|
||||||
});
|
});
|
||||||
expect(globOutput).to.eql([
|
expect(globOutput).to.deep.equal([
|
||||||
'/fictional/project/abc.config.js',
|
'/fictional/project/abc.config.js',
|
||||||
'/fictional/project/added.js',
|
'/fictional/project/added.js',
|
||||||
'/fictional/project/bower_components/omitted/file.js',
|
|
||||||
'/fictional/project/node_modules/root-lvl.js',
|
|
||||||
'/fictional/project/xyz.conf.js',
|
'/fictional/project/xyz.conf.js',
|
||||||
|
'/fictional/project/node_modules/root-lvl.js',
|
||||||
|
'/fictional/project/bower_components/omitted/file.js',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -514,10 +521,10 @@ build/
|
||||||
packageRootPath: '/my/proj',
|
packageRootPath: '/my/proj',
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(exportMapPaths).to.eql([
|
expect(exportMapPaths).to.deep.equal([
|
||||||
{ internal: './internal-path.js', exposed: './exposed-path.js' },
|
{ internal: './internal-path.js', exposed: './exposed-path.js' },
|
||||||
{ internal: './internal/folder-a/path.js', exposed: './external/folder-a/path.js' },
|
|
||||||
{ internal: './internal/folder-b/path.js', exposed: './external/folder-b/path.js' },
|
{ internal: './internal/folder-b/path.js', exposed: './external/folder-b/path.js' },
|
||||||
|
{ internal: './internal/folder-a/path.js', exposed: './external/folder-a/path.js' },
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -532,7 +539,7 @@ build/
|
||||||
const exportMapPaths = await InputDataService.getPathsFromExportMap(exports, {
|
const exportMapPaths = await InputDataService.getPathsFromExportMap(exports, {
|
||||||
packageRootPath: '/my/proj',
|
packageRootPath: '/my/proj',
|
||||||
});
|
});
|
||||||
expect(exportMapPaths).to.eql([
|
expect(exportMapPaths).to.deep.equal([
|
||||||
{ internal: './internal-path.js', exposed: './exposed-path.js' },
|
{ internal: './internal-path.js', exposed: './exposed-path.js' },
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
@ -550,7 +557,7 @@ build/
|
||||||
const exportMapPaths = await InputDataService.getPathsFromExportMap(exports, {
|
const exportMapPaths = await InputDataService.getPathsFromExportMap(exports, {
|
||||||
packageRootPath: '/my/proj',
|
packageRootPath: '/my/proj',
|
||||||
});
|
});
|
||||||
expect(exportMapPaths).to.eql([
|
expect(exportMapPaths).to.deep.equal([
|
||||||
{ internal: './internal-exports-folder/file-a.js', exposed: './file-a.js' },
|
{ internal: './internal-exports-folder/file-a.js', exposed: './file-a.js' },
|
||||||
{ internal: './internal-exports-folder/file-b.js', exposed: './file-b.js' },
|
{ internal: './internal-exports-folder/file-b.js', exposed: './file-b.js' },
|
||||||
{ internal: './internal-exports-folder/file-c.js', exposed: './file-c.js' },
|
{ internal: './internal-exports-folder/file-c.js', exposed: './file-c.js' },
|
||||||
|
|
@ -569,12 +576,12 @@ build/
|
||||||
const exportMapPaths = await InputDataService.getPathsFromExportMap(exports, {
|
const exportMapPaths = await InputDataService.getPathsFromExportMap(exports, {
|
||||||
packageRootPath: '/my/proj',
|
packageRootPath: '/my/proj',
|
||||||
});
|
});
|
||||||
expect(exportMapPaths).to.eql([
|
expect(exportMapPaths).to.deep.equal([
|
||||||
|
{ internal: './internal-folder/file-a.js', exposed: './exposed-folder/file-a.js' },
|
||||||
{
|
{
|
||||||
internal: './internal-folder/another-folder/file-b.js',
|
internal: './internal-folder/another-folder/file-b.js',
|
||||||
exposed: './exposed-folder/another-folder/file-b.js',
|
exposed: './exposed-folder/another-folder/file-b.js',
|
||||||
},
|
},
|
||||||
{ internal: './internal-folder/file-a.js', exposed: './exposed-folder/file-a.js' },
|
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -591,9 +598,9 @@ build/
|
||||||
const exportMapPaths = await InputDataService.getPathsFromExportMap(exports, {
|
const exportMapPaths = await InputDataService.getPathsFromExportMap(exports, {
|
||||||
packageRootPath: '/my/proj',
|
packageRootPath: '/my/proj',
|
||||||
});
|
});
|
||||||
expect(exportMapPaths).to.eql([
|
expect(exportMapPaths).to.deep.equal([
|
||||||
{ internal: './folder-a/file.js', exposed: './exposed-folder/folder-a/file.js' },
|
{ exposed: './exposed-folder/folder-b/file.js', internal: './folder-b/file.js' },
|
||||||
{ internal: './folder-b/file.js', exposed: './exposed-folder/folder-b/file.js' },
|
{ exposed: './exposed-folder/folder-a/file.js', internal: './folder-a/file.js' },
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -611,7 +618,7 @@ build/
|
||||||
const exportMapPaths = await InputDataService.getPathsFromExportMap(exports, {
|
const exportMapPaths = await InputDataService.getPathsFromExportMap(exports, {
|
||||||
packageRootPath: '/my/proj',
|
packageRootPath: '/my/proj',
|
||||||
});
|
});
|
||||||
expect(exportMapPaths).to.eql([
|
expect(exportMapPaths).to.deep.equal([
|
||||||
{ internal: './internal-folder/file-a.js', exposed: './exposed-folder/file-a.js' },
|
{ internal: './internal-folder/file-a.js', exposed: './exposed-folder/file-a.js' },
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
@ -631,7 +638,7 @@ build/
|
||||||
const exportMapPaths = await InputDataService.getPathsFromExportMap(exports, {
|
const exportMapPaths = await InputDataService.getPathsFromExportMap(exports, {
|
||||||
packageRootPath: '/my/proj',
|
packageRootPath: '/my/proj',
|
||||||
});
|
});
|
||||||
expect(exportMapPaths).to.eql([
|
expect(exportMapPaths).to.deep.equal([
|
||||||
{ internal: './esm-exports/file.js', exposed: './file.js' },
|
{ internal: './esm-exports/file.js', exposed: './file.js' },
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
@ -650,7 +657,7 @@ build/
|
||||||
packageRootPath: '/my/proj',
|
packageRootPath: '/my/proj',
|
||||||
nodeResolveMode: 'require',
|
nodeResolveMode: 'require',
|
||||||
});
|
});
|
||||||
expect(exportMapPaths).to.eql([
|
expect(exportMapPaths).to.deep.equal([
|
||||||
{ internal: './cjs-exports/file.cjs', exposed: './file.cjs' },
|
{ internal: './cjs-exports/file.cjs', exposed: './file.cjs' },
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
@ -669,7 +676,7 @@ build/
|
||||||
packageRootPath: '/my/proj',
|
packageRootPath: '/my/proj',
|
||||||
nodeResolveMode: 'develop',
|
nodeResolveMode: 'develop',
|
||||||
});
|
});
|
||||||
expect(exportMapPaths).to.eql([
|
expect(exportMapPaths).to.deep.equal([
|
||||||
{ internal: './develop-exports/file.js', exposed: './file.js' },
|
{ internal: './develop-exports/file.js', exposed: './file.js' },
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
@ -693,7 +700,7 @@ build/
|
||||||
const exportMapPaths = await InputDataService.getPathsFromExportMap(exports, {
|
const exportMapPaths = await InputDataService.getPathsFromExportMap(exports, {
|
||||||
packageRootPath: '/my/proj',
|
packageRootPath: '/my/proj',
|
||||||
});
|
});
|
||||||
expect(exportMapPaths).to.eql([
|
expect(exportMapPaths).to.deep.equal([
|
||||||
{ internal: './index.js', exposed: '.' },
|
{ internal: './index.js', exposed: '.' },
|
||||||
{ internal: './file.js', exposed: './exposed-file.js' },
|
{ internal: './file.js', exposed: './exposed-file.js' },
|
||||||
]);
|
]);
|
||||||
|
|
@ -714,7 +721,7 @@ build/
|
||||||
const exportMapPaths = await InputDataService.getPathsFromExportMap(exports, {
|
const exportMapPaths = await InputDataService.getPathsFromExportMap(exports, {
|
||||||
packageRootPath: '/my/proj',
|
packageRootPath: '/my/proj',
|
||||||
});
|
});
|
||||||
expect(exportMapPaths).to.eql([
|
expect(exportMapPaths).to.deep.equal([
|
||||||
{ internal: './internal-folder/file-a.js', exposed: './exposed-folder/file-a.js' },
|
{ internal: './internal-folder/file-a.js', exposed: './exposed-folder/file-a.js' },
|
||||||
{ internal: './internal-folder/file-b.js', exposed: './exposed-folder/file-b.js' },
|
{ internal: './internal-folder/file-b.js', exposed: './exposed-folder/file-b.js' },
|
||||||
]);
|
]);
|
||||||
|
|
@ -733,7 +740,7 @@ build/
|
||||||
const exportMapPaths = await InputDataService.getPathsFromExportMap(exports, {
|
const exportMapPaths = await InputDataService.getPathsFromExportMap(exports, {
|
||||||
packageRootPath: '/my/proj',
|
packageRootPath: '/my/proj',
|
||||||
});
|
});
|
||||||
expect(exportMapPaths).to.eql([
|
expect(exportMapPaths).to.deep.equal([
|
||||||
{ internal: './internal-folder/file-a.js', exposed: './exposed-folder/file-a.js' },
|
{ internal: './internal-folder/file-a.js', exposed: './exposed-folder/file-a.js' },
|
||||||
{ internal: './internal-folder/file-b.js', exposed: './exposed-folder/file-b.js' },
|
{ internal: './internal-folder/file-b.js', exposed: './exposed-folder/file-b.js' },
|
||||||
]);
|
]);
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ describe('QueryService', () => {
|
||||||
describe('Retrieving QueryConfig', () => {
|
describe('Retrieving QueryConfig', () => {
|
||||||
it('"getQueryConfigFromRegexSearchString"', async () => {
|
it('"getQueryConfigFromRegexSearchString"', async () => {
|
||||||
const result = QueryService.getQueryConfigFromRegexSearchString('x');
|
const result = QueryService.getQueryConfigFromRegexSearchString('x');
|
||||||
expect(result).to.eql({ type: 'search', regexString: 'x' });
|
expect(result).to.deep.equal({ type: 'search', regexString: 'x' });
|
||||||
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
|
|
@ -25,7 +25,7 @@ describe('QueryService', () => {
|
||||||
describe('"getQueryConfigFromFeatureString"', () => {
|
describe('"getQueryConfigFromFeatureString"', () => {
|
||||||
it('with tag, attr-key and attr-value', async () => {
|
it('with tag, attr-key and attr-value', async () => {
|
||||||
const result = QueryService.getQueryConfigFromFeatureString('tg-icon[size=xs]');
|
const result = QueryService.getQueryConfigFromFeatureString('tg-icon[size=xs]');
|
||||||
expect(result).to.eql({
|
expect(result).to.deep.equal({
|
||||||
type: 'feature',
|
type: 'feature',
|
||||||
feature: {
|
feature: {
|
||||||
name: 'size',
|
name: 'size',
|
||||||
|
|
@ -41,7 +41,7 @@ describe('QueryService', () => {
|
||||||
|
|
||||||
it('with only tag', async () => {
|
it('with only tag', async () => {
|
||||||
const result = QueryService.getQueryConfigFromFeatureString('tg-icon');
|
const result = QueryService.getQueryConfigFromFeatureString('tg-icon');
|
||||||
expect(result).to.eql({
|
expect(result).to.deep.equal({
|
||||||
type: 'feature',
|
type: 'feature',
|
||||||
feature: {
|
feature: {
|
||||||
tag: 'tg-icon',
|
tag: 'tg-icon',
|
||||||
|
|
@ -52,7 +52,7 @@ describe('QueryService', () => {
|
||||||
|
|
||||||
it('with only attr-key', async () => {
|
it('with only attr-key', async () => {
|
||||||
const result = QueryService.getQueryConfigFromFeatureString('[attr]');
|
const result = QueryService.getQueryConfigFromFeatureString('[attr]');
|
||||||
expect(result).to.eql({
|
expect(result).to.deep.equal({
|
||||||
type: 'feature',
|
type: 'feature',
|
||||||
feature: {
|
feature: {
|
||||||
name: 'attr',
|
name: 'attr',
|
||||||
|
|
@ -68,7 +68,7 @@ describe('QueryService', () => {
|
||||||
|
|
||||||
it('with only attr-key and attr-value', async () => {
|
it('with only attr-key and attr-value', async () => {
|
||||||
const result = QueryService.getQueryConfigFromFeatureString('[attr=x]');
|
const result = QueryService.getQueryConfigFromFeatureString('[attr=x]');
|
||||||
expect(result).to.eql({
|
expect(result).to.deep.equal({
|
||||||
type: 'feature',
|
type: 'feature',
|
||||||
feature: {
|
feature: {
|
||||||
name: 'attr',
|
name: 'attr',
|
||||||
|
|
@ -85,7 +85,7 @@ describe('QueryService', () => {
|
||||||
describe('With partial value', async () => {
|
describe('With partial value', async () => {
|
||||||
it('with tag, attr-key and attr-value', async () => {
|
it('with tag, attr-key and attr-value', async () => {
|
||||||
const result = QueryService.getQueryConfigFromFeatureString('tg-icon*[size*=xs*]');
|
const result = QueryService.getQueryConfigFromFeatureString('tg-icon*[size*=xs*]');
|
||||||
expect(result).to.eql({
|
expect(result).to.deep.equal({
|
||||||
type: 'feature',
|
type: 'feature',
|
||||||
feature: {
|
feature: {
|
||||||
name: 'size',
|
name: 'size',
|
||||||
|
|
@ -101,7 +101,7 @@ describe('QueryService', () => {
|
||||||
|
|
||||||
it('with only tag', async () => {
|
it('with only tag', async () => {
|
||||||
const result = QueryService.getQueryConfigFromFeatureString('tg-icon*');
|
const result = QueryService.getQueryConfigFromFeatureString('tg-icon*');
|
||||||
expect(result).to.eql({
|
expect(result).to.deep.equal({
|
||||||
type: 'feature',
|
type: 'feature',
|
||||||
feature: {
|
feature: {
|
||||||
tag: 'tg-icon',
|
tag: 'tg-icon',
|
||||||
|
|
@ -112,7 +112,7 @@ describe('QueryService', () => {
|
||||||
|
|
||||||
it('with only attr-key', async () => {
|
it('with only attr-key', async () => {
|
||||||
const result = QueryService.getQueryConfigFromFeatureString('[attr*]');
|
const result = QueryService.getQueryConfigFromFeatureString('[attr*]');
|
||||||
expect(result).to.eql({
|
expect(result).to.deep.equal({
|
||||||
type: 'feature',
|
type: 'feature',
|
||||||
feature: {
|
feature: {
|
||||||
name: 'attr',
|
name: 'attr',
|
||||||
|
|
@ -128,7 +128,7 @@ describe('QueryService', () => {
|
||||||
|
|
||||||
it('with only attr-key and attr-value', async () => {
|
it('with only attr-key and attr-value', async () => {
|
||||||
const result = QueryService.getQueryConfigFromFeatureString('[attr*=x*]');
|
const result = QueryService.getQueryConfigFromFeatureString('[attr*=x*]');
|
||||||
expect(result).to.eql({
|
expect(result).to.deep.equal({
|
||||||
type: 'feature',
|
type: 'feature',
|
||||||
feature: {
|
feature: {
|
||||||
name: 'attr',
|
name: 'attr',
|
||||||
|
|
@ -158,7 +158,7 @@ describe('QueryService', () => {
|
||||||
'find-imports',
|
'find-imports',
|
||||||
myAnalyzerCfg,
|
myAnalyzerCfg,
|
||||||
);
|
);
|
||||||
expect(result).to.eql({
|
expect(result).to.deep.equal({
|
||||||
type: 'ast-analyzer',
|
type: 'ast-analyzer',
|
||||||
analyzerName: 'find-imports',
|
analyzerName: 'find-imports',
|
||||||
analyzerConfig: myAnalyzerCfg,
|
analyzerConfig: myAnalyzerCfg,
|
||||||
|
|
@ -171,7 +171,7 @@ describe('QueryService', () => {
|
||||||
/** @type {* & Analyzer} */ (DummyAnalyzer),
|
/** @type {* & Analyzer} */ (DummyAnalyzer),
|
||||||
myAnalyzerCfg,
|
myAnalyzerCfg,
|
||||||
);
|
);
|
||||||
expect(result).to.eql({
|
expect(result).to.deep.equal({
|
||||||
type: 'ast-analyzer',
|
type: 'ast-analyzer',
|
||||||
analyzerName: 'find-dummy-analyzer',
|
analyzerName: 'find-dummy-analyzer',
|
||||||
analyzerConfig: myAnalyzerCfg,
|
analyzerConfig: myAnalyzerCfg,
|
||||||
|
|
@ -186,7 +186,7 @@ describe('QueryService', () => {
|
||||||
// it('with FeatureConfig', async () => {
|
// it('with FeatureConfig', async () => {
|
||||||
// const featureCfg = QueryService.getQueryConfigFromFeatureString('tg-icon[size=xs]');
|
// const featureCfg = QueryService.getQueryConfigFromFeatureString('tg-icon[size=xs]');
|
||||||
// const result = QueryService.grepSearch(featureCfg);
|
// const result = QueryService.grepSearch(featureCfg);
|
||||||
// expect(result).to.eql({
|
// expect(result).to.deep.equal({
|
||||||
// type: 'ast-analyzer',
|
// type: 'ast-analyzer',
|
||||||
// analyzerName: 'find-imports',
|
// analyzerName: 'find-imports',
|
||||||
// analyzerConfig: { x: 'y' },
|
// analyzerConfig: { x: 'y' },
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,17 @@
|
||||||
import { expect } from 'chai';
|
import { expect } from 'chai';
|
||||||
import { it } from 'mocha';
|
import { it } from 'mocha';
|
||||||
import { mock } from '../../../test-helpers/mock-project-helpers.js';
|
|
||||||
import { getSourceCodeFragmentOfDeclaration } from '../../../src/program/utils/index.js';
|
import { getSourceCodeFragmentOfDeclaration } from '../../../src/program/utils/index.js';
|
||||||
import { memoizeConfig } from '../../../src/program/utils/memoize.js';
|
import { mock } from '../../../test-helpers/mock-project-helpers.js';
|
||||||
|
import { memoize } from '../../../src/program/utils/memoize.js';
|
||||||
|
|
||||||
describe('getSourceCodeFragmentOfDeclaration', () => {
|
describe('getSourceCodeFragmentOfDeclaration', () => {
|
||||||
const initialMemoizeSsCacheDisabled = memoizeConfig.isCacheDisabled;
|
const initialMemoizeCacheEnabled = memoize.isCacheEnabled;
|
||||||
before(() => {
|
before(() => {
|
||||||
memoizeConfig.isCacheDisabled = true;
|
memoize.disableCaching();
|
||||||
});
|
});
|
||||||
after(() => {
|
after(() => {
|
||||||
memoizeConfig.isCacheDisabled = initialMemoizeSsCacheDisabled;
|
memoize.restoreCaching(initialMemoizeCacheEnabled);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Named specifiers', () => {
|
describe('Named specifiers', () => {
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,11 @@
|
||||||
import { expect } from 'chai';
|
import { expect } from 'chai';
|
||||||
import { it } from 'mocha';
|
import { it } from 'mocha';
|
||||||
import { memoize, memoizeConfig } from '../../../src/program/utils/memoize.js';
|
import { memoize } from '../../../src/program/utils/memoize.js';
|
||||||
|
|
||||||
const cacheDisabledInitialValue = memoizeConfig.isCacheDisabled;
|
|
||||||
|
|
||||||
describe('Memoize', () => {
|
describe('Memoize', () => {
|
||||||
beforeEach(() => {
|
// This is important, since memoization only works when cache is disabled.
|
||||||
// This is important, since memoization only works
|
// We want to prevent that another test unintentionally disabled caching.
|
||||||
memoizeConfig.isCacheDisabled = false;
|
memoize.restoreCaching();
|
||||||
});
|
|
||||||
afterEach(() => {
|
|
||||||
memoizeConfig.isCacheDisabled = cacheDisabledInitialValue;
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('With primitives', () => {
|
describe('With primitives', () => {
|
||||||
describe('Numbers', () => {
|
describe('Numbers', () => {
|
||||||
|
|
@ -136,15 +130,15 @@ describe('Memoize', () => {
|
||||||
const sumMemoized = memoize(sum);
|
const sumMemoized = memoize(sum);
|
||||||
|
|
||||||
// Put in cache for args combination
|
// Put in cache for args combination
|
||||||
expect(sumMemoized([1], [2])).to.eql([1, 2]);
|
expect(sumMemoized([1], [2])).to.deep.equal([1, 2]);
|
||||||
expect(sumCalled).to.equal(1);
|
expect(sumCalled).to.equal(1);
|
||||||
|
|
||||||
// Return from cache
|
// Return from cache
|
||||||
expect(sumMemoized([1], [2])).to.eql([1, 2]);
|
expect(sumMemoized([1], [2])).to.deep.equal([1, 2]);
|
||||||
expect(sumCalled).to.equal(1);
|
expect(sumCalled).to.equal(1);
|
||||||
|
|
||||||
// Put in cache for args combination
|
// Put in cache for args combination
|
||||||
expect(sumMemoized([1], [3])).to.eql([1, 3]);
|
expect(sumMemoized([1], [3])).to.deep.equal([1, 3]);
|
||||||
expect(sumCalled).to.equal(2);
|
expect(sumCalled).to.equal(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -162,17 +156,17 @@ describe('Memoize', () => {
|
||||||
}
|
}
|
||||||
const sum2Memoized = memoize(sum2);
|
const sum2Memoized = memoize(sum2);
|
||||||
|
|
||||||
expect(sumMemoized([1], [2])).to.eql([1, 2]);
|
expect(sumMemoized([1], [2])).to.deep.equal([1, 2]);
|
||||||
expect(sumCalled).to.equal(1);
|
expect(sumCalled).to.equal(1);
|
||||||
expect(sum2Called).to.equal(0);
|
expect(sum2Called).to.equal(0);
|
||||||
|
|
||||||
expect(sum2Memoized([1], [2])).to.eql([1, 2]);
|
expect(sum2Memoized([1], [2])).to.deep.equal([1, 2]);
|
||||||
expect(sumCalled).to.equal(1);
|
expect(sumCalled).to.equal(1);
|
||||||
expect(sum2Called).to.equal(1);
|
expect(sum2Called).to.equal(1);
|
||||||
|
|
||||||
// Both cached
|
// Both cached
|
||||||
expect(sumMemoized([1], [2])).to.eql([1, 2]);
|
expect(sumMemoized([1], [2])).to.deep.equal([1, 2]);
|
||||||
expect(sum2Memoized([1], [2])).to.eql([1, 2]);
|
expect(sum2Memoized([1], [2])).to.deep.equal([1, 2]);
|
||||||
expect(sumCalled).to.equal(1);
|
expect(sumCalled).to.equal(1);
|
||||||
expect(sum2Called).to.equal(1);
|
expect(sum2Called).to.equal(1);
|
||||||
});
|
});
|
||||||
|
|
@ -188,15 +182,15 @@ describe('Memoize', () => {
|
||||||
const sumMemoized = memoize(sum, { serializeObjects: true });
|
const sumMemoized = memoize(sum, { serializeObjects: true });
|
||||||
|
|
||||||
// Put in cache for args combination
|
// Put in cache for args combination
|
||||||
expect(sumMemoized({ x: 1 }, { y: 2 })).to.eql({ x: 1, y: 2 });
|
expect(sumMemoized({ x: 1 }, { y: 2 })).to.deep.equal({ x: 1, y: 2 });
|
||||||
expect(sumCalled).to.equal(1);
|
expect(sumCalled).to.equal(1);
|
||||||
|
|
||||||
// Return from cache
|
// Return from cache
|
||||||
expect(sumMemoized({ x: 1 }, { y: 2 })).to.eql({ x: 1, y: 2 });
|
expect(sumMemoized({ x: 1 }, { y: 2 })).to.deep.equal({ x: 1, y: 2 });
|
||||||
expect(sumCalled).to.equal(1);
|
expect(sumCalled).to.equal(1);
|
||||||
|
|
||||||
// Put in cache for args combination
|
// Put in cache for args combination
|
||||||
expect(sumMemoized({ x: 1 }, { y: 3 })).to.eql({ x: 1, y: 3 });
|
expect(sumMemoized({ x: 1 }, { y: 3 })).to.deep.equal({ x: 1, y: 3 });
|
||||||
expect(sumCalled).to.equal(2);
|
expect(sumCalled).to.equal(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -214,17 +208,17 @@ describe('Memoize', () => {
|
||||||
}
|
}
|
||||||
const sum2Memoized = memoize(sum2, { serializeObjects: true });
|
const sum2Memoized = memoize(sum2, { serializeObjects: true });
|
||||||
|
|
||||||
expect(sumMemoized({ x: 1 }, { y: 2 })).to.eql({ x: 1, y: 2 });
|
expect(sumMemoized({ x: 1 }, { y: 2 })).to.deep.equal({ x: 1, y: 2 });
|
||||||
expect(sumCalled).to.equal(1);
|
expect(sumCalled).to.equal(1);
|
||||||
expect(sum2Called).to.equal(0);
|
expect(sum2Called).to.equal(0);
|
||||||
|
|
||||||
expect(sum2Memoized({ x: 1 }, { y: 2 })).to.eql({ x: 1, y: 2 });
|
expect(sum2Memoized({ x: 1 }, { y: 2 })).to.deep.equal({ x: 1, y: 2 });
|
||||||
expect(sumCalled).to.equal(1);
|
expect(sumCalled).to.equal(1);
|
||||||
expect(sum2Called).to.equal(1);
|
expect(sum2Called).to.equal(1);
|
||||||
|
|
||||||
// Both cached
|
// Both cached
|
||||||
expect(sumMemoized({ x: 1 }, { y: 2 })).to.eql({ x: 1, y: 2 });
|
expect(sumMemoized({ x: 1 }, { y: 2 })).to.deep.equal({ x: 1, y: 2 });
|
||||||
expect(sum2Memoized({ x: 1 }, { y: 2 })).to.eql({ x: 1, y: 2 });
|
expect(sum2Memoized({ x: 1 }, { y: 2 })).to.deep.equal({ x: 1, y: 2 });
|
||||||
expect(sumCalled).to.equal(1);
|
expect(sumCalled).to.equal(1);
|
||||||
expect(sum2Called).to.equal(1);
|
expect(sum2Called).to.equal(1);
|
||||||
});
|
});
|
||||||
|
|
@ -242,13 +236,13 @@ describe('Memoize', () => {
|
||||||
|
|
||||||
// Put in cache for args combination
|
// Put in cache for args combination
|
||||||
const result = sumMemoized({ x: 1 }, { y: 2 });
|
const result = sumMemoized({ x: 1 }, { y: 2 });
|
||||||
expect(result).to.eql({ x: 1, y: 2 });
|
expect(result).to.deep.equal({ x: 1, y: 2 });
|
||||||
expect(sumCalled).to.equal(1);
|
expect(sumCalled).to.equal(1);
|
||||||
|
|
||||||
// Return from cache
|
// Return from cache
|
||||||
const resultCached = sumMemoized({ x: 1 }, { y: 2 });
|
const resultCached = sumMemoized({ x: 1 }, { y: 2 });
|
||||||
expect(resultCached).to.equal(result);
|
expect(resultCached).to.equal(result);
|
||||||
expect(resultCached).to.eql({ x: 1, y: 2 });
|
expect(resultCached).to.deep.equal({ x: 1, y: 2 });
|
||||||
expect(sumCalled).to.equal(1);
|
expect(sumCalled).to.equal(1);
|
||||||
|
|
||||||
// Outside world can edit returned reference
|
// Outside world can edit returned reference
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,14 @@ import {
|
||||||
mockTargetAndReferenceProject,
|
mockTargetAndReferenceProject,
|
||||||
} from '../../../test-helpers/mock-project-helpers.js';
|
} from '../../../test-helpers/mock-project-helpers.js';
|
||||||
import { resolveImportPath } from '../../../src/program/utils/resolve-import-path.js';
|
import { resolveImportPath } from '../../../src/program/utils/resolve-import-path.js';
|
||||||
import { memoizeConfig } from '../../../src/program/utils/memoize.js';
|
import { memoize } from '../../../src/program/utils/memoize.js';
|
||||||
|
|
||||||
describe('resolveImportPath', () => {
|
describe('resolveImportPath', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
memoizeConfig.isCacheDisabled = true;
|
memoize.disableCaching();
|
||||||
});
|
});
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
memoizeConfig.isCacheDisabled = false;
|
memoize.restoreCaching();
|
||||||
restoreMockedProjects();
|
restoreMockedProjects();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ describe('swcTraverse', () => {
|
||||||
};
|
};
|
||||||
swcTraverse(swcAst, visitor);
|
swcTraverse(swcAst, visitor);
|
||||||
|
|
||||||
expect(foundTypes).to.eql([
|
expect(foundTypes).to.deep.equal([
|
||||||
'Module',
|
'Module',
|
||||||
'ImportDeclaration',
|
'ImportDeclaration',
|
||||||
'ImportDefaultSpecifier',
|
'ImportDefaultSpecifier',
|
||||||
|
|
@ -166,7 +166,7 @@ describe('swcTraverse', () => {
|
||||||
expect(declaratorPaths[2].scope.id).to.equal(2);
|
expect(declaratorPaths[2].scope.id).to.equal(2);
|
||||||
|
|
||||||
expect(declaratorPaths[0].node.id.value).to.equal('globalScope');
|
expect(declaratorPaths[0].node.id.value).to.equal('globalScope');
|
||||||
expect(Object.keys(declaratorPaths[0].scope.bindings)).to.eql([
|
expect(Object.keys(declaratorPaths[0].scope.bindings)).to.deep.equal([
|
||||||
'globalScope',
|
'globalScope',
|
||||||
'alsoGlobalScope',
|
'alsoGlobalScope',
|
||||||
]);
|
]);
|
||||||
|
|
@ -180,8 +180,8 @@ describe('swcTraverse', () => {
|
||||||
declaratorPaths[3].node,
|
declaratorPaths[3].node,
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(Object.keys(declaratorPaths[1].scope.bindings)).to.eql(['middleScope']);
|
expect(Object.keys(declaratorPaths[1].scope.bindings)).to.deep.equal(['middleScope']);
|
||||||
expect(Object.keys(declaratorPaths[2].scope.bindings)).to.eql(['deepestScope']);
|
expect(Object.keys(declaratorPaths[2].scope.bindings)).to.deep.equal(['deepestScope']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('creates scopes for nested FunctionDeclaration', async () => {
|
it('creates scopes for nested FunctionDeclaration', async () => {
|
||||||
|
|
@ -336,7 +336,7 @@ describe('swcTraverse', () => {
|
||||||
};
|
};
|
||||||
swcTraverse(swcAst, visitor, { needsAdvancedPaths: true });
|
swcTraverse(swcAst, visitor, { needsAdvancedPaths: true });
|
||||||
|
|
||||||
expect(Object.keys(declaratorPaths[0].scope.bindings)).to.eql([
|
expect(Object.keys(declaratorPaths[0].scope.bindings)).to.deep.equal([
|
||||||
'globalScope',
|
'globalScope',
|
||||||
'alsoGlobalScope',
|
'alsoGlobalScope',
|
||||||
]);
|
]);
|
||||||
|
|
@ -370,12 +370,12 @@ describe('swcTraverse', () => {
|
||||||
};
|
};
|
||||||
swcTraverse(swcAst, visitor, { needsAdvancedPaths: true });
|
swcTraverse(swcAst, visitor, { needsAdvancedPaths: true });
|
||||||
|
|
||||||
expect(Object.keys(declaratorPaths[0].scope.bindings)).to.eql([
|
expect(Object.keys(declaratorPaths[0].scope.bindings)).to.deep.equal([
|
||||||
'globalScope',
|
'globalScope',
|
||||||
'stillGlobalScope',
|
'stillGlobalScope',
|
||||||
]);
|
]);
|
||||||
expect(Object.keys(declaratorPaths[1].scope.bindings)).to.eql(['middleScope']);
|
expect(Object.keys(declaratorPaths[1].scope.bindings)).to.deep.equal(['middleScope']);
|
||||||
expect(Object.keys(declaratorPaths[2].scope.bindings)).to.eql(['insideFnScope']);
|
expect(Object.keys(declaratorPaths[2].scope.bindings)).to.deep.equal(['insideFnScope']);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -420,8 +420,10 @@ describe('swcTraverse', () => {
|
||||||
expect(babelScopes.length).to.equal(swcScopes.length);
|
expect(babelScopes.length).to.equal(swcScopes.length);
|
||||||
for (let i = 0; i < babelScopes.length; i += 1) {
|
for (let i = 0; i < babelScopes.length; i += 1) {
|
||||||
expect(babelScopes[i].uid - babelRootScopeIdOffset).to.equal(swcScopes[i].id);
|
expect(babelScopes[i].uid - babelRootScopeIdOffset).to.equal(swcScopes[i].id);
|
||||||
expect(Object.keys(babelScopes[i].bindings)).to.eql(Object.keys(swcScopes[i].bindings));
|
expect(Object.keys(babelScopes[i].bindings)).to.deep.equal(
|
||||||
// expect(babelScopes[i].references).to.eql(swcResults[i].references);
|
Object.keys(swcScopes[i].bindings),
|
||||||
|
);
|
||||||
|
// expect(babelScopes[i].references).to.deep.equal(swcResults[i].references);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,9 +38,9 @@ describe('traverseHtml', () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(foundDivs).to.eql(['a-lvl1', 'b']);
|
expect(foundDivs).to.deep.equal(['a-lvl1', 'b']);
|
||||||
expect(foundSpans).to.eql(['a-lvl2']);
|
expect(foundSpans).to.deep.equal(['a-lvl2']);
|
||||||
expect(foundMyTags).to.eql(['a-lvl3']);
|
expect(foundMyTags).to.deep.equal(['a-lvl3']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('traverses different levels in DOM order', async () => {
|
it('traverses different levels in DOM order', async () => {
|
||||||
|
|
@ -72,7 +72,7 @@ describe('traverseHtml', () => {
|
||||||
traverseHtml(ast, processObj);
|
traverseHtml(ast, processObj);
|
||||||
|
|
||||||
// call order based on dom tree
|
// call order based on dom tree
|
||||||
expect(callOrder).to.eql(['div#a-lvl1', 'span#a-lvl2', 'my-tag#a-lvl3', 'div#b']);
|
expect(callOrder).to.deep.equal(['div#a-lvl1', 'span#a-lvl2', 'my-tag#a-lvl3', 'div#b']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('allows to stop traversal (for performance)', async () => {
|
it('allows to stop traversal (for performance)', async () => {
|
||||||
|
|
@ -104,7 +104,7 @@ describe('traverseHtml', () => {
|
||||||
};
|
};
|
||||||
traverseHtml(ast, processObj);
|
traverseHtml(ast, processObj);
|
||||||
|
|
||||||
expect(callOrder).to.eql(['div#a-lvl1']);
|
expect(callOrder).to.deep.equal(['div#a-lvl1']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('allows to traverse within a path', async () => {
|
it('allows to traverse within a path', async () => {
|
||||||
|
|
@ -135,6 +135,6 @@ describe('traverseHtml', () => {
|
||||||
};
|
};
|
||||||
traverseHtml(ast, processObj);
|
traverseHtml(ast, processObj);
|
||||||
|
|
||||||
expect(callOrder).to.eql(['my-tag#a-lvl3', 'not-found#a-lvl4']);
|
expect(callOrder).to.deep.equal(['my-tag#a-lvl3', 'not-found#a-lvl4']);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,6 @@
|
||||||
"outDir": "./dist-types",
|
"outDir": "./dist-types",
|
||||||
"rootDir": "."
|
"rootDir": "."
|
||||||
},
|
},
|
||||||
"include": ["types"],
|
"include": ["types", "src", "test-node"],
|
||||||
"exclude": ["dist-types"]
|
"exclude": ["dist-types"]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { File } from '@babel/types';
|
import { File } from '@babel/types';
|
||||||
|
import Vol from 'memfs';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of a variable in a local context. Examples:
|
* The name of a variable in a local context. Examples:
|
||||||
|
|
@ -152,6 +153,8 @@ export interface ProjectInputDataWithAstMeta extends ProjectInputDataWithMeta {
|
||||||
*/
|
*/
|
||||||
export type AnyMatchString = string;
|
export type AnyMatchString = string;
|
||||||
|
|
||||||
|
export type FsAdapter = Vol;
|
||||||
|
|
||||||
export type ProvidenceConfig = {
|
export type ProvidenceConfig = {
|
||||||
/* Whether analyzer should be run or a grep should be performed */
|
/* Whether analyzer should be run or a grep should be performed */
|
||||||
queryMethod: 'ast' | 'grep';
|
queryMethod: 'ast' | 'grep';
|
||||||
|
|
@ -169,6 +172,7 @@ export type ProvidenceConfig = {
|
||||||
writeLogFile: boolean;
|
writeLogFile: boolean;
|
||||||
skipCheckMatchCompatibility: boolean;
|
skipCheckMatchCompatibility: boolean;
|
||||||
fallbackToBabel: boolean;
|
fallbackToBabel: boolean;
|
||||||
|
fs: FsAdapter;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -182,6 +186,7 @@ export type PackageJson = {
|
||||||
devDependencies?: { [dependency: string]: string };
|
devDependencies?: { [dependency: string]: string };
|
||||||
workspaces?: string[];
|
workspaces?: string[];
|
||||||
main?: string;
|
main?: string;
|
||||||
|
exports?: { [key: string]: string };
|
||||||
};
|
};
|
||||||
|
|
||||||
export type LernaJson = {
|
export type LernaJson = {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue