UNPKG

react-native-web-headroom

Version:
205 lines (153 loc) 7.29 kB
'use strict'; /* global Symbol */ var assertArray = function (t, value, length, assertType) { t.ok(Array.isArray(value), 'value is an array'); t.equal(value.length, length, 'length is ' + length); if (typeof assertType === 'function') { for (var i = 0; i < value.length; i += 1) { assertType(value[i]); } } }; module.exports = function (promiseFinally, t) { if (typeof Promise !== 'function') { return t.skip('No global Promise detected'); } t.test('onFinally arguments', function (st) { st.plan(2); promiseFinally(Promise.resolve(42), function () { st.equal(arguments.length, 0, 'resolved promise passes no arguments to onFinally'); })['catch'](st.fail); promiseFinally(Promise.reject(NaN), function () { st.equal(arguments.length, 0, 'rejected promise passes no arguments to onFinally'); }).then(st.fail); }); t.test('onFinally fulfillment', function (st) { st.plan(6); promiseFinally(Promise.resolve(42), function () { return Promise.resolve(Infinity); }).then(function (x) { st.equal(x, 42, 'resolved promise onFinally resolution does not affect promise resolution value'); })['catch'](st.fail); promiseFinally(Promise.resolve(42), function () { return Promise.reject(-Infinity); })['catch'](function (x) { st.equal(x, -Infinity, 'resolved promise onFinally returning a rejected Promise rejects with the new rejection value'); })['catch'](st.fail); promiseFinally(Promise.resolve(42), function () { throw Function; })['catch'](function (e) { st.equal(e, Function, 'resolved promise onFinally throwing rejects with the thrown rejection value'); })['catch'](st.fail); promiseFinally(Promise.reject(42), function () { return Promise.resolve(Infinity); })['catch'](function (e) { st.equal(e, 42, 'rejected promise onFinally resolution does not affect promise rejection value'); })['catch'](st.fail); promiseFinally(Promise.reject(42), function () { return Promise.reject(-Infinity); })['catch'](function (x) { st.equal(x, -Infinity, 'rejected promise onFinally returning a rejected Promise rejects with the new rejection value'); })['catch'](st.fail); promiseFinally(Promise.reject(42), function () { throw Function; })['catch'](function (e) { st.equal(e, Function, 'rejected promise onFinally throwing rejects with the thrown rejection value'); })['catch'](st.fail); }); var Subclass = (function () { try { // eslint-disable-next-line no-new-func return Function('class Subclass extends Promise { constructor(...args) { super(...args); this.thenArgs = []; } then(...args) { Subclass.thenArgs.push(args); this.thenArgs.push(args); return super.then(...args); } } Subclass.thenArgs = []; return Subclass;')(); } catch (e) { /**/ } return false; }()); t.test('inheritance', { skip: !Subclass }, function (st) { st.test('preserves correct subclass when chained', function (s2t) { var promise = promiseFinally(Subclass.resolve()); s2t.ok(promise instanceof Subclass, 'promise is instanceof Subclass'); s2t.equal(promise.constructor, Subclass, 'promise.constructor is Subclass'); s2t.end(); }); st.test('preserves correct subclass when rejected', function (s2t) { var promise = promiseFinally(Subclass.resolve(), function () { throw new Error('OMG'); }); s2t.ok(promise instanceof Subclass, 'promise is instanceof Subclass'); s2t.equal(promise.constructor, Subclass, 'promise.constructor is Subclass'); promise['catch'](function () {}); // avoid unhandled rejection warning s2t.end(); }); st.test('preserves correct subclass when someone returns a thenable', function (s2t) { var promise = promiseFinally(Subclass.resolve(), function () { return Promise.resolve(1); }); s2t.ok(promise instanceof Subclass, 'promise is instanceof Subclass'); s2t.equal(promise.constructor, Subclass, 'promise.constructor is Subclass'); s2t.end(); }); st.test('invokes the subclass’ then', function (s2t) { Subclass.thenArgs.length = 0; var original = Subclass.resolve(); promiseFinally(original, function () {}); assertArray(s2t, original.thenArgs, 1); assertArray(s2t, Subclass.thenArgs, 1); s2t.end(); }); st.test('passes the original onFinally when not a function', function (s2t) { Subclass.thenArgs.length = 0; var original = Subclass.resolve(); var sentinel = {}; promiseFinally(original, sentinel); assertArray(s2t, original.thenArgs, 1, Array.isArray); assertArray(s2t, Subclass.thenArgs, 1, Array.isArray); assertArray(s2t, original.thenArgs[0], 2, function (x) { s2t.equal(x, sentinel); }); s2t.end(); }); st.test('when onFinally is a function, passes thenFinally/catchFinally', function (s2t) { Subclass.thenArgs.length = 0; var sentinel = {}; var original = Subclass.resolve(sentinel); var onFinallyArgs = []; var onFinally = function onFinallyHandler() { onFinallyArgs.push(Array.prototype.slice.call(arguments)); return 42; }; var promise = promiseFinally(original, onFinally); assertArray(s2t, original.thenArgs, 1, Array.isArray); assertArray(s2t, Subclass.thenArgs, 1, Array.isArray); var thenArgs = original.thenArgs[0]; assertArray(s2t, thenArgs, 2, function (x) { s2t.equal(typeof x, 'function'); }); s2t.deepEqual(onFinallyArgs, [], 'onFinally not yet called'); s2t.test('thenFinally works as expected', function (s3t) { onFinallyArgs.length = 0; s3t.plan(6); assertArray(s3t, Subclass.thenArgs, 1); promise.then(function (x) { s3t.equal(x, sentinel, 'original resolution value provided'); s3t.deepEqual(onFinallyArgs, [[]], 'onFinally called once with no args'); assertArray(s3t, Subclass.thenArgs, 9); s3t.end(); })['catch'](s3t.fail); }); s2t.test('catchFinally works as expected', function (s3t) { onFinallyArgs.length = 0; s3t.plan(17); var thrown = { toString: function () { return 'thrown object'; } }; var onFinallyRejects = function onFinallyThrower() { onFinally.apply(undefined, arguments); throw thrown; }; Subclass.thenArgs.length = 0; var rejectedPromise = promiseFinally(original, onFinallyRejects); assertArray(s3t, Subclass.thenArgs, 1); var rejectedPromiseCatch = function (e) { s3t.equal(e, thrown, 'original rejection value provided'); s3t.deepEqual(onFinallyArgs, [[]], 'onFinally called once with no args'); assertArray(s3t, Subclass.thenArgs, 3); // 1) initial call with thenFinally/catchFinally // 2) rejectedPromise.then call // 3) rejectedPromise.then -> onFinally call assertArray(s3t, Subclass.thenArgs[0], 2, function (x) { s3t.equal(typeof x, 'function'); }); assertArray(s3t, Subclass.thenArgs[1], 2); s3t.deepEqual(Subclass.thenArgs[1], [s3t.fail, rejectedPromiseCatch], 'rejectedPromise.then call args'); assertArray(s3t, Subclass.thenArgs[2], 2); s3t.equal(Subclass.thenArgs[2][0], undefined, 'final .then call gets no onFulfill'); s3t.equal(typeof Subclass.thenArgs[2][1], 'function', 'final .then call gets an onReject'); s3t.end(); }; rejectedPromise.then(s3t.fail, rejectedPromiseCatch)['catch'](s3t.fail); }); s2t.end(); }); }); return t.comment('tests completed'); };