error.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /*
  2. * Should
  3. * Copyright(c) 2010-2014 TJ Holowaychuk <tj@vision-media.ca>
  4. * MIT Licensed
  5. */
  6. var util = require('../util');
  7. module.exports = function(should, Assertion) {
  8. var i = should.format;
  9. /**
  10. * Assert given function throws error with such message.
  11. *
  12. * @name throw
  13. * @memberOf Assertion
  14. * @category assertion errors
  15. * @alias Assertion#throwError
  16. * @param {string|RegExp|Function|Object|GeneratorFunction|GeneratorObject} [message] Message to match or properties
  17. * @param {Object} [properties] Optional properties that will be matched to thrown error
  18. * @example
  19. *
  20. * (function(){ throw new Error('fail') }).should.throw();
  21. * (function(){ throw new Error('fail') }).should.throw('fail');
  22. * (function(){ throw new Error('fail') }).should.throw(/fail/);
  23. *
  24. * (function(){ throw new Error('fail') }).should.throw(Error);
  25. * var error = new Error();
  26. * error.a = 10;
  27. * (function(){ throw error; }).should.throw(Error, { a: 10 });
  28. * (function(){ throw error; }).should.throw({ a: 10 });
  29. * (function*() {
  30. * yield throwError();
  31. * }).should.throw();
  32. */
  33. Assertion.add('throw', function(message, properties) {
  34. var fn = this.obj
  35. , err = {}
  36. , errorInfo = ''
  37. , thrown = false;
  38. if(util.isGeneratorFunction(fn)) {
  39. return should(fn()).throw(message, properties);
  40. } else if(util.isGeneratorObject(fn)) {
  41. return should(fn.next.bind(fn)).throw(message, properties);
  42. }
  43. this.is.a.Function();
  44. var errorMatched = true;
  45. try {
  46. fn();
  47. } catch(e) {
  48. thrown = true;
  49. err = e;
  50. }
  51. if(thrown) {
  52. if(message) {
  53. if('string' == typeof message) {
  54. errorMatched = message == err.message;
  55. } else if(message instanceof RegExp) {
  56. errorMatched = message.test(err.message);
  57. } else if('function' == typeof message) {
  58. errorMatched = err instanceof message;
  59. } else if(null != message) {
  60. try {
  61. should(err).match(message);
  62. } catch(e) {
  63. if(e instanceof should.AssertionError) {
  64. errorInfo = ": " + e.message;
  65. errorMatched = false;
  66. } else {
  67. throw e;
  68. }
  69. }
  70. }
  71. if(!errorMatched) {
  72. if('string' == typeof message || message instanceof RegExp) {
  73. errorInfo = " with a message matching " + i(message) + ", but got '" + err.message + "'";
  74. } else if('function' == typeof message) {
  75. errorInfo = " of type " + util.functionName(message) + ", but got " + util.functionName(err.constructor);
  76. }
  77. } else if('function' == typeof message && properties) {
  78. try {
  79. should(err).match(properties);
  80. } catch(e) {
  81. if(e instanceof should.AssertionError) {
  82. errorInfo = ": " + e.message;
  83. errorMatched = false;
  84. } else {
  85. throw e;
  86. }
  87. }
  88. }
  89. } else {
  90. errorInfo = " (got " + i(err) + ")";
  91. }
  92. }
  93. this.params = { operator: 'to throw exception' + errorInfo };
  94. this.assert(thrown);
  95. this.assert(errorMatched);
  96. });
  97. Assertion.alias('throw', 'throwError');
  98. };