evil-promises.js 1.4 KB

123456789101112131415161718192021222324252627282930313233343536
  1. describe('Evil promises should not be able to break invariants', function () {
  2. 'use strict';
  3. specify('resolving to a promise that calls onFulfilled twice', function (done) {
  4. // note that we have to create a trivial subclass, as otherwise the
  5. // Promise.resolve(evilPromise) is just the identity function.
  6. // (And in fact, most native Promise implementations use a private
  7. // [[PromiseConstructor]] field in `Promise.resolve` which can't be
  8. // easily patched in an ES5 engine, so instead of
  9. // `Promise.resolve(evilPromise)` we'll use
  10. // `new Promise(function(r){r(evilPromise);})` below.)
  11. var EvilPromise = function (executor) {
  12. var self = new Promise(executor);
  13. Object.setPrototypeOf(self, EvilPromise.prototype);
  14. return self;
  15. };
  16. if (!Object.setPrototypeOf) { return done(); } // skip test if on IE < 11
  17. Object.setPrototypeOf(EvilPromise, Promise);
  18. EvilPromise.prototype = Object.create(Promise.prototype, {
  19. constructor: { value: EvilPromise }
  20. });
  21. var evilPromise = EvilPromise.resolve();
  22. evilPromise.then = function (f) {
  23. f(1);
  24. f(2);
  25. };
  26. var calledAlready = false;
  27. new Promise(function (r) { r(evilPromise); }).then(function (value) {
  28. assert.strictEqual(calledAlready, false);
  29. calledAlready = true;
  30. assert.strictEqual(value, 1);
  31. }).then(done, done);
  32. });
  33. });