activity-area-hot-city.test.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. import test from 'node:test'
  2. import assert from 'node:assert/strict'
  3. import fs from 'node:fs'
  4. import path from 'node:path'
  5. import vm from 'node:vm'
  6. const areaFile = path.resolve('components/pages/activityArea/index.vue')
  7. const flushPromises = () => new Promise(resolve => setImmediate(resolve))
  8. const regionRows = [
  9. { id: '320000', pid: '0', name: '江苏省' },
  10. { id: '320100', pid: '320000', name: '南京市' },
  11. { id: '320102', pid: '320100', name: '玄武区' },
  12. { id: '320500', pid: '320000', name: '苏州市' },
  13. { id: '320505', pid: '320500', name: '虎丘区' },
  14. { id: '440000', pid: '0', name: '广东省' },
  15. { id: '440100', pid: '440000', name: '广州市' },
  16. { id: '440103', pid: '440100', name: '荔湾区' },
  17. { id: '440300', pid: '440000', name: '深圳市' },
  18. { id: '440303', pid: '440300', name: '罗湖区' }
  19. ]
  20. async function mountActivityArea () {
  21. const source = fs.readFileSync(areaFile, 'utf8')
  22. const script = source.match(/<script setup[^>]*>([\s\S]*?)<\/script>/)[1]
  23. .replace(/^\s*import\s+.*$/gm, '') +
  24. '\nglobalThis.__area = { handleHotCityClick, handlePickerStart, handlePickerChange, handleReset, handleConfirm, pickerValue }'
  25. const lifecycle = {}
  26. const emitted = []
  27. const nextTicks = []
  28. const context = {
  29. ref: value => ({ value }),
  30. computed: getter => ({ get value () { return getter() } }),
  31. watch: () => {},
  32. nextTick: callback => nextTicks.push(callback),
  33. getCurrentInstance: () => ({
  34. proxy: {
  35. $api: {
  36. get: () => Promise.resolve({ data: { code: 0, data: regionRows } })
  37. }
  38. }
  39. }),
  40. defineEmits: () => (name, payload) => emitted.push({ name, payload }),
  41. defineExpose: () => {},
  42. onMounted: callback => { lifecycle.mounted = callback },
  43. uni: { showToast: () => {} },
  44. console
  45. }
  46. vm.runInNewContext(script, context)
  47. lifecycle.mounted()
  48. await flushPromises()
  49. return {
  50. area: context.__area,
  51. emitted,
  52. flushNextTicks: () => {
  53. while (nextTicks.length) nextTicks.shift()()
  54. }
  55. }
  56. }
  57. test('点击非省会热门城市后保持目标城市而不是回退到省会', async () => {
  58. const cases = [
  59. { hotCity: '苏州', staleValue: [0, 0, 0], city: '苏州市', cityId: '320500', area: '虎丘区' },
  60. { hotCity: '深圳', staleValue: [1, 0, 0], city: '深圳市', cityId: '440300', area: '罗湖区' }
  61. ]
  62. for (const expected of cases) {
  63. const { area, emitted, flushNextTicks } = await mountActivityArea()
  64. area.handleHotCityClick(expected.hotCity)
  65. flushNextTicks()
  66. // picker-view 的上一轮滚动动画可能在程序化定位后才派发 change。
  67. area.handlePickerChange({ detail: { value: expected.staleValue } })
  68. area.handleConfirm()
  69. const result = emitted.at(-1).payload
  70. assert.equal(result.city, expected.city)
  71. assert.equal(result.cityId, expected.cityId)
  72. assert.equal(result.area, expected.area)
  73. }
  74. })
  75. test('连续点击热门城市时以最后一次选择为准', async () => {
  76. const { area, emitted, flushNextTicks } = await mountActivityArea()
  77. area.handleHotCityClick('苏州')
  78. area.handleHotCityClick('深圳')
  79. flushNextTicks()
  80. area.handleConfirm()
  81. const result = emitted.at(-1).payload
  82. assert.equal(result.province, '广东省')
  83. assert.equal(result.city, '深圳市')
  84. assert.equal(result.cityId, '440300')
  85. assert.equal(result.area, '罗湖区')
  86. })
  87. test('热门城市定位后仍允许手动滚动和重置', async () => {
  88. const { area, emitted, flushNextTicks } = await mountActivityArea()
  89. area.handleHotCityClick('苏州')
  90. flushNextTicks()
  91. area.handlePickerStart()
  92. area.handlePickerChange({ detail: { value: [0, 0, 0] } })
  93. area.handleConfirm()
  94. assert.equal(emitted.at(-1).payload.city, '南京市')
  95. area.handleHotCityClick('深圳')
  96. flushNextTicks()
  97. area.handleReset()
  98. area.handleConfirm()
  99. assert.equal(emitted.at(-1).payload.province, '江苏省')
  100. assert.equal(emitted.at(-1).payload.city, '南京市')
  101. assert.equal(emitted.at(-1).payload.area, '玄武区')
  102. })