/**1* Copyright (c) 2014, Facebook, Inc. All rights reserved.2*3* This source code is licensed under the BSD-style license found in the4* LICENSE file in the root directory of this source tree. An additional grant5* of patent rights can be found in the PATENTS file in the same directory.6*/7'use strict';89var FakeTimers = require('./lib/FakeTimers');1011function _deepCopy(obj) {12var newObj = {};13var value;14for (var key in obj) {15value = obj[key];16if (typeof value === 'object' && value !== null) {17value = _deepCopy(value);18}19newObj[key] = value;20}21return newObj;22}2324function JSDomEnvironment(config) {25// We lazily require jsdom because it takes a good ~.5s to load.26//27// Since this file may be require'd at the top of other files that may/may not28// use it (depending on the context -- such as TestRunner.js when operating as29// a workerpool parent), this is the best way to ensure we only spend time30// require()ing this when necessary.31this.global = require('./lib/jsdom-compat').jsdom().parentWindow;3233// Node's error-message stack size is limited at 10, but it's pretty useful to34// see more than that when a test fails.35this.global.Error.stackTraceLimit = 100;3637// Setup defaults for navigator.onLine38// TODO: It's questionable as to whether this should go here39// It's a pretty rarely depended on feature, so maybe tests that care40// about it should just shim it themselves?)41this.global.navigator.onLine = true;4243// Pass through the node implementation of some needed APIs44this.global.ArrayBuffer = ArrayBuffer;45this.global.Float32Array = Float32Array;46this.global.Int16Array = Int16Array;47this.global.Int32Array = Int32Array;48this.global.Int8Array = Int8Array;49this.global.Uint8Array = Uint8Array;50this.global.Uint16Array = Uint16Array;51this.global.Uint32Array = Uint32Array;52this.global.DataView = DataView;53this.global.Buffer = Buffer;54this.global.process = process;55this.global.setImmediate = setImmediate;56this.global.clearImmediate = clearImmediate;5758this.fakeTimers = new FakeTimers(this.global);5960// I kinda wish tests just did this manually rather than relying on a61// helper function to do it, but I'm keeping it for backward compat reasons62// while we get jest deployed internally. Then we can look into removing it.63//64// #337675465if (!this.global.hasOwnProperty('mockSetReadOnlyProperty')) {66this.global.mockSetReadOnlyProperty = function(obj, property, value) {67obj.__defineGetter__(property, function() {68return value;69});70};71}7273// jsdom doesn't have support for window.Image, so we just replace it with a74// dummy constructor75try {76/* jshint nonew:false */77new this.global.Image();78} catch (e) {79this.global.Image = function Image() {};80}8182// Pass through the node `process` global.83// TODO: Consider locking this down somehow so tests can't do crazy stuff to84// worker processes...85this.global.process = process;8687// Apply any user-specified global vars88var globalValues = _deepCopy(config.globals);89for (var customGlobalKey in globalValues) {90// Always deep-copy objects so isolated test environments can't share memory91this.global[customGlobalKey] = globalValues[customGlobalKey];92}93}9495JSDomEnvironment.prototype.dispose = function() {96// TODO: In node 0.8.8 (at least), closing each jsdom context appears to97// reproducibly cause a worker to segfault after a large number of tests98// have run (repro cases had > 1200).99//100// Disabling this to solve the problem for now -- but we should come101// back and investigate this soon. There's a reasonable chance that not102// closing out our contexts is eating an absurd amount of memory...103//this.global.close();104};105106JSDomEnvironment.prototype.runSourceText = function(sourceText, fileName) {107return this.global.run(sourceText, fileName);108};109110JSDomEnvironment.prototype.runWithRealTimers = function(cb) {111this.fakeTimers.runWithRealTimers(cb);112};113114module.exports = JSDomEnvironment;115116117