|
|
@@ -0,0 +1,104 @@
|
|
|
+import test from 'node:test'
|
|
|
+import assert from 'node:assert/strict'
|
|
|
+import fs from 'node:fs'
|
|
|
+import path from 'node:path'
|
|
|
+import vm from 'node:vm'
|
|
|
+
|
|
|
+const homeFile = path.resolve('pages/home.vue')
|
|
|
+const flushPromises = () => new Promise(resolve => setImmediate(resolve))
|
|
|
+
|
|
|
+function deferred () {
|
|
|
+ let resolve
|
|
|
+ const promise = new Promise(done => { resolve = done })
|
|
|
+ return { promise, resolve }
|
|
|
+}
|
|
|
+
|
|
|
+function mountHomePage () {
|
|
|
+ const source = fs.readFileSync(homeFile, 'utf8')
|
|
|
+ const script = source.match(/<script setup[^>]*>([\s\S]*?)<\/script>/)[1]
|
|
|
+ .replace(/^\s*import\s+.*$/gm, '') +
|
|
|
+ '\nglobalThis.__home = { changeType, activityList, queryParams }'
|
|
|
+
|
|
|
+ const lifecycle = {}
|
|
|
+ const activityRequests = []
|
|
|
+ const api = {
|
|
|
+ get (url, params) {
|
|
|
+ if (url === '/core/advertisement/manage/page') {
|
|
|
+ return Promise.resolve({ data: { code: 0, data: { list: [] } } })
|
|
|
+ }
|
|
|
+ if (url === '/core/activity/category/list') {
|
|
|
+ return Promise.resolve({
|
|
|
+ data: {
|
|
|
+ code: 0,
|
|
|
+ data: [{ id: 'category-1', categoryName: '分类一', iconUrl: 'icon.png' }]
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ if (url === '/core/activity/page') {
|
|
|
+ const request = deferred()
|
|
|
+ activityRequests.push({ params: { ...params }, ...request })
|
|
|
+ return request.promise
|
|
|
+ }
|
|
|
+ throw new Error(`unexpected request: ${url}`)
|
|
|
+ },
|
|
|
+ post () {
|
|
|
+ return Promise.resolve({ data: { code: 0 } })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const selectorQuery = {
|
|
|
+ in () { return this },
|
|
|
+ select () { return this },
|
|
|
+ boundingClientRect () { return this },
|
|
|
+ exec (callback) { callback([]) }
|
|
|
+ }
|
|
|
+ const context = {
|
|
|
+ ref: value => ({ value }),
|
|
|
+ computed: getter => ({ get value () { return getter() } }),
|
|
|
+ getCurrentInstance: () => ({ proxy: { $api: api, $showToast: () => {} } }),
|
|
|
+ onMounted: callback => { lifecycle.mounted = callback },
|
|
|
+ nextTick: callback => callback(),
|
|
|
+ watch: () => {},
|
|
|
+ useUserStore: () => ({ token: '' }),
|
|
|
+ onLoad: () => {},
|
|
|
+ onShareAppMessage: () => {},
|
|
|
+ onShareTimeline: () => {},
|
|
|
+ onPullDownRefresh: () => {},
|
|
|
+ uni: {
|
|
|
+ getStorageSync: () => '',
|
|
|
+ createSelectorQuery: () => selectorQuery,
|
|
|
+ stopPullDownRefresh: () => {}
|
|
|
+ },
|
|
|
+ Date,
|
|
|
+ console
|
|
|
+ }
|
|
|
+ vm.runInNewContext(script, context)
|
|
|
+ lifecycle.mounted()
|
|
|
+
|
|
|
+ return { home: context.__home, activityRequests }
|
|
|
+}
|
|
|
+
|
|
|
+test('点击分类后忽略晚到的全部活动响应', async () => {
|
|
|
+ const { home, activityRequests } = mountHomePage()
|
|
|
+ await flushPromises()
|
|
|
+
|
|
|
+ assert.equal(activityRequests.length, 1)
|
|
|
+ assert.equal(activityRequests[0].params.categoryId, '')
|
|
|
+
|
|
|
+ home.changeType({ id: 'category-1' })
|
|
|
+ assert.equal(activityRequests.length, 2)
|
|
|
+ assert.equal(activityRequests[1].params.categoryId, 'category-1')
|
|
|
+
|
|
|
+ activityRequests[1].resolve({
|
|
|
+ data: { code: 0, data: { list: [{ id: 'filtered-activity' }] } }
|
|
|
+ })
|
|
|
+ await flushPromises()
|
|
|
+ assert.deepEqual(Array.from(home.activityList.value, item => item.id), ['filtered-activity'])
|
|
|
+
|
|
|
+ activityRequests[0].resolve({
|
|
|
+ data: { code: 0, data: { list: [{ id: 'stale-all-activity' }] } }
|
|
|
+ })
|
|
|
+ await flushPromises()
|
|
|
+
|
|
|
+ assert.deepEqual(Array.from(home.activityList.value, item => item.id), ['filtered-activity'])
|
|
|
+ assert.equal(home.queryParams.value.categoryId, 'category-1')
|
|
|
+})
|