mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-01-06 08:08:10 +08:00
188 lines
6.1 KiB
JavaScript
188 lines
6.1 KiB
JavaScript
/* eslint global-require:0 */
|
|
import _ from 'underscore';
|
|
|
|
import ReactTestUtils from 'react-dom/test-utils';
|
|
import Config from '../../src/config';
|
|
import SpecLoader from './spec-loader';
|
|
import TimeReporter from './time-reporter';
|
|
import GuiReporter from './gui-reporter';
|
|
import jasmineExports from './jasmine';
|
|
import ConsoleReporter from './console-reporter';
|
|
import MasterAfterEach from './master-after-each';
|
|
import MasterBeforeEach from './master-before-each';
|
|
import TestConstants from './test-constants';
|
|
import * as jasmineExtensions from './jasmine-extensions';
|
|
import * as reactTestUtilsExtensions from './react-test-utils-extensions';
|
|
|
|
class SpecRunner {
|
|
runSpecs(loadSettings) {
|
|
this.loadSettings = loadSettings;
|
|
this._extendGlobalWindow();
|
|
this._setupJasmine();
|
|
this._setupAppEnv();
|
|
this._setupWindow();
|
|
Object.assign(ReactTestUtils, reactTestUtilsExtensions);
|
|
MasterBeforeEach.setup(this.loadSettings, window.beforeEach);
|
|
MasterAfterEach.setup(this.loadSettings, window.afterEach);
|
|
SpecLoader.loadSpecs(this.loadSettings, this.jasmineEnv);
|
|
this.jasmineEnv.execute();
|
|
}
|
|
|
|
/**
|
|
* Put jasmine methods on the global scope so they can be used anywhere
|
|
* without importing jasmine.
|
|
*/
|
|
_extendGlobalWindow() {
|
|
Object.assign(
|
|
window,
|
|
{
|
|
jasmine: jasmineExports.jasmine,
|
|
|
|
it: this._makeItAsync(jasmineExports.it),
|
|
// it: jasmineExports.it,
|
|
fit: this._makeItAsync(jasmineExports.fit),
|
|
xit: jasmineExports.xit,
|
|
runs: jasmineExports.runs,
|
|
waits: jasmineExports.waits,
|
|
spyOn: jasmineExports.spyOn,
|
|
expect: jasmineExports.expect,
|
|
waitsFor: jasmineExports.waitsFor,
|
|
describe: jasmineExports.describe,
|
|
xdescribe: jasmineExports.xdescribe,
|
|
afterEach: this._makeSurroundAsync(jasmineExports.afterEach),
|
|
beforeEach: this._makeSurroundAsync(jasmineExports.beforeEach),
|
|
testNowMoment: jasmineExtensions.testNowMoment,
|
|
waitsForPromise: jasmineExtensions.waitsForPromise,
|
|
},
|
|
TestConstants
|
|
);
|
|
|
|
this.jasmineEnv = jasmineExports.jasmine.getEnv();
|
|
}
|
|
|
|
_runAsync(userFn) {
|
|
if (!userFn) return true;
|
|
const resp = userFn.apply(this);
|
|
if (resp && resp.then) {
|
|
return jasmineExtensions.waitsForPromise(() => {
|
|
return resp;
|
|
});
|
|
}
|
|
return resp;
|
|
}
|
|
|
|
_makeItAsync(jasmineIt) {
|
|
const self = this;
|
|
return (desc, userFn) => {
|
|
return jasmineIt(desc, function asyncIt() {
|
|
self._runAsync.call(this, userFn);
|
|
});
|
|
};
|
|
}
|
|
|
|
_makeSurroundAsync(jasmineBeforeAfter) {
|
|
const self = this;
|
|
return userFn => {
|
|
return jasmineBeforeAfter(function asyncBeforeAfter() {
|
|
self._runAsync.call(this, userFn);
|
|
});
|
|
};
|
|
}
|
|
|
|
_setupJasmine() {
|
|
this._addReporters();
|
|
this._initializeDOM();
|
|
this._extendJasmineMethods();
|
|
|
|
// On load, this will require "jasmine-focused" which looks up the
|
|
// global `jasmine` object and extends onto it:
|
|
// fdescribe, ffdescribe, fffdescribe, fit, ffit, fffit
|
|
require('jasmine-tagged');
|
|
|
|
// On load this will extend jasmine's `beforeEach`
|
|
require('jasmine-json');
|
|
}
|
|
|
|
_setupAppEnv() {
|
|
// We need to mock the config even before `beforeEach` runs because it
|
|
// gets accessed on module definitions
|
|
const fakePersistedConfig = { env: 'production' };
|
|
AppEnv.config = new Config();
|
|
AppEnv.config.settings = fakePersistedConfig;
|
|
|
|
AppEnv.restoreWindowDimensions();
|
|
AppEnv.themes.loadStaticStylesheets();
|
|
AppEnv.themes.requireStylesheet('../../static/jasmine');
|
|
AppEnv.themes.initialLoadComplete = true;
|
|
AppEnv.keymaps.loadKeymaps();
|
|
}
|
|
|
|
_setupWindow() {
|
|
window.addEventListener('core:close', () => window.close());
|
|
window.addEventListener('beforeunload', () => {
|
|
AppEnv.storeWindowDimensions();
|
|
return AppEnv.saveSync();
|
|
});
|
|
}
|
|
|
|
_addReporters() {
|
|
const timeReporter = new TimeReporter();
|
|
const consoleReporter = new ConsoleReporter();
|
|
|
|
const loadSettings = AppEnv.getLoadSettings();
|
|
|
|
if (loadSettings.jUnitXmlPath) {
|
|
// jasmine-reporters extends the jasmine global with methods, so needs to
|
|
// be `required` at runtime. The `jasmine` object has to be attached to the
|
|
// global scope before it gets extended. This is done in
|
|
// `_extendGlobalWindow`
|
|
require('jasmine-reporters');
|
|
const jUnitXmlReporter = new jasmine.JUnitXmlReporter(loadSettings.jUnitXmlPath, true, true);
|
|
this.jasmineEnv.addReporter(jUnitXmlReporter);
|
|
}
|
|
this.jasmineEnv.addReporter(timeReporter);
|
|
this.jasmineEnv.addReporter(consoleReporter);
|
|
|
|
if (loadSettings.showSpecsInWindow) {
|
|
this.jasmineEnv.addReporter(GuiReporter);
|
|
AppEnv.show();
|
|
} else {
|
|
// this package's dep `jasmine-focused` also adds methods to the
|
|
// `jasmine` global
|
|
// NOTE: this reporter MUST be added last as it exits the test process
|
|
// when complete, which may result in e.g. your XML output not getting
|
|
// written to disk if that reporter is added afterward.
|
|
const TerminalReporter = require('./terminal-reporter').default;
|
|
|
|
const terminalReporter = new TerminalReporter();
|
|
this.jasmineEnv.addReporter(terminalReporter);
|
|
}
|
|
}
|
|
|
|
_initializeDOM() {
|
|
const div = document.createElement('div');
|
|
div.id = 'jasmine-content';
|
|
document.body.appendChild(div);
|
|
document.querySelector('html').style.overflow = 'initial';
|
|
document.querySelector('body').style.overflow = 'initial';
|
|
}
|
|
|
|
_extendJasmineMethods() {
|
|
const jasmine = jasmineExports.jasmine;
|
|
|
|
// Use underscore's definition of equality for toEqual assertions
|
|
jasmine.getEnv().addEqualityTester(_.isEqual);
|
|
|
|
jasmine.unspy = jasmineExtensions.unspy;
|
|
jasmine.attachToDOM = jasmineExtensions.attachToDOM;
|
|
|
|
const origEmitObject = jasmine.StringPrettyPrinter.prototype.emitObject;
|
|
jasmine.StringPrettyPrinter.prototype.emitObject = function emitObject(obj) {
|
|
if (obj.inspect) {
|
|
return this.append(obj.inspect());
|
|
}
|
|
return origEmitObject.call(this, obj);
|
|
};
|
|
}
|
|
}
|
|
export default new SpecRunner();
|