UNPKG

soda-test

Version:

Package for Unit and API tests

122 lines 4.89 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.testCase = exports.testStep = void 0; const testInfo_1 = require("./testInfo"); function createFactory(constructorMethod, args) { args = args || []; return () => new constructorMethod(...args); } class StepsCalls { addMethod(name) { this[name] = function (...args) { this.__lastCall = { methodName: name, args }; }; } append(calls) { for (const name of Object.keys(calls)) { if (!this[name]) { this[name] = calls[name]; } } } } // The testStep descorator is defined on a method in a (test-steps) class. // The class has a metadata named "soda-steps" of type StepsCalls that holds information about // all the test-step methods. This decorator adds the method name to the "soda-steps" (create it first if does not exist) function testStep() { return (target, propertyKey) => { if (!Reflect.hasMetadata("soda-steps", target)) { Reflect.defineMetadata("soda-steps", new StepsCalls(), target); } const steps = Reflect.getMetadata("soda-steps", target); steps.addMethod(propertyKey); }; } exports.testStep = testStep; // this methods returns a "StepsClass" instances that holds information about all the steps in that target class type // note taht targetType might defined from a nother class, so it should holds steps defines in base class too. function getSodaSteps(target) { const steps = new StepsCalls(); if (!target) return steps; const parent = Reflect.getPrototypeOf(target); steps.append(getSodaSteps(parent)); if (Reflect.hasMetadata("soda-steps", target)) { steps.append(Reflect.getMetadata("soda-steps", target)); } return steps; } // testCase is a decorator defined on a method that defines calls to test-steps // text - the name of the test-case // stepsConstructor - the class that holds the test-steps to be used // constructorArgs - optionaly arguments to the constractor for the class of the test-stpes function testCase(text, stepsConstructor, constructorArgs, extraData) { return (target, propertyKey, descriptor) => { // testStepsTarget is the prototype of the steps-class const testStepsTarget = stepsConstructor.prototype; // validate the steps-class as an "soda-steps" metadata if (!Reflect.hasMetadata("soda-steps", testStepsTarget)) { console.error(`cannot create case ${text}`); return; } // create the case info in this class info const tcase = (0, testInfo_1.getInfo)(target).getCase(propertyKey, text, createFactory(stepsConstructor, constructorArgs)); if (extraData) { tcase.extraData = extraData; } // get lists of the possible steps from steps-class const steps = getSodaSteps(testStepsTarget); // steps.__lastCall = undefined; let lastStep = undefined; let lastInstanceIndex = undefined; let lastExtraData = undefined; let comments = []; let lastComments = undefined; const addTestStep = () => { if (steps.__lastCall) { const text = lastStep; const instanceIndex = lastInstanceIndex; const methodName = steps.__lastCall.methodName; const args = steps.__lastCall.args; tcase.its.push({ itText: text, extraData: lastExtraData, instanceIndex: lastInstanceIndex, comments: lastComments, pending: false, sinons: null, method: function () { const method = this.instances[instanceIndex][methodName]; return method.apply(this.instances[instanceIndex], args); } }); } }; const stepMethod = (text, instanceIndex, extraData) => { if (!instanceIndex) instanceIndex = 0; addTestStep(); lastStep = text; lastExtraData = extraData; lastComments = comments; comments = []; lastInstanceIndex = instanceIndex; return steps; }; stepMethod.comment = (text, extraData) => { const comment = { commentText: text, extraData }; comments.push(comment); }; descriptor.value(stepMethod); addTestStep(); }; } exports.testCase = testCase; //# sourceMappingURL=testCase.js.map