refactor: update zone.js and tests to work with ESM (#48521)

* Adjusts tests to no longer rely on CommonJS features. Switches them to
  ESM
* Updates test initialization files to not double-initialize Jasmine now
  that bootstrap files are loaded after Jasmine. The `jasmine.boot`
  setup was hacky from `rules_nodejs` and will break in the future
  regardless if we e.g. use `rules_js` with actual unmodified `jasmine`.

PR Close #48521
This commit is contained in:
Paul Gschwendtner
2022-12-14 19:48:57 +00:00
parent 2aa62de2c0
commit cc5d3b75e2
39 changed files with 826 additions and 768 deletions
+19 -4
View File
@@ -612,15 +612,30 @@ jobs:
- custom_attach_workspace
- init_environment
- install_java
- run: |
yarn bazel build -- \
//packages/zone.js/bundles:zone.umd.js \
//packages/zone.js:npm_package \
//packages/zone.js/test/closure:closure_js \
//packages/zone.js:zone_externs
- run: |
mkdir -p packages/zone.js/build/
mkdir -p packages/zone.js/build/test/
mkdir -p packages/zone.js/test/
cp dist/bin/packages/zone.js/bundles/zone.umd.js packages/zone.js/build/zone.umd.js
cp dist/bin/packages/zone.js/npm_package/bundles/zone-mix.umd.js ./packages/zone.js/test/extra/
cp dist/bin/packages/zone.js/npm_package/bundles/zone-patch-electron.umd.js ./packages/zone.js/test/extra/
cp dist/bin/packages/zone.js/test/closure/zone.closure.mjs ./packages/zone.js/build/test/zone.closure.mjs
cp dist/bin/packages/zone.js/zone_externs.js ./packages/zone.js/build/zone_externs.js
# Install
- run: yarn --cwd packages/zone.js install --frozen-lockfile --non-interactive --cache-folder ~/.cache/yarn
# Run zone.js tools tests
- run: yarn --cwd packages/zone.js promisetest
- run: yarn --cwd packages/zone.js promisefinallytest
- run: yarn bazel build //packages/zone.js:npm_package &&
cp dist/bin/packages/zone.js/npm_package/bundles/zone-mix.umd.js ./packages/zone.js/test/extra/ &&
cp dist/bin/packages/zone.js/npm_package/bundles/zone-patch-electron.umd.js ./packages/zone.js/test/extra/ &&
cp dist/bin/packages/zone.js/npm_package/bundles/zone.umd.js ./packages/zone.js/build/test/closure/zone.js
- run: yarn --cwd packages/zone.js jest:test
- run: yarn --cwd packages/zone.js jest:nodetest
- run: yarn --cwd packages/zone.js electrontest
+1
View File
@@ -1 +1,2 @@
/node_modules/
build
+1 -2
View File
@@ -1,4 +1,4 @@
load("@npm//@bazel/concatjs:index.bzl", "ts_library")
load("//tools:defaults.bzl", "ts_library")
package(default_visibility = ["//visibility:public"])
@@ -27,6 +27,5 @@ ts_library(
"@npm//@types/jasmine",
"@npm//@types/node",
"@npm//rxjs",
"@npm//tslib",
],
)
+3 -4
View File
@@ -20,16 +20,15 @@
"jest-environment-node": "^29.0.3",
"mocha": "^10.0.0",
"mock-require": "3.0.3",
"promises-aplus-tests": "^2.1.2",
"typescript": "~4.9.3"
"promises-aplus-tests": "^2.1.2"
},
"scripts": {
"closuretest": "./scripts/closure/closure_compiler.sh",
"electrontest": "cd test/extra && node electron.js",
"jest:test": "jest --config ./test/jest/jest.config.js ./test/jest/jest.spec.js",
"jest:nodetest": "jest --config ./test/jest/jest.node.config.js ./test/jest/jest.spec.js",
"promisetest": "tsc -p . && node ./test/promise/promise-test.js",
"promisefinallytest": "tsc -p . && mocha ./test/promise/promise.finally.spec.js"
"promisetest": "node ./test/promise/promise-test.mjs",
"promisefinallytest": "mocha ./test/promise/promise.finally.spec.mjs"
},
"repository": {
"type": "git",
@@ -1,7 +1,7 @@
# compile closure test source file
$(npm bin)/tsc -p .
# Run the Google Closure compiler java runnable with zone externs
java -jar ./node_modules/google-closure-compiler-java/compiler.jar --flagfile './scripts/closure/closure_flagfile' --externs './lib/closure/zone_externs.js' --externs './node_modules/@externs/nodejs/v8/global.js' --process_common_js_modules
java -jar ./node_modules/google-closure-compiler-java/compiler.jar --flagfile './scripts/closure/closure_flagfile' --externs './build/zone_externs.js' --externs './node_modules/@externs/nodejs/v8/global.js' --process_common_js_modules
# the names of Zone exposed API should be kept correctly with zone externs, test program should exit with 0.
node build/closure/zone-closure-bundle.js
@@ -1,6 +1,6 @@
--compilation_level ADVANCED_OPTIMIZATIONS
--js_output_file "build/closure/zone-closure-bundle.js"
--rewrite_polyfills false
--js "build/test/closure/zone.js"
--js "build/test/closure/zone.closure.js"
--js "build/zone.umd.js"
--js "build/test/zone.closure.mjs"
--formatting PRETTY_PRINT
+24 -50
View File
@@ -1,7 +1,7 @@
load("//tools:defaults.bzl", "jasmine_node_test", "ts_library")
load("//tools:defaults.bzl", "jasmine_node_test", "ts_library", "zone_compatible_jasmine_node_test")
load("//packages/zone.js/test:karma_test.bzl", "karma_test")
package(default_visibility = ["//:__pkg__"])
package(default_visibility = ["//:__subpackages__"])
exports_files([
"assets/sample.json",
@@ -67,14 +67,8 @@ ts_library(
ts_library(
name = "test_node_lib",
testonly = True,
srcs = glob(["node/*.ts"]) + [
"node-env-setup.ts",
"test-env-setup-jasmine-no-patch-clock.ts",
],
srcs = glob(["node/*.ts"]),
deps = [
":common_spec_env",
":common_spec_srcs",
":common_spec_util",
"//packages/zone.js/lib",
"@npm//@types/shelljs",
"@npm//@types/systemjs",
@@ -87,28 +81,12 @@ ts_library(
ts_library(
name = "node_entry_point",
testonly = True,
srcs = ["node_entry_point.init.ts"],
deps = [
":common_spec_env",
":common_spec_srcs",
":common_spec_util",
"//packages/zone.js/lib",
"@npm//@types/shelljs",
"@npm//@types/systemjs",
"@npm//rxjs",
"@npm//shelljs",
"@npm//systemjs",
srcs = [
"node-env-setup.ts",
"node_entry_point.init.ts",
],
)
ts_library(
name = "node_entry_point_no_patch_clock",
testonly = True,
srcs = ["node_entry_point_no_patch_clock.init.ts"],
deps = [
":common_spec_env",
":common_spec_srcs",
":common_spec_util",
"//packages/zone.js/lib",
"@npm//@types/shelljs",
"@npm//@types/systemjs",
@@ -145,13 +123,12 @@ ts_library(
ts_library(
name = "node_error_disable_policy_entry_point",
testonly = True,
srcs = ["node_error_disable_policy_entry_point.init.ts"],
srcs = [
"node_error_disable_policy.ts",
"node_error_disable_policy_entry_point.init.ts",
],
deps = [
":common_spec_env",
":common_spec_util",
":error_spec_srcs",
":node_error_entry_point",
"//packages/zone.js/lib",
],
)
@@ -161,8 +138,6 @@ ts_library(
srcs = ["node_error_entry_point.init.ts"],
deps = [
":common_spec_env",
":common_spec_util",
":error_spec_srcs",
"//packages/zone.js/lib",
],
)
@@ -170,33 +145,25 @@ ts_library(
ts_library(
name = "node_error_lazy_policy_entry_point",
testonly = True,
srcs = ["node_error_lazy_policy_entry_point.init.ts"],
srcs = [
"node_error_lazy_policy.ts",
"node_error_lazy_policy_entry_point.init.ts",
],
deps = [
":common_spec_env",
":common_spec_util",
":error_spec_srcs",
":node_error_entry_point",
"//packages/zone.js/lib",
],
)
jasmine_node_test(
zone_compatible_jasmine_node_test(
name = "test_node",
bootstrap = [":node_entry_point"],
deps = [
":common_spec_srcs",
":test_node_lib",
],
)
jasmine_node_test(
name = "test_node_no_jasmine_clock",
bootstrap = [":node_entry_point_no_patch_clock"],
deps = [
":test_node_lib",
],
)
jasmine_node_test(
zone_compatible_jasmine_node_test(
name = "test_node_bluebird",
bootstrap = [":node_bluebird_entry_point"],
deps = [
@@ -207,11 +174,17 @@ jasmine_node_test(
jasmine_node_test(
name = "test_node_error_disable_policy",
bootstrap = [":node_error_disable_policy_entry_point"],
deps = [
":error_spec_srcs",
],
)
jasmine_node_test(
name = "test_node_error_lazy_policy",
bootstrap = [":node_error_lazy_policy_entry_point"],
deps = [
":error_spec_srcs",
],
)
ts_library(
@@ -219,6 +192,7 @@ ts_library(
testonly = True,
srcs = ["npm_package/npm_package.spec.ts"],
deps = [
"@npm//@bazel/runfiles",
"@npm//@types/shelljs",
],
)
+15
View File
@@ -0,0 +1,15 @@
load("//tools:defaults.bzl", "ts_library")
ts_library(
name = "closure",
testonly = True,
srcs = ["zone.closure.ts"],
deps = ["//packages/zone.js/lib:zone_d_ts"],
)
filegroup(
name = "closure_js",
testonly = True,
srcs = [":closure"],
output_group = "es6_sources",
)
@@ -5,7 +5,7 @@
* 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 './zone.js';
import '../zone.umd.js';
const testClosureFunction = () => {
const logs: string[] = [];
// call all Zone exposed functions
+1 -1
View File
@@ -308,7 +308,7 @@ describe('ZoneAwareError', () => {
hasZoneStack = zoneAwareFrames.filter(f => frames[i].indexOf(f) !== -1).length > 0;
}
if (!hasZoneStack) {
console.log('stack', err.originalStack);
console.log('stack', hasZoneStack, frames, err.originalStack);
}
expect(hasZoneStack).toBe(true);
} else {
@@ -63,31 +63,6 @@ describe(
log = [];
});
xit('should allow set es6 Promise after load ZoneAwarePromise', (done) => {
const ES6Promise = require('es6-promise').Promise;
const NativePromise = global[zoneSymbol('Promise')];
try {
global['Promise'] = ES6Promise;
Zone.assertZonePatched();
expect(global[zoneSymbol('Promise')]).toBe(ES6Promise);
const promise = Promise.resolve(0);
console.log('promise', promise);
promise
.then(value => {
expect(value).toBe(0);
done();
})
.catch(error => {
fail(error);
});
} finally {
global['Promise'] = NativePromise;
Zone.assertZonePatched();
expect(global[zoneSymbol('Promise')]).toBe(NativePromise);
}
});
it('should pretend to be a native code', () => {
expect(String(Promise).indexOf('[native code]') >= 0).toBe(true);
});
+7 -4
View File
@@ -7,7 +7,10 @@
*/
import {closeSync, exists, fstatSync, openSync, read, unlink, unlinkSync, unwatchFile, watch, watchFile, write, writeFile} from 'fs';
import * as util from 'util';
import url from 'url';
import util from 'util';
const currentFile = url.fileURLToPath(import.meta.url);
describe('nodejs file system', () => {
describe('async method patch test', () => {
@@ -94,7 +97,7 @@ describe('nodejs file system', () => {
describe('util.promisify', () => {
it('fs.exists should work with util.promisify', (done: DoneFn) => {
const promisifyExists = util.promisify(exists);
promisifyExists(__filename)
promisifyExists(currentFile)
.then(
r => {
expect(r).toBe(true);
@@ -107,7 +110,7 @@ describe('util.promisify', () => {
it('fs.read should work with util.promisify', (done: DoneFn) => {
const promisifyRead = util.promisify(read);
const fd = openSync(__filename, 'r');
const fd = openSync(currentFile, 'r');
const stats = fstatSync(fd);
const bufferSize = stats.size;
const chunkSize = 512;
@@ -129,7 +132,7 @@ describe('util.promisify', () => {
it('fs.write should work with util.promisify', (done: DoneFn) => {
const promisifyWrite = util.promisify(write);
const dest = __filename + 'write';
const dest = currentFile + 'write';
const fd = openSync(dest, 'a');
const stats = fstatSync(fd);
const chunkSize = 512;
+2 -1
View File
@@ -5,7 +5,8 @@
* 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
*/
const http = require('http');
import http from 'http';
describe('http test', () => {
it('http.request should be patched as eventTask', (done) => {
const server = http.createServer((req: any, res: any) => {
@@ -8,17 +8,14 @@
// Must be loaded before zone loads, so that zone can detect WTF.
import './test_fake_polyfill';
// Setup tests for Zone without microtask support
import '../lib/zone';
import '../lib/common/promise';
import '../lib/common/to-string';
import '../lib/node/node';
// Setup test environment
require('@bazel/jasmine').boot();
import './test-env-setup-jasmine';
import './wtf_mock';
import '../lib/zone-spec/async-test';
import '../lib/zone-spec/fake-async-test';
import '../lib/zone-spec/long-stack-trace';
@@ -27,7 +24,6 @@ import '../lib/zone-spec/sync-test';
import '../lib/zone-spec/task-tracking';
import '../lib/zone-spec/wtf';
import '../lib/rxjs/rxjs';
import '../lib/testing/promise-testing';
const globalErrors = (jasmine as any).GlobalErrors;
@@ -16,18 +16,10 @@
// Must be loaded before zone loads, so that zone can detect WTF.
import './node-env-setup';
import './test_fake_polyfill';
// Setup tests for Zone without microtask support
import '../lib/node/rollup-main';
require('@bazel/jasmine').boot();
// Zone symbol prefix is set to '__zone_symbol2__' in node-env-setup.ts.
import './test-env-setup-jasmine';
if (typeof global !== 'undefined' &&
(global as any)['__zone_symbol_test__fakeAsyncAutoFakeAsyncWhenClockPatched'] !== false) {
(global as any)['__zone_symbol_test__fakeAsyncAutoFakeAsyncWhenClockPatched'] = true;
}
import './wtf_mock';
import '../lib/testing/zone-testing';
import '../lib/zone-spec/task-tracking';
@@ -1,36 +0,0 @@
/**
* @license
* Copyright Google LLC 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
*/
/**
* @license
* Copyright Google LLC 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
*/
// Must be loaded before zone loads, so that zone can detect WTF.
import './node-env-setup';
import './test_fake_polyfill';
// Setup tests for Zone without microtask support
import '../lib/node/rollup-main';
require('@bazel/jasmine').boot();
import './test-env-setup-jasmine-no-patch-clock';
// Zone symbol prefix is set to '__zone_symbol2__' in node-env-setup.ts.
if (typeof global !== 'undefined' &&
(global as any)['__zone_symbol_test__fakeAsyncAutoFakeAsyncWhenClockPatched'] !== false) {
(global as any)['__zone_symbol_test__fakeAsyncAutoFakeAsyncWhenClockPatched'] = true;
}
import './wtf_mock';
import '../lib/testing/zone-testing';
import '../lib/zone-spec/task-tracking';
import '../lib/zone-spec/wtf';
import '../lib/rxjs/rxjs';
import '../lib/rxjs/rxjs-fake-async';
import '../lib/jasmine/jasmine';
@@ -0,0 +1,10 @@
/**
* @license
* Copyright Google LLC 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
*/
process.env['errorpolicy'] = (global as any)['__Zone_Error_ZoneJsInternalStackFrames_policy'] =
'disable';
@@ -6,6 +6,6 @@
* found in the LICENSE file at https://angular.io/license
*/
process.env['errorpolicy'] = (global as any)['__Zone_Error_ZoneJsInternalStackFrames_policy'] =
'disable';
import './node_error_entry_point';
// Note: Make sure to define the policy before loading the basic entry point.
import './node_error_disable_policy';
import './node_error_entry_point.init';
@@ -8,18 +8,11 @@
// Must be loaded before zone loads, so that zone can detect WTF.
import './test_fake_polyfill';
// Setup tests for Zone without microtask support
import '../lib/zone';
import '../lib/common/promise';
import '../lib/common/to-string';
process.env['errorpolicy'] = (global as any)['__Zone_Error_ZoneJsInternalStackFrames_policy'] =
'disable';
// Setup test environment
require('@bazel/jasmine').boot();
import './test-env-setup-jasmine';
import './wtf_mock';
import '../lib/common/error-rewrite';
import '../lib/node/node';
@@ -31,5 +24,4 @@ import '../lib/zone-spec/sync-test';
import '../lib/zone-spec/task-tracking';
import '../lib/zone-spec/wtf';
import '../lib/rxjs/rxjs';
import '../lib/testing/promise-testing';
@@ -0,0 +1,10 @@
/**
* @license
* Copyright Google LLC 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
*/
process.env['errorpolicy'] = (global as any)['__Zone_Error_ZoneJsInternalStackFrames_policy'] =
'lazy';
@@ -6,6 +6,6 @@
* found in the LICENSE file at https://angular.io/license
*/
process.env['errorpolicy'] = (global as any)['__Zone_Error_ZoneJsInternalStackFrames_policy'] =
'lazy';
import './node_error_entry_point';
// Note: Make sure to define the policy before loading the basic entry point.
import './node_error_lazy_policy';
import './node_error_entry_point.init';
@@ -5,8 +5,9 @@
* 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 * as path from 'path';
import * as shx from 'shelljs';
import {runfiles} from '@bazel/runfiles';
import path from 'path';
import shx from 'shelljs';
function checkInSubFolder(subFolder: string, testFn: Function) {
shx.cd(subFolder);
@@ -16,7 +17,7 @@ function checkInSubFolder(subFolder: string, testFn: Function) {
describe('Zone.js npm_package', () => {
beforeEach(() => {
shx.cd(path.dirname(require.resolve('angular/packages/zone.js/npm_package/package.json')));
shx.cd(path.dirname(runfiles.resolve('angular/packages/zone.js/npm_package/package.json')));
});
describe('misc root files', () => {
describe('README.md', () => {
@@ -1,6 +1,7 @@
require('../../build/lib/node/rollup-main');
import '../../build/zone.umd.js';
Zone[Zone.__symbol__('ignoreConsoleErrorUncaughtError')] = true;
module.exports.deferred = function() {
const deferred = function () {
const p = {};
p.promise = new Promise((resolve, reject) => {
p.resolve = resolve;
@@ -9,10 +10,12 @@ module.exports.deferred = function() {
return p;
};
module.exports.resolved = (val) => {
const resolved = (val) => {
return Promise.resolve(val);
};
module.exports.rejected = (reason) => {
const rejected = (reason) => {
return Promise.reject(reason);
};
export default {deferred, resolved, rejected};
@@ -1,10 +0,0 @@
const promisesAplusTests = require('promises-aplus-tests');
const adapter = require('./promise-adapter');
promisesAplusTests(adapter, {reporter: 'dot'}, function(err) {
if (err) {
console.error(err);
process.exit(1);
} else {
process.exit(0);
}
});
@@ -0,0 +1,11 @@
import promisesAplusTests from 'promises-aplus-tests';
import adapter from './promise-adapter.mjs';
promisesAplusTests(adapter, {reporter: 'dot'}, function (err) {
if (err) {
console.error(err);
process.exit(1);
} else {
process.exit(0);
}
});
@@ -1,392 +0,0 @@
'use strict';
var assert = require('assert');
var adapter = require('./promise-adapter');
var P = global[Zone.__symbol__('Promise')];
var someRejectionReason = {message: 'some rejection reason'};
var anotherReason = {message: 'another rejection reason'};
process.on('unhandledRejection', function(reason, promise) {
console.log('unhandledRejection', reason);
});
describe('mocha promise sanity check', () => {
it('passes with a resolved promise', () => {
return P.resolve(3);
});
it('passes with a rejected then resolved promise', () => {
return P.reject(someRejectionReason).catch(x => 'this should be resolved');
});
var ifPromiseIt = P === Promise ? it : it.skip;
ifPromiseIt('is the native Promise', () => {
assert.equal(P, Promise);
});
});
describe('onFinally', () => {
describe('no callback', () => {
specify('from resolved', (done) => {
adapter.resolved(3)
.then((x) => {
assert.strictEqual(x, 3);
return x;
})
.finally()
.then(
function onFulfilled(x) {
assert.strictEqual(x, 3);
done();
},
function onRejected() {
done(new Error('should not be called'));
});
});
specify('from rejected', (done) => {
adapter.rejected(someRejectionReason)
.catch((e) => {
assert.strictEqual(e, someRejectionReason);
throw e;
})
.finally()
.then(
function onFulfilled() {
done(new Error('should not be called'));
},
function onRejected(reason) {
assert.strictEqual(reason, someRejectionReason);
done();
});
});
});
describe('throws an exception', () => {
specify('from resolved', (done) => {
adapter.resolved(3)
.then((x) => {
assert.strictEqual(x, 3);
return x;
})
.finally(function onFinally() {
assert(arguments.length === 0);
throw someRejectionReason;
})
.then(
function onFulfilled() {
done(new Error('should not be called'));
},
function onRejected(reason) {
assert.strictEqual(reason, someRejectionReason);
done();
});
});
specify('from rejected', (done) => {
adapter.rejected(anotherReason)
.finally(function onFinally() {
assert(arguments.length === 0);
throw someRejectionReason;
})
.then(
function onFulfilled() {
done(new Error('should not be called'));
},
function onRejected(reason) {
assert.strictEqual(reason, someRejectionReason);
done();
});
});
});
describe('returns a non-promise', () => {
specify('from resolved', (done) => {
adapter.resolved(3)
.then((x) => {
assert.strictEqual(x, 3);
return x;
})
.finally(function onFinally() {
assert(arguments.length === 0);
return 4;
})
.then(
function onFulfilled(x) {
assert.strictEqual(x, 3);
done();
},
function onRejected() {
done(new Error('should not be called'));
});
});
specify('from rejected', (done) => {
adapter.rejected(anotherReason)
.catch((e) => {
assert.strictEqual(e, anotherReason);
throw e;
})
.finally(function onFinally() {
assert(arguments.length === 0);
throw someRejectionReason;
})
.then(
function onFulfilled() {
done(new Error('should not be called'));
},
function onRejected(e) {
assert.strictEqual(e, someRejectionReason);
done();
});
});
});
describe('returns a pending-forever promise', () => {
specify('from resolved', (done) => {
var timeout;
adapter.resolved(3)
.then((x) => {
assert.strictEqual(x, 3);
return x;
})
.finally(function onFinally() {
assert(arguments.length === 0);
timeout = setTimeout(done, 0.1e3);
return new P(() => {}); // forever pending
})
.then(
function onFulfilled(x) {
clearTimeout(timeout);
done(new Error('should not be called'));
},
function onRejected() {
clearTimeout(timeout);
done(new Error('should not be called'));
});
});
specify('from rejected', (done) => {
var timeout;
adapter.rejected(someRejectionReason)
.catch((e) => {
assert.strictEqual(e, someRejectionReason);
throw e;
})
.finally(function onFinally() {
assert(arguments.length === 0);
timeout = setTimeout(done, 0.1e3);
return new P(() => {}); // forever pending
})
.then(
function onFulfilled(x) {
clearTimeout(timeout);
done(new Error('should not be called'));
},
function onRejected() {
clearTimeout(timeout);
done(new Error('should not be called'));
});
});
});
describe('returns an immediately-fulfilled promise', () => {
specify('from resolved', (done) => {
adapter.resolved(3)
.then((x) => {
assert.strictEqual(x, 3);
return x;
})
.finally(function onFinally() {
assert(arguments.length === 0);
return adapter.resolved(4);
})
.then(
function onFulfilled(x) {
assert.strictEqual(x, 3);
done();
},
function onRejected() {
done(new Error('should not be called'));
});
});
specify('from rejected', (done) => {
adapter.rejected(someRejectionReason)
.catch((e) => {
assert.strictEqual(e, someRejectionReason);
throw e;
})
.finally(function onFinally() {
assert(arguments.length === 0);
return adapter.resolved(4);
})
.then(
function onFulfilled() {
done(new Error('should not be called'));
},
function onRejected(e) {
assert.strictEqual(e, someRejectionReason);
done();
});
});
});
describe('returns an immediately-rejected promise', () => {
specify('from resolved ', (done) => {
adapter.resolved(3)
.then((x) => {
assert.strictEqual(x, 3);
return x;
})
.finally(function onFinally() {
assert(arguments.length === 0);
return adapter.rejected(4);
})
.then(
function onFulfilled(x) {
done(new Error('should not be called'));
},
function onRejected(e) {
assert.strictEqual(e, 4);
done();
});
});
specify('from rejected', (done) => {
const newReason = {};
adapter.rejected(someRejectionReason)
.catch((e) => {
assert.strictEqual(e, someRejectionReason);
throw e;
})
.finally(function onFinally() {
assert(arguments.length === 0);
return adapter.rejected(newReason);
})
.then(
function onFulfilled(x) {
done(new Error('should not be called'));
},
function onRejected(e) {
assert.strictEqual(e, newReason);
done();
});
});
});
describe('returns a fulfilled-after-a-second promise', () => {
specify('from resolved', (done) => {
var timeout;
adapter.resolved(3)
.then((x) => {
assert.strictEqual(x, 3);
return x;
})
.finally(function onFinally() {
assert(arguments.length === 0);
timeout = setTimeout(done, 1.5e3);
return new P((resolve) => {
setTimeout(() => resolve(4), 1e3);
});
})
.then(
function onFulfilled(x) {
clearTimeout(timeout);
assert.strictEqual(x, 3);
done();
},
function onRejected() {
clearTimeout(timeout);
done(new Error('should not be called'));
});
});
specify('from rejected', (done) => {
var timeout;
adapter.rejected(3)
.catch((e) => {
assert.strictEqual(e, 3);
throw e;
})
.finally(function onFinally() {
assert(arguments.length === 0);
timeout = setTimeout(done, 1.5e3);
return new P((resolve) => {
setTimeout(() => resolve(4), 1e3);
});
})
.then(
function onFulfilled() {
clearTimeout(timeout);
done(new Error('should not be called'));
},
function onRejected(e) {
clearTimeout(timeout);
assert.strictEqual(e, 3);
done();
});
});
});
describe('returns a rejected-after-a-second promise', () => {
specify('from resolved', (done) => {
var timeout;
adapter.resolved(3)
.then((x) => {
assert.strictEqual(x, 3);
return x;
})
.finally(function onFinally() {
assert(arguments.length === 0);
timeout = setTimeout(done, 1.5e3);
return new P((resolve, reject) => {
setTimeout(() => reject(4), 1e3);
});
})
.then(
function onFulfilled() {
clearTimeout(timeout);
done(new Error('should not be called'));
},
function onRejected(e) {
clearTimeout(timeout);
assert.strictEqual(e, 4);
done();
});
});
specify('from rejected', (done) => {
var timeout;
adapter.rejected(someRejectionReason)
.catch((e) => {
assert.strictEqual(e, someRejectionReason);
throw e;
})
.finally(function onFinally() {
assert(arguments.length === 0);
timeout = setTimeout(done, 1.5e3);
return new P((resolve, reject) => {
setTimeout(() => reject(anotherReason), 1e3);
});
})
.then(
function onFulfilled() {
clearTimeout(timeout);
done(new Error('should not be called'));
},
function onRejected(e) {
clearTimeout(timeout);
assert.strictEqual(e, anotherReason);
done();
});
});
});
specify('has the correct property descriptor', () => {
var descriptor = Object.getOwnPropertyDescriptor(Promise.prototype, 'finally');
assert.strictEqual(descriptor.writable, true);
assert.strictEqual(descriptor.configurable, true);
});
});
@@ -0,0 +1,425 @@
'use strict';
import assert from 'assert';
import adapter from './promise-adapter.mjs';
var P = global[Zone.__symbol__('Promise')];
var someRejectionReason = {message: 'some rejection reason'};
var anotherReason = {message: 'another rejection reason'};
process.on('unhandledRejection', function (reason, promise) {
console.log('unhandledRejection', reason);
});
describe('mocha promise sanity check', () => {
it('passes with a resolved promise', () => {
return P.resolve(3);
});
it('passes with a rejected then resolved promise', () => {
return P.reject(someRejectionReason).catch((x) => 'this should be resolved');
});
var ifPromiseIt = P === Promise ? it : it.skip;
ifPromiseIt('is the native Promise', () => {
assert.equal(P, Promise);
});
});
describe('onFinally', () => {
describe('no callback', () => {
specify('from resolved', (done) => {
adapter
.resolved(3)
.then((x) => {
assert.strictEqual(x, 3);
return x;
})
.finally()
.then(
function onFulfilled(x) {
assert.strictEqual(x, 3);
done();
},
function onRejected() {
done(new Error('should not be called'));
}
);
});
specify('from rejected', (done) => {
adapter
.rejected(someRejectionReason)
.catch((e) => {
assert.strictEqual(e, someRejectionReason);
throw e;
})
.finally()
.then(
function onFulfilled() {
done(new Error('should not be called'));
},
function onRejected(reason) {
assert.strictEqual(reason, someRejectionReason);
done();
}
);
});
});
describe('throws an exception', () => {
specify('from resolved', (done) => {
adapter
.resolved(3)
.then((x) => {
assert.strictEqual(x, 3);
return x;
})
.finally(function onFinally() {
assert(arguments.length === 0);
throw someRejectionReason;
})
.then(
function onFulfilled() {
done(new Error('should not be called'));
},
function onRejected(reason) {
assert.strictEqual(reason, someRejectionReason);
done();
}
);
});
specify('from rejected', (done) => {
adapter
.rejected(anotherReason)
.finally(function onFinally() {
assert(arguments.length === 0);
throw someRejectionReason;
})
.then(
function onFulfilled() {
done(new Error('should not be called'));
},
function onRejected(reason) {
assert.strictEqual(reason, someRejectionReason);
done();
}
);
});
});
describe('returns a non-promise', () => {
specify('from resolved', (done) => {
adapter
.resolved(3)
.then((x) => {
assert.strictEqual(x, 3);
return x;
})
.finally(function onFinally() {
assert(arguments.length === 0);
return 4;
})
.then(
function onFulfilled(x) {
assert.strictEqual(x, 3);
done();
},
function onRejected() {
done(new Error('should not be called'));
}
);
});
specify('from rejected', (done) => {
adapter
.rejected(anotherReason)
.catch((e) => {
assert.strictEqual(e, anotherReason);
throw e;
})
.finally(function onFinally() {
assert(arguments.length === 0);
throw someRejectionReason;
})
.then(
function onFulfilled() {
done(new Error('should not be called'));
},
function onRejected(e) {
assert.strictEqual(e, someRejectionReason);
done();
}
);
});
});
describe('returns a pending-forever promise', () => {
specify('from resolved', (done) => {
var timeout;
adapter
.resolved(3)
.then((x) => {
assert.strictEqual(x, 3);
return x;
})
.finally(function onFinally() {
assert(arguments.length === 0);
timeout = setTimeout(done, 0.1e3);
return new P(() => {}); // forever pending
})
.then(
function onFulfilled(x) {
clearTimeout(timeout);
done(new Error('should not be called'));
},
function onRejected() {
clearTimeout(timeout);
done(new Error('should not be called'));
}
);
});
specify('from rejected', (done) => {
var timeout;
adapter
.rejected(someRejectionReason)
.catch((e) => {
assert.strictEqual(e, someRejectionReason);
throw e;
})
.finally(function onFinally() {
assert(arguments.length === 0);
timeout = setTimeout(done, 0.1e3);
return new P(() => {}); // forever pending
})
.then(
function onFulfilled(x) {
clearTimeout(timeout);
done(new Error('should not be called'));
},
function onRejected() {
clearTimeout(timeout);
done(new Error('should not be called'));
}
);
});
});
describe('returns an immediately-fulfilled promise', () => {
specify('from resolved', (done) => {
adapter
.resolved(3)
.then((x) => {
assert.strictEqual(x, 3);
return x;
})
.finally(function onFinally() {
assert(arguments.length === 0);
return adapter.resolved(4);
})
.then(
function onFulfilled(x) {
assert.strictEqual(x, 3);
done();
},
function onRejected() {
done(new Error('should not be called'));
}
);
});
specify('from rejected', (done) => {
adapter
.rejected(someRejectionReason)
.catch((e) => {
assert.strictEqual(e, someRejectionReason);
throw e;
})
.finally(function onFinally() {
assert(arguments.length === 0);
return adapter.resolved(4);
})
.then(
function onFulfilled() {
done(new Error('should not be called'));
},
function onRejected(e) {
assert.strictEqual(e, someRejectionReason);
done();
}
);
});
});
describe('returns an immediately-rejected promise', () => {
specify('from resolved ', (done) => {
adapter
.resolved(3)
.then((x) => {
assert.strictEqual(x, 3);
return x;
})
.finally(function onFinally() {
assert(arguments.length === 0);
return adapter.rejected(4);
})
.then(
function onFulfilled(x) {
done(new Error('should not be called'));
},
function onRejected(e) {
assert.strictEqual(e, 4);
done();
}
);
});
specify('from rejected', (done) => {
const newReason = {};
adapter
.rejected(someRejectionReason)
.catch((e) => {
assert.strictEqual(e, someRejectionReason);
throw e;
})
.finally(function onFinally() {
assert(arguments.length === 0);
return adapter.rejected(newReason);
})
.then(
function onFulfilled(x) {
done(new Error('should not be called'));
},
function onRejected(e) {
assert.strictEqual(e, newReason);
done();
}
);
});
});
describe('returns a fulfilled-after-a-second promise', () => {
specify('from resolved', (done) => {
var timeout;
adapter
.resolved(3)
.then((x) => {
assert.strictEqual(x, 3);
return x;
})
.finally(function onFinally() {
assert(arguments.length === 0);
timeout = setTimeout(done, 1.5e3);
return new P((resolve) => {
setTimeout(() => resolve(4), 1e3);
});
})
.then(
function onFulfilled(x) {
clearTimeout(timeout);
assert.strictEqual(x, 3);
done();
},
function onRejected() {
clearTimeout(timeout);
done(new Error('should not be called'));
}
);
});
specify('from rejected', (done) => {
var timeout;
adapter
.rejected(3)
.catch((e) => {
assert.strictEqual(e, 3);
throw e;
})
.finally(function onFinally() {
assert(arguments.length === 0);
timeout = setTimeout(done, 1.5e3);
return new P((resolve) => {
setTimeout(() => resolve(4), 1e3);
});
})
.then(
function onFulfilled() {
clearTimeout(timeout);
done(new Error('should not be called'));
},
function onRejected(e) {
clearTimeout(timeout);
assert.strictEqual(e, 3);
done();
}
);
});
});
describe('returns a rejected-after-a-second promise', () => {
specify('from resolved', (done) => {
var timeout;
adapter
.resolved(3)
.then((x) => {
assert.strictEqual(x, 3);
return x;
})
.finally(function onFinally() {
assert(arguments.length === 0);
timeout = setTimeout(done, 1.5e3);
return new P((resolve, reject) => {
setTimeout(() => reject(4), 1e3);
});
})
.then(
function onFulfilled() {
clearTimeout(timeout);
done(new Error('should not be called'));
},
function onRejected(e) {
clearTimeout(timeout);
assert.strictEqual(e, 4);
done();
}
);
});
specify('from rejected', (done) => {
var timeout;
adapter
.rejected(someRejectionReason)
.catch((e) => {
assert.strictEqual(e, someRejectionReason);
throw e;
})
.finally(function onFinally() {
assert(arguments.length === 0);
timeout = setTimeout(done, 1.5e3);
return new P((resolve, reject) => {
setTimeout(() => reject(anotherReason), 1e3);
});
})
.then(
function onFulfilled() {
clearTimeout(timeout);
done(new Error('should not be called'));
},
function onRejected(e) {
clearTimeout(timeout);
assert.strictEqual(e, anotherReason);
done();
}
);
});
});
specify('has the correct property descriptor', () => {
var descriptor = Object.getOwnPropertyDescriptor(Promise.prototype, 'finally');
assert.strictEqual(descriptor.writable, true);
assert.strictEqual(descriptor.configurable, true);
});
});
+5 -14
View File
@@ -4,24 +4,15 @@
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"experimentalDecorators": true,
"module": "commonjs",
"moduleResolution": "node",
"outDir": "./build",
"rootDir": ".",
"target": "ES2015",
"target": "es2020",
"module": "Node16",
"moduleResolution": "node",
"noEmitOnError": false,
"stripInternal": false,
"strict": true,
"lib": [
"es5",
"dom",
"es2015.collection",
"es2015.iterable",
"es2015.promise",
],
"lib": ["es5", "dom", "es2015.collection", "es2015.iterable", "es2015.promise"]
},
"files": [
"./type.test.ts",
"./node_modules/zone.js/zone.d.ts"
],
"files": ["./type.test.ts", "./node_modules/zone.js/zone.d.ts"]
}
+2 -1
View File
@@ -1,5 +1,6 @@
import 'zone.js/bundles/zone.umd';
import * as domino from 'domino';
require('zone.js/bundles/zone.umd');
// Zone public API should be included
Zone.current.fork({name: 'testZone'}).run(() => {});
@@ -0,0 +1,58 @@
load("//tools:defaults.bzl", "jasmine_node_test", "ts_library")
ts_library(
name = "patched_init",
testonly = True,
srcs = [
"enable-clock-patch.ts",
"patched.init.ts",
],
deps = [
"//packages/zone.js/test:node_entry_point",
],
)
ts_library(
name = "test_patched_lib",
testonly = True,
srcs = [
"fake-async-patched-clock.spec.ts",
],
deps = [
"//packages/zone.js/lib:zone_d_ts",
],
)
ts_library(
name = "unpatched_init",
testonly = True,
srcs = [
"unpatched.init.ts",
],
deps = [
"//packages/zone.js/test:node_entry_point",
],
)
ts_library(
name = "test_unpatched_lib",
testonly = True,
srcs = [
"fake-async-unpatched-clock.spec.ts",
],
deps = [
"//packages/zone.js/lib:zone_d_ts",
],
)
jasmine_node_test(
name = "test_patched",
bootstrap = [":patched_init"],
deps = [":test_patched_lib"],
)
jasmine_node_test(
name = "test_unpatched",
bootstrap = [":unpatched_init"],
deps = [":test_unpatched_lib"],
)
@@ -5,4 +5,5 @@
* 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
*/
(global as any)[(global as any).Zone.__symbol__('fakeAsyncAutoFakeAsyncWhenClockPatched')] = false;
(global as any)['__zone_symbol_test__fakeAsyncAutoFakeAsyncWhenClockPatched'] = true;
@@ -0,0 +1,67 @@
/**
* @license
* Copyright Google LLC 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
*/
describe('fake async unpatched clock tests', () => {
let spy: any;
beforeEach(() => {
spy = jasmine.createSpy('timer');
jasmine.clock().install();
});
afterEach(() => {
jasmine.clock().uninstall();
});
it('should check date type correctly', () => {
const d: any = new Date();
expect(d instanceof Date).toBe(true);
});
it('should get date diff correctly', () => {
const start = Date.now();
jasmine.clock().tick(100);
const end = Date.now();
expect(end - start).toBe(100);
});
it('should tick correctly', () => {
const start = Date.now();
jasmine.clock().tick(100);
const end = Date.now();
expect(end - start).toBe(100);
});
it('should mock date correctly', () => {
const baseTime = new Date(2013, 9, 23);
jasmine.clock().mockDate(baseTime);
const start = Date.now();
expect(start).toBe(baseTime.getTime());
jasmine.clock().tick(100);
const end = Date.now();
expect(end - start).toBe(100);
expect(end).toBe(baseTime.getTime() + 100);
});
it('should handle new Date correctly', () => {
const baseTime = new Date(2013, 9, 23);
jasmine.clock().mockDate(baseTime);
const start = new Date();
expect(start.getTime()).toBe(baseTime.getTime());
jasmine.clock().tick(100);
const end = new Date();
expect(end.getTime() - start.getTime()).toBe(100);
expect(end.getTime()).toBe(baseTime.getTime() + 100);
});
it('should handle setTimeout correctly', () => {
setTimeout(spy, 100);
expect(spy).not.toHaveBeenCalled();
jasmine.clock().tick(100);
expect(spy).toHaveBeenCalled();
});
})
@@ -0,0 +1,115 @@
/**
* @license
* Copyright Google LLC 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
*/
// Note: We uninstall the clock before starting the tests. This is necessary because
// ZoneJS is loaded after Jasmine has captured the global timing functions. Jasmine
// now doesn't allow `clock().install` because Zone modified e.g. `setTimeout`.
// Uninstalling results in Jasmine resetting to the original NodeJS globals.
// This is fine for this test as it doesn't rely on e.g. patched `setTimeout`.
// https://github.com/jasmine/jasmine/blob/169a2a8ad23a7e5cb12be0a2df02ea4337b9811a/src/core/Clock.js#L17.
jasmine.clock().uninstall();
describe('fake async unpatched clock tests', () => {
const fakeAsync = (Zone as any)[Zone.__symbol__('fakeAsyncTest')].fakeAsync;
let spy: any;
beforeEach(() => {
spy = jasmine.createSpy('timer');
jasmine.clock().install();
});
afterEach(() => {
jasmine.clock().uninstall();
});
it('should check date type correctly', fakeAsync(() => {
const d: any = new Date();
expect(d instanceof Date).toBe(true);
}));
it('should check date type correctly without fakeAsync', () => {
const d: any = new Date();
expect(d instanceof Date).toBe(true);
});
it('should tick correctly', fakeAsync(() => {
jasmine.clock().mockDate();
const start = Date.now();
jasmine.clock().tick(100);
const end = Date.now();
expect(end - start).toBe(100);
}));
it('should tick correctly without fakeAsync', () => {
jasmine.clock().mockDate();
const start = Date.now();
jasmine.clock().tick(100);
const end = Date.now();
expect(end - start).toBe(100);
});
it('should mock date correctly', fakeAsync(() => {
const baseTime = new Date(2013, 9, 23);
jasmine.clock().mockDate(baseTime);
const start = Date.now();
expect(start).toBe(baseTime.getTime());
jasmine.clock().tick(100);
const end = Date.now();
expect(end - start).toBe(100);
expect(end).toBe(baseTime.getTime() + 100);
expect(new Date().getFullYear()).toEqual(2013);
}));
it('should mock date correctly without fakeAsync', () => {
const baseTime = new Date(2013, 9, 23);
jasmine.clock().mockDate(baseTime);
const start = Date.now();
expect(start).toBe(baseTime.getTime());
jasmine.clock().tick(100);
const end = Date.now();
expect(end - start).toBe(100);
expect(end).toBe(baseTime.getTime() + 100);
expect(new Date().getFullYear()).toEqual(2013);
});
it('should handle new Date correctly', fakeAsync(() => {
const baseTime = new Date(2013, 9, 23);
jasmine.clock().mockDate(baseTime);
const start = new Date();
expect(start.getTime()).toBe(baseTime.getTime());
jasmine.clock().tick(100);
const end = new Date();
expect(end.getTime() - start.getTime()).toBe(100);
expect(end.getTime()).toBe(baseTime.getTime() + 100);
}));
it('should handle new Date correctly without fakeAsync', () => {
const baseTime = new Date(2013, 9, 23);
jasmine.clock().mockDate(baseTime);
const start = new Date();
expect(start.getTime()).toBe(baseTime.getTime());
jasmine.clock().tick(100);
const end = new Date();
expect(end.getTime() - start.getTime()).toBe(100);
expect(end.getTime()).toBe(baseTime.getTime() + 100);
});
it('should handle setTimeout correctly', fakeAsync(() => {
setTimeout(spy, 100);
expect(spy).not.toHaveBeenCalled();
jasmine.clock().tick(100);
expect(spy).toHaveBeenCalled();
}));
it('should handle setTimeout correctly without fakeAsync', () => {
setTimeout(spy, 100);
expect(spy).not.toHaveBeenCalled();
jasmine.clock().tick(100);
expect(spy).toHaveBeenCalled();
});
})
@@ -0,0 +1,10 @@
/**
* @license
* Copyright Google LLC 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 './enable-clock-patch';
import '../../node_entry_point.init';
@@ -0,0 +1,9 @@
/**
* @license
* Copyright Google LLC 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 '../../node_entry_point.init';
@@ -25,13 +25,6 @@ function emptyRun() {
(supportNode as any).message = 'support node';
function supportClock() {
const _global: any = typeof window === 'undefined' ? global : window;
return typeof jasmine.clock === 'function' &&
_global[zoneSymbol('fakeAsyncAutoFakeAsyncWhenClockPatched')];
}
(supportClock as any).message = 'support patch clock';
describe('FakeAsyncTestZoneSpec', () => {
let FakeAsyncTestZoneSpec = (Zone as any)['FakeAsyncTestZoneSpec'];
@@ -1067,173 +1060,7 @@ describe('FakeAsyncTestZoneSpec', () => {
});
});
describe(
'fakeAsyncTest should work without patch jasmine.clock',
ifEnvSupports(
() => {
return !supportClock() && supportNode();
},
() => {
const fakeAsync = (Zone as any)[Zone.__symbol__('fakeAsyncTest')].fakeAsync;
let spy: any;
beforeEach(() => {
spy = jasmine.createSpy('timer');
jasmine.clock().install();
});
afterEach(() => {
jasmine.clock().uninstall();
});
it('should check date type correctly', fakeAsync(() => {
const d: any = new Date();
expect(d instanceof Date).toBe(true);
}));
it('should check date type correctly without fakeAsync', () => {
const d: any = new Date();
expect(d instanceof Date).toBe(true);
});
it('should tick correctly', fakeAsync(() => {
jasmine.clock().mockDate();
const start = Date.now();
jasmine.clock().tick(100);
const end = Date.now();
expect(end - start).toBe(100);
}));
it('should tick correctly without fakeAsync', () => {
jasmine.clock().mockDate();
const start = Date.now();
jasmine.clock().tick(100);
const end = Date.now();
expect(end - start).toBe(100);
});
it('should mock date correctly', fakeAsync(() => {
const baseTime = new Date(2013, 9, 23);
jasmine.clock().mockDate(baseTime);
const start = Date.now();
expect(start).toBe(baseTime.getTime());
jasmine.clock().tick(100);
const end = Date.now();
expect(end - start).toBe(100);
expect(end).toBe(baseTime.getTime() + 100);
expect(new Date().getFullYear()).toEqual(2013);
}));
it('should mock date correctly without fakeAsync', () => {
const baseTime = new Date(2013, 9, 23);
jasmine.clock().mockDate(baseTime);
const start = Date.now();
expect(start).toBe(baseTime.getTime());
jasmine.clock().tick(100);
const end = Date.now();
expect(end - start).toBe(100);
expect(end).toBe(baseTime.getTime() + 100);
expect(new Date().getFullYear()).toEqual(2013);
});
it('should handle new Date correctly', fakeAsync(() => {
const baseTime = new Date(2013, 9, 23);
jasmine.clock().mockDate(baseTime);
const start = new Date();
expect(start.getTime()).toBe(baseTime.getTime());
jasmine.clock().tick(100);
const end = new Date();
expect(end.getTime() - start.getTime()).toBe(100);
expect(end.getTime()).toBe(baseTime.getTime() + 100);
}));
it('should handle new Date correctly without fakeAsync', () => {
const baseTime = new Date(2013, 9, 23);
jasmine.clock().mockDate(baseTime);
const start = new Date();
expect(start.getTime()).toBe(baseTime.getTime());
jasmine.clock().tick(100);
const end = new Date();
expect(end.getTime() - start.getTime()).toBe(100);
expect(end.getTime()).toBe(baseTime.getTime() + 100);
});
it('should handle setTimeout correctly', fakeAsync(() => {
setTimeout(spy, 100);
expect(spy).not.toHaveBeenCalled();
jasmine.clock().tick(100);
expect(spy).toHaveBeenCalled();
}));
it('should handle setTimeout correctly without fakeAsync', () => {
setTimeout(spy, 100);
expect(spy).not.toHaveBeenCalled();
jasmine.clock().tick(100);
expect(spy).toHaveBeenCalled();
});
},
emptyRun));
describe('fakeAsyncTest should patch jasmine.clock', ifEnvSupports(supportClock, () => {
let spy: any;
beforeEach(() => {
spy = jasmine.createSpy('timer');
jasmine.clock().install();
});
afterEach(() => {
jasmine.clock().uninstall();
});
it('should check date type correctly', () => {
const d: any = new Date();
expect(d instanceof Date).toBe(true);
});
it('should get date diff correctly', () => {
const start = Date.now();
jasmine.clock().tick(100);
const end = Date.now();
expect(end - start).toBe(100);
});
it('should tick correctly', () => {
const start = Date.now();
jasmine.clock().tick(100);
const end = Date.now();
expect(end - start).toBe(100);
});
it('should mock date correctly', () => {
const baseTime = new Date(2013, 9, 23);
jasmine.clock().mockDate(baseTime);
const start = Date.now();
expect(start).toBe(baseTime.getTime());
jasmine.clock().tick(100);
const end = Date.now();
expect(end - start).toBe(100);
expect(end).toBe(baseTime.getTime() + 100);
});
it('should handle new Date correctly', () => {
const baseTime = new Date(2013, 9, 23);
jasmine.clock().mockDate(baseTime);
const start = new Date();
expect(start.getTime()).toBe(baseTime.getTime());
jasmine.clock().tick(100);
const end = new Date();
expect(end.getTime() - start.getTime()).toBe(100);
expect(end.getTime()).toBe(baseTime.getTime() + 100);
});
it('should handle setTimeout correctly', () => {
setTimeout(spy, 100);
expect(spy).not.toHaveBeenCalled();
jasmine.clock().tick(100);
expect(spy).toHaveBeenCalled();
});
}, emptyRun));
describe('fakeAsyncTest should patch rxjs scheduler', ifEnvSupports(supportClock, () => {
describe('fakeAsyncTest should patch rxjs scheduler', ifEnvSupports(() => isNode, () => {
let FakeAsyncTestZoneSpec = (Zone as any)['FakeAsyncTestZoneSpec'];
let testZoneSpec: any;
let fakeAsyncTestZone: Zone;
+5 -5
View File
@@ -1,7 +1,9 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es2015",
"module": "esnext",
"target": "es2020",
"moduleResolution": "node",
"esModuleInterop": true,
"outDir": "build",
"inlineSourceMap": true,
"inlineSources": true,
@@ -18,9 +20,7 @@
"es2015.symbol",
"es2015.symbol.wellknown"
],
"typeRoots": [
"node_modules/@types"
],
"typeRoots": ["node_modules/@types"]
},
"exclude": [
"node_modules",
-5
View File
@@ -3379,11 +3379,6 @@ type-fest@^0.21.3:
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37"
integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==
typescript@~4.9.3:
version "4.9.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.3.tgz#3aea307c1746b8c384435d8ac36b8a2e580d85db"
integrity sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==
unbox-primitive@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e"
+2 -2
View File
@@ -429,12 +429,12 @@ def npm_package_bin(args = [], **kwargs):
# TODO(devversion): Jasmine Node tests are only bundled using `spec_bundle`
# because `async/await` syntax needs to be downleveled for ZoneJS. In the
# future this can be removed when ZoneJS can work with native async/await in NodeJS.
def zone_compatible_jasmine_node_test(name, external = [], deps = [], bootstrap = [], **kwargs):
def zone_compatible_jasmine_node_test(name, external = [], srcs = [], deps = [], bootstrap = [], **kwargs):
spec_bundle(
name = "%s_bundle" % name,
# Specs from this attribute are filtered and will be executed. We
# add bootstrap here for discovery of the module mappings aspect.
deps = deps + bootstrap,
deps = srcs + deps + bootstrap,
bootstrap = bootstrap,
external = external + ["domino", "typescript"],
platform = "node",