Skip to content

Commit

Permalink
feat(share): added share function
Browse files Browse the repository at this point in the history
  • Loading branch information
dggluz committed Aug 14, 2018
1 parent 74c8978 commit f5ba613
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 0 deletions.
95 changes: 95 additions & 0 deletions src/share.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { Task, operators } from '@acamica/task'
import { assertFork, jestAssertNever, jestAssertUntypedNeverCalled } from './testing-utils'
import { share } from './share'

const { map } = operators

describe('share', () => {
it('should be lazy (dont call if not forked)', cb => {
// GIVEN: a manually created task
const task = new Task(resolve => {
// This should not be called
expect(true).toBe(false)
})

// WHEN: we share but we dont fork
task.pipe(share())

// THEN: the content of the task is never called
setTimeout(cb, 20)
})

it('should be lazy (called when forked)', cb => {
// GIVEN: a manually created task
const task = new Task(resolve => {
// This should be called
expect(true).toBe(true)
cb()
})

// WHEN: we share and fork
task.pipe(share())

// THEN: the content of the task is called
task.fork(x => x, x => x)
})

it('Should call the constructor twice if we dont use it', cb => {
// GIVEN: a manually created task that uses and modifies a global variable
let i = 0
const task = new Task<number, never>(resolve => {
resolve(i++)
})

// WHEN: we transform the value without using share
const result = task.pipe(map(n => '' + n))

// THEN: the first time we fork we should have the value 0
result.fork(jestAssertNever(cb), x => expect(x).toBe('0'))

// THEN: and the second time, the value 1
result.fork(jestAssertNever(cb), assertFork(cb, x => expect(x).toBe('1')))
})

it('Should call the constructor once if we use it', cb => {
// GIVEN: a manually created task that uses and modifies a global variable
let i = 0
const task = new Task<number, never>(resolve => {
resolve(i++)
})

// WHEN: we transform the value using share
const result = task.pipe(
map(n => '' + n),
share()
)
// THEN: the first time we fork we should have the value 0
result.fork(jestAssertNever(cb), x => expect(x).toBe('0'))

// THEN: and the second time as well
result.fork(jestAssertNever(cb), assertFork(cb, x => expect(x).toBe('0')))
})

it('Should share the error', cb => {
// GIVEN: a manually created task that rejects only once
let i = 0
const task = new Task<number, string>((resolve, reject) => {
if (i++ === 0) {
reject('buu')
} else {
resolve(i)
}
})

// WHEN: we transform the value using share
const result = task.pipe(
map(n => '' + n),
share()
)

// THEN: both times we fork we should get the error
result.fork(assertFork(cb, x => expect(x).toBe('buu')), jestAssertUntypedNeverCalled(cb))

result.fork(assertFork(cb, x => expect(x).toBe('buu')), jestAssertUntypedNeverCalled(cb))
})
})
14 changes: 14 additions & 0 deletions src/share.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Task } from '@acamica/task'
import { toPromise } from './to-promise'

export function share<T, E>() {
let result: Promise<T> | undefined
return function(input: Task<T, E>): Task<T, E> {
return new Task((outerResolve, outerReject) => {
if (typeof result === 'undefined') {
result = toPromise(input)
}
result.then(outerResolve, outerReject)
})
}
}

0 comments on commit f5ba613

Please sign in to comment.