pre.test.js 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. 'use strict';
  2. const assert = require('assert');
  3. const Kareem = require('../');
  4. const { beforeEach, describe, it } = require('mocha');
  5. describe('execPre', function() {
  6. var hooks;
  7. beforeEach(function() {
  8. hooks = new Kareem();
  9. });
  10. it('handles errors with multiple pres', function(done) {
  11. var execed = {};
  12. hooks.pre('cook', function(done) {
  13. execed.first = true;
  14. done();
  15. });
  16. hooks.pre('cook', function(done) {
  17. execed.second = true;
  18. done('error!');
  19. });
  20. hooks.pre('cook', function(done) {
  21. execed.third = true;
  22. done();
  23. });
  24. hooks.execPre('cook', null, function(err) {
  25. assert.equal('error!', err);
  26. assert.equal(2, Object.keys(execed).length);
  27. assert.ok(execed.first);
  28. assert.ok(execed.second);
  29. done();
  30. });
  31. });
  32. it('sync errors', function(done) {
  33. var called = 0;
  34. hooks.pre('cook', function(next) {
  35. throw new Error('woops!');
  36. });
  37. hooks.pre('cook', function(next) {
  38. ++called;
  39. next();
  40. });
  41. hooks.execPre('cook', null, function(err) {
  42. assert.equal(err.message, 'woops!');
  43. assert.equal(called, 0);
  44. done();
  45. });
  46. });
  47. it('unshift', function() {
  48. var f1 = function() {};
  49. var f2 = function() {};
  50. hooks.pre('cook', false, f1);
  51. hooks.pre('cook', false, f2, null, true);
  52. assert.strictEqual(hooks._pres.get('cook')[0].fn, f2);
  53. assert.strictEqual(hooks._pres.get('cook')[1].fn, f1);
  54. });
  55. it('throws error if no function', function() {
  56. assert.throws(() => hooks.pre('test'), /got "undefined"/);
  57. });
  58. it('arbitrary options', function() {
  59. const f1 = function() {};
  60. const f2 = function() {};
  61. hooks.pre('cook', { foo: 'bar' }, f1);
  62. hooks.pre('cook', { bar: 'baz' }, f2, null, true);
  63. assert.equal(hooks._pres.get('cook')[1].foo, 'bar');
  64. assert.equal(hooks._pres.get('cook')[0].bar, 'baz');
  65. });
  66. it('handles async errors', function(done) {
  67. var execed = {};
  68. hooks.pre('cook', true, function(next, done) {
  69. execed.first = true;
  70. setTimeout(
  71. function() {
  72. done('error!');
  73. },
  74. 5);
  75. next();
  76. });
  77. hooks.pre('cook', true, function(next, done) {
  78. execed.second = true;
  79. setTimeout(
  80. function() {
  81. done('other error!');
  82. },
  83. 10);
  84. next();
  85. });
  86. hooks.execPre('cook', null, function(err) {
  87. assert.equal('error!', err);
  88. assert.equal(2, Object.keys(execed).length);
  89. assert.ok(execed.first);
  90. assert.ok(execed.second);
  91. done();
  92. });
  93. });
  94. it('handles async errors in next()', function(done) {
  95. var execed = {};
  96. hooks.pre('cook', true, function(next, done) {
  97. execed.first = true;
  98. setTimeout(
  99. function() {
  100. done('other error!');
  101. },
  102. 15);
  103. next();
  104. });
  105. hooks.pre('cook', true, function(next, done) {
  106. execed.second = true;
  107. setTimeout(
  108. function() {
  109. next('error!');
  110. done('another error!');
  111. },
  112. 5);
  113. });
  114. hooks.execPre('cook', null, function(err) {
  115. assert.equal('error!', err);
  116. assert.equal(2, Object.keys(execed).length);
  117. assert.ok(execed.first);
  118. assert.ok(execed.second);
  119. done();
  120. });
  121. });
  122. it('handles async errors in next() when already done', function(done) {
  123. var execed = {};
  124. hooks.pre('cook', true, function(next, done) {
  125. execed.first = true;
  126. setTimeout(
  127. function() {
  128. done('other error!');
  129. },
  130. 5);
  131. next();
  132. });
  133. hooks.pre('cook', true, function(next, done) {
  134. execed.second = true;
  135. setTimeout(
  136. function() {
  137. next('error!');
  138. done('another error!');
  139. },
  140. 25);
  141. });
  142. hooks.execPre('cook', null, function(err) {
  143. assert.equal('other error!', err);
  144. assert.equal(2, Object.keys(execed).length);
  145. assert.ok(execed.first);
  146. assert.ok(execed.second);
  147. done();
  148. });
  149. });
  150. it('async pres with clone()', function(done) {
  151. var execed = false;
  152. hooks.pre('cook', true, function(next, done) {
  153. execed = true;
  154. setTimeout(
  155. function() {
  156. done();
  157. },
  158. 5);
  159. next();
  160. });
  161. hooks.clone().execPre('cook', null, function(err) {
  162. assert.ifError(err);
  163. assert.ok(execed);
  164. done();
  165. });
  166. });
  167. it('returns correct error when async pre errors', function(done) {
  168. var execed = {};
  169. hooks.pre('cook', true, function(next, done) {
  170. execed.first = true;
  171. setTimeout(
  172. function() {
  173. done('other error!');
  174. },
  175. 5);
  176. next();
  177. });
  178. hooks.pre('cook', function(next) {
  179. execed.second = true;
  180. setTimeout(
  181. function() {
  182. next('error!');
  183. },
  184. 15);
  185. });
  186. hooks.execPre('cook', null, function(err) {
  187. assert.equal('other error!', err);
  188. assert.equal(2, Object.keys(execed).length);
  189. assert.ok(execed.first);
  190. assert.ok(execed.second);
  191. done();
  192. });
  193. });
  194. it('lets async pres run when fully sync pres are done', function(done) {
  195. var execed = {};
  196. hooks.pre('cook', true, function(next, done) {
  197. execed.first = true;
  198. setTimeout(
  199. function() {
  200. done();
  201. },
  202. 5);
  203. next();
  204. });
  205. hooks.pre('cook', function() {
  206. execed.second = true;
  207. });
  208. hooks.execPre('cook', null, function(err) {
  209. assert.ifError(err);
  210. assert.equal(2, Object.keys(execed).length);
  211. assert.ok(execed.first);
  212. assert.ok(execed.second);
  213. done();
  214. });
  215. });
  216. it('allows passing arguments to the next pre', function(done) {
  217. var execed = {};
  218. hooks.pre('cook', function(next) {
  219. execed.first = true;
  220. next(null, 'test');
  221. });
  222. hooks.pre('cook', function(next, p) {
  223. execed.second = true;
  224. assert.equal(p, 'test');
  225. next();
  226. });
  227. hooks.pre('cook', function(next, p) {
  228. execed.third = true;
  229. assert.ok(!p);
  230. next();
  231. });
  232. hooks.execPre('cook', null, function(err) {
  233. assert.ifError(err);
  234. assert.equal(3, Object.keys(execed).length);
  235. assert.ok(execed.first);
  236. assert.ok(execed.second);
  237. assert.ok(execed.third);
  238. done();
  239. });
  240. });
  241. it('handles sync errors in pre if there are more hooks', function(done) {
  242. var execed = {};
  243. hooks.pre('cook', function() {
  244. execed.first = true;
  245. throw new Error('Oops!');
  246. });
  247. hooks.pre('cook', function() {
  248. execed.second = true;
  249. });
  250. hooks.execPre('cook', null, function(err) {
  251. assert.ok(err);
  252. assert.ok(execed.first);
  253. assert.equal(err.message, 'Oops!');
  254. done();
  255. });
  256. });
  257. it('supports skipWrappedFunction', function(done) {
  258. var execed = {};
  259. hooks.pre('cook', function(callback) {
  260. callback(Kareem.skipWrappedFunction(42));
  261. });
  262. hooks.pre('cook', function() {
  263. execed.second = true;
  264. });
  265. hooks.execPre('cook', null, function(err) {
  266. assert.ok(execed.second);
  267. assert.ok(err instanceof Kareem.skipWrappedFunction);
  268. done();
  269. });
  270. });
  271. });
  272. describe('execPreSync', function() {
  273. var hooks;
  274. beforeEach(function() {
  275. hooks = new Kareem();
  276. });
  277. it('executes hooks synchronously', function() {
  278. var execed = {};
  279. hooks.pre('cook', function() {
  280. execed.first = true;
  281. });
  282. hooks.pre('cook', function() {
  283. execed.second = true;
  284. });
  285. hooks.execPreSync('cook', null);
  286. assert.ok(execed.first);
  287. assert.ok(execed.second);
  288. });
  289. it('works with no hooks specified', function() {
  290. assert.doesNotThrow(function() {
  291. hooks.execPreSync('cook', null);
  292. });
  293. });
  294. });