Skip to content

Commit 05ab39b

Browse files
fix(unit-test): updated operator tests
1 parent 8c666a7 commit 05ab39b

14 files changed

+337
-69
lines changed

eslint.config.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ export default [
2424
globals: {
2525
...globals.browser,
2626
expect: 'readonly',
27-
global: 'readonly'
27+
global: 'readonly',
28+
__dirname: 'readonly'
2829
}
2930
},
3031
plugins: {

packages/mocks/blob.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@ import { mockAsync } from './async';
44

55
export const mockBlob = () => {
66
return vi.fn(([e], type) => ({
7-
text: () => {
8-
console.log(type);
9-
return mockAsync(new TextDecoder().decode(e));
10-
},
11-
type: e.type
7+
text: () => mockAsync(new TextDecoder().decode(e)),
8+
type
129
}));
1310
};
2.15 MB
Binary file not shown.

packages/operators/src/blob.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ export const blobToXML = () => {
2525
);
2626
};
2727

28-
export const blobToVideo = () => {
29-
return source => source.pipe();
28+
export const blobToURL = () => {
29+
return source => source.pipe(map(blob => URL.createObjectURL(blob)));
3030
};
3131

3232
export const blobTo = () => {
@@ -40,12 +40,12 @@ const getOperator = blob => {
4040
};
4141

4242
const TYPES = {
43-
'video/*': blobToVideo,
43+
'video/*': blobToURL,
4444
'application/json': blobToJSON,
4545
'text/plain': blobToText,
4646
'text/html': blobToXML,
4747
'text/xml': blobToXML,
4848
'application/xml': blobToXML,
4949
'application/xhtml+xml': blobToXML,
50-
'image/svg+xml': blobToVideo
50+
'image/svg+xml': blobToXML
5151
};

packages/operators/src/blob.test.js

Lines changed: 105 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,117 @@
1-
import { describe, test } from 'vitest';
1+
import { mockBlob } from '#mocks/blob.js';
2+
import fs from 'node:fs';
3+
import { map } from 'rxjs';
4+
import { TestScheduler } from 'rxjs/testing';
5+
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
26

37
describe('blob', () => {
4-
test('blob to text', () => {
5-
//
8+
let testScheduler;
9+
10+
beforeEach(() => {
11+
vi.spyOn(global, 'Blob').mockImplementation(mockBlob());
12+
testScheduler = new TestScheduler((actual, expected) => expect(actual).deep.equal(expected));
613
});
714

8-
test('blob to json', () => {
9-
//
15+
afterEach(() => {
16+
vi.restoreAllMocks();
1017
});
1118

12-
test('blob to xml', () => {
13-
//
19+
test('blob to text', async () => {
20+
const { blobToText } = await import('./blob.js');
21+
22+
const expectedVal = {
23+
a: 'hello world',
24+
b: 'foo bar'
25+
};
26+
27+
const triggerVal = {
28+
a: new Blob([new TextEncoder().encode(expectedVal.a)], 'text/plain'),
29+
b: new Blob([new TextEncoder().encode(expectedVal.b)], 'text/plain')
30+
};
31+
32+
testScheduler.run(({ cold, expectObservable }) => {
33+
expectObservable(cold('a-b|', triggerVal).pipe(blobToText())).toBe('a-b|', expectedVal);
34+
});
1435
});
1536

16-
test('blob to video', () => {
17-
//
37+
test('blob to json', async () => {
38+
const { blobToJSON } = await import('./blob.js');
39+
40+
const expectedVal = {
41+
a: { hello: 'world' },
42+
b: { foo: 'bar' }
43+
};
44+
45+
const triggerVal = {
46+
a: new Blob([new TextEncoder().encode(JSON.stringify(expectedVal.a))], 'application/json'),
47+
b: new Blob([new TextEncoder().encode(JSON.stringify(expectedVal.b))], 'application/json')
48+
};
49+
50+
testScheduler.run(({ cold, expectObservable }) => {
51+
expectObservable(cold('a-b|', triggerVal).pipe(blobToJSON())).toBe('a-b|', expectedVal);
52+
});
1853
});
1954

20-
test('blob to (auto detect)', () => {
21-
//
55+
test('blob to xml', async () => {
56+
const { blobToXML } = await import('./blob.js');
57+
58+
const expectedVal = {
59+
a: new DOMParser().parseFromString('<xml></xml>', 'text/xml'),
60+
b: new DOMParser().parseFromString('<xml><a></a></xml>', 'text/xml')
61+
};
62+
63+
const triggerVal = {
64+
a: new Blob([new TextEncoder().encode('<xml></xml>')], 'text/xml'),
65+
b: new Blob([new TextEncoder().encode('<xml><a></a></xml>')], 'text/xml')
66+
};
67+
68+
testScheduler.run(({ cold, expectObservable }) => {
69+
expectObservable(cold('a-b|', triggerVal).pipe(blobToXML())).toBe('a-b|', expectedVal);
70+
});
71+
});
72+
73+
test('blob to url', async () => {
74+
vi.restoreAllMocks();
75+
76+
const { blobToURL } = await import('./blob.js');
77+
78+
const triggerVal = {
79+
a: new Blob([fs.readFileSync(`${__dirname}/../fixtures/videos/demo.mp4`)], 'video/mp4')
80+
};
81+
82+
const expectedVal = {
83+
a: 'blob:nodedata:'
84+
};
85+
86+
testScheduler.run(({ cold, expectObservable }) => {
87+
expectObservable(
88+
cold('a|', triggerVal).pipe(
89+
blobToURL(),
90+
map(v => v.replace(/([a-z0-9-]+)$/, ''))
91+
)
92+
).toBe('a|', expectedVal);
93+
});
94+
});
95+
96+
test('blob to (auto detect)', async () => {
97+
const { blobTo } = await import('./blob.js');
98+
99+
const expectedVal = {
100+
a: 'hello world',
101+
b: { foo: 'bar' },
102+
c: new DOMParser().parseFromString('<xml><a></a></xml>', 'text/xml'),
103+
d: new Blob([new TextEncoder().encode('aha')], 'x-text/plain')
104+
};
105+
106+
const triggerVal = {
107+
a: new Blob([new TextEncoder().encode('hello world')], 'text/plain'),
108+
b: new Blob([new TextEncoder().encode(JSON.stringify({ foo: 'bar' }))], 'application/json'),
109+
c: new Blob([new TextEncoder().encode('<xml><a></a></xml>')], 'text/xml'),
110+
d: expectedVal.d
111+
};
112+
113+
testScheduler.run(({ cold, expectObservable }) => {
114+
expectObservable(cold('a-b-c-d|', triggerVal).pipe(blobTo())).toBe('a-b-c-d|', expectedVal);
115+
});
22116
});
23117
});

packages/operators/src/request.test.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ import { test, describe, beforeEach, expect, vi, afterAll, beforeAll } from 'vit
99

1010
import { log, logResult } from './log.js';
1111
import { resolveBlob, resolveJSON } from './response.js';
12-
import { EstimateTime } from './stream/stats/EstimateTime.js';
13-
import { Progress } from './stream/stats/Progress.js';
14-
import { TransferRate } from './stream/stats/TransferRate.js';
12+
import EstimateTime from './stream/stats/EstimateTime.js';
13+
import Progress from './stream/stats/Progress.js';
14+
import TransferRate from './stream/stats/TransferRate.js';
1515
import { MBYTE, SECOND } from './stream/stats/utils.js';
1616

1717
describe.skip('request', () => {
@@ -176,13 +176,13 @@ describe.skip('request - demo ', () => {
176176
body: formData
177177
});
178178

179-
const progressUpload = new Progress();
179+
const progressUpload = Progress.create();
180180
progressUpload.subscribe({
181181
next: e => console.log('UPLOAD', e),
182182
complete: () => console.log('complete')
183183
});
184184

185-
const progressDownload = new Progress();
185+
const progressDownload = Progress.create();
186186
progressDownload.subscribe({
187187
next: e => console.log('DOWNLOAD', e),
188188
complete: () => console.log('complete')
@@ -205,13 +205,13 @@ describe('test', () => {
205205
test('progress on download', async () => {
206206
const { request } = await import('./request.js');
207207

208-
const progress = new Progress();
208+
const progress = Progress.create();
209209
progress.subscribe({ next: e => console.log('DOWNLOAD', e) });
210210

211-
const byteRate = new TransferRate(MBYTE, SECOND);
211+
const byteRate = TransferRate.create(MBYTE, SECOND);
212212
byteRate.subscribe({ next: e => console.log('RATE', e) });
213213

214-
const estimateTime = new EstimateTime(SECOND);
214+
const estimateTime = EstimateTime.create(SECOND);
215215
estimateTime.subscribe({ next: e => console.log('ESTIMATE', e) });
216216

217217
const fileMap = {

packages/operators/src/stream/stats/EstimateTime.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,17 @@ import { concatWith, distinctUntilChanged, map, of, Subject } from 'rxjs';
22

33
import { calcReceivedStats, MSECOND } from './utils';
44

5-
export class EstimateTime extends Subject {
6-
constructor(timeUnit = MSECOND) {
7-
super();
8-
return this.pipe(
5+
export default {
6+
create: (timeUnit = MSECOND) => {
7+
return new Subject().pipe(
98
calcReceivedStats(),
109
calcEstimatedTime(),
1110
concatWith(of(0)),
1211
distinctUntilChanged(),
1312
convertEstimedTimeTo(timeUnit)
1413
);
1514
}
16-
}
15+
};
1716

1817
const calcEstimatedTime = () => {
1918
return source =>
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { tap } from 'rxjs';
2+
import { TestScheduler } from 'rxjs/testing';
3+
import { beforeEach, describe, expect, test } from 'vitest';
4+
5+
import EstimateTime from './EstimateTime';
6+
import { SECOND } from './utils';
7+
8+
describe('EstimateTime', () => {
9+
let testScheduler;
10+
11+
beforeEach(() => {
12+
testScheduler = new TestScheduler((actual, expected) => expect(actual).deep.equal(expected));
13+
});
14+
15+
test('calc estimate time - millisecond', async () => {
16+
const triggerVal = {
17+
a: { value: new TextEncoder().encode('abc'), total: 26, period: 1 },
18+
b: { value: new TextEncoder().encode('def'), total: 26, period: 2 },
19+
c: { value: new TextEncoder().encode('ghi'), total: 26, period: 3 },
20+
d: { value: new TextEncoder().encode('jkl'), total: 26, period: 4 },
21+
e: { value: new TextEncoder().encode('mno'), total: 26, period: 5 },
22+
f: { value: new TextEncoder().encode('pqr'), total: 26, period: 6 },
23+
g: { value: new TextEncoder().encode('stu'), total: 26, period: 7 },
24+
h: { value: new TextEncoder().encode('vwx'), total: 26, period: 8 },
25+
i: { value: new TextEncoder().encode('yz'), total: 26, period: 9 }
26+
};
27+
28+
const expectedVal = {
29+
a: 8,
30+
b: 7,
31+
c: 6,
32+
d: 5,
33+
e: 4,
34+
f: 3,
35+
g: 2,
36+
h: 1,
37+
i: 0
38+
};
39+
40+
const estimateTime = EstimateTime.create();
41+
42+
testScheduler.run(({ cold, expectObservable }) => {
43+
expectObservable(estimateTime).toBe('a-b-c-d-e-f-g-h-i', expectedVal);
44+
expectObservable(
45+
cold('a-b-c-d-e-f-g-h-i|', triggerVal).pipe(tap(val => estimateTime.next(val)))
46+
);
47+
});
48+
});
49+
50+
test('calc estimate time - second', async () => {
51+
const triggerVal = {
52+
a: { value: new TextEncoder().encode('abc'), total: 26, period: 1 },
53+
b: { value: new TextEncoder().encode('def'), total: 26, period: 2 },
54+
c: { value: new TextEncoder().encode('ghi'), total: 26, period: 3 },
55+
d: { value: new TextEncoder().encode('jkl'), total: 26, period: 4 },
56+
e: { value: new TextEncoder().encode('mno'), total: 26, period: 5 },
57+
f: { value: new TextEncoder().encode('pqr'), total: 26, period: 6 },
58+
g: { value: new TextEncoder().encode('stu'), total: 26, period: 7 },
59+
h: { value: new TextEncoder().encode('vwx'), total: 26, period: 8 },
60+
i: { value: new TextEncoder().encode('yz'), total: 26, period: 9 }
61+
};
62+
63+
const expectedVal = {
64+
a: 0.008,
65+
b: 0.007,
66+
c: 0.006,
67+
d: 0.005,
68+
e: 0.004,
69+
f: 0.003,
70+
g: 0.002,
71+
h: 0.001,
72+
i: 0
73+
};
74+
75+
const estimateTimeSecond = EstimateTime.create(SECOND);
76+
77+
testScheduler.run(({ cold, expectObservable }) => {
78+
expectObservable(estimateTimeSecond).toBe('a-b-c-d-e-f-g-h-i', expectedVal);
79+
expectObservable(
80+
cold('a-b-c-d-e-f-g-h-i|', triggerVal).pipe(tap(val => estimateTimeSecond.next(val)))
81+
);
82+
});
83+
});
84+
});

packages/operators/src/stream/stats/Progress.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,16 @@ import { concatWith, distinctUntilChanged, map, of, Subject } from 'rxjs';
22

33
import { calcReceivedStats } from './utils';
44

5-
export class Progress extends Subject {
6-
constructor() {
7-
super();
8-
return this.pipe(
5+
export default {
6+
create: () => {
7+
return new Subject().pipe(
98
calcReceivedStats(),
109
calcPercentageProgress(),
1110
concatWith(of(100)),
1211
distinctUntilChanged()
1312
);
1413
}
15-
}
14+
};
1615

1716
const calcPercentageProgress = () => {
1817
return source => source.pipe(map(({ value, total }) => Math.floor((value / total) * 100)));

0 commit comments

Comments
 (0)