utils.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. 'use strict';
  5. module.metadata = {
  6. 'stability': 'unstable'
  7. };
  8. const { defer } = require('../core/promise');
  9. const { setInterval, clearInterval } = require('../timers');
  10. function getTestNames (exports)
  11. Object.keys(exports).filter(name => /^test/.test(name))
  12. function isTestAsync (fn) fn.length > 1
  13. function isHelperAsync (fn) fn.length > 2
  14. /*
  15. * Takes an `exports` object of a test file and a function `beforeFn`
  16. * to be run before each test. `beforeFn` is called with a `name` string
  17. * as the first argument of the test name, and may specify a second
  18. * argument function `done` to indicate that this function should
  19. * resolve asynchronously
  20. */
  21. function before (exports, beforeFn) {
  22. getTestNames(exports).map(name => {
  23. let testFn = exports[name];
  24. if (!isTestAsync(testFn) && !isHelperAsync(beforeFn)) {
  25. exports[name] = function (assert) {
  26. beforeFn(name, assert);
  27. testFn(assert);
  28. };
  29. }
  30. else if (isTestAsync(testFn) && !isHelperAsync(beforeFn)) {
  31. exports[name] = function (assert, done) {
  32. beforeFn(name, assert);
  33. testFn(assert, done);
  34. };
  35. }
  36. else if (!isTestAsync(testFn) && isHelperAsync(beforeFn)) {
  37. exports[name] = function (assert, done) {
  38. beforeFn(name, assert, () => {
  39. testFn(assert);
  40. done();
  41. });
  42. };
  43. } else if (isTestAsync(testFn) && isHelperAsync(beforeFn)) {
  44. exports[name] = function (assert, done) {
  45. beforeFn(name, assert, () => {
  46. testFn(assert, done);
  47. });
  48. };
  49. }
  50. });
  51. }
  52. exports.before = before;
  53. /*
  54. * Takes an `exports` object of a test file and a function `afterFn`
  55. * to be run after each test. `afterFn` is called with a `name` string
  56. * as the first argument of the test name, and may specify a second
  57. * argument function `done` to indicate that this function should
  58. * resolve asynchronously
  59. */
  60. function after (exports, afterFn) {
  61. getTestNames(exports).map(name => {
  62. let testFn = exports[name];
  63. if (!isTestAsync(testFn) && !isHelperAsync(afterFn)) {
  64. exports[name] = function (assert) {
  65. testFn(assert);
  66. afterFn(name, assert);
  67. };
  68. }
  69. else if (isTestAsync(testFn) && !isHelperAsync(afterFn)) {
  70. exports[name] = function (assert, done) {
  71. testFn(assert, () => {
  72. afterFn(name, assert);
  73. done();
  74. });
  75. };
  76. }
  77. else if (!isTestAsync(testFn) && isHelperAsync(afterFn)) {
  78. exports[name] = function (assert, done) {
  79. testFn(assert);
  80. afterFn(name, assert, done);
  81. };
  82. } else if (isTestAsync(testFn) && isHelperAsync(afterFn)) {
  83. exports[name] = function (assert, done) {
  84. testFn(assert, () => {
  85. afterFn(name, assert, done);
  86. });
  87. };
  88. }
  89. });
  90. }
  91. exports.after = after;
  92. function waitUntil (predicate, delay) {
  93. let { promise, resolve } = defer();
  94. let interval = setInterval(() => {
  95. if (!predicate()) return;
  96. clearInterval(interval);
  97. resolve();
  98. }, delay || 10);
  99. return promise;
  100. }
  101. exports.waitUntil = waitUntil;