Skip to content

Commit bc21ed2

Browse files
authoredFeb 24, 2021
feat: add usePagination (#26)
* feat: add usePagination * refactor: update usePagination * refactor: update example demo * feat: add totalPage * refactor: update example demo * refactor: update ts * chore: updage pkg * refactor: update ts * test: add usePagination test case * refactor: update * refactor: update * docs: update example * docs: restore example
1 parent 1c92e3c commit bc21ed2

File tree

5 files changed

+434
-0
lines changed

5 files changed

+434
-0
lines changed
 

‎package.json

+3
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,12 @@
6262
"@rollup/plugin-node-resolve": "^10.0.0",
6363
"@types/jest": "^26.0.15",
6464
"@types/lodash": "^4.14.165",
65+
"@types/mockjs": "^1.0.3",
6566
"@typescript-eslint/eslint-plugin": "^4.8.2",
6667
"@typescript-eslint/parser": "^4.8.2",
6768
"@vue/babel-plugin-jsx": "^1.0.0-rc.3",
6869
"@vue/test-utils": "^2.0.0-beta.8",
70+
"axios": "^0.21.1",
6971
"babel-jest": "^26.6.0",
7072
"babel-loader": "^8.2.1",
7173
"eslint": "^7.14.0",
@@ -79,6 +81,7 @@
7981
"jest-environment-jsdom-global": "^2.0.4",
8082
"lint-staged": "^10.5.2",
8183
"lodash": "^4.17.20",
84+
"mockjs": "^1.1.0",
8285
"node-fetch": "^2.6.1",
8386
"np": "^7.0.0",
8487
"prettier": "^2.2.0",

‎src/__tests__/pagination.test.tsx

+274
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,274 @@
1+
import { mount, shallowMount } from '@vue/test-utils';
2+
import fetchMock from 'fetch-mock';
3+
import Mock from 'mockjs';
4+
import { defineComponent, reactive, Ref, ref, watchEffect } from 'vue';
5+
import {
6+
clearGlobalOptions,
7+
GlobalOptions,
8+
setGlobalOptions,
9+
} from '../core/config';
10+
import {
11+
FOCUS_LISTENER,
12+
RECONNECT_LISTENER,
13+
VISIBLE_LISTENER,
14+
} from '../core/utils/listener';
15+
import { usePagination, RequestConfig } from '../index';
16+
import { waitForAll, waitForTime } from './utils';
17+
import { failedRequest } from './utils/request';
18+
declare let jsdom: any;
19+
20+
type CustomPropertyMockDataType = {
21+
result: Array<{ name: string; age: number }>;
22+
myTotal: { a: { b: { total: number } } };
23+
myTotalPage: { a: { b: { totalPage: number } } };
24+
};
25+
26+
type NormalMockDataType = {
27+
result: Array<{ name: string; age: number }>;
28+
total: number;
29+
};
30+
31+
describe('usePagination', () => {
32+
beforeAll(() => {
33+
jest.useFakeTimers('modern');
34+
});
35+
36+
const normalApi = 'http://example.com/normal';
37+
const customPropertyApi = 'http://example.com/custom';
38+
39+
// mock fetch
40+
const normalMockData: NormalMockDataType = Mock.mock({
41+
'result|10': [
42+
{
43+
name: '@name',
44+
'age|18-36': 1,
45+
},
46+
],
47+
total: 100,
48+
});
49+
50+
const customPropertyMockData: CustomPropertyMockDataType = Mock.mock({
51+
'result|10': [
52+
{
53+
name: '@name',
54+
'age|18-36': 1,
55+
},
56+
],
57+
myTotal: { a: { b: { total: 100 } } },
58+
myTotalPage: { a: { b: { totalPage: 99 } } },
59+
});
60+
61+
fetchMock.get(normalApi, normalMockData);
62+
fetchMock.get(customPropertyApi, customPropertyMockData);
63+
64+
const originalError = console.error;
65+
beforeEach(() => {
66+
console.error = jest.fn();
67+
// clear global options
68+
clearGlobalOptions();
69+
70+
// clear listener
71+
RECONNECT_LISTENER.clear();
72+
FOCUS_LISTENER.clear();
73+
VISIBLE_LISTENER.clear();
74+
});
75+
76+
afterEach(() => {
77+
console.error = originalError;
78+
});
79+
80+
test('should be defined', () => {
81+
expect(usePagination).toBeDefined();
82+
});
83+
84+
test('usePagination should work', async () => {
85+
const wrapper = shallowMount(
86+
defineComponent({
87+
setup() {
88+
const {
89+
data,
90+
total,
91+
params,
92+
current,
93+
pageSize,
94+
totalPage,
95+
} = usePagination<NormalMockDataType>(normalApi);
96+
return () => (
97+
<div>
98+
<div class="result">{JSON.stringify(data.value?.result)}</div>
99+
<div class="params">{JSON.stringify(params.value)}</div>
100+
<div class="total">{total.value}</div>
101+
<div class="current">{current.value}</div>
102+
<div class="pageSize">{pageSize.value}</div>
103+
<div class="totalPage">{totalPage.value}</div>
104+
</div>
105+
);
106+
},
107+
}),
108+
);
109+
110+
const paramsEl = wrapper.find('.params');
111+
const resultEl = wrapper.find('.result');
112+
const totalEl = wrapper.find('.total');
113+
const currentEl = wrapper.find('.current');
114+
const pageSizeEl = wrapper.find('.pageSize');
115+
const totalPageEl = wrapper.find('.totalPage');
116+
117+
expect(resultEl.text()).toBe('');
118+
expect(currentEl.text()).toBe('1');
119+
expect(pageSizeEl.text()).toBe('10');
120+
expect(paramsEl.text()).toBe('[{"current":1,"pageSize":10}]');
121+
expect(totalEl.text()).toBe('0');
122+
expect(totalPageEl.text()).toBe('0');
123+
124+
await waitForTime(1000);
125+
expect(resultEl.text()).toBe(JSON.stringify(normalMockData.result));
126+
expect(currentEl.text()).toBe('1');
127+
expect(pageSizeEl.text()).toBe('10');
128+
expect(paramsEl.text()).toBe('[{"current":1,"pageSize":10}]');
129+
expect(totalEl.text()).toBe(`${normalMockData.total}`);
130+
expect(totalPageEl.text()).toBe('10');
131+
});
132+
133+
test('changeCurrent should work', async () => {
134+
let _current = 1;
135+
const wrapper = shallowMount(
136+
defineComponent({
137+
setup() {
138+
const {
139+
total,
140+
params,
141+
current,
142+
pageSize,
143+
totalPage,
144+
changeCurrent,
145+
} = usePagination(normalApi);
146+
return () => (
147+
<div>
148+
<button
149+
class="params"
150+
onClick={() => changeCurrent((_current += 1))}
151+
>
152+
{JSON.stringify(params.value)}
153+
</button>
154+
<div class="total">{total.value}</div>
155+
<div class="current">{current.value}</div>
156+
<div class="pageSize">{pageSize.value}</div>
157+
<div class="totalPage">{totalPage.value}</div>
158+
</div>
159+
);
160+
},
161+
}),
162+
);
163+
164+
const paramsEl = wrapper.find('.params');
165+
const totalEl = wrapper.find('.total');
166+
const currentEl = wrapper.find('.current');
167+
const pageSizeEl = wrapper.find('.pageSize');
168+
const totalPageEl = wrapper.find('.totalPage');
169+
170+
for (let index = 0; index < 100; index++) {
171+
paramsEl.trigger('click');
172+
await waitForTime(1000);
173+
expect(paramsEl.text()).toBe(`[{"current":${_current},"pageSize":10}]`);
174+
expect(totalEl.text()).toBe('100');
175+
expect(currentEl.text()).toBe(`${_current}`);
176+
expect(pageSizeEl.text()).toBe('10');
177+
expect(totalPageEl.text()).toBe('10');
178+
}
179+
});
180+
181+
test('changePageSize should work', async () => {
182+
let _pageSize = 10;
183+
const wrapper = shallowMount(
184+
defineComponent({
185+
setup() {
186+
const {
187+
total,
188+
params,
189+
current,
190+
pageSize,
191+
totalPage,
192+
changePageSize,
193+
} = usePagination(normalApi);
194+
return () => (
195+
<div>
196+
<button
197+
class="params"
198+
onClick={() => changePageSize((_pageSize += 1))}
199+
>
200+
{JSON.stringify(params.value)}
201+
</button>
202+
<div class="total">{total.value}</div>
203+
<div class="current">{current.value}</div>
204+
<div class="pageSize">{pageSize.value}</div>
205+
<div class="totalPage">{totalPage.value}</div>
206+
</div>
207+
);
208+
},
209+
}),
210+
);
211+
212+
const paramsEl = wrapper.find('.params');
213+
const totalEl = wrapper.find('.total');
214+
const currentEl = wrapper.find('.current');
215+
const pageSizeEl = wrapper.find('.pageSize');
216+
const totalPageEl = wrapper.find('.totalPage');
217+
218+
for (let index = 0; index < 100; index++) {
219+
paramsEl.trigger('click');
220+
await waitForTime(1000);
221+
expect(paramsEl.text()).toBe(`[{"current":1,"pageSize":${_pageSize}}]`);
222+
expect(totalEl.text()).toBe('100');
223+
expect(currentEl.text()).toBe('1');
224+
expect(pageSizeEl.text()).toBe(`${_pageSize}`);
225+
expect(totalPageEl.text()).toBe(`${Math.ceil(100 / _pageSize)}`);
226+
}
227+
});
228+
229+
test('custom pagination property should work', async () => {
230+
const wrapper = shallowMount(
231+
defineComponent({
232+
setup() {
233+
const {
234+
data,
235+
total,
236+
params,
237+
current,
238+
pageSize,
239+
totalPage,
240+
} = usePagination(customPropertyApi, {
241+
pagination: {
242+
currentKey: 'myCurrent',
243+
pageSizeKey: 'myPageSize',
244+
totalKey: 'myTotal.a.b.total',
245+
totalPageKey: 'myTotalPage.a.b.totalPage',
246+
},
247+
});
248+
return () => (
249+
<div>
250+
<div class="params">{JSON.stringify(params.value)}</div>
251+
<div class="total">{total.value}</div>
252+
<div class="current">{current.value}</div>
253+
<div class="pageSize">{pageSize.value}</div>
254+
<div class="totalPage">{totalPage.value}</div>
255+
</div>
256+
);
257+
},
258+
}),
259+
);
260+
261+
const paramsEl = wrapper.find('.params');
262+
const totalEl = wrapper.find('.total');
263+
const currentEl = wrapper.find('.current');
264+
const pageSizeEl = wrapper.find('.pageSize');
265+
const totalPageEl = wrapper.find('.totalPage');
266+
267+
await waitForTime(1000);
268+
expect(paramsEl.text()).toBe('[{"myCurrent":1,"myPageSize":10}]');
269+
expect(totalEl.text()).toBe('100');
270+
expect(currentEl.text()).toBe('1');
271+
expect(pageSizeEl.text()).toBe('10');
272+
expect(totalPageEl.text()).toBe('99');
273+
});
274+
});

‎src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export { setGlobalOptions } from './core/config';
22
export { default as RequestConfig } from './RequestConfig';
33
export { default as useRequest } from './useRequest';
4+
export { default as usePagination } from './usePagination';

0 commit comments

Comments
 (0)
Please sign in to comment.