import { beforeEach, describe, expect, it, vi } from 'vitest' const cancelFns: Array> = [] const axiosCancelTokenMock = vi.fn(function (this: any, executor: (cancel: ReturnType) => void) { const cancel = vi.fn() cancelFns.push(cancel) executor(cancel) this.__type = 'cancel-token' }) vi.mock('axios', () => ({ default: { CancelToken: axiosCancelTokenMock } })) import CancelToken from '../../../script/cancalToken' describe('CancelToken', () => { beforeEach(() => { CancelToken.pending.clear() CancelToken.whiteRequest = [] cancelFns.length = 0 axiosCancelTokenMock.mockClear() }) it('getUrl 会按 method 和 url 生成唯一键', () => { expect(CancelToken.getUrl({ method: 'get', url: '/users' })).toBe('get&/users') }) it('addPending 会创建 cancelToken 并把取消函数放入 pending', () => { const config: any = { method: 'get', url: '/users' } CancelToken.addPending(config) expect(axiosCancelTokenMock).toHaveBeenCalledTimes(1) expect(config.cancelToken).toBeDefined() expect(CancelToken.pending.get('get&/users')).toBe(cancelFns[0]) }) it('相同请求重复 addPending 时保留第一次注册的取消函数', () => { const config: any = { method: 'get', url: '/users' } CancelToken.addPending(config) CancelToken.addPending(config) expect(axiosCancelTokenMock).toHaveBeenCalledTimes(2) expect(CancelToken.pending.size).toBe(1) expect(CancelToken.pending.get('get&/users')).toBe(cancelFns[0]) }) it('removePending 会执行取消并删除对应 pending 项', () => { const config: any = { method: 'get', url: '/users' } CancelToken.addPending(config) CancelToken.removePending(config) expect(cancelFns[0]).toHaveBeenCalledWith('get&/users') expect(CancelToken.pending.has('get&/users')).toBe(false) }) it('whiteRequest 命中时 removePending 不会取消也不会删除', () => { const config: any = { method: 'get', url: '/users' } CancelToken.addPending(config) CancelToken.whiteRequest = ['/users'] CancelToken.removePending(config) expect(cancelFns[0]).not.toHaveBeenCalled() expect(CancelToken.pending.get('get&/users')).toBe(cancelFns[0]) }) it('removePending 对不存在的请求安全无异常', () => { expect(() => CancelToken.removePending({ method: 'post', url: '/missing' })).not.toThrow() }) it('clearPending 会取消所有请求并清空 pending', () => { CancelToken.addPending({ method: 'get', url: '/users' } as any) CancelToken.addPending({ method: 'post', url: '/roles' } as any) CancelToken.clearPending() expect(cancelFns[0]).toHaveBeenCalledWith('get&/users') expect(cancelFns[1]).toHaveBeenCalledWith('post&/roles') expect(CancelToken.pending.size).toBe(0) }) })