Skip to content

Commit 84b2614

Browse files
fix(operators): added fetch tests
1 parent 4ab3e81 commit 84b2614

14 files changed

+376
-118
lines changed

packages/operators/src/request/autoPagination.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { request } from './request';
55
export const autoPagination = ({ resolveRoute }) => {
66
return source =>
77
source.pipe(
8-
concatMap(({ url }) => from(resolveRoute(url)).pipe(request(), getNext(resolveRoute, url))),
8+
concatMap(url => from(resolveRoute(url)).pipe(request(), getNext(resolveRoute, url))),
99
map(resp => resp.clone())
1010
);
1111
};

packages/operators/src/request/autoPagination.test.js

Lines changed: 88 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,99 @@
1-
import { concatAll, map, of } from 'rxjs';
2-
import { beforeEach, describe, expect, test } from 'vitest';
1+
import { concatAll, concatMap, delay, from, map, of, toArray } from 'rxjs';
2+
import { TestScheduler } from 'rxjs/testing';
3+
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
34

45
import { log } from '../log';
5-
import { autoPagination } from './autoPagination';
66
import { resolveJSON } from './response';
77

8-
describe('auto pagination', function () {
8+
describe('auto pagination - mocked', function () {
9+
const testScheduler = new TestScheduler((actual, expected) => {
10+
expect(actual).to.eql(expected);
11+
});
12+
913
beforeEach(function () {
10-
//
14+
vi.doMock('./request', importOriginal => ({
15+
request: () => source => source.pipe(concatMap(({ v, t }) => of(v).pipe(delay(t))))
16+
}));
17+
18+
Object.prototype.clone = vi.fn();
19+
vi.spyOn(Object.prototype, 'clone').mockImplementation(function (e) {
20+
return { ...JSON.parse(JSON.stringify(this)) };
21+
});
1122
});
1223

13-
test('auto pagination', async function () {
24+
afterEach(() => {
25+
vi.doUnmock('./request');
26+
});
27+
28+
test('classic testing', async () => {
29+
const { autoPagination } = await import('./autoPagination');
30+
31+
const triggerValues = {
32+
a: { t: 2, v: { value: 'a', next: 1 } },
33+
b: { t: 5, v: { value: 'b', next: 2 } },
34+
c: { t: 3, v: { value: 'c', next: 3 } },
35+
d: { t: 1, v: { value: 'd', next: 4 } },
36+
e: { t: 4, v: { value: 'e', next: null } }
37+
};
38+
39+
const expectedVal = Array.from(Object.entries(triggerValues)).map(([k, { v }]) => v);
40+
41+
const triggerVal = Object.values(triggerValues);
42+
await new Promise((done, error) => {
43+
of(triggerVal[0])
44+
.pipe(
45+
autoPagination({
46+
resolveRoute: (conf, resp) =>
47+
((!resp || resp.next) && [triggerVal[resp?.next || 0]]) || []
48+
}),
49+
toArray()
50+
)
51+
.subscribe({
52+
next: e => expect(e).toStrictEqual(expectedVal),
53+
complete: () => done(),
54+
error: () => error()
55+
});
56+
});
57+
});
58+
59+
test.skip('marble testing', async () => {
60+
const { autoPagination } = await import('./autoPagination');
61+
62+
const triggerVal = {
63+
a: { t: 2, v: { value: 'a', next: 'b' } },
64+
b: { t: 5, v: { value: 'b', next: 'c' } },
65+
c: { t: 3, v: { value: 'c', next: 'd' } },
66+
d: { t: 1, v: { value: 'd', next: 'e' } },
67+
e: { t: 4, v: { value: 'e', next: null } }
68+
};
69+
70+
const expectedVal = Object.fromEntries(
71+
Array.from(Object.entries(triggerVal)).map(([k, { v }]) => [k, v])
72+
);
73+
74+
testScheduler.run(({ cold, expectObservable }) => {
75+
expectObservable(
76+
cold('-a-------------------', triggerVal).pipe(
77+
autoPagination({
78+
resolveRoute: (conf, resp) =>
79+
((!resp || resp.next) && [triggerVal[resp?.next || 'a']]) || []
80+
})
81+
)
82+
).toBe('---a----b--cd---e----', expectedVal);
83+
});
84+
});
85+
});
86+
87+
describe.skip('auto pagination - demo', function () {
88+
beforeEach(function () {
89+
vi.resetModules();
90+
});
91+
92+
test('sample testing', async function () {
93+
const { autoPagination } = await import('./autoPagination');
94+
1495
return new Promise(done => {
15-
return of({ url: new URL('https://dummyjson.com/products') })
96+
return of(new URL('https://dummyjson.com/products'))
1697
.pipe(
1798
autoPagination({
1899
resolveRoute: async (url, resp) => {
Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
import { ReplaySubject, share, timer } from 'rxjs';
1+
import { ReplaySubject, share, tap, timer } from 'rxjs';
22

33
export const cache = ttl => {
44
return source =>
55
source.pipe(
66
share({
77
// TODO: check if a buffer size is neccessary
88
connector: () => new ReplaySubject(),
9-
resetOnComplete: () => timer(ttl)
9+
// resetOnError: false,
10+
resetOnComplete: () => timer(ttl),
11+
resetOnRefCountZero: false
1012
})
1113
);
1214
};

packages/operators/src/request/cache.test.js

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,54 @@
11
import fetchMock from 'fetch-mock';
2-
import { defer, of, tap } from 'rxjs';
2+
import { defer, delay, from, interval, map, mapTo, of, tap, throttleTime } from 'rxjs';
3+
import { TestScheduler } from 'rxjs/testing';
34
import { afterEach, beforeEach, describe, expect, test } from 'vitest';
45

56
import { cache } from './cache';
67
import { requestText } from './request';
78

9+
describe('cache - mocked', function () {
10+
beforeEach(function () {
11+
//
12+
});
13+
14+
afterEach(function () {
15+
//
16+
});
17+
18+
test.skip('cache resetted after 100ms', async function () {
19+
let counter = 0;
20+
const a = of(counter).pipe(
21+
tap(e => console.log('U', e)),
22+
cache(5)
23+
);
24+
25+
defer(() => a)
26+
.pipe(delay(2))
27+
.subscribe(e => console.log(e));
28+
defer(() => a)
29+
.pipe(delay(2))
30+
.subscribe(e => console.log(e));
31+
32+
await new Promise(done => setTimeout(done), 500);
33+
34+
defer(() => a)
35+
.pipe(delay(100))
36+
.subscribe(e => console.log(e));
37+
38+
await new Promise(done => setTimeout(done), 1000);
39+
});
40+
});
41+
842
describe('cache', function () {
943
beforeEach(function () {
1044
let counter = 0;
1145
fetchMock.mockGlobal().get(
1246
'https://httpbin.org/my-url-fast',
13-
() => {
14-
return new Response(++counter, {
47+
() =>
48+
new Response(++counter, {
1549
status: 200,
1650
headers: { 'Content-type': 'plain/text' }
17-
});
18-
},
51+
}),
1952
{ delay: 0, repeat: 2 }
2053
);
2154
});
@@ -25,7 +58,11 @@ describe('cache', function () {
2558
});
2659

2760
test('cache resetted after 100ms', async function () {
28-
const a = of('https://httpbin.org/my-url-fast').pipe(requestText(), cache(1000));
61+
const a = of('https://httpbin.org/my-url-fast').pipe(
62+
requestText(),
63+
tap(() => console.log('CHECK')),
64+
cache(1000)
65+
);
2966
await new Promise(done => {
3067
a.subscribe({
3168
next: e => expect(e).toBe('1'),

packages/operators/src/request/concurrentRequest.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { mergeMap, of, tap } from 'rxjs';
1+
import { mergeMap, of } from 'rxjs';
22

33
import { request } from './request';
44

packages/operators/src/request/concurrentRequest.sample.js

Lines changed: 0 additions & 31 deletions
This file was deleted.
Lines changed: 74 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,96 @@
1-
import { concatMap, delay, of, tap, toArray } from 'rxjs';
1+
import { concatAll, concatMap, delay, from, map, of, tap, toArray } from 'rxjs';
22
import { TestScheduler } from 'rxjs/testing';
3-
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
3+
import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from 'vitest';
44

5-
import { concurrentRequest } from './concurrentRequest';
5+
import { log } from '../log';
6+
import { resolveJSON } from './response';
67

7-
describe('multi fetch33', function () {
8+
describe('concurrent request - mocked', function () {
89
const testScheduler = new TestScheduler((actual, expected) => {
910
expect(actual).to.eql(expected);
1011
});
1112

13+
const getTriggerValues = () => ({
14+
a: { t: 2, v: 'a' },
15+
b: { t: 5, v: 'b' },
16+
c: { t: 1, v: 'c' },
17+
d: { t: 3, v: 'd' },
18+
e: { t: 4, v: 'e' }
19+
});
20+
1221
beforeEach(function () {
13-
vi.mock('./request.js', async importOriginal => {
14-
return {
15-
request: () => source => source.pipe(concatMap(({ v, t }) => of(v).pipe(delay(t))))
16-
};
17-
});
22+
vi.doMock('./request', importOriginal => ({
23+
request: () => source => source.pipe(concatMap(({ v, t }) => of(v).pipe(delay(t))))
24+
}));
1825
});
1926

2027
afterEach(() => {
21-
vi.resetAllMocks();
28+
vi.doUnmock('./request');
2229
});
2330

24-
test('test', async () => {
25-
const values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(v => ({ v, t: Math.random() * 1000 }));
26-
const sortedResult = [...values].sort((a, b) => a.t - b.t).map(({ v }) => v);
31+
test('classic testing', async () => {
32+
const { concurrentRequest } = await import('./concurrentRequest');
2733

28-
await new Promise(done => {
29-
of(...values)
30-
.pipe(concurrentRequest(values.length), toArray())
31-
.subscribe({ next: e => expect(e).to.eql(sortedResult), complete: () => done() });
34+
const triggerVal = Object.values(getTriggerValues());
35+
const sortedVal = [...triggerVal].sort((a, b) => a.t - b.t).map(({ v }) => v);
36+
37+
await new Promise((done, error) => {
38+
from(triggerVal)
39+
.pipe(concurrentRequest(triggerVal.length), toArray())
40+
.subscribe({
41+
next: e => expect(e).toStrictEqual(sortedVal),
42+
complete: () => done(),
43+
error: e => error(e)
44+
});
3245
});
3346
});
3447

35-
test('test2', async () => {
36-
const triggerValues = {
37-
a: { t: 2, v: 'a' },
38-
b: { t: 5, v: 'b' },
39-
c: { t: 0, v: 'c' },
40-
d: { t: 1, v: 'd' },
41-
e: { t: 1, v: 'd' }
42-
};
43-
const expectedValues = Object.fromEntries(
44-
Array.from(Object.entries(triggerValues)).map(([k, { v }]) => [k, v])
45-
);
48+
test('marble testing', async () => {
49+
const { concurrentRequest } = await import('./concurrentRequest');
50+
51+
const triggerVal = getTriggerValues();
52+
const expectedVal = Object.fromEntries(Object.entries(triggerVal).map(([k, { v }]) => [k, v]));
4653

4754
testScheduler.run(({ cold, expectObservable }) => {
48-
expectObservable(cold('-a-b-c-(de)', triggerValues).pipe(concurrentRequest(3), tap())).toBe(
49-
'---a-c--(bde)',
50-
expectedValues
51-
);
55+
expectObservable(
56+
cold('-a-b-(cd)-e----', triggerVal).pipe(concurrentRequest(Object.keys(triggerVal).length))
57+
).toBe('---a--c-(bd)--e', expectedVal);
58+
});
59+
});
60+
});
61+
62+
describe.skip('concurrent request - demo', function () {
63+
beforeAll(function () {
64+
vi.resetModules();
65+
});
66+
67+
test('sample testing', async () => {
68+
const { concurrentRequest } = await import('./concurrentRequest');
69+
70+
await new Promise(done => {
71+
of(
72+
new URL('https://dummyjson.com/products?limit=10&skip=0&select=title,price'),
73+
new URL('https://dummyjson.com/products?limit=10&skip=10&select=title,price'),
74+
new URL('https://dummyjson.com/products?limit=10&skip=20&select=title,price'),
75+
new URL('https://dummyjson.com/products?limit=10&skip=30&select=title,price'),
76+
new URL('https://dummyjson.com/products?limit=10&skip=40&select=title,price'),
77+
new URL('https://dummyjson.com/products?limit=10&skip=50&select=title,price'),
78+
new URL('https://dummyjson.com/products?limit=10&skip=60&select=title,price'),
79+
new URL('https://dummyjson.com/products?limit=10&skip=70&select=title,price'),
80+
new URL('https://dummyjson.com/products?limit=10&skip=80&select=title,price')
81+
)
82+
.pipe(
83+
concurrentRequest(4),
84+
log(false),
85+
resolveJSON(),
86+
log(false),
87+
map(({ products }) => products),
88+
concatAll()
89+
)
90+
.subscribe({
91+
next: e => console.log(e),
92+
complete: () => done()
93+
});
5294
});
5395
});
5496
});

packages/operators/src/request/lazyPagination.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import { concatMap, map } from 'rxjs';
1+
import { concatMap, map, tap } from 'rxjs';
22

33
import { concurrentRequest } from './concurrentRequest';
44

5-
export const lazyPagination = ({ resolveRoute }) => {
5+
export const lazyPagination = ({ pager, concurrent, resolveRoute }) => {
66
return source =>
77
source.pipe(
8-
concatMap(({ url, pager, concurrent }) => {
8+
concatMap(({ url }) => {
99
return pager.pipe(
1010
map(options => resolveRoute(url, options)),
1111
concurrentRequest(concurrent)

0 commit comments

Comments
 (0)