195 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			195 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 'use strict';
 | |
| 
 | |
| function _jestUtil() {
 | |
|   const data = require('jest-util');
 | |
| 
 | |
|   _jestUtil = function _jestUtil() {
 | |
|     return data;
 | |
|   };
 | |
| 
 | |
|   return data;
 | |
| }
 | |
| 
 | |
| function _jestMock() {
 | |
|   const data = _interopRequireDefault(require('jest-mock'));
 | |
| 
 | |
|   _jestMock = function _jestMock() {
 | |
|     return data;
 | |
|   };
 | |
| 
 | |
|   return data;
 | |
| }
 | |
| 
 | |
| function _fakeTimers() {
 | |
|   const data = require('@jest/fake-timers');
 | |
| 
 | |
|   _fakeTimers = function _fakeTimers() {
 | |
|     return data;
 | |
|   };
 | |
| 
 | |
|   return data;
 | |
| }
 | |
| 
 | |
| function _jsdom() {
 | |
|   const data = require('jsdom');
 | |
| 
 | |
|   _jsdom = function _jsdom() {
 | |
|     return data;
 | |
|   };
 | |
| 
 | |
|   return data;
 | |
| }
 | |
| 
 | |
| function _interopRequireDefault(obj) {
 | |
|   return obj && obj.__esModule ? obj : {default: obj};
 | |
| }
 | |
| 
 | |
| function _objectSpread(target) {
 | |
|   for (var i = 1; i < arguments.length; i++) {
 | |
|     var source = arguments[i] != null ? arguments[i] : {};
 | |
|     var ownKeys = Object.keys(source);
 | |
|     if (typeof Object.getOwnPropertySymbols === 'function') {
 | |
|       ownKeys = ownKeys.concat(
 | |
|         Object.getOwnPropertySymbols(source).filter(function(sym) {
 | |
|           return Object.getOwnPropertyDescriptor(source, sym).enumerable;
 | |
|         })
 | |
|       );
 | |
|     }
 | |
|     ownKeys.forEach(function(key) {
 | |
|       _defineProperty(target, key, source[key]);
 | |
|     });
 | |
|   }
 | |
|   return target;
 | |
| }
 | |
| 
 | |
| 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 JSDOMEnvironment {
 | |
|   constructor(config, options = {}) {
 | |
|     _defineProperty(this, 'dom', void 0);
 | |
| 
 | |
|     _defineProperty(this, 'fakeTimers', void 0);
 | |
| 
 | |
|     _defineProperty(this, 'global', void 0);
 | |
| 
 | |
|     _defineProperty(this, 'errorEventListener', void 0);
 | |
| 
 | |
|     _defineProperty(this, 'moduleMocker', void 0);
 | |
| 
 | |
|     this.dom = new (_jsdom()).JSDOM(
 | |
|       '<!DOCTYPE html>',
 | |
|       _objectSpread(
 | |
|         {
 | |
|           pretendToBeVisual: true,
 | |
|           runScripts: 'dangerously',
 | |
|           url: config.testURL,
 | |
|           virtualConsole: new (_jsdom()).VirtualConsole().sendTo(
 | |
|             options.console || console
 | |
|           )
 | |
|         },
 | |
|         config.testEnvironmentOptions
 | |
|       )
 | |
|     );
 | |
|     const global = (this.global = this.dom.window.document.defaultView);
 | |
| 
 | |
|     if (!global) {
 | |
|       throw new Error('JSDOM did not return a Window object');
 | |
|     } // Node's error-message stack size is limited at 10, but it's pretty useful
 | |
|     // to see more than that when a test fails.
 | |
| 
 | |
|     this.global.Error.stackTraceLimit = 100;
 | |
|     (0, _jestUtil().installCommonGlobals)(global, config.globals); // Report uncaught errors.
 | |
| 
 | |
|     this.errorEventListener = event => {
 | |
|       if (userErrorListenerCount === 0 && event.error) {
 | |
|         process.emit('uncaughtException', event.error);
 | |
|       }
 | |
|     };
 | |
| 
 | |
|     global.addEventListener('error', this.errorEventListener); // However, don't report them as uncaught if the user listens to 'error' event.
 | |
|     // In that case, we assume the might have custom error handling logic.
 | |
| 
 | |
|     const originalAddListener = global.addEventListener;
 | |
|     const originalRemoveListener = global.removeEventListener;
 | |
|     let userErrorListenerCount = 0;
 | |
| 
 | |
|     global.addEventListener = function(...args) {
 | |
|       if (args[0] === 'error') {
 | |
|         userErrorListenerCount++;
 | |
|       }
 | |
| 
 | |
|       return originalAddListener.apply(this, args);
 | |
|     };
 | |
| 
 | |
|     global.removeEventListener = function(...args) {
 | |
|       if (args[0] === 'error') {
 | |
|         userErrorListenerCount--;
 | |
|       }
 | |
| 
 | |
|       return originalRemoveListener.apply(this, args);
 | |
|     };
 | |
| 
 | |
|     this.moduleMocker = new (_jestMock()).default.ModuleMocker(global);
 | |
|     const timerConfig = {
 | |
|       idToRef: id => id,
 | |
|       refToId: ref => ref
 | |
|     };
 | |
|     this.fakeTimers = new (_fakeTimers()).JestFakeTimers({
 | |
|       config,
 | |
|       global: global,
 | |
|       moduleMocker: this.moduleMocker,
 | |
|       timerConfig
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   setup() {
 | |
|     return Promise.resolve();
 | |
|   }
 | |
| 
 | |
|   teardown() {
 | |
|     if (this.fakeTimers) {
 | |
|       this.fakeTimers.dispose();
 | |
|     }
 | |
| 
 | |
|     if (this.global) {
 | |
|       if (this.errorEventListener) {
 | |
|         this.global.removeEventListener('error', this.errorEventListener);
 | |
|       } // Dispose "document" to prevent "load" event from triggering.
 | |
| 
 | |
|       Object.defineProperty(this.global, 'document', {
 | |
|         value: null
 | |
|       });
 | |
|       this.global.close();
 | |
|     }
 | |
| 
 | |
|     this.errorEventListener = null; // @ts-ignore
 | |
| 
 | |
|     this.global = null;
 | |
|     this.dom = null;
 | |
|     this.fakeTimers = null;
 | |
|     return Promise.resolve();
 | |
|   }
 | |
| 
 | |
|   runScript(script) {
 | |
|     if (this.dom) {
 | |
|       return this.dom.runVMScript(script);
 | |
|     }
 | |
| 
 | |
|     return null;
 | |
|   }
 | |
| }
 | |
| 
 | |
| module.exports = JSDOMEnvironment;
 |