wrap.test.js 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. 'use strict';
  2. var assert = require('assert');
  3. var Kareem = require('../');
  4. const { beforeEach, describe, it } = require('mocha');
  5. describe('wrap()', function() {
  6. var hooks;
  7. beforeEach(function() {
  8. hooks = new Kareem();
  9. });
  10. it('handles pre errors', function(done) {
  11. hooks.pre('cook', function(done) {
  12. done('error!');
  13. });
  14. hooks.post('cook', function(obj) {
  15. obj.tofu = 'no';
  16. });
  17. var obj = { bacon: 0, eggs: 0 };
  18. var args = [obj];
  19. args.push(function(error, result) {
  20. assert.equal('error!', error);
  21. assert.ok(!result);
  22. assert.equal(undefined, obj.tofu);
  23. done();
  24. });
  25. hooks.wrap(
  26. 'cook',
  27. function(o, callback) {
  28. // Should never get called
  29. assert.ok(false);
  30. callback(null, o);
  31. },
  32. obj,
  33. args);
  34. });
  35. it('handles pre errors when no callback defined', function(done) {
  36. hooks.pre('cook', function(done) {
  37. done('error!');
  38. });
  39. hooks.post('cook', function(obj) {
  40. obj.tofu = 'no';
  41. });
  42. var obj = { bacon: 0, eggs: 0 };
  43. var args = [obj];
  44. hooks.wrap(
  45. 'cook',
  46. function(o, callback) {
  47. // Should never get called
  48. assert.ok(false);
  49. callback(null, o);
  50. },
  51. obj,
  52. args);
  53. setTimeout(
  54. function() {
  55. done();
  56. },
  57. 25);
  58. });
  59. it('handles errors in wrapped function', function(done) {
  60. hooks.pre('cook', function(done) {
  61. done();
  62. });
  63. hooks.post('cook', function(obj) {
  64. obj.tofu = 'no';
  65. });
  66. var obj = { bacon: 0, eggs: 0 };
  67. var args = [obj];
  68. args.push(function(error, result) {
  69. assert.equal('error!', error);
  70. assert.ok(!result);
  71. assert.equal(undefined, obj.tofu);
  72. done();
  73. });
  74. hooks.wrap(
  75. 'cook',
  76. function(o, callback) {
  77. callback('error!');
  78. },
  79. obj,
  80. args);
  81. });
  82. it('handles errors in post', function(done) {
  83. hooks.pre('cook', function(done) {
  84. done();
  85. });
  86. hooks.post('cook', function(obj, callback) {
  87. obj.tofu = 'no';
  88. callback('error!');
  89. });
  90. var obj = { bacon: 0, eggs: 0 };
  91. var args = [obj];
  92. args.push(function(error, result) {
  93. assert.equal('error!', error);
  94. assert.ok(!result);
  95. assert.equal('no', obj.tofu);
  96. done();
  97. });
  98. hooks.wrap(
  99. 'cook',
  100. function(o, callback) {
  101. callback(null, o);
  102. },
  103. obj,
  104. args);
  105. });
  106. it('defers errors to post hooks if enabled', function(done) {
  107. hooks.pre('cook', function(done) {
  108. done(new Error('fail'));
  109. });
  110. hooks.post('cook', function(error, res, callback) {
  111. callback(new Error('another error occurred'));
  112. });
  113. var args = [];
  114. args.push(function(error) {
  115. assert.equal(error.message, 'another error occurred');
  116. done();
  117. });
  118. hooks.wrap(
  119. 'cook',
  120. function(callback) {
  121. assert.ok(false);
  122. callback();
  123. },
  124. null,
  125. args,
  126. { useErrorHandlers: true, numCallbackParams: 1 });
  127. });
  128. it('error handlers with no callback', function(done) {
  129. hooks.pre('cook', function(done) {
  130. done(new Error('fail'));
  131. });
  132. hooks.post('cook', function(error, callback) {
  133. assert.equal(error.message, 'fail');
  134. done();
  135. });
  136. var args = [];
  137. hooks.wrap(
  138. 'cook',
  139. function(callback) {
  140. assert.ok(false);
  141. callback();
  142. },
  143. null,
  144. args,
  145. { useErrorHandlers: true });
  146. });
  147. it('error handlers with no error', function(done) {
  148. hooks.post('cook', function(error, callback) {
  149. callback(new Error('another error occurred'));
  150. });
  151. var args = [];
  152. args.push(function(error) {
  153. assert.ifError(error);
  154. done();
  155. });
  156. hooks.wrap(
  157. 'cook',
  158. function(callback) {
  159. callback();
  160. },
  161. null,
  162. args,
  163. { useErrorHandlers: true });
  164. });
  165. it('works with no args', function(done) {
  166. hooks.pre('cook', function(done) {
  167. done();
  168. });
  169. hooks.post('cook', function(callback) {
  170. obj.tofu = 'no';
  171. callback();
  172. });
  173. var obj = { bacon: 0, eggs: 0 };
  174. var args = [];
  175. hooks.wrap(
  176. 'cook',
  177. function(callback) {
  178. callback(null);
  179. },
  180. obj,
  181. args);
  182. setTimeout(
  183. function() {
  184. assert.equal('no', obj.tofu);
  185. done();
  186. },
  187. 25);
  188. });
  189. it('handles pre errors with no args', function(done) {
  190. hooks.pre('cook', function(done) {
  191. done('error!');
  192. });
  193. hooks.post('cook', function(callback) {
  194. obj.tofu = 'no';
  195. callback();
  196. });
  197. var obj = { bacon: 0, eggs: 0 };
  198. var args = [];
  199. hooks.wrap(
  200. 'cook',
  201. function(callback) {
  202. callback(null);
  203. },
  204. obj,
  205. args);
  206. setTimeout(
  207. function() {
  208. assert.equal(undefined, obj.tofu);
  209. done();
  210. },
  211. 25);
  212. });
  213. it('handles wrapped function errors with no args', function(done) {
  214. hooks.pre('cook', function(done) {
  215. obj.waffles = false;
  216. done();
  217. });
  218. hooks.post('cook', function(callback) {
  219. obj.tofu = 'no';
  220. callback();
  221. });
  222. var obj = { bacon: 0, eggs: 0 };
  223. var args = [];
  224. hooks.wrap(
  225. 'cook',
  226. function(callback) {
  227. callback('error!');
  228. },
  229. obj,
  230. args);
  231. setTimeout(
  232. function() {
  233. assert.equal(false, obj.waffles);
  234. assert.equal(undefined, obj.tofu);
  235. done();
  236. },
  237. 25);
  238. });
  239. it('supports overwriteResult', function(done) {
  240. hooks.post('cook', function(eggs, callback) {
  241. callback(Kareem.overwriteResult(5));
  242. });
  243. const args = [(err, res) => {
  244. assert.ifError(err);
  245. assert.equal(res, 5);
  246. done();
  247. }];
  248. hooks.wrap(
  249. 'cook',
  250. function(callback) {
  251. callback(null, 4);
  252. },
  253. null,
  254. args);
  255. });
  256. it('supports skipWrappedFunction', function(done) {
  257. const execed = {};
  258. hooks.pre('cook', function pre(callback) {
  259. execed.pre = true;
  260. callback(Kareem.skipWrappedFunction(3));
  261. });
  262. hooks.post('cook', function(res, callback) {
  263. assert.equal(res, 3);
  264. execed.post = true;
  265. callback();
  266. });
  267. const args = [(err, res) => {
  268. assert.ifError(err);
  269. assert.equal(res, 3);
  270. assert.ok(execed.pre);
  271. assert.ok(execed.post);
  272. assert.ok(!execed.wrapped);
  273. done();
  274. }];
  275. hooks.wrap(
  276. 'cook',
  277. function wrapped(callback) {
  278. execed.wrapped = true;
  279. callback();
  280. },
  281. null,
  282. args);
  283. });
  284. it('supports skipWrappedFunction with arguments', function(done) {
  285. const execed = {};
  286. hooks.pre('cook', function pre(callback, arg) {
  287. execed.pre = true;
  288. assert.strictEqual(arg, 4);
  289. callback(Kareem.skipWrappedFunction(3));
  290. });
  291. hooks.post('cook', function(res, callback) {
  292. assert.equal(res, 3);
  293. execed.post = true;
  294. callback();
  295. });
  296. const args = [4, (err, res) => {
  297. assert.ifError(err);
  298. assert.equal(res, 3);
  299. assert.ok(execed.pre);
  300. assert.ok(execed.post);
  301. assert.ok(!execed.wrapped);
  302. done();
  303. }];
  304. hooks.wrap(
  305. 'cook',
  306. function wrapped(arg, callback) {
  307. execed.wrapped = true;
  308. callback();
  309. },
  310. null,
  311. args);
  312. });
  313. it('handles post errors with no args', function(done) {
  314. hooks.pre('cook', function(done) {
  315. obj.waffles = false;
  316. done();
  317. });
  318. hooks.post('cook', function(callback) {
  319. obj.tofu = 'no';
  320. callback('error!');
  321. });
  322. var obj = { bacon: 0, eggs: 0 };
  323. var args = [];
  324. hooks.wrap(
  325. 'cook',
  326. function(callback) {
  327. callback();
  328. },
  329. obj,
  330. args);
  331. setTimeout(
  332. function() {
  333. assert.equal(false, obj.waffles);
  334. assert.equal('no', obj.tofu);
  335. done();
  336. },
  337. 25);
  338. });
  339. it('catches sync errors', function(done) {
  340. hooks.pre('cook', function(done) {
  341. done();
  342. });
  343. hooks.post('cook', function(callback) {
  344. callback();
  345. });
  346. var args = [];
  347. args.push(function(error) {
  348. assert.equal(error.message, 'oops!');
  349. done();
  350. });
  351. hooks.wrap(
  352. 'cook',
  353. function() {
  354. throw new Error('oops!');
  355. },
  356. null,
  357. args);
  358. });
  359. it('sync wrappers', function() {
  360. var calledPre = 0;
  361. var calledFn = 0;
  362. var calledPost = 0;
  363. hooks.pre('cook', function() {
  364. ++calledPre;
  365. });
  366. hooks.post('cook', function() {
  367. ++calledPost;
  368. });
  369. var wrapper = hooks.createWrapperSync('cook', function() { ++calledFn; });
  370. wrapper();
  371. assert.equal(calledPre, 1);
  372. assert.equal(calledFn, 1);
  373. assert.equal(calledPost, 1);
  374. });
  375. it('sync wrappers with overwriteResult', function() {
  376. hooks.pre('cook', function() {
  377. });
  378. hooks.post('cook', function() {
  379. return Kareem.overwriteResult(5);
  380. });
  381. const wrapper = hooks.createWrapperSync('cook', function() { return 4; });
  382. assert.strictEqual(wrapper(), 5);
  383. });
  384. });