cluster_app_mock.js 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. 'use strict';
  2. const debug = require('debug')('egg-mock:middleware:cluster_app_mock');
  3. const is = require('is-type-of');
  4. const co = require('co');
  5. module.exports = () => {
  6. return function clusterAppMock(ctx, next) {
  7. if (ctx.path !== '/__egg_mock_call_function') return next();
  8. debug('%s %s, body: %j', ctx.method, ctx.url, ctx.request.body);
  9. const { method, property, args, needResult } = ctx.request.body;
  10. if (!method) {
  11. ctx.status = 422;
  12. ctx.body = {
  13. success: false,
  14. error: 'Missing method',
  15. };
  16. return;
  17. }
  18. if (args && !Array.isArray(args)) {
  19. ctx.status = 422;
  20. ctx.body = {
  21. success: false,
  22. error: 'args should be an Array instance',
  23. };
  24. return;
  25. }
  26. if (property) {
  27. if (!ctx.app[property] || typeof ctx.app[property][method] !== 'function') {
  28. ctx.status = 422;
  29. ctx.body = {
  30. success: false,
  31. error: `method "${method}" not exists on app.${property}`,
  32. };
  33. return;
  34. }
  35. } else {
  36. if (typeof ctx.app[method] !== 'function') {
  37. ctx.status = 422;
  38. ctx.body = {
  39. success: false,
  40. error: `method "${method}" not exists on app`,
  41. };
  42. return;
  43. }
  44. }
  45. debug('call %s with %j', method, args);
  46. for (let i = 0; i < args.length; i++) {
  47. const arg = args[i];
  48. if (arg && typeof arg === 'object') {
  49. // convert __egg_mock_type back to function
  50. if (arg.__egg_mock_type === 'function') {
  51. // eslint-disable-next-line
  52. args[i] = eval(`(function() { return ${arg.value} })()`);
  53. } else if (arg.__egg_mock_type === 'error') {
  54. const err = new Error(arg.message);
  55. err.name = arg.name;
  56. err.stack = arg.stack;
  57. for (const key in arg) {
  58. if (key !== 'name' && key !== 'message' && key !== 'stack' && key !== '__egg_mock_type') {
  59. err[key] = arg[key];
  60. }
  61. }
  62. args[i] = err;
  63. }
  64. }
  65. }
  66. const target = property ? ctx.app[property] : ctx.app;
  67. let fn = target[method];
  68. if (is.generatorFunction(fn)) fn = co.wrap(fn);
  69. try {
  70. Promise.resolve(fn.call(target, ...args)).then(result => {
  71. ctx.body = needResult ? { success: true, result } : { success: true };
  72. });
  73. } catch (err) {
  74. ctx.status = 500;
  75. ctx.body = { success: false, error: err.message };
  76. }
  77. };
  78. };