🎨 增强兼容性

pull/1/head
954270063@qq.com 2020-04-21 10:02:11 +08:00
parent b3c11c0252
commit b31aca0e74
13 changed files with 96 additions and 122 deletions

View File

@ -130,18 +130,18 @@ axios.post('/test', { test: 1 }, {
|参数|类型|默认值|说明|全平台兼容| |参数|类型|默认值|说明|全平台兼容|
|:-|:-|:-|:-|:-| |:-|:-|:-|:-|:-|
|adapter|Function|[查看](https://github.com/early-autumn/axios-miniprogram/blob/master/src/helpers/defaults.ts#L11)|自定义适配器|是| |adapter|Function|[查看](https://github.com/early-autumn/axios-miniprogram/blob/master/src/defaults.ts#L11)|自定义适配器|是|
|baseURL|String| |基础地址|是| |baseURL|String| |基础地址|是|
|url|String| |请求地址|是| |url|String| |请求地址|是|
|method|String|get|请求方法| | |method|String|get|请求方法| |
|params|Object| |请求参数|是| |params|Object| |请求参数|是|
|data|String/Object/ArrayBuffer| |请求数据|是| |data|String/Object/ArrayBuffer| |请求数据|是|
|headers|Object|[查看](https://github.com/early-autumn/axios-miniprogram/blob/master/src/helpers/defaults.ts#L13)|请求头|是| |headers|Object|[查看](https://github.com/early-autumn/axios-miniprogram/blob/master/src/defaults.ts#L13)|请求头|是|
|validateStatus|Function|[查看](https://github.com/early-autumn/axios-miniprogram/blob/master/src/helpers/defaults.ts#L30)|自定义合法状态码|是| |validateStatus|Function|[查看](https://github.com/early-autumn/axios-miniprogram/blob/master/src/defaults.ts#L30)|自定义合法状态码|是|
|paramsSerializer|Function| |自定义参数序列化|是| |paramsSerializer|Function| |自定义参数序列化|是|
|transformRequest|Function/Array<.Function>| |自定义转换请求数据|是| |transformRequest|Function/Array<.Function>| |自定义转换请求数据|是|
|transformResponse|Function/Array<.Function>| |自定义转换响应数据|是| |transformResponse|Function/Array<.Function>| |自定义转换响应数据|是|
|cancelToken|Object| |取消令牌| | |cancelToken|Object||取消令牌| |
|timeout|Number|0|超时时间| | |timeout|Number|0|超时时间| |
|dataType|String|json|响应数据格式|是| |dataType|String|json|响应数据格式|是|
|responseType|String|text|响应数据类型|是| |responseType|String|text|响应数据类型|是|

View File

@ -2,7 +2,7 @@
* @Author: early-autumn * @Author: early-autumn
* @Date: 2020-04-16 00:48:45 * @Date: 2020-04-16 00:48:45
* @LastEditors: early-autumn * @LastEditors: early-autumn
* @LastEditTime: 2020-04-20 14:24:07 * @LastEditTime: 2020-04-21 09:49:45
*/ */
import { AxiosRequestConfig, AxiosResponse, Response } from '../types'; import { AxiosRequestConfig, AxiosResponse, Response } from '../types';
import transformRequest from './transformRequest'; import transformRequest from './transformRequest';
@ -44,7 +44,7 @@ export default function request(config: AxiosRequestConfig): Promise<AxiosRespon
* *
* @param res * @param res
*/ */
function validateStatus(res: Response): void { function handleResponse(res: Response): void {
const response = transformResponse(res, config); const response = transformResponse(res, config);
if (config.validateStatus === undefined || config.validateStatus(response.status)) { if (config.validateStatus === undefined || config.validateStatus(response.status)) {
@ -57,7 +57,7 @@ export default function request(config: AxiosRequestConfig): Promise<AxiosRespon
// 使用适配器发送请求 // 使用适配器发送请求
const task = adapter({ const task = adapter({
...request, ...request,
success: validateStatus, success: handleResponse,
fail: catchError, fail: catchError,
}); });
@ -65,7 +65,10 @@ export default function request(config: AxiosRequestConfig): Promise<AxiosRespon
// 则调用取消令牌里的 listener 监听用户的取消操作 // 则调用取消令牌里的 listener 监听用户的取消操作
if (cancelToken !== undefined) { if (cancelToken !== undefined) {
cancelToken.listener.then(function onCanceled(reason): void { cancelToken.listener.then(function onCanceled(reason): void {
task.abort(); if (task !== undefined) {
task.abort();
}
reject(reason); reject(reason);
}); });
} }

View File

@ -2,7 +2,7 @@
* @Author: early-autumn * @Author: early-autumn
* @Date: 2020-04-13 15:23:53 * @Date: 2020-04-13 15:23:53
* @LastEditors: early-autumn * @LastEditors: early-autumn
* @LastEditTime: 2020-04-20 21:28:26 * @LastEditTime: 2020-04-21 10:00:50
*/ */
/** /**
* *
@ -223,7 +223,7 @@ export interface AdapterRequestTask {
* *
*/ */
export interface Adapter { export interface Adapter {
(config: AdapterRequestConfig): AdapterRequestTask; (config: AdapterRequestConfig): AdapterRequestTask | void;
} }
/** /**

View File

@ -2,43 +2,30 @@
* @Author: early-autumn * @Author: early-autumn
* @Date: 2020-04-20 13:58:00 * @Date: 2020-04-20 13:58:00
* @LastEditors: early-autumn * @LastEditors: early-autumn
* @LastEditTime: 2020-04-20 22:32:14 * @LastEditTime: 2020-04-21 09:33:06
*/ */
import axios from '../src/axios'; import axios from '../src/axios';
const task = { abort: jest.fn() };
describe('测试 src/axios.ts', () => { describe('测试 src/axios.ts', () => {
it('default', (done) => { it('default', () => {
axios('/test').catch((error) => { axios('/test').then(undefined, (error) => {
expect(error.isAxiosError).toBe(true); expect(error.isAxiosError).toBe(true);
expect(error.message).toBe('平台适配失败,您需要参阅文档使用自定义适配器手动适配当前平台'); expect(error.message).toBe('平台适配失败,您需要参阅文档使用自定义适配器手动适配当前平台');
done();
}); });
}); });
it('axios call', async () => { it('axios call', async () => {
axios.defaults.adapter = jest.fn((config) => { axios.defaults.adapter = (config): any => {
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: {} }); config.success({ status: 200, data: {}, headers: {} });
return task; expect(config.method).toBe(config.url.toUpperCase().replace('/', ''));
});
return 'task';
};
await axios({ url: '/get' });
await axios('/get');
await axios.request({ url: '/get' });
await axios.options('options'); await axios.options('options');
await axios.get('get'); await axios.get('get');
await axios.head('head'); await axios.head('head');
@ -55,13 +42,13 @@ describe('测试 src/axios.ts', () => {
id: 1, id: 1,
}; };
axios.defaults.adapter = (config) => { axios.defaults.adapter = (config): any => {
config.success({ status: 200, data: {}, headers: {} });
expect(config.method).toBe('GET'); expect(config.method).toBe('GET');
expect(config.url).toBe('/test?id=1'); expect(config.url).toBe('/test?id=1');
config.success({ status: 200, data: '', headers: {} }); return 'task';
return task;
}; };
await axios({ await axios({
@ -79,14 +66,14 @@ describe('测试 src/axios.ts', () => {
const data = { const data = {
id: 1, id: 1,
}; };
axios.defaults.adapter = (config) => { axios.defaults.adapter = (config): any => {
config.success({ status: 200, data: '', headers: {} });
expect(config.method).toBe('POST'); expect(config.method).toBe('POST');
expect(config.url).toBe(url); expect(config.url).toBe(url);
expect(config.data).toEqual(data); expect(config.data).toEqual(data);
config.success({ status: 200, data: '', headers: {} }); return 'task';
return task;
}; };
await axios({ await axios({

View File

@ -2,36 +2,32 @@
* @Author: early-autumn * @Author: early-autumn
* @Date: 2020-04-20 15:17:50 * @Date: 2020-04-20 15:17:50
* @LastEditors: early-autumn * @LastEditors: early-autumn
* @LastEditTime: 2020-04-20 22:10:39 * @LastEditTime: 2020-04-21 09:01:02
*/ */
import CancelToken from '../../src/cancel/CancelToken'; import CancelToken from '../../src/cancel/CancelToken';
describe('测试 src/cancel/CancelToken.ts', () => { describe('测试 src/cancel/CancelToken.ts', () => {
it('实例化', (done) => { it('实例化', () => {
const token = new CancelToken(function(cancel) { const token = new CancelToken(function(cancel) {
cancel('取消'); cancel('取消');
}); });
setTimeout(() => { // 应该抛出取消
// 应该抛出取消 expect(() => token.throwIfRequested()).toThrow();
expect(() => token.throwIfRequested()).toThrow();
done();
});
}); });
it('工厂方法', async () => { it('工厂方法', () => {
const source = CancelToken.source(); const source = CancelToken.source();
// 还没有取消 返回 Undefuned // 还没有取消 返回 Undefuned
expect(source.token.throwIfRequested()).toBeUndefined(); expect(source.token.throwIfRequested()).toBeUndefined();
await source.cancel('取消'); source.cancel('取消');
// 应该抛出取消 // 应该抛出取消
expect(() => source.token.throwIfRequested()).toThrow(); expect(() => source.token.throwIfRequested()).toThrow();
// 重复取消无效 // 重复取消无效
await source.cancel('取消'); source.cancel('取消');
}); });
}); });

View File

@ -2,14 +2,14 @@
* @Author: early-autumn * @Author: early-autumn
* @Date: 2020-04-20 15:12:17 * @Date: 2020-04-20 15:12:17
* @LastEditors: early-autumn * @LastEditors: early-autumn
* @LastEditTime: 2020-04-20 15:17:16 * @LastEditTime: 2020-04-21 08:57:38
*/ */
import isCancel from '../../src/cancel/isCancel'; import isCancel from '../../src/cancel/isCancel';
import Cancel from '../../src/cancel/Cancel'; import Cancel from '../../src/cancel/Cancel';
describe('测试 src/cancel/isCancel', () => { describe('测试 src/cancel/isCancel', () => {
it('是一个取消?', () => { it('是一个取消?', () => {
const cancel1 = 0; const cancel1 = {};
const cancel2 = new Cancel(); const cancel2 = new Cancel();
expect(isCancel(cancel1)).toBe(false); expect(isCancel(cancel1)).toBe(false);

View File

@ -2,7 +2,7 @@
* @Author: early-autumn * @Author: early-autumn
* @Date: 2020-04-20 20:47:09 * @Date: 2020-04-20 20:47:09
* @LastEditors: early-autumn * @LastEditors: early-autumn
* @LastEditTime: 2020-04-20 22:17:18 * @LastEditTime: 2020-04-21 09:34:14
*/ */
import Axios from '../../src/core/Axios'; import Axios from '../../src/core/Axios';
@ -20,13 +20,13 @@ describe('测试 src/core/Axios.ts', () => {
expect(instance.getUri({ url: '/test', params: { id: 1 } })).toEqual('/test?id=1'); expect(instance.getUri({ url: '/test', params: { id: 1 } })).toEqual('/test?id=1');
}); });
it('interceptors 成功', async () => { it('interceptors 成功', () => {
instance.defaults.adapter = function adapter({ data, success }) { instance.defaults.adapter = function adapter({ data, success }): any {
expect(data).toBe('interceptors_request'); expect(data).toBe('interceptors_request');
success({ data: 'data', headers: {} }); success({ data: 'data', headers: {} });
return { abort: jest.fn() }; return 'task';
}; };
instance.interceptors.request.use(function(config) { instance.interceptors.request.use(function(config) {
@ -39,7 +39,7 @@ describe('测试 src/core/Axios.ts', () => {
return response; return response;
}); });
await instance instance
.request({ .request({
method: 'post', method: 'post',
data: '', data: '',
@ -47,27 +47,23 @@ describe('测试 src/core/Axios.ts', () => {
.then(({ data }) => expect(data).toBe('interceptors_response')); .then(({ data }) => expect(data).toBe('interceptors_response'));
}); });
it('interceptors 失败', async () => { it('interceptors 失败', () => {
instance.interceptors.response.use(function(response) { instance.interceptors.response.use((response) => Promise.reject(response));
throw response;
});
await instance instance
.request({ .request({
method: 'post', method: 'post',
data: '', data: '',
}) })
.catch((error) => expect(error.data).toBe('interceptors_response')); .then(undefined, (error) => expect(error.data).toBe('interceptors_response'));
instance.interceptors.request.use(function(config) { instance.interceptors.request.use((config) => Promise.reject(config));
throw config;
});
await instance instance
.request({ .request({
method: 'post', method: 'post',
data: '', data: '',
}) })
.catch((error) => expect(error.method).toBe('post')); .then(undefined, (error) => expect(error.method).toBe('post'));
}); });
}); });

View File

@ -2,53 +2,46 @@
* @Author: early-autumn * @Author: early-autumn
* @Date: 2020-04-20 22:42:46 * @Date: 2020-04-20 22:42:46
* @LastEditors: early-autumn * @LastEditors: early-autumn
* @LastEditTime: 2020-04-20 23:22:29 * @LastEditTime: 2020-04-21 09:57:39
*/ */
import { CancelAction } from '../../src/types';
import dispatchRequest from '../../src/core/dispatchRequest'; import dispatchRequest from '../../src/core/dispatchRequest';
import CancelToken from '../../src/cancel/CancelToken'; import CancelToken from '../../src/cancel/CancelToken';
import isCancel from '../../src/cancel/isCancel'; import isCancel from '../../src/cancel/isCancel';
import { CancelAction } from '../../src/types';
const task = {
abort: jest.fn(),
};
describe('测试 src/core/dispatchRequest.ts', () => { describe('测试 src/core/dispatchRequest.ts', () => {
it('默认', async () => { it('默认', () => {
await dispatchRequest({}).catch((err) => { dispatchRequest({}).then(undefined, (err) => {
expect(err.message).toBe('平台适配失败,您需要参阅文档使用自定义适配器手动适配当前平台'); expect(err.message).toBe('平台适配失败,您需要参阅文档使用自定义适配器手动适配当前平台');
}); });
}); });
it('请求失败', async () => { it('请求失败', () => {
await dispatchRequest({ dispatchRequest({
adapter({ success }) { adapter({ success }): any {
success({ status: 200, data: '' }); success({ status: 200, data: '' });
return task;
return 'task';
}, },
validateStatus(status) { validateStatus(status) {
return status === -1; return status === -1;
}, },
}).catch((err) => expect(err.response.status).toBe(200)); }).then(undefined, (err) => expect(err.response.status).toBe(200));
}); });
it('取消请求', () => { it('取消请求', () => {
try { let cancel: CancelAction;
let cancel: CancelAction;
dispatchRequest({ dispatchRequest({
adapter({ success }) { adapter({ success }) {
cancel(); cancel();
setTimeout(() => { setTimeout(() => {
success({ status: 200, data: '' }); success({ status: 200, data: '' });
}); });
return task; },
}, cancelToken: new CancelToken(function executor(c) {
cancelToken: new CancelToken(function executor(c) { cancel = c;
cancel = c; }),
}), }).then(undefined, (err) => expect(isCancel(err)).toBe(true));
});
} catch (err) {
expect(isCancel(err)).toBe(true);
}
}); });
}); });

View File

@ -2,42 +2,41 @@
* @Author: early-autumn * @Author: early-autumn
* @Date: 2020-04-20 22:51:26 * @Date: 2020-04-20 22:51:26
* @LastEditors: early-autumn * @LastEditors: early-autumn
* @LastEditTime: 2020-04-20 23:26:18 * @LastEditTime: 2020-04-21 09:37:30
*/ */
import request from '../../src/core/request'; import request from '../../src/core/request';
import CancelToken from '../../src/cancel/CancelToken'; import CancelToken from '../../src/cancel/CancelToken';
import isCancel from '../../src/cancel/isCancel'; import isCancel from '../../src/cancel/isCancel';
const task = {
abort: jest.fn(),
};
describe('测试 src/core/request.ts', () => { describe('测试 src/core/request.ts', () => {
it('默认', async () => { it('默认', () => {
await request({}).catch((err) => { request({}).then(undefined, (err) =>
expect(err.message).toBe('平台适配失败,您需要参阅文档使用自定义适配器手动适配当前平台'); expect(err.message).toBe('平台适配失败,您需要参阅文档使用自定义适配器手动适配当前平台')
}); );
}); });
it('请求失败', async () => { it('请求失败', () => {
await request({ request({
adapter({ fail }) { adapter({ fail }): any {
fail({}); fail({});
return task;
return 'task';
}, },
}).catch((err) => { }).then(undefined, (err) => expect(err.message).toBe('配置不正确或者网络异常'));
expect(err.message).toBe('配置不正确或者网络异常');
});
}); });
it('取消请求', async () => { it('取消请求', () => {
await request({ request({
adapter() { adapter({ fail }) {
return task; setTimeout(fail);
return {
abort: jest.fn(),
};
}, },
cancelToken: new CancelToken(function executor(c) { cancelToken: new CancelToken(function executor(c) {
c(); c();
}), }),
}).catch((err) => expect(isCancel(err)).toBe(true)); }).then(undefined, (err) => expect(isCancel(err)).toBe(true));
}); });
}); });