Innovenergy_trunk/frontend/node_modules/testcafe/lib/compiler/test-file/test-file-parser-base.js

232 lines
31 KiB
JavaScript
Raw Normal View History

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TestFileParserBase = exports.Test = exports.Fixture = void 0;
const promisified_functions_1 = require("../../utils/promisified-functions");
const util_1 = require("util");
const runtime_1 = require("../../errors/runtime");
const types_1 = require("../../errors/types");
const METHODS_SPECIFYING_NAME = ['only', 'skip'];
const COMPUTED_NAME_TEXT_TMP = '<computed name>(line: %s)';
const SKIP_PROPERTY_NAME = 'skip';
function getLoc(loc) {
// NOTE: Don't modify the Babel's parser data structure
const locCopy = Object.assign({}, loc);
// NOTE: 'fileName' and 'identifierName' fields with 'undefined' values added in the SourceLocation class constructor.
// https://github.com/babel/babel/blob/d51aa6d76177b544590cdfe3868f9f4d33d8813d/packages/babel-parser/src/util/location.js#L22
// Since this is useless information, we remove it.
delete locCopy.filename;
delete locCopy.identifierName;
delete locCopy.start.index;
delete locCopy.end.index;
return locCopy;
}
class Fixture {
constructor(name, start, end, loc, meta, isSkipped) {
this.name = name;
this.loc = getLoc(loc);
this.start = start;
this.end = end;
this.meta = meta;
this.tests = [];
this.isSkipped = !!isSkipped;
}
}
exports.Fixture = Fixture;
class Test {
constructor(name, start, end, loc, meta, isSkipped) {
this.name = name;
this.loc = getLoc(loc);
this.start = start;
this.end = end;
this.meta = meta;
this.isSkipped = !!isSkipped;
}
}
exports.Test = Test;
class TestFileParserBase {
constructor(tokenType) {
this.tokenType = tokenType;
}
static formatComputedName(line) {
return (0, util_1.format)(COMPUTED_NAME_TEXT_TMP, line);
}
isAsyncFn( /* token */) {
throw new Error('Not implemented');
}
getRValue( /* token */) {
throw new Error('Not implemented');
}
getFunctionBody( /* token */) {
throw new Error('Not implemented');
}
formatFnData( /* name, value, token */) {
throw new Error('Not implemented');
}
analyzeMemberExp( /* token */) {
throw new Error('Not implemented');
}
formatFnArg( /* arg */) {
throw new Error('Not implemented');
}
getFnCall( /* token */) {
throw new Error('Not implemented');
}
getTaggedTemplateExp( /* token */) {
throw new Error('Not implemented');
}
analyzeFnCall( /* token */) {
throw new Error('Not implemented');
}
parse( /* filePath, code */) {
throw new Error('Not implemented');
}
getTokenType( /* token */) {
throw new Error('Not implemented');
}
getCalleeToken( /* token */) {
throw new Error('Not implemented');
}
getMemberFnName() {
throw new Error('Not implemented');
}
getKeyValue() {
throw new Error('Not implemented');
}
getStringValue() {
throw new Error('Not implemented');
}
isApiFn(fn) {
return fn === 'fixture' || fn === 'test';
}
serializeObjExp(token) {
if (this.getTokenType(token) !== this.tokenType.ObjectLiteralExpression)
return {};
return token.properties.reduce((obj, prop) => {
const { key, value } = this.getKeyValue(prop);
if (typeof value !== 'string')
return {};
obj[key] = value;
return obj;
}, {});
}
processMetaArgs(token) {
if (this.getTokenType(token) !== this.tokenType.CallExpression)
return null;
const args = token.arguments;
let meta = {};
if (args.length === 2) {
const value = this.getStringValue(args[1]);
if (typeof value !== 'string')
return {};
meta = { [this.formatFnArg(args[0])]: value };
}
else if (args.length === 1)
meta = this.serializeObjExp(args[0]);
return meta;
}
getMetaInfo(callStack) {
return callStack.reduce((metaCalls, exp) => {
if (this.getTokenType(exp) !== this.tokenType.CallExpression)
return metaCalls;
const callee = this.getCalleeToken(exp);
const calleeType = this.getTokenType(callee);
const isCalleeMemberExp = calleeType === this.tokenType.PropertyAccessExpression;
if (isCalleeMemberExp && this.getMemberFnName(exp) === 'meta')
return [this.processMetaArgs(exp)].concat(metaCalls);
return metaCalls;
}, []);
}
static isSkipped(originalToken, token = originalToken) {
var _a, _b;
const needSkip = ((_a = token === null || token === void 0 ? void 0 : token.property) === null || _a === void 0 ? void 0 : _a.name) === SKIP_PROPERTY_NAME || ((_b = token === null || token === void 0 ? void 0 : token.name) === null || _b === void 0 ? void 0 : _b.text) === SKIP_PROPERTY_NAME;
if (!needSkip) {
token = token.callee || token.tag || token.object || token.expression;
return token ? TestFileParserBase.isSkipped(originalToken, token) : false;
}
return true;
}
checkExpDefineTargetName(type, apiFn) {
//NOTE: fixture('fixtureName').chainFn or test('testName').chainFn
const isDirectCall = type === this.tokenType.Identifier;
//NOTE: fixture.skip('fixtureName'), test.only('testName') etc.
const isMemberCall = type === this.tokenType.PropertyAccessExpression &&
METHODS_SPECIFYING_NAME.indexOf(apiFn) > -1;
//NOTE: fixture.before().after()('fixtureName'), test.before()`testName`.after() etc.
const isTailCall = type === this.tokenType.CallExpression;
return isDirectCall || isMemberCall || isTailCall;
}
analyzeToken(token) {
const tokenType = this.tokenType;
const currTokenType = this.getTokenType(token);
switch (currTokenType) {
case tokenType.ExpressionStatement:
case tokenType.TypeAssertionExpression:
return this.analyzeToken(token.expression);
case tokenType.FunctionDeclaration:
case tokenType.FunctionExpression:
if (this.isAsyncFn(token))
return null;
return this.getFunctionBody(token).map(this.analyzeToken, this);
case tokenType.VariableDeclaration:
case tokenType.VariableStatement: {
const variableValue = this.getRValue(token); // Skip variable declarations like `var foo;`
return variableValue ? this.analyzeToken(variableValue) : null;
}
case tokenType.CallExpression:
case tokenType.PropertyAccessExpression:
case tokenType.TaggedTemplateExpression:
return this.analyzeFnCall(token);
case tokenType.ReturnStatement:
return token.argument ? this.analyzeToken(token.argument) : null;
}
return null;
}
collectTestCafeCalls(astBody) {
let calls = [];
astBody.forEach(token => {
const callExps = this.analyzeToken(token);
if (callExps)
calls = calls.concat(callExps);
});
return calls;
}
analyze(astBody) {
const fixtures = [];
const testCafeAPICalls = this.collectTestCafeCalls(astBody);
testCafeAPICalls.forEach(call => {
if (!call || typeof call.value !== 'string')
return;
if (call.fnName === 'fixture') {
fixtures.push(new Fixture(call.value, call.start, call.end, call.loc, call.meta, call.isSkipped));
return;
}
if (!fixtures.length)
return;
// NOTE: If the fixture is skipped, mark all the tests in the fixture skipped, otherwise, use the current test identifier
const currentFixture = fixtures[fixtures.length - 1];
const testIsSkipped = currentFixture.isSkipped || call.isSkipped;
const test = new Test(call.value, call.start, call.end, call.loc, call.meta, testIsSkipped);
currentFixture.tests.push(test);
});
return fixtures;
}
async readFile(filePath) {
let fileContent = '';
try {
fileContent = await (0, promisified_functions_1.readFile)(filePath, 'utf8');
}
catch (err) {
throw new runtime_1.GeneralError(types_1.RUNTIME_ERRORS.cannotFindSpecifiedTestSource, filePath);
}
return fileContent;
}
async getTestList(filePath) {
const fileContent = await this.readFile(filePath);
return this.parse(fileContent);
}
getTestListFromCode(code) {
return this.parse(code);
}
}
exports.TestFileParserBase = TestFileParserBase;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC1maWxlLXBhcnNlci1iYXNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbXBpbGVyL3Rlc3QtZmlsZS90ZXN0LWZpbGUtcGFyc2VyLWJhc2UuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNkVBQTZEO0FBQzdELCtCQUE4QjtBQUM5QixrREFBb0Q7QUFDcEQsOENBQW9EO0FBRXBELE1BQU0sdUJBQXVCLEdBQUcsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7QUFDakQsTUFBTSxzQkFBc0IsR0FBSSwyQkFBMkIsQ0FBQztBQUM1RCxNQUFNLGtCQUFrQixHQUFRLE1BQU0sQ0FBQztBQUV2QyxTQUFTLE1BQU0sQ0FBRSxHQUFHO0lBQ2hCLHVEQUF1RDtJQUN2RCxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUV2QyxzSEFBc0g7SUFDdEgsOEhBQThIO0lBQzlILG1EQUFtRDtJQUNuRCxPQUFPLE9BQU8sQ0FBQyxRQUFRLENBQUM7SUFDeEIsT0FBTyxPQUFPLENBQUMsY0FBYyxDQUFDO0lBQzlCLE9BQU8sT0FBTyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUM7SUFDM0IsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQztJQUV6QixPQUFPLE9BQU8sQ0FBQztBQUNuQixDQUFDO0FBRUQsTUFBYSxPQUFPO0lBQ2hCLFlBQWEsSUFBSSxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTO1FBQy9DLElBQUksQ0FBQyxJQUFJLEdBQVEsSUFBSSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxHQUFHLEdBQVMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzdCLElBQUksQ0FBQyxLQUFLLEdBQU8sS0FBSyxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxHQUFHLEdBQVMsR0FBRyxDQUFDO1FBQ3JCLElB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