pull/1/head
parent
b505dade41
commit
1f4f65ffd1
|
@ -33,10 +33,10 @@ $ npm i axios-miniprogram
|
|||
|
||||
## 使用
|
||||
|
||||
可以通过将相关配置传递给`axios`来发送请求。
|
||||
|
||||
### `axios(config)`
|
||||
|
||||
可以通过将相关配置传递给`axios`来发送请求。
|
||||
|
||||
```typescript
|
||||
// 发送 GET 请求
|
||||
axios({
|
||||
|
@ -61,10 +61,10 @@ axios({
|
|||
});
|
||||
```
|
||||
|
||||
也可以通过直接把`url`传给`axios`来发送请求。
|
||||
|
||||
### `axios(url, config?)`
|
||||
|
||||
也可以通过直接把`url`传给`axios`来发送请求。
|
||||
|
||||
```typescript
|
||||
// 默认发送 GET 请求
|
||||
axios('/test/xxx').then((response) => {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "axios-miniprogram",
|
||||
"version": "1.0.7",
|
||||
"version": "1.0.9",
|
||||
"description": "基于 Promise 的 HTTP 请求库,适用于各大小程序平台。",
|
||||
"main": "package/index.js",
|
||||
"miniprogram": "package",
|
||||
|
|
|
@ -2,43 +2,58 @@
|
|||
* @Author: early-autumn
|
||||
* @Date: 2020-04-17 12:18:25
|
||||
* @LastEditors: early-autumn
|
||||
* @LastEditTime: 2020-04-20 01:14:16
|
||||
* @LastEditTime: 2020-04-20 21:51:02
|
||||
*/
|
||||
import { Adapter, Platform } from './types';
|
||||
import warning from './helpers/warning';
|
||||
|
||||
// 微信小程序
|
||||
declare let wx: Platform;
|
||||
// 支付宝小程序
|
||||
declare let my: Platform;
|
||||
// 百度小程序
|
||||
declare let swan: Platform;
|
||||
// 字节跳动小程序
|
||||
declare let tt: Platform;
|
||||
// QQ 小程序
|
||||
declare let qq: Platform;
|
||||
// uniapp
|
||||
declare let uni: Platform;
|
||||
|
||||
const platformList = [
|
||||
() => wx.request,
|
||||
() => my.request,
|
||||
() => swan.request,
|
||||
() => tt.request,
|
||||
() => qq.request,
|
||||
() => uni.request,
|
||||
];
|
||||
|
||||
/**
|
||||
* 设置当前平台适配器
|
||||
*
|
||||
* 使用 try + catch递归 的方式实现平台的查找, 解决 typescript 开发时, wx,my,... 等全局变量未定义可能会报错导致程序被中止的问题
|
||||
*
|
||||
* 比如 ReferenceError: wx is not defined
|
||||
*/
|
||||
function adaptive(): Adapter | undefined {
|
||||
switch (true) {
|
||||
// 微信小程序
|
||||
case wx !== undefined:
|
||||
return wx.request;
|
||||
// 支付宝小程序
|
||||
case my !== undefined:
|
||||
return my.request ?? my.httpRequest;
|
||||
// 百度小程序
|
||||
case swan !== undefined:
|
||||
return swan.request;
|
||||
// 字节跳动小程序
|
||||
case tt !== undefined:
|
||||
return tt.request;
|
||||
// QQ 小程序
|
||||
case qq !== undefined:
|
||||
return qq.request;
|
||||
// uniapp
|
||||
case uni !== undefined:
|
||||
return uni.request;
|
||||
default:
|
||||
warning('暂未适配此平台,您需要参阅文档使用自定义适配器手动适配当前平台');
|
||||
function adaptive(adapter?: Adapter): Adapter | undefined {
|
||||
if (adapter !== undefined) {
|
||||
return adapter;
|
||||
}
|
||||
|
||||
let request: Adapter | undefined;
|
||||
|
||||
try {
|
||||
const platform = platformList.shift();
|
||||
|
||||
if (platform === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
request = platform();
|
||||
|
||||
throw 'next';
|
||||
} catch (err) {
|
||||
return adaptive(request);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* @Author: early-autumn
|
||||
* @Date: 2020-04-15 12:45:18
|
||||
* @LastEditors: early-autumn
|
||||
* @LastEditTime: 2020-04-20 09:27:03
|
||||
* @LastEditTime: 2020-04-20 14:48:03
|
||||
*/
|
||||
import { AxiosRequestConfig, Data, AxiosResponse, AxiosBaseInstance, AxiosInstance } from './types';
|
||||
import Axios from './core/Axios';
|
||||
|
@ -50,8 +50,10 @@ function createInstance(config: AxiosRequestConfig): AxiosInstance {
|
|||
return instance.request(requestConfig);
|
||||
}
|
||||
|
||||
// Axios 实例的所有属性和方法合并至 axios 函数
|
||||
Object.assign(axios, instance, Object.getPrototypeOf(instance));
|
||||
// instance 的属性设置到 axios 函数中
|
||||
Object.assign(axios, instance);
|
||||
// instance 的方法设置到 axios 函数中
|
||||
Object.setPrototypeOf(axios, Object.getPrototypeOf(instance));
|
||||
|
||||
return axios as AxiosInstance;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* @Author: early-autumn
|
||||
* @Date: 2020-04-14 09:23:25
|
||||
* @LastEditors: early-autumn
|
||||
* @LastEditTime: 2020-04-17 09:27:59
|
||||
* @LastEditTime: 2020-04-20 15:15:27
|
||||
*/
|
||||
import Cancel from './Cancel';
|
||||
|
||||
|
@ -11,6 +11,6 @@ import Cancel from './Cancel';
|
|||
*
|
||||
* @param value 判断的值
|
||||
*/
|
||||
export default function isCancel(value: any) {
|
||||
return value && value instanceof Cancel;
|
||||
export default function isCancel(value: any): boolean {
|
||||
return !!value && value instanceof Cancel;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* @Author: early-autumn
|
||||
* @Date: 2020-04-13 18:00:27
|
||||
* @LastEditors: early-autumn
|
||||
* @LastEditTime: 2020-04-20 09:12:46
|
||||
* @LastEditTime: 2020-04-20 13:21:44
|
||||
*/
|
||||
import { Method, Params, Data, Interceptors, AxiosRequestConfig, AxiosResponse, Axios } from '../types';
|
||||
import buildURL from '../helpers/buildURL';
|
||||
|
@ -14,7 +14,7 @@ export default class AxiosStatic implements Axios {
|
|||
/**
|
||||
* 默认配置
|
||||
*/
|
||||
defaults: AxiosRequestConfig;
|
||||
public defaults: AxiosRequestConfig;
|
||||
|
||||
/**
|
||||
* Axios 拦截器
|
||||
|
@ -35,9 +35,9 @@ export default class AxiosStatic implements Axios {
|
|||
* @param config Axios 请求配置
|
||||
*/
|
||||
public getUri(config: AxiosRequestConfig): string {
|
||||
config = mergeConfig(this.defaults, config);
|
||||
const { url = '', params, paramsSerializer } = mergeConfig(this.defaults, config);
|
||||
|
||||
return buildURL(config.url ?? '', config.params, config.paramsSerializer).replace(/^\?/, '');
|
||||
return buildURL(url, params, paramsSerializer).replace(/^\?/, '');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -46,9 +46,7 @@ export default class AxiosStatic implements Axios {
|
|||
* @param config Axios 请求配置
|
||||
*/
|
||||
public request<T extends Data>(config: AxiosRequestConfig): Promise<AxiosResponse<T>> {
|
||||
config = mergeConfig(this.defaults, config);
|
||||
|
||||
let promiseRequest = Promise.resolve(config);
|
||||
let promiseRequest = Promise.resolve(mergeConfig(this.defaults, config));
|
||||
|
||||
// 执行请求拦截器
|
||||
this.interceptors.request.forEach(function executor({ resolved, rejected }) {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* @Author: early-autumn
|
||||
* @Date: 2020-04-14 22:23:39
|
||||
* @LastEditors: early-autumn
|
||||
* @LastEditTime: 2020-04-19 18:49:43
|
||||
* @LastEditTime: 2020-04-20 13:23:04
|
||||
*/
|
||||
import { AxiosRequestConfig, RequestConfig, AxiosResponse } from '../types';
|
||||
|
||||
|
@ -13,22 +13,22 @@ class AxiosError extends Error {
|
|||
/**
|
||||
* 是 Axios 错误
|
||||
*/
|
||||
isAxiosError: boolean;
|
||||
public isAxiosError: boolean;
|
||||
|
||||
/**
|
||||
* Axios 请求配置
|
||||
*/
|
||||
config: AxiosRequestConfig;
|
||||
public config: AxiosRequestConfig;
|
||||
|
||||
/**
|
||||
* 通用请求配置
|
||||
*/
|
||||
request: RequestConfig;
|
||||
public request: RequestConfig;
|
||||
|
||||
/**
|
||||
* Axios 响应体
|
||||
*/
|
||||
response?: AxiosResponse;
|
||||
public response?: AxiosResponse;
|
||||
|
||||
constructor(message: string, config: AxiosRequestConfig, request: RequestConfig, response?: AxiosResponse) {
|
||||
super(message);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* @Author: early-autumn
|
||||
* @Date: 2020-04-13 18:01:16
|
||||
* @LastEditors: early-autumn
|
||||
* @LastEditTime: 2020-04-20 00:54:32
|
||||
* @LastEditTime: 2020-04-20 13:36:32
|
||||
*/
|
||||
import { AxiosRequestConfig, AxiosResponse } from '../types';
|
||||
import isCancel from '../cancel/isCancel';
|
||||
|
@ -29,8 +29,6 @@ function throwIfCancellationRequested(config: AxiosRequestConfig) {
|
|||
export default function dispatchRequest(config: AxiosRequestConfig): Promise<AxiosResponse> {
|
||||
throwIfCancellationRequested(config);
|
||||
|
||||
config.method = config.method ?? 'get';
|
||||
|
||||
config.headers = flattenHeaders(config);
|
||||
|
||||
config.data = transformData(config.data ?? {}, config.headers, config.transformRequest);
|
||||
|
|
|
@ -2,10 +2,11 @@
|
|||
* @Author: early-autumn
|
||||
* @Date: 2020-04-18 12:00:01
|
||||
* @LastEditors: early-autumn
|
||||
* @LastEditTime: 2020-04-20 00:41:57
|
||||
* @LastEditTime: 2020-04-20 13:44:26
|
||||
*/
|
||||
import { AliasMethod, Headers, AxiosRequestConfig } from '../types';
|
||||
import { Headers, AxiosRequestConfig } from '../types';
|
||||
import { omit } from '../helpers/utils';
|
||||
import { methodToLowercase } from './transformMethod';
|
||||
|
||||
/**
|
||||
* 拉平请求头
|
||||
|
@ -19,7 +20,7 @@ export default function flattenHeaders(config: AxiosRequestConfig): Headers {
|
|||
return {};
|
||||
}
|
||||
|
||||
const method = (config.method as string).toLowerCase() as AliasMethod;
|
||||
const method = methodToLowercase(config.method);
|
||||
|
||||
return {
|
||||
...(headers.common ?? {}),
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* @Author: early-autumn
|
||||
* @Date: 2020-04-15 22:48:25
|
||||
* @LastEditors: early-autumn
|
||||
* @LastEditTime: 2020-04-20 10:32:06
|
||||
* @LastEditTime: 2020-04-20 20:27:37
|
||||
*/
|
||||
import { AnyObject, AxiosRequestConfig } from '../types';
|
||||
import { isPlainObject, deepMerge } from '../helpers/utils';
|
||||
|
@ -78,12 +78,8 @@ function deepMergeConfig(
|
|||
keys.forEach((key) => {
|
||||
if (isPlainObject(config2[key])) {
|
||||
config[key] = deepMerge(config1[key] ?? {}, config2[key] as AnyObject);
|
||||
} else if (config2[key] !== undefined) {
|
||||
config[key] = config2[key];
|
||||
} else if (isPlainObject(config1[key])) {
|
||||
config[key] = deepMerge(config1[key] as AnyObject);
|
||||
} else if (config1[key] !== undefined) {
|
||||
config[key] = config1[key];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
* @Author: early-autumn
|
||||
* @Date: 2020-04-16 00:48:45
|
||||
* @LastEditors: early-autumn
|
||||
* @LastEditTime: 2020-04-20 01:12:12
|
||||
* @LastEditTime: 2020-04-20 14:24:07
|
||||
*/
|
||||
import { AxiosRequestConfig, AxiosResponse, Response } from '../types';
|
||||
import warning from '../helpers/warning';
|
||||
import transformRequest from './transformRequest';
|
||||
import transformResponse from './transformResponse';
|
||||
import createError from './createError';
|
||||
|
@ -35,8 +34,7 @@ export default function request(config: AxiosRequestConfig): Promise<AxiosRespon
|
|||
}
|
||||
|
||||
if (adapter === undefined) {
|
||||
catchError('暂未适配此平台,您需要参阅文档使用自定义适配器手动适配当前平台');
|
||||
warning('暂未适配此平台,您需要参阅文档使用自定义适配器手动适配当前平台');
|
||||
catchError('平台适配失败,您需要参阅文档使用自定义适配器手动适配当前平台');
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* @Author: early-autumn
|
||||
* @Date: 2020-04-20 13:31:45
|
||||
* @LastEditors: early-autumn
|
||||
* @LastEditTime: 2020-04-20 13:45:11
|
||||
*/
|
||||
import { AliasMethod, AdapterMethod, Method } from '../types';
|
||||
|
||||
/**
|
||||
* 请求方法转全小写
|
||||
*
|
||||
* @param config Axios 请求配置
|
||||
*/
|
||||
export function methodToLowercase(method: Method = 'get'): AliasMethod {
|
||||
return method.toLowerCase() as AliasMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求方法转全大写
|
||||
*
|
||||
* @param config Axios 请求配置
|
||||
*/
|
||||
export function methodToUppercase(method: Method = 'GET'): AdapterMethod {
|
||||
return method.toUpperCase() as AdapterMethod;
|
||||
}
|
|
@ -2,24 +2,25 @@
|
|||
* @Author: early-autumn
|
||||
* @Date: 2020-04-17 15:05:43
|
||||
* @LastEditors: early-autumn
|
||||
* @LastEditTime: 2020-04-20 09:19:49
|
||||
* @LastEditTime: 2020-04-20 13:41:15
|
||||
*/
|
||||
import { AdapterMethod, AxiosRequestConfig, RequestConfig } from '../types';
|
||||
import { AxiosRequestConfig, RequestConfig } from '../types';
|
||||
import { pick } from '../helpers/utils';
|
||||
import isAbsoluteURL from '../helpers/isAbsoluteURL';
|
||||
import combineURL from '../helpers/combineURL';
|
||||
import buildURL from '../helpers/buildURL';
|
||||
import { methodToUppercase } from './transformMethod';
|
||||
|
||||
type PickKeys = 'dataType' | 'responseType' | 'timeout' | 'enableHttp2' | 'enableQuic' | 'enableCache' | 'sslVerify';
|
||||
|
||||
/**
|
||||
* 请求方法转全大写
|
||||
*
|
||||
* @param config Axios 请求配置
|
||||
*/
|
||||
function methodUppercase(config: AxiosRequestConfig): AdapterMethod {
|
||||
return (config.method ?? 'get').toUpperCase() as AdapterMethod;
|
||||
}
|
||||
type PickKeys =
|
||||
| 'data'
|
||||
| 'headers'
|
||||
| 'dataType'
|
||||
| 'responseType'
|
||||
| 'timeout'
|
||||
| 'enableHttp2'
|
||||
| 'enableQuic'
|
||||
| 'enableCache'
|
||||
| 'sslVerify';
|
||||
|
||||
/**
|
||||
* 根据配置中的 baseURL 和 url 和 params 生成完整 URL
|
||||
|
@ -42,9 +43,11 @@ function transformURL(config: AxiosRequestConfig): string {
|
|||
*/
|
||||
export default function transformRequest(config: AxiosRequestConfig): RequestConfig {
|
||||
const url = transformURL(config);
|
||||
const method = methodUppercase(config);
|
||||
const method = methodToUppercase(config.method);
|
||||
const pickRequest = pick<AxiosRequestConfig, PickKeys>(
|
||||
config,
|
||||
'data',
|
||||
'headers',
|
||||
'dataType',
|
||||
'responseType',
|
||||
'timeout',
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* @Author: early-autumn
|
||||
* @Date: 2020-04-15 22:09:38
|
||||
* @LastEditors: early-autumn
|
||||
* @LastEditTime: 2020-04-20 09:26:14
|
||||
* @LastEditTime: 2020-04-20 22:26:29
|
||||
*/
|
||||
import { AxiosRequestConfig } from './types';
|
||||
import adaptive from './adaptive';
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* @Author: early-autumn
|
||||
* @Date: 2020-04-13 21:45:45
|
||||
* @LastEditors: early-autumn
|
||||
* @LastEditTime: 2020-04-20 09:35:48
|
||||
* @LastEditTime: 2020-04-20 21:21:23
|
||||
*/
|
||||
import { AnyObject, Params } from '../types';
|
||||
import { encode, isPlainObject, isDate } from './utils';
|
||||
|
@ -28,7 +28,7 @@ function generateURL(url: string, serializedParams: string): string {
|
|||
const prefix = url.indexOf('?') === -1 ? '?' : '&';
|
||||
serializedParams = `${prefix}${serializedParams}`;
|
||||
|
||||
return `${url}${serializedParams}`;
|
||||
return `${url.replace(/\/*$/, '')}${serializedParams}`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
* @Author: early-autumn
|
||||
* @Date: 2020-04-19 22:30:24
|
||||
* @LastEditors: early-autumn
|
||||
* @LastEditTime: 2020-04-20 09:49:35
|
||||
*/
|
||||
|
||||
/**
|
||||
* 不中断程序的报错
|
||||
*
|
||||
* @param message 错误信息
|
||||
*/
|
||||
export default function warning(message: string): void {
|
||||
const errMsg = `[axios-miniprogram]
|
||||
${message}`;
|
||||
|
||||
if (typeof console !== 'undefined' && typeof console.error === 'function') {
|
||||
console.error(errMsg);
|
||||
}
|
||||
|
||||
try {
|
||||
throw new Error(errMsg);
|
||||
} catch (e) {}
|
||||
}
|
11
src/types.ts
11
src/types.ts
|
@ -2,7 +2,7 @@
|
|||
* @Author: early-autumn
|
||||
* @Date: 2020-04-13 15:23:53
|
||||
* @LastEditors: early-autumn
|
||||
* @LastEditTime: 2020-04-20 10:32:48
|
||||
* @LastEditTime: 2020-04-20 21:28:26
|
||||
*/
|
||||
/**
|
||||
* 任意值对象
|
||||
|
@ -176,7 +176,7 @@ export interface Response {
|
|||
/**
|
||||
* 响应头 Headers
|
||||
*/
|
||||
headers: Headers;
|
||||
headers?: Headers;
|
||||
|
||||
/**
|
||||
* 响应数据
|
||||
|
@ -230,10 +230,7 @@ export interface Adapter {
|
|||
* 平台
|
||||
*/
|
||||
export interface Platform {
|
||||
// 请求函数
|
||||
request?: Adapter;
|
||||
// 兼容支付宝小程序
|
||||
httpRequest?: Adapter;
|
||||
request: Adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -387,7 +384,7 @@ export interface AxiosResponse<T extends Data = Data> {
|
|||
* 拦截器成功的回调函数
|
||||
*/
|
||||
export interface InterceptorResolved<T = any> {
|
||||
(value: T): Promise<T>;
|
||||
(value: T): T | Promise<T>;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* @Author: early-autumn
|
||||
* @Date: 2020-04-20 17:22:26
|
||||
* @LastEditors: early-autumn
|
||||
* @LastEditTime: 2020-04-20 22:20:47
|
||||
*/
|
||||
import adaptive from '../src/adaptive';
|
||||
|
||||
declare global {
|
||||
namespace NodeJS {
|
||||
interface Global {
|
||||
wx: any;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
describe('测试 src/adaptive.ts', () => {
|
||||
it('适配成功', () => {
|
||||
const request = jest.fn();
|
||||
global.wx = {
|
||||
request,
|
||||
};
|
||||
|
||||
const adapter = adaptive();
|
||||
|
||||
expect(adapter).toBe(request);
|
||||
});
|
||||
|
||||
it('适配失败', () => {
|
||||
global.wx = undefined;
|
||||
|
||||
expect(adaptive()).toBeUndefined();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* @Author: early-autumn
|
||||
* @Date: 2020-04-20 13:58:00
|
||||
* @LastEditors: early-autumn
|
||||
* @LastEditTime: 2020-04-20 22:32:14
|
||||
*/
|
||||
import axios from '../src/axios';
|
||||
|
||||
const task = { abort: jest.fn() };
|
||||
|
||||
describe('测试 src/axios.ts', () => {
|
||||
it('default', (done) => {
|
||||
axios('/test').catch((error) => {
|
||||
expect(error.isAxiosError).toBe(true);
|
||||
expect(error.message).toBe('平台适配失败,您需要参阅文档使用自定义适配器手动适配当前平台');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('axios call', async () => {
|
||||
axios.defaults.adapter = jest.fn((config) => {
|
||||
expect(config.method).toBe('GET');
|
||||
expect(config.url).toBe('/test');
|
||||
|
||||
config.success({ status: 200, data: '{"a":0}', headers: {} });
|
||||
|
||||
return task;
|
||||
});
|
||||
|
||||
await axios({ url: '/test' });
|
||||
await axios('/test');
|
||||
await axios.request({ url: '/test' });
|
||||
|
||||
axios.defaults.adapter = jest.fn((config) => {
|
||||
expect(config.method).toBe(config.url.toUpperCase().replace('/', ''));
|
||||
|
||||
config.success({ status: 200, data: {}, headers: {} });
|
||||
|
||||
return task;
|
||||
});
|
||||
|
||||
await axios.options('options');
|
||||
await axios.get('get');
|
||||
await axios.head('head');
|
||||
await axios.post('post');
|
||||
await axios.put('put');
|
||||
await axios.delete('delete');
|
||||
await axios.trace('trace');
|
||||
await axios.connect('connect');
|
||||
});
|
||||
|
||||
it('axios 携带参数', async () => {
|
||||
const url = '/test';
|
||||
const params = {
|
||||
id: 1,
|
||||
};
|
||||
|
||||
axios.defaults.adapter = (config) => {
|
||||
expect(config.method).toBe('GET');
|
||||
expect(config.url).toBe('/test?id=1');
|
||||
|
||||
config.success({ status: 200, data: '', headers: {} });
|
||||
|
||||
return task;
|
||||
};
|
||||
|
||||
await axios({
|
||||
url,
|
||||
params,
|
||||
});
|
||||
await axios(url, {
|
||||
params,
|
||||
});
|
||||
await axios.get(url, params);
|
||||
});
|
||||
|
||||
it('axios 携带数据', async () => {
|
||||
const url = '/test';
|
||||
const data = {
|
||||
id: 1,
|
||||
};
|
||||
axios.defaults.adapter = (config) => {
|
||||
expect(config.method).toBe('POST');
|
||||
expect(config.url).toBe(url);
|
||||
expect(config.data).toEqual(data);
|
||||
|
||||
config.success({ status: 200, data: '', headers: {} });
|
||||
|
||||
return task;
|
||||
};
|
||||
|
||||
await axios({
|
||||
method: 'post',
|
||||
url,
|
||||
data,
|
||||
});
|
||||
await axios(url, {
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
await axios.post(url, data);
|
||||
});
|
||||
|
||||
it('axios.create 工厂方法', () => {
|
||||
const instance = axios.create();
|
||||
|
||||
expect(instance.defaults).toEqual(axios.defaults);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* @Author: early-autumn
|
||||
* @Date: 2020-04-20 15:09:33
|
||||
* @LastEditors: early-autumn
|
||||
* @LastEditTime: 2020-04-20 15:17:27
|
||||
*/
|
||||
import Cancel from '../../src/cancel/Cancel';
|
||||
|
||||
describe('测试 src/cancel/Cancel.ts', () => {
|
||||
it('默认', () => {
|
||||
const cancel = new Cancel();
|
||||
|
||||
expect(cancel.toString()).toBe('Cancel');
|
||||
});
|
||||
|
||||
it('自定义', () => {
|
||||
const cancel = new Cancel('custom');
|
||||
|
||||
expect(cancel.toString()).toBe('Cancel: custom');
|
||||
});
|
||||
});
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* @Author: early-autumn
|
||||
* @Date: 2020-04-20 15:17:50
|
||||
* @LastEditors: early-autumn
|
||||
* @LastEditTime: 2020-04-20 22:10:39
|
||||
*/
|
||||
import CancelToken from '../../src/cancel/CancelToken';
|
||||
|
||||
describe('测试 src/cancel/CancelToken.ts', () => {
|
||||
it('实例化', (done) => {
|
||||
const token = new CancelToken(function(cancel) {
|
||||
cancel('取消');
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
// 应该抛出取消
|
||||
expect(() => token.throwIfRequested()).toThrow();
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('工厂方法', async () => {
|
||||
const source = CancelToken.source();
|
||||
|
||||
// 还没有取消 返回 Undefuned
|
||||
expect(source.token.throwIfRequested()).toBeUndefined();
|
||||
|
||||
await source.cancel('取消');
|
||||
|
||||
// 应该抛出取消
|
||||
expect(() => source.token.throwIfRequested()).toThrow();
|
||||
|
||||
// 重复取消无效
|
||||
await source.cancel('取消');
|
||||
});
|
||||
});
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* @Author: early-autumn
|
||||
* @Date: 2020-04-20 15:12:17
|
||||
* @LastEditors: early-autumn
|
||||
* @LastEditTime: 2020-04-20 15:17:16
|
||||
*/
|
||||
import isCancel from '../../src/cancel/isCancel';
|
||||
import Cancel from '../../src/cancel/Cancel';
|
||||
|
||||
describe('测试 src/cancel/isCancel', () => {
|
||||
it('是一个取消?', () => {
|
||||
const cancel1 = 0;
|
||||
const cancel2 = new Cancel();
|
||||
|
||||
expect(isCancel(cancel1)).toBe(false);
|
||||
expect(isCancel(cancel2)).toBe(true);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* @Author: early-autumn
|
||||
* @Date: 2020-04-20 20:47:09
|
||||
* @LastEditors: early-autumn
|
||||
* @LastEditTime: 2020-04-20 22:17:18
|
||||
*/
|
||||
import Axios from '../../src/core/Axios';
|
||||
|
||||
const instance = new Axios();
|
||||
|
||||
describe('测试 src/core/Axios.ts', () => {
|
||||
it('defaults', () => {
|
||||
expect(instance.defaults).toEqual({});
|
||||
});
|
||||
|
||||
it('getUri', () => {
|
||||
expect(instance.getUri({})).toEqual('');
|
||||
expect(instance.getUri({ url: '/test' })).toEqual('/test');
|
||||
expect(instance.getUri({ url: '', params: { id: 1 } })).toEqual('id=1');
|
||||
expect(instance.getUri({ url: '/test', params: { id: 1 } })).toEqual('/test?id=1');
|
||||
});
|
||||
|
||||
it('interceptors 成功', async () => {
|
||||
instance.defaults.adapter = function adapter({ data, success }) {
|
||||
expect(data).toBe('interceptors_request');
|
||||
|
||||
success({ data: 'data', headers: {} });
|
||||
|
||||
return { abort: jest.fn() };
|
||||
};
|
||||
|
||||
instance.interceptors.request.use(function(config) {
|
||||
config.data = 'interceptors_request';
|
||||
return config;
|
||||
});
|
||||
|
||||
instance.interceptors.response.use(function(response) {
|
||||
response.data = 'interceptors_response';
|
||||
return response;
|
||||
});
|
||||
|
||||
await instance
|
||||
.request({
|
||||
method: 'post',
|
||||
data: '',
|
||||
})
|
||||
.then(({ data }) => expect(data).toBe('interceptors_response'));
|
||||
});
|
||||
|
||||
it('interceptors 失败', async () => {
|
||||
instance.interceptors.response.use(function(response) {
|
||||
throw response;
|
||||
});
|
||||
|
||||
await instance
|
||||
.request({
|
||||
method: 'post',
|
||||
data: '',
|
||||
})
|
||||
.catch((error) => expect(error.data).toBe('interceptors_response'));
|
||||
|
||||
instance.interceptors.request.use(function(config) {
|
||||
throw config;
|
||||
});
|
||||
|
||||
await instance
|
||||
.request({
|
||||
method: 'post',
|
||||
data: '',
|
||||
})
|
||||
.catch((error) => expect(error.method).toBe('post'));
|
||||
});
|
||||
});
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* @Author: early-autumn
|
||||
* @Date: 2020-04-20 15:40:44
|
||||
* @LastEditors: early-autumn
|
||||
* @LastEditTime: 2020-04-20 22:05:48
|
||||
*/
|
||||
import InterceptorManager from '../../src/core/InterceptorManager';
|
||||
|
||||
describe('测试 src/core/InterceptorManager.ts', () => {
|
||||
it('实例化', () => {
|
||||
const interceptor = new InterceptorManager();
|
||||
const executor = jest.fn();
|
||||
|
||||
interceptor.forEach(executor);
|
||||
|
||||
// executor 不应该被执行
|
||||
expect(executor.mock.calls.length).toBe(0);
|
||||
});
|
||||
|
||||
it('注册和取消注册', () => {
|
||||
const interceptor = new InterceptorManager();
|
||||
const executor1 = jest.fn();
|
||||
const executor2 = jest.fn();
|
||||
const id1 = interceptor.use(() => undefined);
|
||||
const id2 = interceptor.use(() => undefined);
|
||||
interceptor.forEach(executor1);
|
||||
|
||||
// executor1 应该被执行了两次
|
||||
expect(executor1.mock.calls.length).toBe(2);
|
||||
|
||||
interceptor.eject(id1);
|
||||
interceptor.eject(id2);
|
||||
interceptor.forEach(executor2);
|
||||
|
||||
// executor2 不应该被执行
|
||||
expect(executor2.mock.calls.length).toBe(0);
|
||||
});
|
||||
|
||||
it('倒序遍历', () => {
|
||||
const interceptor = new InterceptorManager();
|
||||
let id = 0;
|
||||
|
||||
// 应该后被执行
|
||||
interceptor.use((id) => expect(id).toBe(1));
|
||||
|
||||
// 应该先被执行
|
||||
interceptor.use((id) => expect(id).toBe(0));
|
||||
|
||||
interceptor.forEach(({ resolved }) => {
|
||||
resolved(id++);
|
||||
}, 'reverse');
|
||||
});
|
||||
|
||||
it('异常', () => {
|
||||
const interceptor = new InterceptorManager();
|
||||
|
||||
interceptor.use(() => undefined);
|
||||
|
||||
interceptor.forEach(({ rejected }) => rejected('error'));
|
||||
});
|
||||
});
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* @Author: early-autumn
|
||||
* @Date: 2020-04-20 20:39:42
|
||||
* @LastEditors: early-autumn
|
||||
* @LastEditTime: 2020-04-20 20:45:17
|
||||
*/
|
||||
import flattenHeaders from '../../src/core/flattenHeaders';
|
||||
|
||||
describe('测试 src/core/flattenHeaders.ts', () => {
|
||||
it('默认', () => {
|
||||
expect(flattenHeaders({})).toEqual({});
|
||||
});
|
||||
|
||||
it('默认 get', () => {
|
||||
expect(
|
||||
flattenHeaders({
|
||||
headers: {
|
||||
common: { common: 'common' },
|
||||
get: { get: 'get' },
|
||||
post: { post: 'post' },
|
||||
rest: 'rest',
|
||||
},
|
||||
})
|
||||
).toEqual({ common: 'common', get: 'get', rest: 'rest' });
|
||||
});
|
||||
|
||||
it('拉平', () => {
|
||||
expect(
|
||||
flattenHeaders({
|
||||
method: 'post',
|
||||
headers: {
|
||||
common: { common: 'common' },
|
||||
get: { get: 'get' },
|
||||
post: { post: 'post' },
|
||||
rest: 'rest',
|
||||
},
|
||||
})
|
||||
).toEqual({ common: 'common', post: 'post', rest: 'rest' });
|
||||
});
|
||||
});
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* @Author: early-autumn
|
||||
* @Date: 2020-04-20 19:16:32
|
||||
* @LastEditors: early-autumn
|
||||
* @LastEditTime: 2020-04-20 20:29:17
|
||||
*/
|
||||
import mergeConfig from '../../src/core/mergeConfig';
|
||||
import defaults from '../../src/defaults';
|
||||
import { AxiosRequestConfig } from '../../src/types';
|
||||
|
||||
describe('测试 src/core/mergeConfig.ts', () => {
|
||||
it('默认', () => {
|
||||
expect(mergeConfig()).toEqual({});
|
||||
|
||||
expect(mergeConfig({ baseURL: 'https://www.xxx.com' })).toEqual({ baseURL: 'https://www.xxx.com' });
|
||||
|
||||
expect(mergeConfig(undefined, { baseURL: 'https://www.xxx.com' })).toEqual({ baseURL: 'https://www.xxx.com' });
|
||||
});
|
||||
|
||||
it('只取 config2', () => {
|
||||
const config2 = { url: 'https://www.config2.com', data: { config2: 0 } };
|
||||
const config = mergeConfig(defaults, config2);
|
||||
|
||||
expect(config.url).toEqual(config2.url);
|
||||
expect(config.data).toEqual(config2.data);
|
||||
});
|
||||
|
||||
it('优先取 config2', () => {
|
||||
expect(mergeConfig(defaults, {})).toEqual(defaults);
|
||||
|
||||
const config2: AxiosRequestConfig = {
|
||||
baseURL: 'https://www.config2.com',
|
||||
method: 'post',
|
||||
timeout: 10000,
|
||||
};
|
||||
|
||||
const config = mergeConfig(defaults, config2);
|
||||
|
||||
expect(config.baseURL).toEqual(config2.baseURL);
|
||||
expect(config.method).toEqual(config2.method);
|
||||
expect(config.timeout).toEqual(config2.timeout);
|
||||
});
|
||||
|
||||
it('深度合并', () => {
|
||||
const config1 = { params: { config1: 0 }, headers: { Config1: '0' } };
|
||||
const config2 = { params: { config2: 0 }, headers: { Config2: '0' } };
|
||||
|
||||
expect(mergeConfig(config1, {})).toEqual(config1);
|
||||
|
||||
expect(mergeConfig(config1, config2)).toEqual({
|
||||
params: { config1: 0, config2: 0 },
|
||||
headers: { Config1: '0', Config2: '0' },
|
||||
});
|
||||
|
||||
expect(mergeConfig({ params: {} }, { params: { config: 'config2' } })).toEqual({
|
||||
params: { config: 'config2' },
|
||||
});
|
||||
|
||||
expect(mergeConfig({ params: { config: 'config1' } }, {})).toEqual({
|
||||
params: { config: 'config1' },
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* @Author: early-autumn
|
||||
* @Date: 2020-04-20 20:31:29
|
||||
* @LastEditors: early-autumn
|
||||
* @LastEditTime: 2020-04-20 20:38:49
|
||||
*/
|
||||
import { Data } from '../../src/types';
|
||||
import transformData from '../../src/core/transformData';
|
||||
|
||||
describe('测试 src/core/transformData.ts', () => {
|
||||
it('默认', () => {
|
||||
expect(transformData({ a: 1 }, {})).toEqual({ a: 1 });
|
||||
});
|
||||
|
||||
it('转换', () => {
|
||||
function transform(data: Data) {
|
||||
return data + '1';
|
||||
}
|
||||
expect(transformData('1', {}, transform)).toEqual('11');
|
||||
});
|
||||
|
||||
it('多次转换', () => {
|
||||
const transforms = [
|
||||
function transform(data: Data) {
|
||||
return data + '1';
|
||||
},
|
||||
function transform(data: Data) {
|
||||
return data + '1';
|
||||
},
|
||||
];
|
||||
expect(transformData('1', {}, transforms)).toEqual('111');
|
||||
});
|
||||
});
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* @Author: early-autumn
|
||||
* @Date: 2020-04-20 16:14:52
|
||||
* @LastEditors: early-autumn
|
||||
* @LastEditTime: 2020-04-20 16:17:39
|
||||
*/
|
||||
import { methodToLowercase, methodToUppercase } from '../../src/core/transformMethod';
|
||||
|
||||
describe('测试 src/core/transformMethod.ts', () => {
|
||||
it('默认', () => {
|
||||
expect(methodToLowercase()).toBe('get');
|
||||
expect(methodToUppercase()).toBe('GET');
|
||||
});
|
||||
|
||||
it('传参', () => {
|
||||
expect(methodToLowercase('POST')).toBe('post');
|
||||
expect(methodToUppercase('post')).toBe('POST');
|
||||
});
|
||||
});
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* @Author: early-autumn
|
||||
* @Date: 2020-04-20 21:08:23
|
||||
* @LastEditors: early-autumn
|
||||
* @LastEditTime: 2020-04-20 21:17:31
|
||||
*/
|
||||
import transformRequest from '../../src/core/transformRequest';
|
||||
|
||||
describe('测试 src/core/transformRequest.ts', () => {
|
||||
it('默认', () => {
|
||||
expect(transformRequest({})).toEqual({
|
||||
url: '/',
|
||||
method: 'GET',
|
||||
headers: undefined,
|
||||
data: undefined,
|
||||
dataType: undefined,
|
||||
enableCache: undefined,
|
||||
enableHttp2: undefined,
|
||||
enableQuic: undefined,
|
||||
header: undefined,
|
||||
responseType: undefined,
|
||||
sslVerify: undefined,
|
||||
timeout: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
it('基本', () => {
|
||||
const request = transformRequest({
|
||||
baseURL: 'https://www.xxx.com///',
|
||||
method: 'get',
|
||||
url: '/test',
|
||||
params: {
|
||||
id: 1,
|
||||
},
|
||||
});
|
||||
const request2 = transformRequest({
|
||||
baseURL: 'https://www.xxx.com',
|
||||
method: 'get',
|
||||
url: 'https://www.yyy.com/test/',
|
||||
params: {
|
||||
id: 1,
|
||||
},
|
||||
});
|
||||
|
||||
expect(request.url).toEqual('https://www.xxx.com/test?id=1');
|
||||
expect(request2.url).toEqual('https://www.yyy.com/test?id=1');
|
||||
});
|
||||
});
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* @Author: early-autumn
|
||||
* @Date: 2020-04-20 21:25:08
|
||||
* @LastEditors: early-autumn
|
||||
* @LastEditTime: 2020-04-20 21:34:20
|
||||
*/
|
||||
import transformResponse from '../../src/core/transformResponse';
|
||||
|
||||
describe('测试 src/core/transformResponse.ts', () => {
|
||||
it('默认', () => {
|
||||
expect(transformResponse({ data: {} }, {})).toEqual({
|
||||
status: 400,
|
||||
statusText: 'Bad Adapter',
|
||||
data: {},
|
||||
headers: {},
|
||||
config: {},
|
||||
cookies: undefined,
|
||||
profile: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
it('status + headers', () => {
|
||||
expect(transformResponse({ status: 200, headers: { status: 'ok' }, data: {} }, {})).toEqual({
|
||||
status: 200,
|
||||
statusText: 'OK',
|
||||
data: {},
|
||||
headers: { status: 'ok' },
|
||||
config: {},
|
||||
cookies: undefined,
|
||||
profile: undefined,
|
||||
});
|
||||
});
|
||||
it('statusCode + header', () => {
|
||||
expect(transformResponse({ statusCode: 204, header: { status: 'ok' }, data: {} }, {})).toEqual({
|
||||
status: 204,
|
||||
statusText: '',
|
||||
data: {},
|
||||
headers: { status: 'ok' },
|
||||
config: {},
|
||||
cookies: undefined,
|
||||
profile: undefined,
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue