11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ciconst common = require('../common'); 31cb0ef41Sopenharmony_ciconst assert = require('assert'); 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci// Run all tests in parallel and check their outcome at the end. 61cb0ef41Sopenharmony_ciconst promises = []; 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci// Thenable object without `catch` method, 91cb0ef41Sopenharmony_ci// shouldn't be considered as a valid Thenable 101cb0ef41Sopenharmony_ciconst invalidThenable = { 111cb0ef41Sopenharmony_ci then: (fulfill, reject) => { 121cb0ef41Sopenharmony_ci fulfill(); 131cb0ef41Sopenharmony_ci }, 141cb0ef41Sopenharmony_ci}; 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_ci// Function that returns a Thenable function, 171cb0ef41Sopenharmony_ci// a function with `catch` and `then` methods attached, 181cb0ef41Sopenharmony_ci// shouldn't be considered as a valid Thenable. 191cb0ef41Sopenharmony_ciconst invalidThenableFunc = () => { 201cb0ef41Sopenharmony_ci function f() {} 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_ci f.then = (fulfill, reject) => { 231cb0ef41Sopenharmony_ci fulfill(); 241cb0ef41Sopenharmony_ci }; 251cb0ef41Sopenharmony_ci f.catch = () => {}; 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_ci return f; 281cb0ef41Sopenharmony_ci}; 291cb0ef41Sopenharmony_ci 301cb0ef41Sopenharmony_ci// Test assert.rejects() and assert.doesNotReject() by checking their 311cb0ef41Sopenharmony_ci// expected output and by verifying that they do not work sync 321cb0ef41Sopenharmony_ci 331cb0ef41Sopenharmony_ci// Check `assert.rejects`. 341cb0ef41Sopenharmony_ci{ 351cb0ef41Sopenharmony_ci const rejectingFn = async () => assert.fail(); 361cb0ef41Sopenharmony_ci const errObj = { 371cb0ef41Sopenharmony_ci code: 'ERR_ASSERTION', 381cb0ef41Sopenharmony_ci name: 'AssertionError', 391cb0ef41Sopenharmony_ci message: 'Failed' 401cb0ef41Sopenharmony_ci }; 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_ci // `assert.rejects` accepts a function or a promise 431cb0ef41Sopenharmony_ci // or a thenable as first argument. 441cb0ef41Sopenharmony_ci promises.push(assert.rejects(rejectingFn, errObj)); 451cb0ef41Sopenharmony_ci promises.push(assert.rejects(rejectingFn(), errObj)); 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ci const validRejectingThenable = { 481cb0ef41Sopenharmony_ci then: (fulfill, reject) => { 491cb0ef41Sopenharmony_ci reject({ code: 'FAIL' }); 501cb0ef41Sopenharmony_ci }, 511cb0ef41Sopenharmony_ci catch: () => {} 521cb0ef41Sopenharmony_ci }; 531cb0ef41Sopenharmony_ci promises.push(assert.rejects(validRejectingThenable, { code: 'FAIL' })); 541cb0ef41Sopenharmony_ci 551cb0ef41Sopenharmony_ci // `assert.rejects` should not accept thenables that 561cb0ef41Sopenharmony_ci // use a function as `obj` and that have no `catch` handler. 571cb0ef41Sopenharmony_ci promises.push(assert.rejects( 581cb0ef41Sopenharmony_ci assert.rejects(invalidThenable, {}), 591cb0ef41Sopenharmony_ci { 601cb0ef41Sopenharmony_ci code: 'ERR_INVALID_ARG_TYPE' 611cb0ef41Sopenharmony_ci }) 621cb0ef41Sopenharmony_ci ); 631cb0ef41Sopenharmony_ci promises.push(assert.rejects( 641cb0ef41Sopenharmony_ci assert.rejects(invalidThenableFunc, {}), 651cb0ef41Sopenharmony_ci { 661cb0ef41Sopenharmony_ci code: 'ERR_INVALID_RETURN_VALUE' 671cb0ef41Sopenharmony_ci }) 681cb0ef41Sopenharmony_ci ); 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_ci const err = new Error('foobar'); 711cb0ef41Sopenharmony_ci const validate = () => { return 'baz'; }; 721cb0ef41Sopenharmony_ci promises.push(assert.rejects( 731cb0ef41Sopenharmony_ci () => assert.rejects(Promise.reject(err), validate), 741cb0ef41Sopenharmony_ci { 751cb0ef41Sopenharmony_ci message: 'The "validate" validation function is expected to ' + 761cb0ef41Sopenharmony_ci "return \"true\". Received 'baz'\n\nCaught error:\n\n" + 771cb0ef41Sopenharmony_ci 'Error: foobar', 781cb0ef41Sopenharmony_ci code: 'ERR_ASSERTION', 791cb0ef41Sopenharmony_ci actual: err, 801cb0ef41Sopenharmony_ci expected: validate, 811cb0ef41Sopenharmony_ci name: 'AssertionError', 821cb0ef41Sopenharmony_ci operator: 'rejects', 831cb0ef41Sopenharmony_ci } 841cb0ef41Sopenharmony_ci )); 851cb0ef41Sopenharmony_ci} 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ci{ 881cb0ef41Sopenharmony_ci const handler = (err) => { 891cb0ef41Sopenharmony_ci assert(err instanceof assert.AssertionError, 901cb0ef41Sopenharmony_ci `${err.name} is not instance of AssertionError`); 911cb0ef41Sopenharmony_ci assert.strictEqual(err.code, 'ERR_ASSERTION'); 921cb0ef41Sopenharmony_ci assert.strictEqual(err.message, 931cb0ef41Sopenharmony_ci 'Missing expected rejection (mustNotCall).'); 941cb0ef41Sopenharmony_ci assert.strictEqual(err.operator, 'rejects'); 951cb0ef41Sopenharmony_ci assert.ok(!err.stack.includes('at Function.rejects')); 961cb0ef41Sopenharmony_ci return true; 971cb0ef41Sopenharmony_ci }; 981cb0ef41Sopenharmony_ci 991cb0ef41Sopenharmony_ci let promise = assert.rejects(async () => {}, common.mustNotCall()); 1001cb0ef41Sopenharmony_ci promises.push(assert.rejects(promise, common.mustCall(handler))); 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_ci promise = assert.rejects(() => {}, common.mustNotCall()); 1031cb0ef41Sopenharmony_ci promises.push(assert.rejects(promise, { 1041cb0ef41Sopenharmony_ci name: 'TypeError', 1051cb0ef41Sopenharmony_ci code: 'ERR_INVALID_RETURN_VALUE', 1061cb0ef41Sopenharmony_ci // FIXME(JakobJingleheimer): This should match on key words, like /Promise/ and /undefined/. 1071cb0ef41Sopenharmony_ci message: 'Expected instance of Promise to be returned ' + 1081cb0ef41Sopenharmony_ci 'from the "promiseFn" function but got undefined.' 1091cb0ef41Sopenharmony_ci })); 1101cb0ef41Sopenharmony_ci 1111cb0ef41Sopenharmony_ci promise = assert.rejects(Promise.resolve(), common.mustNotCall()); 1121cb0ef41Sopenharmony_ci promises.push(assert.rejects(promise, common.mustCall(handler))); 1131cb0ef41Sopenharmony_ci} 1141cb0ef41Sopenharmony_ci 1151cb0ef41Sopenharmony_ci{ 1161cb0ef41Sopenharmony_ci const THROWN_ERROR = new Error(); 1171cb0ef41Sopenharmony_ci 1181cb0ef41Sopenharmony_ci promises.push(assert.rejects(() => { 1191cb0ef41Sopenharmony_ci throw THROWN_ERROR; 1201cb0ef41Sopenharmony_ci }, {}).catch(common.mustCall((err) => { 1211cb0ef41Sopenharmony_ci assert.strictEqual(err, THROWN_ERROR); 1221cb0ef41Sopenharmony_ci }))); 1231cb0ef41Sopenharmony_ci} 1241cb0ef41Sopenharmony_ci 1251cb0ef41Sopenharmony_cipromises.push(assert.rejects( 1261cb0ef41Sopenharmony_ci assert.rejects('fail', {}), 1271cb0ef41Sopenharmony_ci { 1281cb0ef41Sopenharmony_ci code: 'ERR_INVALID_ARG_TYPE', 1291cb0ef41Sopenharmony_ci message: 'The "promiseFn" argument must be of type function or an ' + 1301cb0ef41Sopenharmony_ci "instance of Promise. Received type string ('fail')" 1311cb0ef41Sopenharmony_ci } 1321cb0ef41Sopenharmony_ci)); 1331cb0ef41Sopenharmony_ci 1341cb0ef41Sopenharmony_ci{ 1351cb0ef41Sopenharmony_ci const handler = (generated, actual, err) => { 1361cb0ef41Sopenharmony_ci assert.strictEqual(err.generatedMessage, generated); 1371cb0ef41Sopenharmony_ci assert.strictEqual(err.code, 'ERR_ASSERTION'); 1381cb0ef41Sopenharmony_ci assert.strictEqual(err.actual, actual); 1391cb0ef41Sopenharmony_ci assert.strictEqual(err.operator, 'rejects'); 1401cb0ef41Sopenharmony_ci assert.match(err.stack, /rejects/); 1411cb0ef41Sopenharmony_ci return true; 1421cb0ef41Sopenharmony_ci }; 1431cb0ef41Sopenharmony_ci const err = new Error(); 1441cb0ef41Sopenharmony_ci promises.push(assert.rejects( 1451cb0ef41Sopenharmony_ci assert.rejects(Promise.reject(null), { code: 'FOO' }), 1461cb0ef41Sopenharmony_ci handler.bind(null, true, null) 1471cb0ef41Sopenharmony_ci )); 1481cb0ef41Sopenharmony_ci promises.push(assert.rejects( 1491cb0ef41Sopenharmony_ci assert.rejects(Promise.reject(5), { code: 'FOO' }, 'AAAAA'), 1501cb0ef41Sopenharmony_ci handler.bind(null, false, 5) 1511cb0ef41Sopenharmony_ci )); 1521cb0ef41Sopenharmony_ci promises.push(assert.rejects( 1531cb0ef41Sopenharmony_ci assert.rejects(Promise.reject(err), { code: 'FOO' }, 'AAAAA'), 1541cb0ef41Sopenharmony_ci handler.bind(null, false, err) 1551cb0ef41Sopenharmony_ci )); 1561cb0ef41Sopenharmony_ci} 1571cb0ef41Sopenharmony_ci 1581cb0ef41Sopenharmony_ci// Check `assert.doesNotReject`. 1591cb0ef41Sopenharmony_ci{ 1601cb0ef41Sopenharmony_ci // `assert.doesNotReject` accepts a function or a promise 1611cb0ef41Sopenharmony_ci // or a thenable as first argument. 1621cb0ef41Sopenharmony_ci /* eslint-disable no-restricted-syntax */ 1631cb0ef41Sopenharmony_ci let promise = assert.doesNotReject(() => new Map(), common.mustNotCall()); 1641cb0ef41Sopenharmony_ci promises.push(assert.rejects(promise, { 1651cb0ef41Sopenharmony_ci message: 'Expected instance of Promise to be returned ' + 1661cb0ef41Sopenharmony_ci 'from the "promiseFn" function but got an instance of Map.', 1671cb0ef41Sopenharmony_ci code: 'ERR_INVALID_RETURN_VALUE', 1681cb0ef41Sopenharmony_ci name: 'TypeError' 1691cb0ef41Sopenharmony_ci })); 1701cb0ef41Sopenharmony_ci promises.push(assert.doesNotReject(async () => {})); 1711cb0ef41Sopenharmony_ci promises.push(assert.doesNotReject(Promise.resolve())); 1721cb0ef41Sopenharmony_ci 1731cb0ef41Sopenharmony_ci // `assert.doesNotReject` should not accept thenables that 1741cb0ef41Sopenharmony_ci // use a function as `obj` and that have no `catch` handler. 1751cb0ef41Sopenharmony_ci const validFulfillingThenable = { 1761cb0ef41Sopenharmony_ci then: (fulfill, reject) => { 1771cb0ef41Sopenharmony_ci fulfill(); 1781cb0ef41Sopenharmony_ci }, 1791cb0ef41Sopenharmony_ci catch: () => {} 1801cb0ef41Sopenharmony_ci }; 1811cb0ef41Sopenharmony_ci promises.push(assert.doesNotReject(validFulfillingThenable)); 1821cb0ef41Sopenharmony_ci promises.push(assert.rejects( 1831cb0ef41Sopenharmony_ci assert.doesNotReject(invalidThenable), 1841cb0ef41Sopenharmony_ci { 1851cb0ef41Sopenharmony_ci code: 'ERR_INVALID_ARG_TYPE' 1861cb0ef41Sopenharmony_ci }) 1871cb0ef41Sopenharmony_ci ); 1881cb0ef41Sopenharmony_ci promises.push(assert.rejects( 1891cb0ef41Sopenharmony_ci assert.doesNotReject(invalidThenableFunc), 1901cb0ef41Sopenharmony_ci { 1911cb0ef41Sopenharmony_ci code: 'ERR_INVALID_RETURN_VALUE' 1921cb0ef41Sopenharmony_ci }) 1931cb0ef41Sopenharmony_ci ); 1941cb0ef41Sopenharmony_ci 1951cb0ef41Sopenharmony_ci const handler1 = (err) => { 1961cb0ef41Sopenharmony_ci assert(err instanceof assert.AssertionError, 1971cb0ef41Sopenharmony_ci `${err.name} is not instance of AssertionError`); 1981cb0ef41Sopenharmony_ci assert.strictEqual(err.code, 'ERR_ASSERTION'); 1991cb0ef41Sopenharmony_ci assert.strictEqual(err.message, 'Failed'); 2001cb0ef41Sopenharmony_ci return true; 2011cb0ef41Sopenharmony_ci }; 2021cb0ef41Sopenharmony_ci const handler2 = (err) => { 2031cb0ef41Sopenharmony_ci assert(err instanceof assert.AssertionError, 2041cb0ef41Sopenharmony_ci `${err.name} is not instance of AssertionError`); 2051cb0ef41Sopenharmony_ci assert.strictEqual(err.code, 'ERR_ASSERTION'); 2061cb0ef41Sopenharmony_ci assert.strictEqual(err.message, 2071cb0ef41Sopenharmony_ci 'Got unwanted rejection.\nActual message: "Failed"'); 2081cb0ef41Sopenharmony_ci assert.strictEqual(err.operator, 'doesNotReject'); 2091cb0ef41Sopenharmony_ci assert.ok(err.stack); 2101cb0ef41Sopenharmony_ci assert.ok(!err.stack.includes('at Function.doesNotReject')); 2111cb0ef41Sopenharmony_ci return true; 2121cb0ef41Sopenharmony_ci }; 2131cb0ef41Sopenharmony_ci 2141cb0ef41Sopenharmony_ci const rejectingFn = async () => assert.fail(); 2151cb0ef41Sopenharmony_ci 2161cb0ef41Sopenharmony_ci promise = assert.doesNotReject(rejectingFn, common.mustCall(handler1)); 2171cb0ef41Sopenharmony_ci promises.push(assert.rejects(promise, common.mustCall(handler2))); 2181cb0ef41Sopenharmony_ci 2191cb0ef41Sopenharmony_ci promise = assert.doesNotReject(rejectingFn(), common.mustCall(handler1)); 2201cb0ef41Sopenharmony_ci promises.push(assert.rejects(promise, common.mustCall(handler2))); 2211cb0ef41Sopenharmony_ci 2221cb0ef41Sopenharmony_ci promise = assert.doesNotReject(() => assert.fail(), common.mustNotCall()); 2231cb0ef41Sopenharmony_ci promises.push(assert.rejects(promise, common.mustCall(handler1))); 2241cb0ef41Sopenharmony_ci 2251cb0ef41Sopenharmony_ci promises.push(assert.rejects( 2261cb0ef41Sopenharmony_ci assert.doesNotReject(123), 2271cb0ef41Sopenharmony_ci { 2281cb0ef41Sopenharmony_ci code: 'ERR_INVALID_ARG_TYPE', 2291cb0ef41Sopenharmony_ci message: 'The "promiseFn" argument must be of type ' + 2301cb0ef41Sopenharmony_ci 'function or an instance of Promise. Received type number (123)' 2311cb0ef41Sopenharmony_ci } 2321cb0ef41Sopenharmony_ci )); 2331cb0ef41Sopenharmony_ci /* eslint-enable no-restricted-syntax */ 2341cb0ef41Sopenharmony_ci} 2351cb0ef41Sopenharmony_ci 2361cb0ef41Sopenharmony_ci// Make sure all async code gets properly executed. 2371cb0ef41Sopenharmony_ciPromise.all(promises).then(common.mustCall()); 238