293 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			293 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 'use strict';
 | |
| 
 | |
| Object.defineProperty(exports, '__esModule', {
 | |
|   value: true
 | |
| });
 | |
| exports.default = void 0;
 | |
| 
 | |
| var _assert = require('assert');
 | |
| 
 | |
| var _ExpectationFailed = _interopRequireDefault(
 | |
|   require('../ExpectationFailed')
 | |
| );
 | |
| 
 | |
| var _expectationResultFactory = _interopRequireDefault(
 | |
|   require('../expectationResultFactory')
 | |
| );
 | |
| 
 | |
| var _assertionErrorMessage = _interopRequireDefault(
 | |
|   require('../assertionErrorMessage')
 | |
| );
 | |
| 
 | |
| function _interopRequireDefault(obj) {
 | |
|   return obj && obj.__esModule ? obj : {default: obj};
 | |
| }
 | |
| 
 | |
| function _defineProperty(obj, key, value) {
 | |
|   if (key in obj) {
 | |
|     Object.defineProperty(obj, key, {
 | |
|       value: value,
 | |
|       enumerable: true,
 | |
|       configurable: true,
 | |
|       writable: true
 | |
|     });
 | |
|   } else {
 | |
|     obj[key] = value;
 | |
|   }
 | |
|   return obj;
 | |
| }
 | |
| 
 | |
| class Spec {
 | |
|   static isPendingSpecException(e) {
 | |
|     return !!(
 | |
|       e &&
 | |
|       e.toString &&
 | |
|       e.toString().indexOf(Spec.pendingSpecExceptionMessage) !== -1
 | |
|     );
 | |
|   }
 | |
| 
 | |
|   constructor(attrs) {
 | |
|     _defineProperty(this, 'id', void 0);
 | |
| 
 | |
|     _defineProperty(this, 'description', void 0);
 | |
| 
 | |
|     _defineProperty(this, 'resultCallback', void 0);
 | |
| 
 | |
|     _defineProperty(this, 'queueableFn', void 0);
 | |
| 
 | |
|     _defineProperty(this, 'beforeAndAfterFns', void 0);
 | |
| 
 | |
|     _defineProperty(this, 'userContext', void 0);
 | |
| 
 | |
|     _defineProperty(this, 'onStart', void 0);
 | |
| 
 | |
|     _defineProperty(this, 'getSpecName', void 0);
 | |
| 
 | |
|     _defineProperty(this, 'queueRunnerFactory', void 0);
 | |
| 
 | |
|     _defineProperty(this, 'throwOnExpectationFailure', void 0);
 | |
| 
 | |
|     _defineProperty(this, 'initError', void 0);
 | |
| 
 | |
|     _defineProperty(this, 'result', void 0);
 | |
| 
 | |
|     _defineProperty(this, 'disabled', void 0);
 | |
| 
 | |
|     _defineProperty(this, 'currentRun', void 0);
 | |
| 
 | |
|     _defineProperty(this, 'markedTodo', void 0);
 | |
| 
 | |
|     _defineProperty(this, 'markedPending', void 0);
 | |
| 
 | |
|     _defineProperty(this, 'expand', void 0);
 | |
| 
 | |
|     this.resultCallback = attrs.resultCallback || function() {};
 | |
| 
 | |
|     this.id = attrs.id;
 | |
|     this.description = attrs.description || '';
 | |
|     this.queueableFn = attrs.queueableFn;
 | |
| 
 | |
|     this.beforeAndAfterFns =
 | |
|       attrs.beforeAndAfterFns ||
 | |
|       function() {
 | |
|         return {
 | |
|           befores: [],
 | |
|           afters: []
 | |
|         };
 | |
|       };
 | |
| 
 | |
|     this.userContext =
 | |
|       attrs.userContext ||
 | |
|       function() {
 | |
|         return {};
 | |
|       };
 | |
| 
 | |
|     this.onStart = attrs.onStart || function() {};
 | |
| 
 | |
|     this.getSpecName =
 | |
|       attrs.getSpecName ||
 | |
|       function() {
 | |
|         return '';
 | |
|       };
 | |
| 
 | |
|     this.queueRunnerFactory = attrs.queueRunnerFactory || function() {};
 | |
| 
 | |
|     this.throwOnExpectationFailure = !!attrs.throwOnExpectationFailure;
 | |
|     this.initError = new Error();
 | |
|     this.initError.name = ''; // Without this line v8 stores references to all closures
 | |
|     // in the stack in the Error object. This line stringifies the stack
 | |
|     // property to allow garbage-collecting objects on the stack
 | |
|     // https://crbug.com/v8/7142
 | |
| 
 | |
|     this.initError.stack = this.initError.stack;
 | |
|     this.queueableFn.initError = this.initError; // @ts-ignore
 | |
| 
 | |
|     this.result = {
 | |
|       id: this.id,
 | |
|       description: this.description,
 | |
|       fullName: this.getFullName(),
 | |
|       failedExpectations: [],
 | |
|       passedExpectations: [],
 | |
|       pendingReason: '',
 | |
|       testPath: attrs.getTestPath()
 | |
|     };
 | |
|   }
 | |
| 
 | |
|   addExpectationResult(passed, data, isError) {
 | |
|     const expectationResult = (0, _expectationResultFactory.default)(
 | |
|       data,
 | |
|       this.initError
 | |
|     );
 | |
| 
 | |
|     if (passed) {
 | |
|       this.result.passedExpectations.push(expectationResult);
 | |
|     } else {
 | |
|       this.result.failedExpectations.push(expectationResult);
 | |
| 
 | |
|       if (this.throwOnExpectationFailure && !isError) {
 | |
|         throw new _ExpectationFailed.default();
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   execute(onComplete, enabled) {
 | |
|     const self = this;
 | |
|     this.onStart(this);
 | |
| 
 | |
|     if (
 | |
|       !this.isExecutable() ||
 | |
|       this.markedPending ||
 | |
|       this.markedTodo ||
 | |
|       enabled === false
 | |
|     ) {
 | |
|       complete(enabled);
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     const fns = this.beforeAndAfterFns();
 | |
|     const allFns = fns.befores.concat(this.queueableFn).concat(fns.afters);
 | |
|     this.currentRun = this.queueRunnerFactory({
 | |
|       queueableFns: allFns,
 | |
| 
 | |
|       onException() {
 | |
|         // @ts-ignore
 | |
|         self.onException.apply(self, arguments);
 | |
|       },
 | |
| 
 | |
|       userContext: this.userContext(),
 | |
|       setTimeout,
 | |
|       clearTimeout,
 | |
|       fail: () => {}
 | |
|     });
 | |
|     this.currentRun.then(() => complete(true));
 | |
| 
 | |
|     function complete(enabledAgain) {
 | |
|       self.result.status = self.status(enabledAgain);
 | |
|       self.resultCallback(self.result);
 | |
| 
 | |
|       if (onComplete) {
 | |
|         onComplete();
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   cancel() {
 | |
|     if (this.currentRun) {
 | |
|       this.currentRun.cancel();
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   onException(error) {
 | |
|     if (Spec.isPendingSpecException(error)) {
 | |
|       this.pend(extractCustomPendingMessage(error));
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     if (error instanceof _ExpectationFailed.default) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     this.addExpectationResult(
 | |
|       false,
 | |
|       {
 | |
|         matcherName: '',
 | |
|         passed: false,
 | |
|         expected: '',
 | |
|         actual: '',
 | |
|         error:
 | |
|           error instanceof _assert.AssertionError
 | |
|             ? (0, _assertionErrorMessage.default)(error, {
 | |
|                 expand: this.expand
 | |
|               })
 | |
|             : error
 | |
|       },
 | |
|       true
 | |
|     );
 | |
|   }
 | |
| 
 | |
|   disable() {
 | |
|     this.disabled = true;
 | |
|   }
 | |
| 
 | |
|   pend(message) {
 | |
|     this.markedPending = true;
 | |
| 
 | |
|     if (message) {
 | |
|       this.result.pendingReason = message;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   todo() {
 | |
|     this.markedTodo = true;
 | |
|   }
 | |
| 
 | |
|   getResult() {
 | |
|     this.result.status = this.status();
 | |
|     return this.result;
 | |
|   }
 | |
| 
 | |
|   status(enabled) {
 | |
|     if (this.disabled || enabled === false) {
 | |
|       return 'disabled';
 | |
|     }
 | |
| 
 | |
|     if (this.markedTodo) {
 | |
|       return 'todo';
 | |
|     }
 | |
| 
 | |
|     if (this.markedPending) {
 | |
|       return 'pending';
 | |
|     }
 | |
| 
 | |
|     if (this.result.failedExpectations.length > 0) {
 | |
|       return 'failed';
 | |
|     } else {
 | |
|       return 'passed';
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   isExecutable() {
 | |
|     return !this.disabled;
 | |
|   }
 | |
| 
 | |
|   getFullName() {
 | |
|     return this.getSpecName(this);
 | |
|   }
 | |
| }
 | |
| 
 | |
| exports.default = Spec;
 | |
| 
 | |
| _defineProperty(Spec, 'pendingSpecExceptionMessage', void 0);
 | |
| 
 | |
| Spec.pendingSpecExceptionMessage = '=> marked Pending';
 | |
| 
 | |
| const extractCustomPendingMessage = function extractCustomPendingMessage(e) {
 | |
|   const fullMessage = e.toString();
 | |
|   const boilerplateStart = fullMessage.indexOf(
 | |
|     Spec.pendingSpecExceptionMessage
 | |
|   );
 | |
|   const boilerplateEnd =
 | |
|     boilerplateStart + Spec.pendingSpecExceptionMessage.length;
 | |
|   return fullMessage.substr(boilerplateEnd);
 | |
| };
 |