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

Commit e60bdde

Browse files
committed
feat(test): unify mocha/jasmine test
1 parent 1ba8519 commit e60bdde

27 files changed

+2636
-471
lines changed

.travis.yml

+2
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ script:
4646
- node ./test/webdriver/test.sauce.js
4747
4848
- yarn test:phantomjs-single
49+
- yarn test-mocha-jasmine-bridge-node
50+
- yarn test-mocha-jasmine-bridge-browser
4951
- node_modules/.bin/karma start karma-dist-sauce-jasmine3.conf.js --single-run
5052
- node_modules/.bin/karma start karma-build-sauce-selenium3-mocha.conf.js --single-run
5153
- node_modules/.bin/gulp test/node
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
2+
module.exports = function(config) {
3+
require('./karma-base.conf.js')(config);
4+
config.files.push('build/test/mocha/mocha-browser-karma.js');
5+
config.files.push('build/test/wtf_mock.js');
6+
config.files.push('build/test/test_fake_polyfill.js');
7+
config.files.push('build/lib/zone.js');
8+
config.files.push('build/lib/common/promise.js');
9+
config.files.push('build/lib/common/error-rewrite.js');
10+
config.files.push('build/test/main.js');
11+
12+
config.plugins.push(require('karma-mocha'));
13+
config.frameworks.push('mocha');
14+
config.client.mocha = {
15+
timeout: 5000 // copied timeout for Jasmine in WebSocket.spec (otherwise Mochas default timeout
16+
// at 2 sec is to low for the tests)
17+
};
18+
};

karma-dist.conf.js

+1-6
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,8 @@ module.exports = function(config) {
1414
config.files.push('dist/zone.js');
1515
config.files.push('dist/zone-patch-user-media.js');
1616
config.files.push('dist/zone-patch-resize-observer.js');
17-
config.files.push('dist/long-stack-trace-zone.js');
18-
config.files.push('dist/proxy.js');
19-
config.files.push('dist/sync-test.js');
20-
config.files.push('dist/async-test.js');
21-
config.files.push('dist/fake-async-test.js');
17+
config.files.push('dist/zone-testing.js');
2218
config.files.push('dist/task-tracking.js');
23-
config.files.push('dist/zone-patch-promise-test.js');
2419
config.files.push('dist/wtf.js');
2520
config.files.push('build/test/main.js');
2621
};

lib/jasmine/jasmine.clock.ts

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
// need to patch jasmine.clock().mockDate and jasmine.clock().tick() so
9+
// they can work properly in FakeAsyncTest
10+
export function patchJasmineClock(jasmine: any, enableClockPatch: boolean) {
11+
const symbol = Zone.__symbol__;
12+
const originalClockFn: Function = ((jasmine as any)[symbol('clock')] = jasmine['clock']);
13+
(jasmine as any)['clock'] = function() {
14+
const clock = originalClockFn.apply(this, arguments);
15+
if (!clock[symbol('patched')]) {
16+
clock[symbol('patched')] = symbol('patched');
17+
const originalTick = (clock[symbol('tick')] = clock.tick);
18+
clock.tick = function() {
19+
const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
20+
if (fakeAsyncZoneSpec) {
21+
return fakeAsyncZoneSpec.tick.apply(fakeAsyncZoneSpec, arguments);
22+
}
23+
return originalTick.apply(this, arguments);
24+
};
25+
const originalMockDate = (clock[symbol('mockDate')] = clock.mockDate);
26+
clock.mockDate = function() {
27+
const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
28+
if (fakeAsyncZoneSpec) {
29+
const dateTime = arguments.length > 0 ? arguments[0] : new Date();
30+
return fakeAsyncZoneSpec.setCurrentRealTime.apply(
31+
fakeAsyncZoneSpec,
32+
dateTime && typeof dateTime.getTime === 'function' ? [dateTime.getTime()] :
33+
arguments);
34+
}
35+
return originalMockDate.apply(this, arguments);
36+
};
37+
// for auto go into fakeAsync feature, we need the flag to enable it
38+
if (enableClockPatch) {
39+
['install', 'uninstall'].forEach(methodName => {
40+
const originalClockFn: Function = (clock[symbol(methodName)] = clock[methodName]);
41+
clock[methodName] = function() {
42+
const FakeAsyncTestZoneSpec = (Zone as any)['FakeAsyncTestZoneSpec'];
43+
if (FakeAsyncTestZoneSpec) {
44+
(jasmine as any)[symbol('clockInstalled')] = 'install' === methodName;
45+
return;
46+
}
47+
return originalClockFn.apply(this, arguments);
48+
};
49+
});
50+
}
51+
}
52+
return clock;
53+
};
54+
}

lib/jasmine/jasmine.ts

+15-57
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
*/
88

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

4244
// whether patch jasmine clock when in fakeAsync
43-
const enableClockPatch = _global[symbol('fakeAsyncPatchLock')] === true;
45+
const enableClockPatch = global[symbol('fakeAsyncPatchLock')] === true;
4446

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

71-
// need to patch jasmine.clock().mockDate and jasmine.clock().tick() so
72-
// they can work properly in FakeAsyncTest
73-
const originalClockFn: Function = ((jasmine as any)[symbol('clock')] = jasmine['clock']);
74-
(jasmine as any)['clock'] = function() {
75-
const clock = originalClockFn.apply(this, arguments);
76-
if (!clock[symbol('patched')]) {
77-
clock[symbol('patched')] = symbol('patched');
78-
const originalTick = (clock[symbol('tick')] = clock.tick);
79-
clock.tick = function() {
80-
const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
81-
if (fakeAsyncZoneSpec) {
82-
return fakeAsyncZoneSpec.tick.apply(fakeAsyncZoneSpec, arguments);
83-
}
84-
return originalTick.apply(this, arguments);
85-
};
86-
const originalMockDate = (clock[symbol('mockDate')] = clock.mockDate);
87-
clock.mockDate = function() {
88-
const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
89-
if (fakeAsyncZoneSpec) {
90-
const dateTime = arguments.length > 0 ? arguments[0] : new Date();
91-
return fakeAsyncZoneSpec.setCurrentRealTime.apply(
92-
fakeAsyncZoneSpec,
93-
dateTime && typeof dateTime.getTime === 'function' ? [dateTime.getTime()] :
94-
arguments);
95-
}
96-
return originalMockDate.apply(this, arguments);
97-
};
98-
// for auto go into fakeAsync feature, we need the flag to enable it
99-
if (enableClockPatch) {
100-
['install', 'uninstall'].forEach(methodName => {
101-
const originalClockFn: Function = (clock[symbol(methodName)] = clock[methodName]);
102-
clock[methodName] = function() {
103-
const FakeAsyncTestZoneSpec = (Zone as any)['FakeAsyncTestZoneSpec'];
104-
if (FakeAsyncTestZoneSpec) {
105-
(jasmine as any)[symbol('clockInstalled')] = 'install' === methodName;
106-
return;
107-
}
108-
return originalClockFn.apply(this, arguments);
109-
};
110-
});
111-
}
112-
}
113-
return clock;
114-
};
115-
73+
patchJasmineClock(jasmine, enableClockPatch);
11674
/**
11775
* Gets a function wrapping the body of a Jasmine `describe` block to execute in a
11876
* synchronous-only zone.
@@ -127,7 +85,6 @@
12785
const isClockInstalled = !!(jasmine as any)[symbol('clockInstalled')];
12886
const testProxyZoneSpec = queueRunner.testProxyZoneSpec;
12987
const testProxyZone = queueRunner.testProxyZone;
130-
let lastDelegate;
13188
if (isClockInstalled && enableClockPatch) {
13289
// auto run a fakeAsync
13390
const fakeAsyncModule = (Zone as any)[Zone.__symbol__('fakeAsyncTest')];
@@ -177,7 +134,8 @@
177134
(jasmine as any).QueueRunner = (function(_super) {
178135
__extends(ZoneQueueRunner, _super);
179136
function ZoneQueueRunner(attrs: {
180-
onComplete: Function; userContext?: any;
137+
onComplete: Function;
138+
userContext?: any;
181139
timeout?: {setTimeout: Function; clearTimeout: Function};
182140
onException?: (error: any) => void;
183141
}) {
@@ -188,13 +146,13 @@
188146
ambientZone.scheduleMicroTask('jasmine.onComplete', fn);
189147
})(attrs.onComplete);
190148

191-
const nativeSetTimeout = _global['__zone_symbol__setTimeout'];
192-
const nativeClearTimeout = _global['__zone_symbol__clearTimeout'];
149+
const nativeSetTimeout = global['__zone_symbol__setTimeout'];
150+
const nativeClearTimeout = global['__zone_symbol__clearTimeout'];
193151
if (nativeSetTimeout) {
194152
// should run setTimeout inside jasmine outside of zone
195153
attrs.timeout = {
196-
setTimeout: nativeSetTimeout ? nativeSetTimeout : _global.setTimeout,
197-
clearTimeout: nativeClearTimeout ? nativeClearTimeout : _global.clearTimeout
154+
setTimeout: nativeSetTimeout ? nativeSetTimeout : global.setTimeout,
155+
clearTimeout: nativeClearTimeout ? nativeClearTimeout : global.clearTimeout
198156
};
199157
}
200158

@@ -272,4 +230,4 @@
272230
};
273231
return ZoneQueueRunner;
274232
})(QueueRunner);
275-
})();
233+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import './jasmine';
+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
export function mappingBDD(jasmine: any, Mocha: any, global: any) {
10+
const mappings: {jasmine: string, Mocha: string}[] = [
11+
{jasmine: 'beforeAll', Mocha: 'before'}, {jasmine: 'afterAll', Mocha: 'after'},
12+
{jasmine: 'xdescribe', Mocha: 'describe.skip'}, {jasmine: 'fdescribe', Mocha: 'describe.only'},
13+
{jasmine: 'xit', Mocha: 'it.skip'}, {jasmine: 'fit', Mocha: 'it.only'}
14+
];
15+
mappings.forEach(map => {
16+
if (!global[map.jasmine]) {
17+
const mocha = map.Mocha;
18+
const chains = mocha.split('.');
19+
let mochaMethod: any = null;
20+
for (let i = 0; i < chains.length; i++) {
21+
mochaMethod = mochaMethod ? mochaMethod[chains[i]] : Mocha[chains[i]];
22+
}
23+
global[map.jasmine] = jasmine[map.jasmine] = function() {
24+
const args = Array.prototype.slice.call(arguments);
25+
if (args.length > 0 && typeof args[args.length - 1] === 'number') {
26+
// get a timeout
27+
const timeout = args[args.length - 1];
28+
if (this && typeof this.timeout === 'function') {
29+
this.timeout(timeout);
30+
}
31+
}
32+
return mochaMethod.apply(this, args);
33+
};
34+
}
35+
});
36+
37+
if (!global['pending']) {
38+
global['pending'] = function() {
39+
const ctx = Mocha.__zone_symbol__current_ctx;
40+
if (ctx && typeof ctx.skip === 'function') {
41+
ctx.skip();
42+
}
43+
};
44+
}
45+
}
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
import {patchJasmineClock} from '../../jasmine/jasmine.clock';
9+
export function addJasmineClock(jasmine: any) {
10+
jasmine.clock = function() {
11+
return {
12+
tick: function() {},
13+
install: function() {},
14+
uninstall: function() {},
15+
mockDate: function() {}
16+
};
17+
};
18+
patchJasmineClock(jasmine, true);
19+
}

0 commit comments

Comments
 (0)