mockWarn.ts 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. declare global {
  2. namespace jest {
  3. interface Matchers<R, T> {
  4. toHaveBeenWarned(): R
  5. toHaveBeenWarnedLast(): R
  6. toHaveBeenWarnedTimes(n: number): R
  7. }
  8. }
  9. }
  10. export const mockError = () => mockWarn(true)
  11. export function mockWarn(asError = false) {
  12. expect.extend({
  13. toHaveBeenWarned(received: string) {
  14. asserted.add(received)
  15. const passed = warn.mock.calls.some(
  16. args => args[0].indexOf(received) > -1
  17. )
  18. if (passed) {
  19. return {
  20. pass: true,
  21. message: () => `expected "${received}" not to have been warned.`
  22. }
  23. } else {
  24. const msgs = warn.mock.calls.map(args => args[0]).join('\n - ')
  25. return {
  26. pass: false,
  27. message: () =>
  28. `expected "${received}" to have been warned.\n\nActual messages:\n\n - ${msgs}`
  29. }
  30. }
  31. },
  32. toHaveBeenWarnedLast(received: string) {
  33. asserted.add(received)
  34. const passed =
  35. warn.mock.calls[warn.mock.calls.length - 1][0].indexOf(received) > -1
  36. if (passed) {
  37. return {
  38. pass: true,
  39. message: () => `expected "${received}" not to have been warned last.`
  40. }
  41. } else {
  42. const msgs = warn.mock.calls.map(args => args[0]).join('\n - ')
  43. return {
  44. pass: false,
  45. message: () =>
  46. `expected "${received}" to have been warned last.\n\nActual messages:\n\n - ${msgs}`
  47. }
  48. }
  49. },
  50. toHaveBeenWarnedTimes(received: string, n: number) {
  51. asserted.add(received)
  52. let found = 0
  53. warn.mock.calls.forEach(args => {
  54. if (args[0].indexOf(received) > -1) {
  55. found++
  56. }
  57. })
  58. if (found === n) {
  59. return {
  60. pass: true,
  61. message: () =>
  62. `expected "${received}" to have been warned ${n} times.`
  63. }
  64. } else {
  65. return {
  66. pass: false,
  67. message: () =>
  68. `expected "${received}" to have been warned ${n} times but got ${found}.`
  69. }
  70. }
  71. }
  72. })
  73. let warn: jest.SpyInstance
  74. const asserted: Set<string> = new Set()
  75. beforeEach(() => {
  76. asserted.clear()
  77. warn = jest.spyOn(console, asError ? 'error' : 'warn')
  78. warn.mockImplementation(() => {})
  79. })
  80. afterEach(() => {
  81. const assertedArray = Array.from(asserted)
  82. const nonAssertedWarnings = warn.mock.calls
  83. .map(args => args[0])
  84. .filter(received => {
  85. return !assertedArray.some(assertedMsg => {
  86. return received.indexOf(assertedMsg) > -1
  87. })
  88. })
  89. warn.mockRestore()
  90. if (nonAssertedWarnings.length) {
  91. nonAssertedWarnings.forEach(warning => {
  92. console.warn(warning)
  93. })
  94. throw new Error(`test case threw unexpected warnings.`)
  95. }
  96. })
  97. }