lion/packages-node/providence-analytics/test-node/program/Analyzer.testx.js

228 lines
7 KiB
JavaScript

const { expect } = require('chai');
const {
// mockTargetAndReferenceProject,
mockProject,
restoreMockedProjects,
} = require('../../test-helpers/mock-project-helpers.js');
const {
mockWriteToJson,
restoreWriteToJson,
} = require('../../test-helpers/mock-report-service-helpers.js');
const {
suppressNonCriticalLogs,
restoreSuppressNonCriticalLogs,
} = require('../../test-helpers/mock-log-service-helpers.js');
const { QueryService } = require('../../src/program/services/QueryService.js');
const { providence } = require('../../src/program/providence.js');
const dummyAnalyzer = require('../../test-helpers/templates/analyzer-template.js');
const queryResults = [];
describe('Analyzer', () => {
before(() => {
suppressNonCriticalLogs();
mockWriteToJson(queryResults);
});
after(() => {
restoreSuppressNonCriticalLogs();
restoreWriteToJson(queryResults);
});
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.requiredAst).to.equal('string');
const allowedAsts = ['babel', 'typescript', 'es-module-lexer'];
expect(allowedAsts).to.include(dummyAnalyzer.requiredAst);
});
it('has a "requiresReference" boolean', async () => {
expect(typeof dummyAnalyzer.requiresReference).to.equal('boolean');
});
});
describe('Find Analyzers', async () => {
afterEach(() => {
restoreMockedProjects();
});
// Our configuration object
const myQueryConfigObject = QueryService.getQueryConfigFromAnalyzer(dummyAnalyzer);
mockProject([`const validJs = true;`, `let invalidJs = false;`], {
projectName: 'my-project',
projectPath: '/path/to/my-project',
filePaths: ['./test-file1.js', './test-file2.js'],
});
await providence(myQueryConfigObject, {
targetProjectPaths: ['/path/to/my-project'],
});
describe('Prepare phase', () => {
it('looks for a cached result', async () => {});
it('exposes a ".targetMeta" object', async () => {});
it('exposes a ".targetData" object', async () => {});
it('exposes a ".identifier" string', async () => {});
});
describe('Traverse phase', () => {});
describe('Finalize phase', () => {
it('returns an AnalyzerResult', async () => {
const queryResult = queryResults[0];
const { queryOutput, meta } = queryResult;
expect(queryOutput[0]).to.eql({
file: './test-file1.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
// });
// });
// });
});