simple.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. var failIfThrows = function (done) {
  2. 'use strict';
  3. return function (e) {
  4. done(e || new Error());
  5. };
  6. };
  7. describe('Promise', function () {
  8. 'use strict';
  9. specify('sanity check: a fulfilled promise calls its fulfillment handler', function (done) {
  10. Promise.resolve(5).then(function (value) {
  11. assert.strictEqual(value, 5);
  12. }).then(done, failIfThrows(done));
  13. });
  14. specify('directly resolving the promise with itself', function (done) {
  15. var resolvePromise;
  16. var promise = new Promise(function (resolve) { resolvePromise = resolve; });
  17. resolvePromise(promise);
  18. promise.then(
  19. function () {
  20. assert(false, 'Should not be fulfilled');
  21. },
  22. function (err) {
  23. assert(err instanceof TypeError);
  24. }
  25. ).then(done, failIfThrows(done));
  26. });
  27. specify('Stealing a resolver and using it to trigger possible reentrancy bug (#83)', function () {
  28. var stolenResolver;
  29. var StealingPromiseConstructor = function StealingPromiseConstructor(resolver) {
  30. stolenResolver = resolver;
  31. resolver(function () { }, function () { });
  32. };
  33. var iterable = {};
  34. var atAtIterator = '@@iterator'; // on firefox, at least.
  35. iterable[atAtIterator] = function () {
  36. stolenResolver(null, null);
  37. throw new Error(0);
  38. };
  39. assert.doesNotThrow(function () {
  40. Promise.all.call(StealingPromiseConstructor, iterable);
  41. });
  42. });
  43. specify('resolve with a thenable calls it once', function () {
  44. var resolve;
  45. var p = new Promise(function (r) { resolve = r; });
  46. var count = 0;
  47. resolve({
  48. then: function () {
  49. count += 1;
  50. throw new RangeError('reject the promise');
  51. }
  52. });
  53. var a = p.then(function () {})['catch'](function (err) {
  54. assert.equal(count, 1);
  55. assert.ok(err instanceof RangeError);
  56. });
  57. var b = p.then(function () {})['catch'](function (err) {
  58. assert.equal(count, 1);
  59. assert.ok(err instanceof RangeError);
  60. });
  61. return Promise.all([a, b]);
  62. });
  63. specify('resolve with a thenable that throws on .then, rejects the promise synchronously', function () {
  64. var resolve;
  65. var p = new Promise(function (r) { resolve = r; });
  66. var count = 0;
  67. var thenable = Object.defineProperty({}, 'then', {
  68. get: function () {
  69. count += 1;
  70. throw new RangeError('no then for you');
  71. }
  72. });
  73. resolve(thenable);
  74. assert.equal(count, 1);
  75. var a = p.then(function () {})['catch'](function (err) {
  76. assert.equal(count, 1);
  77. assert.ok(err instanceof RangeError);
  78. });
  79. var b = p.then(function () {})['catch'](function (err) {
  80. assert.equal(count, 1);
  81. assert.ok(err instanceof RangeError);
  82. });
  83. return Promise.all([a, b]);
  84. });
  85. });