Skip to content

Commit 4195ed4

Browse files
committed
feat(experimental): added share and toPromise operators
1 parent 689ad03 commit 4195ed4

3 files changed

Lines changed: 137 additions & 2 deletions

File tree

src/operators/experimental.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { Task, UncaughtError } from '../task';
2+
3+
export function toPromise <T> (task: Task<T, any>) {
4+
return new Promise<T>((resolve, reject) =>
5+
task.fork(reject, resolve)
6+
);
7+
}
8+
9+
export function share<T, E> () {
10+
let result: Promise<T> | undefined;
11+
return function (input: Task<T, E>): Task<T, E> {
12+
return new Task((outerResolve, outerReject) => {
13+
if (typeof result === 'undefined') {
14+
result = toPromise(input);
15+
}
16+
result
17+
.then(outerResolve, outerReject);
18+
});
19+
};
20+
}

test/jest-helper.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ import { UncaughtError } from '../src/task';
33
export const jestAssertNever =
44
(cb: jest.DoneCallback) =>
55
(obj: never | UncaughtError) =>
6-
cb('this should never happen')
6+
cb('this should never happen', obj)
77
;
88

99
export const jestAssertUntypedNeverCalled =
1010
(cb: jest.DoneCallback) =>
1111
(obj: any) =>
12-
cb('this should never happen')
12+
cb('this should never happen', obj)
1313
;
1414

1515
export const assertFork = <T>(cb: jest.DoneCallback, fn: (obj: T) => void) => (obj: T) => {
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import { map } from '../../src/operators/basic';
2+
import { share } from '../../src/operators/experimental';
3+
import { Task, UncaughtError } from '../../src/task';
4+
import { assertFork, jestAssertNever, jestAssertUntypedNeverCalled } from '../jest-helper';
5+
6+
7+
describe('share', () => {
8+
it('should be lazy (dont call if not forked)', cb => {
9+
// GIVEN: a manually created task
10+
const task = new Task(resolve => {
11+
// This should not be called
12+
expect(true).toBe(false);
13+
});
14+
15+
// WHEN: we share but we dont fork
16+
task.pipe(share());
17+
18+
// THEN: the content of the task is never called
19+
setTimeout(cb, 20);
20+
});
21+
22+
it('should be lazy (called when forked)', cb => {
23+
// GIVEN: a manually created task
24+
const task = new Task(resolve => {
25+
// This should be called
26+
expect(true).toBe(true);
27+
cb();
28+
});
29+
30+
// WHEN: we share and fork
31+
task.pipe(share());
32+
33+
// THEN: the content of the task is called
34+
task.fork(x => x, x => x);
35+
});
36+
37+
it('Should call the constructor twice if we dont use it', (cb) => {
38+
// GIVEN: a manually created task that uses and modifies a global variable
39+
let i = 0;
40+
const task = new Task<number, never>(resolve => {
41+
resolve(i++);
42+
});
43+
44+
// WHEN: we transform the value without using share
45+
const result = task.pipe(
46+
map(n => '' + n)
47+
);
48+
49+
// THEN: the first time we fork we should have the value 0
50+
result.fork(
51+
jestAssertNever(cb),
52+
x => expect(x).toBe('0')
53+
);
54+
55+
// THEN: and the second time, the value 1
56+
result.fork(
57+
jestAssertNever(cb),
58+
assertFork(cb, x => expect(x).toBe('1'))
59+
);
60+
});
61+
62+
it('Should call the constructor once if we use it', (cb) => {
63+
// GIVEN: a manually created task that uses and modifies a global variable
64+
let i = 0;
65+
const task = new Task<number, never>(resolve => {
66+
resolve(i++);
67+
});
68+
69+
// WHEN: we transform the value using share
70+
const result = task.pipe(
71+
map(n => '' + n),
72+
share()
73+
);
74+
// THEN: the first time we fork we should have the value 0
75+
result.fork(
76+
jestAssertNever(cb),
77+
x => expect(x).toBe('0')
78+
);
79+
80+
// THEN: and the second time as well
81+
result.fork(
82+
jestAssertNever(cb),
83+
assertFork(cb, x => expect(x).toBe('0'))
84+
);
85+
});
86+
87+
it('Should share the error', (cb) => {
88+
// GIVEN: a manually created task that rejects only once
89+
let i = 0;
90+
const task = new Task<number, string>((resolve, reject) => {
91+
if (i++ === 0) {
92+
reject('buu');
93+
} else {
94+
resolve(i);
95+
}
96+
});
97+
98+
// WHEN: we transform the value using share
99+
const result = task.pipe(
100+
map(n => '' + n),
101+
share()
102+
);
103+
104+
// THEN: both times we fork we should get the error
105+
result.fork(
106+
assertFork(cb, x => expect(x).toBe('buu')),
107+
jestAssertUntypedNeverCalled(cb)
108+
);
109+
110+
result.fork(
111+
assertFork(cb, x => expect(x).toBe('buu')),
112+
jestAssertUntypedNeverCalled(cb)
113+
);
114+
});
115+
});

0 commit comments

Comments
 (0)