jasmine_async.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', {
  3. value: true
  4. });
  5. exports.install = install;
  6. var _isGeneratorFn = require('is-generator-fn');
  7. var _isGeneratorFn2 = _interopRequireDefault(_isGeneratorFn);
  8. var _co = require('co');
  9. var _co2 = _interopRequireDefault(_co);
  10. var _is_error = require('./is_error');
  11. var _is_error2 = _interopRequireDefault(_is_error);
  12. function _interopRequireDefault(obj) {
  13. return obj && obj.__esModule ? obj : {default: obj};
  14. }
  15. /**
  16. * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
  17. *
  18. * This source code is licensed under the MIT license found in the
  19. * LICENSE file in the root directory of this source tree.
  20. *
  21. *
  22. */
  23. /**
  24. * This module adds ability to test async promise code with jasmine by
  25. * returning a promise from `it/test` and `before/afterEach/All` blocks.
  26. */
  27. function isPromise(obj) {
  28. return obj && typeof obj.then === 'function';
  29. }
  30. function promisifyLifeCycleFunction(originalFn, env) {
  31. return function(fn, timeout) {
  32. if (!fn) {
  33. return originalFn.call(env);
  34. }
  35. const hasDoneCallback = fn.length > 0;
  36. if (hasDoneCallback) {
  37. // Jasmine will handle it
  38. return originalFn.call(env, fn, timeout);
  39. }
  40. const extraError = new Error();
  41. // We make *all* functions async and run `done` right away if they
  42. // didn't return a promise.
  43. const asyncJestLifecycle = function(done) {
  44. const wrappedFn = (0, _isGeneratorFn2.default)(fn)
  45. ? _co2.default.wrap(fn)
  46. : fn;
  47. const returnValue = wrappedFn.call({});
  48. if (isPromise(returnValue)) {
  49. returnValue.then(done.bind(null, null), error => {
  50. var _checkIsError = (0, _is_error2.default)(error);
  51. const isError = _checkIsError.isError,
  52. message = _checkIsError.message;
  53. if (message) {
  54. extraError.message = message;
  55. }
  56. done.fail(isError ? error : extraError);
  57. });
  58. } else {
  59. done();
  60. }
  61. };
  62. return originalFn.call(env, asyncJestLifecycle, timeout);
  63. };
  64. }
  65. // Similar to promisifyLifeCycleFunction but throws an error
  66. // when the return value is neither a Promise nor `undefined`
  67. function promisifyIt(originalFn, env) {
  68. return function(specName, fn, timeout) {
  69. if (!fn) {
  70. const spec = originalFn.call(env, specName);
  71. spec.pend('not implemented');
  72. return spec;
  73. }
  74. const hasDoneCallback = fn.length > 0;
  75. if (hasDoneCallback) {
  76. return originalFn.call(env, specName, fn, timeout);
  77. }
  78. const extraError = new Error();
  79. const asyncJestTest = function(done) {
  80. const wrappedFn = (0, _isGeneratorFn2.default)(fn)
  81. ? _co2.default.wrap(fn)
  82. : fn;
  83. const returnValue = wrappedFn.call({});
  84. if (isPromise(returnValue)) {
  85. returnValue.then(done.bind(null, null), error => {
  86. var _checkIsError2 = (0, _is_error2.default)(error);
  87. const isError = _checkIsError2.isError,
  88. message = _checkIsError2.message;
  89. if (message) {
  90. extraError.message = message;
  91. }
  92. done.fail(isError ? error : extraError);
  93. });
  94. } else if (returnValue === undefined) {
  95. done();
  96. } else {
  97. done.fail(
  98. new Error(
  99. 'Jest: `it` and `test` must return either a Promise or undefined.'
  100. )
  101. );
  102. }
  103. };
  104. return originalFn.call(env, specName, asyncJestTest, timeout);
  105. };
  106. }
  107. function makeConcurrent(originalFn, env) {
  108. return function(specName, fn, timeout) {
  109. if (env != null && !env.specFilter({getFullName: () => specName || ''})) {
  110. return originalFn.call(env, specName, () => Promise.resolve(), timeout);
  111. }
  112. let promise;
  113. try {
  114. promise = fn();
  115. if (!isPromise(promise)) {
  116. throw new Error(
  117. `Jest: concurrent test "${specName}" must return a Promise.`
  118. );
  119. }
  120. } catch (error) {
  121. return originalFn.call(env, specName, () => Promise.reject(error));
  122. }
  123. return originalFn.call(env, specName, () => promise, timeout);
  124. };
  125. }
  126. function install(global) {
  127. const jasmine = global.jasmine;
  128. const env = jasmine.getEnv();
  129. env.it = promisifyIt(env.it, env);
  130. env.fit = promisifyIt(env.fit, env);
  131. global.it.concurrent = makeConcurrent(env.it, env);
  132. global.it.concurrent.only = makeConcurrent(env.fit, env);
  133. global.it.concurrent.skip = makeConcurrent(env.xit, env);
  134. global.fit.concurrent = makeConcurrent(env.fit);
  135. env.afterAll = promisifyLifeCycleFunction(env.afterAll, env);
  136. env.afterEach = promisifyLifeCycleFunction(env.afterEach, env);
  137. env.beforeAll = promisifyLifeCycleFunction(env.beforeAll, env);
  138. env.beforeEach = promisifyLifeCycleFunction(env.beforeEach, env);
  139. }