Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Commit

Permalink
feat(test): unify mocha/jasmine test
Browse files Browse the repository at this point in the history
  • Loading branch information
JiaLiPassion committed May 5, 2018
1 parent 1ba8519 commit 82bf17f
Show file tree
Hide file tree
Showing 27 changed files with 2,638 additions and 471 deletions.
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ script:
- node ./test/webdriver/test.sauce.js
- yarn add [email protected] [email protected] [email protected]
- yarn test:phantomjs-single
- yarn test-mocha-jasmine-bridge-node
- yarn test-mocha-jasmine-bridge-browser
- node_modules/.bin/karma start karma-dist-sauce-jasmine3.conf.js --single-run
- node_modules/.bin/karma start karma-build-sauce-selenium3-mocha.conf.js --single-run
- node_modules/.bin/gulp test/node
Expand Down
18 changes: 18 additions & 0 deletions karma-build-mocha-jasmine-bridge.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

module.exports = function(config) {
require('./karma-base.conf.js')(config);
config.files.push('build/test/mocha/mocha-browser-karma.js');
config.files.push('build/test/wtf_mock.js');
config.files.push('build/test/test_fake_polyfill.js');
config.files.push('build/lib/zone.js');
config.files.push('build/lib/common/promise.js');
config.files.push('build/lib/common/error-rewrite.js');
config.files.push('build/test/main.js');

config.plugins.push(require('karma-mocha'));
config.frameworks.push('mocha');
config.client.mocha = {
timeout: 5000 // copied timeout for Jasmine in WebSocket.spec (otherwise Mochas default timeout
// at 2 sec is to low for the tests)
};
};
7 changes: 1 addition & 6 deletions karma-dist.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,8 @@ module.exports = function(config) {
config.files.push('dist/zone.js');
config.files.push('dist/zone-patch-user-media.js');
config.files.push('dist/zone-patch-resize-observer.js');
config.files.push('dist/long-stack-trace-zone.js');
config.files.push('dist/proxy.js');
config.files.push('dist/sync-test.js');
config.files.push('dist/async-test.js');
config.files.push('dist/fake-async-test.js');
config.files.push('dist/zone-testing.js');
config.files.push('dist/task-tracking.js');
config.files.push('dist/zone-patch-promise-test.js');
config.files.push('dist/wtf.js');
config.files.push('build/test/main.js');
};
54 changes: 54 additions & 0 deletions lib/jasmine/jasmine.clock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
// need to patch jasmine.clock().mockDate and jasmine.clock().tick() so
// they can work properly in FakeAsyncTest
export function patchJasmineClock(jasmine: any, enableClockPatch: boolean) {
const symbol = Zone.__symbol__;
const originalClockFn: Function = ((jasmine as any)[symbol('clock')] = jasmine['clock']);
(jasmine as any)['clock'] = function() {
const clock = originalClockFn.apply(this, arguments);
if (!clock[symbol('patched')]) {
clock[symbol('patched')] = symbol('patched');
const originalTick = (clock[symbol('tick')] = clock.tick);
clock.tick = function() {
const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
if (fakeAsyncZoneSpec) {
return fakeAsyncZoneSpec.tick.apply(fakeAsyncZoneSpec, arguments);
}
return originalTick.apply(this, arguments);
};
const originalMockDate = (clock[symbol('mockDate')] = clock.mockDate);
clock.mockDate = function() {
const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
if (fakeAsyncZoneSpec) {
const dateTime = arguments.length > 0 ? arguments[0] : new Date();
return fakeAsyncZoneSpec.setCurrentRealTime.apply(
fakeAsyncZoneSpec,
dateTime && typeof dateTime.getTime === 'function' ? [dateTime.getTime()] :
arguments);
}
return originalMockDate.apply(this, arguments);
};
// for auto go into fakeAsync feature, we need the flag to enable it
if (enableClockPatch) {
['install', 'uninstall'].forEach(methodName => {
const originalClockFn: Function = (clock[symbol(methodName)] = clock[methodName]);
clock[methodName] = function() {
const FakeAsyncTestZoneSpec = (Zone as any)['FakeAsyncTestZoneSpec'];
if (FakeAsyncTestZoneSpec) {
(jasmine as any)[symbol('clockInstalled')] = 'install' === methodName;
return;
}
return originalClockFn.apply(this, arguments);
};
});
}
}
return clock;
};
}
72 changes: 15 additions & 57 deletions lib/jasmine/jasmine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
*/

'use strict';
(() => {
import {patchJasmineClock} from './jasmine.clock';
Zone.__load_patch('jasmine', (global: any) => {
const __extends = function(d: any, b: any) {
for (const p in b)
if (b.hasOwnProperty(p)) d[p] = b[p];
Expand All @@ -16,12 +17,13 @@
}
d.prototype = b === null ? Object.create(b) : ((__.prototype = b.prototype), new (__ as any)());
};
const _global: any =
typeof window !== 'undefined' && window || typeof self !== 'undefined' && self || global;
// Patch jasmine's describe/it/beforeEach/afterEach functions so test code always runs
// in a testZone (ProxyZone). (See: angular/zone.js#91 & angular/angular#10503)
if (!Zone) throw new Error('Missing: zone.js');
if (typeof jasmine == 'undefined') throw new Error('Missing: jasmine.js');
if (typeof jasmine == 'undefined') {
// not using jasmine, just return;
return;
}
if ((jasmine as any)['__zone_patch__'])
throw new Error(`'jasmine' has already been patched with 'Zone'.`);
(jasmine as any)['__zone_patch__'] = true;
Expand All @@ -40,7 +42,7 @@
const symbol = Zone.__symbol__;

// whether patch jasmine clock when in fakeAsync
const enableClockPatch = _global[symbol('fakeAsyncPatchLock')] === true;
const enableClockPatch = global[symbol('fakeAsyncPatchLock')] === true;

// Monkey patch all of the jasmine DSL so that each function runs in appropriate zone.
const jasmineEnv: any = jasmine.getEnv();
Expand Down Expand Up @@ -68,51 +70,7 @@
};
});

// need to patch jasmine.clock().mockDate and jasmine.clock().tick() so
// they can work properly in FakeAsyncTest
const originalClockFn: Function = ((jasmine as any)[symbol('clock')] = jasmine['clock']);
(jasmine as any)['clock'] = function() {
const clock = originalClockFn.apply(this, arguments);
if (!clock[symbol('patched')]) {
clock[symbol('patched')] = symbol('patched');
const originalTick = (clock[symbol('tick')] = clock.tick);
clock.tick = function() {
const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
if (fakeAsyncZoneSpec) {
return fakeAsyncZoneSpec.tick.apply(fakeAsyncZoneSpec, arguments);
}
return originalTick.apply(this, arguments);
};
const originalMockDate = (clock[symbol('mockDate')] = clock.mockDate);
clock.mockDate = function() {
const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
if (fakeAsyncZoneSpec) {
const dateTime = arguments.length > 0 ? arguments[0] : new Date();
return fakeAsyncZoneSpec.setCurrentRealTime.apply(
fakeAsyncZoneSpec,
dateTime && typeof dateTime.getTime === 'function' ? [dateTime.getTime()] :
arguments);
}
return originalMockDate.apply(this, arguments);
};
// for auto go into fakeAsync feature, we need the flag to enable it
if (enableClockPatch) {
['install', 'uninstall'].forEach(methodName => {
const originalClockFn: Function = (clock[symbol(methodName)] = clock[methodName]);
clock[methodName] = function() {
const FakeAsyncTestZoneSpec = (Zone as any)['FakeAsyncTestZoneSpec'];
if (FakeAsyncTestZoneSpec) {
(jasmine as any)[symbol('clockInstalled')] = 'install' === methodName;
return;
}
return originalClockFn.apply(this, arguments);
};
});
}
}
return clock;
};

patchJasmineClock(jasmine, enableClockPatch);
/**
* Gets a function wrapping the body of a Jasmine `describe` block to execute in a
* synchronous-only zone.
Expand All @@ -127,7 +85,6 @@
const isClockInstalled = !!(jasmine as any)[symbol('clockInstalled')];
const testProxyZoneSpec = queueRunner.testProxyZoneSpec;
const testProxyZone = queueRunner.testProxyZone;
let lastDelegate;
if (isClockInstalled && enableClockPatch) {
// auto run a fakeAsync
const fakeAsyncModule = (Zone as any)[Zone.__symbol__('fakeAsyncTest')];
Expand Down Expand Up @@ -177,7 +134,8 @@
(jasmine as any).QueueRunner = (function(_super) {
__extends(ZoneQueueRunner, _super);
function ZoneQueueRunner(attrs: {
onComplete: Function; userContext?: any;
onComplete: Function;
userContext?: any;
timeout?: {setTimeout: Function; clearTimeout: Function};
onException?: (error: any) => void;
}) {
Expand All @@ -188,13 +146,13 @@
ambientZone.scheduleMicroTask('jasmine.onComplete', fn);
})(attrs.onComplete);

const nativeSetTimeout = _global['__zone_symbol__setTimeout'];
const nativeClearTimeout = _global['__zone_symbol__clearTimeout'];
const nativeSetTimeout = global['__zone_symbol__setTimeout'];
const nativeClearTimeout = global['__zone_symbol__clearTimeout'];
if (nativeSetTimeout) {
// should run setTimeout inside jasmine outside of zone
attrs.timeout = {
setTimeout: nativeSetTimeout ? nativeSetTimeout : _global.setTimeout,
clearTimeout: nativeClearTimeout ? nativeClearTimeout : _global.clearTimeout
setTimeout: nativeSetTimeout ? nativeSetTimeout : global.setTimeout,
clearTimeout: nativeClearTimeout ? nativeClearTimeout : global.clearTimeout
};
}

Expand Down Expand Up @@ -272,4 +230,4 @@
};
return ZoneQueueRunner;
})(QueueRunner);
})();
});
9 changes: 9 additions & 0 deletions lib/mocha/jasmine-bridge/jasmine-bridge.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import './jasmine';
45 changes: 45 additions & 0 deletions lib/mocha/jasmine-bridge/jasmine.bdd.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

export function mappingBDD(jasmine: any, Mocha: any, global: any) {
const mappings: {jasmine: string, Mocha: string}[] = [
{jasmine: 'beforeAll', Mocha: 'before'}, {jasmine: 'afterAll', Mocha: 'after'},
{jasmine: 'xdescribe', Mocha: 'describe.skip'}, {jasmine: 'fdescribe', Mocha: 'describe.only'},
{jasmine: 'xit', Mocha: 'it.skip'}, {jasmine: 'fit', Mocha: 'it.only'}
];
mappings.forEach(map => {
if (!global[map.jasmine]) {
const mocha = map.Mocha;
const chains = mocha.split('.');
let mochaMethod: any = null;
for (let i = 0; i < chains.length; i++) {
mochaMethod = mochaMethod ? mochaMethod[chains[i]] : Mocha[chains[i]];
}
global[map.jasmine] = jasmine[map.jasmine] = function() {
const args = Array.prototype.slice.call(arguments);
if (args.length > 0 && typeof args[args.length - 1] === 'number') {
// get a timeout
const timeout = args[args.length - 1];
if (this && typeof this.timeout === 'function') {
this.timeout(timeout);
}
}
return mochaMethod.apply(this, args);
};
}
});

if (!global['pending']) {
global['pending'] = function() {
const ctx = Mocha.__zone_symbol__current_ctx;
if (ctx && typeof ctx.skip === 'function') {
ctx.skip();
}
}
}
}
19 changes: 19 additions & 0 deletions lib/mocha/jasmine-bridge/jasmine.clock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {patchJasmineClock} from '../../jasmine/jasmine.clock';
export function addJasmineClock(jasmine: any) {
jasmine.clock = function() {
return {
tick: function() {},
install: function() {},
uninstall: function() {},
mockDate: function() {}
};
};
patchJasmineClock(jasmine, true);
}
Loading

0 comments on commit 82bf17f

Please sign in to comment.