mockWarn.ts 2.7 KB

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