to-have-warned.ts 3.0 KB

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