mobile-pl-plan-date-field.test.ts 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import assert from 'node:assert/strict'
  2. import { readFileSync } from 'node:fs'
  3. import test from 'node:test'
  4. import { parse } from '@vue/compiler-sfc'
  5. import ts from 'typescript'
  6. import { effectScope, nextTick, reactive, ref, watch } from 'vue'
  7. const source = parse(
  8. readFileSync(new URL('../src/views/m/pl/plan/PlanDateField.vue', import.meta.url), 'utf8')
  9. ).descriptor.scriptSetup!.content
  10. function harness() {
  11. const props = reactive({
  12. modelValue: '2026-10-24',
  13. label: '计划日期',
  14. clearable: true,
  15. required: false,
  16. readonly: false,
  17. disabled: false
  18. })
  19. const events: any[] = []
  20. const scope = effectScope()
  21. const bindings = {
  22. ref,
  23. watch,
  24. defineProps: () => props,
  25. defineEmits:
  26. () =>
  27. (...args: any[]) =>
  28. events.push(args)
  29. }
  30. const field = scope.run(() =>
  31. new Function(
  32. ...Object.keys(bindings),
  33. ts.transpile(source, { target: ts.ScriptTarget.ESNext }) +
  34. ';return {open,selected,openPicker,confirm,clear}'
  35. )(...Object.values(bindings))
  36. )
  37. return { props, events, field, scope }
  38. }
  39. test('Vant date field prefills saved date and only emits confirmed selection', () => {
  40. const h = harness()
  41. try {
  42. h.field.openPicker()
  43. assert.deepEqual(h.field.selected.value, ['2026', '10', '24'])
  44. h.field.selected.value = ['2026', '10', '25']
  45. h.field.open.value = false
  46. h.field.confirm({ selectedValues: ['2026', '10', '25'] })
  47. assert.deepEqual(h.events, [])
  48. h.field.openPicker()
  49. h.field.confirm({ selectedValues: ['2026', '10', '26'] })
  50. assert.deepEqual(h.events, [['update:modelValue', '2026-10-26']])
  51. assert.equal(h.field.open.value, false)
  52. } finally {
  53. h.scope.stop()
  54. }
  55. })
  56. test('readonly and disabled dates cannot open; external changes invalidate pending selection', async () => {
  57. const h = harness()
  58. try {
  59. h.props.readonly = true
  60. h.field.openPicker()
  61. assert.equal(h.field.open.value, false)
  62. h.props.readonly = false
  63. h.props.disabled = true
  64. h.field.openPicker()
  65. assert.equal(h.field.open.value, false)
  66. h.props.disabled = false
  67. await nextTick()
  68. h.field.openPicker()
  69. h.props.modelValue = '2026-11-01'
  70. await nextTick()
  71. assert.equal(h.field.open.value, false)
  72. h.field.confirm({ selectedValues: ['2026', '10', '26'] })
  73. assert.deepEqual(h.events, [])
  74. h.field.openPicker()
  75. assert.deepEqual(h.field.selected.value, ['2026', '11', '01'])
  76. } finally {
  77. h.scope.stop()
  78. }
  79. })
  80. test('date can only be cleared from an open optional editable picker', () => {
  81. const h = harness()
  82. try {
  83. h.field.clear()
  84. assert.deepEqual(h.events, [])
  85. for (const key of ['readonly', 'disabled', 'required'] as const) {
  86. h.field.open.value = true
  87. h.props[key] = true
  88. h.field.clear()
  89. assert.deepEqual(h.events, [])
  90. h.props[key] = false
  91. }
  92. h.props.clearable = false
  93. h.field.clear()
  94. assert.deepEqual(h.events, [])
  95. h.props.clearable = true
  96. h.field.openPicker()
  97. h.field.clear()
  98. assert.deepEqual(h.events, [['update:modelValue', '']])
  99. assert.equal(h.field.open.value, false)
  100. } finally {
  101. h.scope.stop()
  102. }
  103. })