229 lines
7.3 KiB
JavaScript
229 lines
7.3 KiB
JavaScript
import { expect } from 'chai';
|
|
import { it } from 'mocha';
|
|
import { mockProject, restoreMockedProjects } from '../../../test-helpers/mock-project-helpers.js';
|
|
import { setupAnalyzerTest } from '../../../test-helpers/setup-analyzer-test.js';
|
|
import { QueryService } from '../../../src/program/core/QueryService.js';
|
|
import { providence } from '../../../src/program/providence.js';
|
|
import { DummyAnalyzer } from '../../../test-helpers/templates/DummyAnalyzer.js';
|
|
|
|
/**
|
|
* @typedef {import('../../../types/index.js').ProvidenceConfig} ProvidenceConfig
|
|
*/
|
|
|
|
setupAnalyzerTest();
|
|
|
|
describe('Analyzer', async () => {
|
|
const dummyAnalyzer = new DummyAnalyzer();
|
|
|
|
describe('Public api', () => {
|
|
it('has a "name" string', async () => {
|
|
expect(typeof dummyAnalyzer.name).to.equal('string');
|
|
});
|
|
|
|
it('has an "execute" function', async () => {
|
|
expect(typeof dummyAnalyzer.execute).to.equal('function');
|
|
});
|
|
|
|
it('has a "requiredAst" string', async () => {
|
|
expect(typeof dummyAnalyzer.constructor.requiredAst).to.equal('string');
|
|
const allowedAsts = ['babel'];
|
|
expect(allowedAsts).to.include(dummyAnalyzer.constructor.requiredAst);
|
|
});
|
|
|
|
it('has a "requiresReference" boolean', async () => {
|
|
expect(typeof DummyAnalyzer.requiresReference).to.equal('boolean');
|
|
});
|
|
});
|
|
|
|
describe.skip('Find Analyzers', async () => {
|
|
afterEach(() => {
|
|
restoreMockedProjects();
|
|
});
|
|
|
|
const myQueryConfigObject = await QueryService.getQueryConfigFromAnalyzer(DummyAnalyzer);
|
|
/** @type {Partial<ProvidenceConfig>} */
|
|
const _providenceCfg = {
|
|
targetProjectPaths: ['/fictional/project'],
|
|
};
|
|
|
|
describe('Prepare phase', () => {
|
|
it.skip('looks for a cached result', async () => {
|
|
// Our configuration object
|
|
mockProject([`const validJs = true;`, `let invalidJs = false;`]);
|
|
// const queryResults = await providence(myQueryConfigObject, _providenceCfg);
|
|
});
|
|
|
|
it('exposes a ".targetMeta" object', async () => {});
|
|
|
|
it('exposes a ".targetData" object', async () => {});
|
|
|
|
it('exposes a ".identifier" string', async () => {});
|
|
});
|
|
|
|
describe('Traverse phase', () => {
|
|
it('schedules a Babel visitor', async () => {});
|
|
it('merges multiple Babel visitors for performance', async () => {});
|
|
it('traverses Babel visitor and stores traversal result', async () => {});
|
|
});
|
|
|
|
describe('Postprocess phase', () => {
|
|
it('optionally post processes traversal result', async () => {});
|
|
});
|
|
|
|
describe('Performance', () => {
|
|
it('memoizes execute functions', async () => {});
|
|
});
|
|
|
|
describe('Finalize phase', () => {
|
|
it.skip('returns an AnalyzerQueryResult', async () => {
|
|
const queryResults = await providence(myQueryConfigObject, _providenceCfg);
|
|
|
|
const queryResult = queryResults[0];
|
|
const { queryOutput, meta } = queryResult;
|
|
|
|
expect(queryOutput[0]).to.eql({
|
|
file: './test-file-0.js',
|
|
meta: {},
|
|
result: [{ matched: 'entry' }],
|
|
});
|
|
expect(queryOutput[1]).to.eql({
|
|
file: './test-file2.js',
|
|
meta: {},
|
|
result: [{ matched: 'entry' }],
|
|
});
|
|
// Local machine info needs to be deleted, so that results are always 'machine agnostic'
|
|
// (which is needed to share cached json results via git)
|
|
expect(meta).to.eql({
|
|
searchType: 'ast-analyzer',
|
|
analyzerMeta: {
|
|
name: 'my-analyzer',
|
|
requiredAst: 'babel',
|
|
identifier: 'my-project_0.1.0-mock__542516121',
|
|
targetProject: {
|
|
name: 'my-project',
|
|
commitHash: '[not-a-git-repo]',
|
|
version: '0.1.0-mock',
|
|
},
|
|
configuration: {
|
|
targetProjectPaths: null,
|
|
optionA: false,
|
|
optionB: '',
|
|
debugEnabled: false,
|
|
gatherFilesConfig: {},
|
|
},
|
|
},
|
|
});
|
|
});
|
|
});
|
|
|
|
// TODO: think of exposing the ast traversal part in a distinct method "traverse", so we can
|
|
// create integrations with (a local version of) https://astexplorer.net
|
|
});
|
|
|
|
// describe.skip('Match Analyzers', () => {
|
|
// const referenceProject = {
|
|
// path: '/exporting/ref/project',
|
|
// name: 'exporting-ref-project',
|
|
// files: [
|
|
// {
|
|
// file: './package.json',
|
|
// code: `{
|
|
// "name": "importing-target-project",
|
|
// "version": "2.20.3",
|
|
// "dependencies": {
|
|
// "exporting-ref-project": "^2.3.0"
|
|
// }
|
|
// }`,
|
|
// },
|
|
// ],
|
|
// };
|
|
|
|
// const matchingTargetProject = {
|
|
// path: '/importing/target/project/v10',
|
|
// files: [
|
|
// {
|
|
// file: './package.json',
|
|
// code: `{
|
|
// "name": "importing-target-project",
|
|
// "version": "10.1.2",
|
|
// "dependencies": {
|
|
// "exporting-ref-project": "^2.3.0"
|
|
// }
|
|
// }`,
|
|
// },
|
|
// ],
|
|
// };
|
|
|
|
// const matchingDevDepTargetProject = {
|
|
// path: '/importing/target/project/v10',
|
|
// files: [
|
|
// {
|
|
// file: './package.json',
|
|
// code: `{
|
|
// "name": "importing-target-project",
|
|
// "version": "10.1.2",
|
|
// "devDependencies": {
|
|
// "exporting-ref-project": "^2.3.0"
|
|
// }
|
|
// }`,
|
|
// },
|
|
// ],
|
|
// };
|
|
|
|
// // A previous version that does not match our reference version
|
|
// const nonMatchingVersionTargetProject = {
|
|
// path: '/importing/target/project/v8',
|
|
// files: [
|
|
// {
|
|
// file: './package.json',
|
|
// code: `{
|
|
// "name": "importing-target-project",
|
|
// "version": "8.1.2",
|
|
// "dependencies": {
|
|
// "exporting-ref-project": "^1.9.0"
|
|
// }
|
|
// }`,
|
|
// },
|
|
// ],
|
|
// };
|
|
|
|
// const nonMatchingDepTargetProject = {
|
|
// path: '/importing/target/project/v8',
|
|
// files: [
|
|
// {
|
|
// file: './package.json',
|
|
// code: `{
|
|
// "name": "importing-target-project",
|
|
// "version": "8.1.2",
|
|
// "dependencies": {
|
|
// "some-other-project": "^0.1.0"
|
|
// }
|
|
// }`,
|
|
// },
|
|
// ],
|
|
// };
|
|
|
|
// it('has a "requiresReference" boolean', async () => {
|
|
// expect(dummyAnalyzer.requiresReference).to.equal(true);
|
|
// });
|
|
|
|
// describe('Prepare phase', () => {
|
|
// it('halts non-compatible reference + target combinations', async () => {
|
|
// mockTargetAndReferenceProject(referenceProject, nonMatchingVersionTargetProject);
|
|
// // Check stubbed LogService.info with reason 'no-matched-version'
|
|
// mockTargetAndReferenceProject(referenceProject, nonMatchingDepTargetProject);
|
|
// // Check stubbed LogService.info with reason 'no-dependency'
|
|
// });
|
|
|
|
// it('starts analysis for compatible reference + target combinations', async () => {
|
|
// mockTargetAndReferenceProject(referenceProject, matchingTargetProject);
|
|
// mockTargetAndReferenceProject(referenceProject, matchingDevDepTargetProject);
|
|
// // _prepare: startAnalysis: true
|
|
// });
|
|
// });
|
|
// });
|
|
});
|
|
|
|
describe('FindAnalyzer', () => {});
|
|
|
|
describe('MatchAnalyzer', () => {});
|