error.spec.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import Alpine from 'alpinejs'
  2. import { wait } from '@testing-library/dom'
  3. global.MutationObserver = class {
  4. observe() {}
  5. }
  6. jest.spyOn(window, 'setTimeout').mockImplementation((callback) => {
  7. callback()
  8. })
  9. const mockConsoleError = jest.spyOn(console, 'error').mockImplementation(() => {})
  10. beforeEach(() => {
  11. jest.clearAllMocks()
  12. })
  13. test('error in x-data eval contains element, expression and original error', async () => {
  14. document.body.innerHTML = `
  15. <div x-data="{ foo: 'bar' ">
  16. <span x-bind:foo="foo.bar"></span>
  17. </div>
  18. `
  19. await expect(Alpine.start()).rejects.toThrow()
  20. expect(mockConsoleError).toHaveBeenCalledWith(
  21. "Alpine: error in expression \"{ foo: 'bar' \" in component:",
  22. document.querySelector('[x-data]'),
  23. "due to \"SyntaxError: Unexpected token ')'\""
  24. )
  25. })
  26. test('error in x-init eval contains element, expression and original error', async () => {
  27. document.body.innerHTML = `
  28. <div x-data x-init="foo.bar = 'baz'">
  29. </div>
  30. `
  31. await Alpine.start()
  32. expect(mockConsoleError).toHaveBeenCalledWith(
  33. "Alpine: error in expression \"foo.bar = 'baz'\" in component:",
  34. document.querySelector('[x-data]'),
  35. "due to \"ReferenceError: foo is not defined\""
  36. )
  37. })
  38. test('error in x-spread eval contains element, expression and original error', async () => {
  39. document.body.innerHTML = `
  40. <div x-data x-spread="foo.bar">
  41. </div>
  42. `
  43. // swallow the rendering error
  44. await expect(Alpine.start()).rejects.toThrow()
  45. expect(mockConsoleError).toHaveBeenCalledWith(
  46. "Alpine: error in expression \"foo.bar\" in component:",
  47. document.querySelector('[x-data]'),
  48. "due to \"ReferenceError: foo is not defined\""
  49. )
  50. })
  51. test('error in x-bind eval contains element, expression and original error', async () => {
  52. document.body.innerHTML = `
  53. <div x-data="{ foo: null }">
  54. <span x-bind:foo="foo.bar"></span>
  55. </div>
  56. `
  57. await Alpine.start()
  58. expect(mockConsoleError).toHaveBeenCalledWith(
  59. "Alpine: error in expression \"foo.bar\" in component:",
  60. document.querySelector('[x-bind:foo]'),
  61. "due to \"TypeError: Cannot read property 'bar' of null\""
  62. )
  63. })
  64. test('error in x-model eval contains element, expression and original error', async () => {
  65. document.body.innerHTML = `
  66. <div x-data="{ foo: null }">
  67. <input x-model="foo.bar">
  68. </div>
  69. `
  70. await Alpine.start()
  71. expect(mockConsoleError).toHaveBeenCalledWith(
  72. "Alpine: error in expression \"foo.bar\" in component:",
  73. document.querySelector('[x-model]'),
  74. "due to \"TypeError: Cannot read property 'bar' of null\""
  75. )
  76. })
  77. test('error in x-for eval contains element, expression and original error', async () => {
  78. document.body.innerHTML = `
  79. <div x-data="{}">
  80. <template x-for="element in foo">
  81. <span x-text="element"></span>
  82. </template>
  83. </div>
  84. `
  85. await expect(Alpine.start()).rejects.toThrow()
  86. expect(mockConsoleError).toHaveBeenCalledWith(
  87. "Alpine: error in expression \"foo\" in component:",
  88. document.querySelector('[x-for]'),
  89. "due to \"ReferenceError: foo is not defined\""
  90. )
  91. })
  92. test('error in x-on eval contains element, expression and original error', async () => {
  93. document.body.innerHTML = `
  94. <div
  95. x-data="{hello: null}"
  96. x-on:click="hello.world"
  97. ></div>
  98. `
  99. await Alpine.start()
  100. document.querySelector('div').click()
  101. await wait(() => {
  102. expect(mockConsoleError).toHaveBeenCalledWith(
  103. "Alpine: error in expression \"hello.world\" in component:",
  104. document.querySelector('[x-data]'),
  105. "due to \"TypeError: Cannot read property 'world' of null\""
  106. )
  107. })
  108. })