calendar.test.tsx 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. import { nextTick } from 'vue'
  2. import { mount } from '@vue/test-utils'
  3. import { describe, expect, it } from 'vitest'
  4. import updateLocale from 'dayjs/plugin/updateLocale'
  5. import dayjs from 'dayjs'
  6. import Calendar from '../src/calendar.vue'
  7. const AXIOM = 'Rem is the best girl'
  8. const setDayjsWeekStart = (weekStart = 0) => {
  9. dayjs.extend(updateLocale)
  10. const dayjsLocale = dayjs.locale()
  11. dayjs.updateLocale(dayjsLocale, {
  12. weekStart,
  13. })
  14. }
  15. describe('Calendar.vue', () => {
  16. it('create', async () => {
  17. const wrapper = mount({
  18. data: () => ({ value: new Date('2019-04-01') }),
  19. render() {
  20. return <Calendar v-model={this.value} />
  21. },
  22. })
  23. const titleEl = wrapper.find('.el-calendar__title')
  24. expect(/2019.*April/.test(titleEl.element?.innerHTML)).toBeTruthy()
  25. expect(wrapper.element.querySelectorAll('thead th').length).toBe(7)
  26. const rows = wrapper.element.querySelectorAll('.el-calendar-table__row')
  27. expect(rows.length).toBe(5)
  28. ;(rows[4].lastElementChild as HTMLElement).click()
  29. await nextTick()
  30. expect(/2019.*May/.test(titleEl.element.innerHTML)).toBeTruthy()
  31. const vm = wrapper.vm
  32. const date = vm.value
  33. expect(date.getFullYear()).toBe(2019)
  34. expect(date.getMonth()).toBe(4)
  35. expect(wrapper.find('.is-selected span').element.innerHTML).toBe('4')
  36. })
  37. it('range', () => {
  38. const wrapper = mount(() => (
  39. <Calendar range={[new Date(2019, 2, 4), new Date(2019, 2, 24)]} />
  40. ))
  41. const titleEl = wrapper.find('.el-calendar__title')
  42. expect(/2019.*March/.test(titleEl.element.innerHTML)).toBeTruthy()
  43. const rows = wrapper.element.querySelectorAll('.el-calendar-table__row')
  44. expect(rows.length).toBe(4)
  45. expect(
  46. wrapper.element.querySelector('.el-calendar__button-group')
  47. ).toBeNull()
  48. })
  49. // https://github.com/element-plus/element-plus/issues/3155
  50. it('range when the start date will be calculated to last month', () => {
  51. const wrapper = mount(() => (
  52. <Calendar range={[new Date(2021, 1, 2), new Date(2021, 1, 28)]} />
  53. ))
  54. const titleEl = wrapper.find('.el-calendar__title')
  55. expect(/2021.*January/.test(titleEl.element.innerHTML)).toBeTruthy()
  56. const rows = wrapper.element.querySelectorAll('.el-calendar-table__row')
  57. expect(rows.length).toBe(5)
  58. expect(
  59. wrapper.element.querySelector('.el-calendar__button-group')
  60. ).toBeNull()
  61. })
  62. it('range tow monthes', async () => {
  63. const wrapper = mount(() => (
  64. <Calendar range={[new Date(2019, 3, 14), new Date(2019, 4, 18)]} />
  65. ))
  66. const titleEl = wrapper.find('.el-calendar__title')
  67. expect(/2019.*April/.test(titleEl.element.innerHTML)).toBeTruthy()
  68. const dateTables = wrapper.element.querySelectorAll(
  69. '.el-calendar-table.is-range'
  70. )
  71. expect(dateTables.length).toBe(2)
  72. const rows = wrapper.element.querySelectorAll('.el-calendar-table__row')
  73. expect(rows.length).toBe(5)
  74. const cell = rows[rows.length - 1].firstElementChild as HTMLElement
  75. cell.click()
  76. await nextTick()
  77. expect(/2019.*May/.test(titleEl.element.innerHTML)).toBeTruthy()
  78. expect(cell?.classList.contains('is-selected')).toBeTruthy()
  79. })
  80. // https://github.com/element-plus/element-plus/issues/3155
  81. it('range tow monthes when the start date will be calculated to last month', async () => {
  82. const wrapper = mount(() => (
  83. <Calendar range={[new Date(2021, 1, 2), new Date(2021, 2, 21)]} />
  84. ))
  85. const titleEl = wrapper.find('.el-calendar__title')
  86. expect(/2021.*January/.test(titleEl.element.innerHTML)).toBeTruthy()
  87. const dateTables = wrapper.element.querySelectorAll(
  88. '.el-calendar-table.is-range'
  89. )
  90. expect(dateTables.length).toBe(3)
  91. const rows = wrapper.element.querySelectorAll('.el-calendar-table__row')
  92. expect(rows.length).toBe(8)
  93. const cell = rows[rows.length - 1].firstElementChild as HTMLElement
  94. cell.click()
  95. await nextTick()
  96. expect(/2021.*March/.test(titleEl.element.innerHTML)).toBeTruthy()
  97. expect(cell?.classList.contains('is-selected')).toBeTruthy()
  98. })
  99. it('firstDayOfWeek', async () => {
  100. // default en locale, weekStart 0 Sunday
  101. const wrapper = mount({
  102. data: () => ({ value: new Date('2019-04-01') }),
  103. render() {
  104. return <Calendar v-model={this.value} />
  105. },
  106. })
  107. const head = wrapper.element.querySelector('.el-calendar-table thead')
  108. expect(head?.firstElementChild?.innerHTML).toBe('Sun')
  109. expect(head?.lastElementChild?.innerHTML).toBe('Sat')
  110. const firstRow = wrapper.element.querySelector('.el-calendar-table__row')
  111. expect(firstRow?.firstElementChild?.innerHTML).toContain('31')
  112. expect(firstRow?.lastElementChild?.innerHTML).toContain('6')
  113. })
  114. it('firstDayOfWeek when set 1', async () => {
  115. setDayjsWeekStart(1)
  116. const wrapper = mount({
  117. data: () => ({ value: new Date('2019-09-01') }),
  118. render() {
  119. return <Calendar v-model={this.value} />
  120. },
  121. })
  122. const head = wrapper.element.querySelector('.el-calendar-table thead')
  123. expect(head?.firstElementChild?.innerHTML).toBe('Mon')
  124. expect(head?.lastElementChild?.innerHTML).toBe('Sun')
  125. const firstRow = wrapper.element.querySelector('.el-calendar-table__row')
  126. expect(firstRow?.firstElementChild?.innerHTML).toContain('26')
  127. expect(firstRow?.lastElementChild?.innerHTML).toContain('1')
  128. const rows = wrapper.element.querySelectorAll('.el-calendar-table__row')
  129. expect(rows.length).toBe(6)
  130. // reset weekStart 0
  131. setDayjsWeekStart()
  132. })
  133. it('firstDayOfWeek in range mode', async () => {
  134. const wrapper = mount({
  135. data: () => ({ value: new Date('2019-03-04') }),
  136. render() {
  137. return (
  138. <Calendar
  139. v-model={this.value}
  140. range={[new Date(2019, 1, 3), new Date(2019, 2, 23)]}
  141. />
  142. )
  143. },
  144. })
  145. const head = wrapper.element.querySelector('.el-calendar-table thead')
  146. expect(head?.firstElementChild?.innerHTML).toBe('Sun')
  147. expect(head?.lastElementChild?.innerHTML).toBe('Sat')
  148. const firstRow = wrapper.element.querySelector('.el-calendar-table__row')
  149. expect(firstRow?.firstElementChild?.innerHTML).toContain('3')
  150. expect(firstRow?.lastElementChild?.innerHTML).toContain('9')
  151. })
  152. it('click previous month or next month', async () => {
  153. const wrapper = mount({
  154. data: () => ({ value: new Date('2019-04-01') }),
  155. render() {
  156. return <Calendar v-model={this.value} />
  157. },
  158. })
  159. await nextTick()
  160. const btns = wrapper.findAll('.el-button')
  161. const prevBtn = btns.at(0)
  162. const nextBtn = btns.at(2)
  163. await prevBtn?.trigger('click')
  164. expect(wrapper.find('.is-selected').text()).toBe('1')
  165. await nextBtn?.trigger('click')
  166. expect(wrapper.find('.is-selected').text()).toBe('1')
  167. })
  168. it('range two years', async () => {
  169. const wrapper = mount(() => (
  170. <Calendar range={[new Date(2022, 0, 1), new Date(2022, 0, 31)]} />
  171. ))
  172. const titleEl = wrapper.find('.el-calendar__title')
  173. expect(/2021.*December/.test(titleEl.element.innerHTML)).toBeTruthy()
  174. const dateTables = wrapper.element.querySelectorAll(
  175. '.el-calendar-table.is-range'
  176. )
  177. expect(dateTables.length).toBe(3)
  178. const rows = wrapper.element.querySelectorAll('.el-calendar-table__row')
  179. expect(rows.length).toBe(6)
  180. const cell = rows[rows.length - 1].firstElementChild as HTMLElement
  181. cell.click()
  182. await nextTick()
  183. expect(/2022.*January/.test(titleEl.element.innerHTML)).toBeTruthy()
  184. expect(cell?.classList.contains('is-selected')).toBeTruthy()
  185. })
  186. it('range two years', async () => {
  187. const wrapper = mount(() => (
  188. <Calendar range={[new Date(2021, 11, 20), new Date(2022, 0, 10)]} />
  189. ))
  190. const titleEl = wrapper.find('.el-calendar__title')
  191. expect(/2021.*December/.test(titleEl.element.innerHTML)).toBeTruthy()
  192. const dateTables = wrapper.element.querySelectorAll(
  193. '.el-calendar-table.is-range'
  194. )
  195. expect(dateTables.length).toBe(2)
  196. const rows = wrapper.element.querySelectorAll('.el-calendar-table__row')
  197. expect(rows.length).toBe(4)
  198. const cell = rows[rows.length - 1].firstElementChild as HTMLElement
  199. cell.click()
  200. await nextTick()
  201. expect(/2022.*January/.test(titleEl.element.innerHTML)).toBeTruthy()
  202. expect(cell?.classList.contains('is-selected')).toBeTruthy()
  203. })
  204. it('slots', async () => {
  205. const wrapper = mount(() => (
  206. <Calendar
  207. v-slots={{
  208. header: () => AXIOM,
  209. 'date-cell': () => AXIOM,
  210. }}
  211. />
  212. ))
  213. expect(wrapper.find('.el-calendar__header').text()).toEqual(AXIOM)
  214. expect(wrapper.find('.current.is-today').text()).toEqual(AXIOM)
  215. })
  216. })