co-mocha.js 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.coMocha = f()}})(function(){var define,module,exports;return (function(){function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}return e})()({1:[function(require,module,exports){
  2. var co = require('co')
  3. var isGenFn = require('is-generator').fn
  4. /**
  5. * Export `co-mocha`.
  6. */
  7. module.exports = coMocha
  8. /**
  9. * Monkey patch the mocha instance with generator support.
  10. *
  11. * @param {Function} mocha
  12. */
  13. function coMocha (mocha) {
  14. // Avoid loading `co-mocha` twice.
  15. if (!mocha || mocha._coMochaIsLoaded) {
  16. return
  17. }
  18. var Runnable = mocha.Runnable
  19. var run = Runnable.prototype.run
  20. /**
  21. * Override the Mocha function runner and enable generator support with co.
  22. *
  23. * @param {Function} fn
  24. */
  25. Runnable.prototype.run = function (fn) {
  26. var oldFn = this.fn
  27. if (isGenFn(oldFn)) {
  28. this.fn = co.wrap(oldFn)
  29. // Replace `toString` to output the original function contents.
  30. this.fn.toString = function () {
  31. // https://github.com/mochajs/mocha/blob/7493bca76662318183e55294e906a4107433e20e/lib/utils.js#L251
  32. return Function.prototype.toString.call(oldFn)
  33. .replace(/^function *\* *\(.*\)\s*{/, 'function () {')
  34. }
  35. }
  36. return run.call(this, fn)
  37. }
  38. mocha._coMochaIsLoaded = true
  39. }
  40. /**
  41. * Find active node mocha instances.
  42. *
  43. * @return {Array}
  44. */
  45. function findNodeJSMocha () {
  46. var children = require.cache || {}
  47. return Object.keys(children)
  48. .filter(function (child) {
  49. var val = children[child].exports
  50. return typeof val === 'function' && val.name === 'Mocha'
  51. })
  52. .map(function (child) {
  53. return children[child].exports
  54. })
  55. }
  56. // Attempt to automatically monkey patch available mocha instances.
  57. var modules = typeof window === 'undefined' ? findNodeJSMocha() : [window.Mocha]
  58. modules.forEach(coMocha)
  59. },{"co":2,"is-generator":3}],2:[function(require,module,exports){
  60. /**
  61. * slice() reference.
  62. */
  63. var slice = Array.prototype.slice;
  64. /**
  65. * Expose `co`.
  66. */
  67. module.exports = co['default'] = co.co = co;
  68. /**
  69. * Wrap the given generator `fn` into a
  70. * function that returns a promise.
  71. * This is a separate function so that
  72. * every `co()` call doesn't create a new,
  73. * unnecessary closure.
  74. *
  75. * @param {GeneratorFunction} fn
  76. * @return {Function}
  77. * @api public
  78. */
  79. co.wrap = function (fn) {
  80. createPromise.__generatorFunction__ = fn;
  81. return createPromise;
  82. function createPromise() {
  83. return co.call(this, fn.apply(this, arguments));
  84. }
  85. };
  86. /**
  87. * Execute the generator function or a generator
  88. * and return a promise.
  89. *
  90. * @param {Function} fn
  91. * @return {Promise}
  92. * @api public
  93. */
  94. function co(gen) {
  95. var ctx = this;
  96. var args = slice.call(arguments, 1)
  97. // we wrap everything in a promise to avoid promise chaining,
  98. // which leads to memory leak errors.
  99. // see https://github.com/tj/co/issues/180
  100. return new Promise(function(resolve, reject) {
  101. if (typeof gen === 'function') gen = gen.apply(ctx, args);
  102. if (!gen || typeof gen.next !== 'function') return resolve(gen);
  103. onFulfilled();
  104. /**
  105. * @param {Mixed} res
  106. * @return {Promise}
  107. * @api private
  108. */
  109. function onFulfilled(res) {
  110. var ret;
  111. try {
  112. ret = gen.next(res);
  113. } catch (e) {
  114. return reject(e);
  115. }
  116. next(ret);
  117. }
  118. /**
  119. * @param {Error} err
  120. * @return {Promise}
  121. * @api private
  122. */
  123. function onRejected(err) {
  124. var ret;
  125. try {
  126. ret = gen.throw(err);
  127. } catch (e) {
  128. return reject(e);
  129. }
  130. next(ret);
  131. }
  132. /**
  133. * Get the next value in the generator,
  134. * return a promise.
  135. *
  136. * @param {Object} ret
  137. * @return {Promise}
  138. * @api private
  139. */
  140. function next(ret) {
  141. if (ret.done) return resolve(ret.value);
  142. var value = toPromise.call(ctx, ret.value);
  143. if (value && isPromise(value)) return value.then(onFulfilled, onRejected);
  144. return onRejected(new TypeError('You may only yield a function, promise, generator, array, or object, '
  145. + 'but the following object was passed: "' + String(ret.value) + '"'));
  146. }
  147. });
  148. }
  149. /**
  150. * Convert a `yield`ed value into a promise.
  151. *
  152. * @param {Mixed} obj
  153. * @return {Promise}
  154. * @api private
  155. */
  156. function toPromise(obj) {
  157. if (!obj) return obj;
  158. if (isPromise(obj)) return obj;
  159. if (isGeneratorFunction(obj) || isGenerator(obj)) return co.call(this, obj);
  160. if ('function' == typeof obj) return thunkToPromise.call(this, obj);
  161. if (Array.isArray(obj)) return arrayToPromise.call(this, obj);
  162. if (isObject(obj)) return objectToPromise.call(this, obj);
  163. return obj;
  164. }
  165. /**
  166. * Convert a thunk to a promise.
  167. *
  168. * @param {Function}
  169. * @return {Promise}
  170. * @api private
  171. */
  172. function thunkToPromise(fn) {
  173. var ctx = this;
  174. return new Promise(function (resolve, reject) {
  175. fn.call(ctx, function (err, res) {
  176. if (err) return reject(err);
  177. if (arguments.length > 2) res = slice.call(arguments, 1);
  178. resolve(res);
  179. });
  180. });
  181. }
  182. /**
  183. * Convert an array of "yieldables" to a promise.
  184. * Uses `Promise.all()` internally.
  185. *
  186. * @param {Array} obj
  187. * @return {Promise}
  188. * @api private
  189. */
  190. function arrayToPromise(obj) {
  191. return Promise.all(obj.map(toPromise, this));
  192. }
  193. /**
  194. * Convert an object of "yieldables" to a promise.
  195. * Uses `Promise.all()` internally.
  196. *
  197. * @param {Object} obj
  198. * @return {Promise}
  199. * @api private
  200. */
  201. function objectToPromise(obj){
  202. var results = new obj.constructor();
  203. var keys = Object.keys(obj);
  204. var promises = [];
  205. for (var i = 0; i < keys.length; i++) {
  206. var key = keys[i];
  207. var promise = toPromise.call(this, obj[key]);
  208. if (promise && isPromise(promise)) defer(promise, key);
  209. else results[key] = obj[key];
  210. }
  211. return Promise.all(promises).then(function () {
  212. return results;
  213. });
  214. function defer(promise, key) {
  215. // predefine the key in the result
  216. results[key] = undefined;
  217. promises.push(promise.then(function (res) {
  218. results[key] = res;
  219. }));
  220. }
  221. }
  222. /**
  223. * Check if `obj` is a promise.
  224. *
  225. * @param {Object} obj
  226. * @return {Boolean}
  227. * @api private
  228. */
  229. function isPromise(obj) {
  230. return 'function' == typeof obj.then;
  231. }
  232. /**
  233. * Check if `obj` is a generator.
  234. *
  235. * @param {Mixed} obj
  236. * @return {Boolean}
  237. * @api private
  238. */
  239. function isGenerator(obj) {
  240. return 'function' == typeof obj.next && 'function' == typeof obj.throw;
  241. }
  242. /**
  243. * Check if `obj` is a generator function.
  244. *
  245. * @param {Mixed} obj
  246. * @return {Boolean}
  247. * @api private
  248. */
  249. function isGeneratorFunction(obj) {
  250. var constructor = obj.constructor;
  251. if (!constructor) return false;
  252. if ('GeneratorFunction' === constructor.name || 'GeneratorFunction' === constructor.displayName) return true;
  253. return isGenerator(constructor.prototype);
  254. }
  255. /**
  256. * Check for plain object.
  257. *
  258. * @param {Mixed} val
  259. * @return {Boolean}
  260. * @api private
  261. */
  262. function isObject(val) {
  263. return Object == val.constructor;
  264. }
  265. },{}],3:[function(require,module,exports){
  266. /**
  267. * Export generator function checks.
  268. */
  269. module.exports = isGenerator
  270. module.exports.fn = isGeneratorFunction
  271. /**
  272. * Check whether an object is a generator.
  273. *
  274. * @param {Object} obj
  275. * @return {Boolean}
  276. */
  277. function isGenerator (obj) {
  278. return obj &&
  279. typeof obj.next === 'function' &&
  280. typeof obj.throw === 'function'
  281. }
  282. /**
  283. * Check whether a function is generator.
  284. *
  285. * @param {Function} fn
  286. * @return {Boolean}
  287. */
  288. function isGeneratorFunction (fn) {
  289. return typeof fn === 'function' &&
  290. fn.constructor &&
  291. fn.constructor.name === 'GeneratorFunction'
  292. }
  293. },{}]},{},[1])(1)
  294. });