Skip to content

Commit

Permalink
feat(controls): Adding wrap controls
Browse files Browse the repository at this point in the history
Wrap controls allows function calls wrapping to ease testing generators
  • Loading branch information
youknowriad committed Jan 31, 2016
1 parent 67876b7 commit 74e4020
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 2 deletions.
22 changes: 22 additions & 0 deletions src/controls/wrap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import is from '../utils/is'

export const call = (value, next, iterate, yieldNext, raiseNext) => {
if (!is.call(value)) return false
try {
next(value.func.apply(value.context, value.args))
} catch (err) {
raiseNext(err)
}
return true
}

export const cps = (value, next, iterate, yieldNext, raiseNext) => {
if (!is.cps(value)) return false
value.func.call(null, ...value.args, (err, result) => {
if (err) raiseNext(err)
else next(result)
})
return true
}

export default [call, cps]
27 changes: 27 additions & 0 deletions src/utils/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,31 @@ export const race = (competitors) => ({

export const delay = (timeout) => new Promise(resolve => {
setTimeout(resolve, timeout)
})

export const invoke = (func, ...args) => ({
type: keys.call,
func: func,
context: null,
args: args
})

export const call = (func, context, ...args) => ({
type: keys.call,
func: func,
context: context,
args: args
})

export const apply = (func, context, args) => ({
type: keys.call,
func: func,
context: context,
args: args
})

export const cps = (func, ...args) => ({
type: keys.cps,
func: func,
args: args
})
4 changes: 3 additions & 1 deletion src/utils/is.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ const is = {
iterator : value => value && is.func(value.next) && is.func(value[Symbol.iterator]),
fork : value => is.obj(value) && value.type === keys.fork,
join : value => is.obj(value) && value.type === keys.join,
race : value => is.obj(value) && value.type === keys.race
race : value => is.obj(value) && value.type === keys.race,
call : value => is.obj(value) && value.type === keys.call,
cps : value => is.obj(value) && value.type === keys.cps
}

export default is
4 changes: 3 additions & 1 deletion src/utils/keys.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ const keys = {
error : Symbol('error'),
fork : Symbol('fork'),
join : Symbol('join'),
race : Symbol('race')
race : Symbol('race'),
call : Symbol('call'),
cps : Symbol('cps')
}

export default keys
103 changes: 103 additions & 0 deletions test/controls/wrap.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import 'babel-polyfill'
import expect from 'expect'
import create from '../../src/create'
import * as wrap from '../../src/controls/wrap'
import {invoke, call, apply, cps} from '../../src/utils/helpers'

describe('Wrap Controls', () => {
it('call control using invoke', () => {
let output
const func = input => input
const generator = function* () {
output = yield invoke(func, 'invoked')
}
const runtime = create([wrap.call])
const expected = 'invoked'

runtime(generator)
expect(output).toEqual(expected)
})

it('call control using call', () => {
let output
const context = { a: 'b' }
const func = function(input) {
return this.a + ' ' + input
}
const generator = function* () {
output = yield call(func, context, 'invoked')
}
const runtime = create([wrap.call])
const expected = 'b invoked'

runtime(generator)
expect(output).toEqual(expected)
})

it('call control using apply', () => {
let output
const context = { a: 'b' }
const func = function(input) {
return this.a + ' ' + input
}
const generator = function* () {
output = yield apply(func, context, ['invoked'])
}
const runtime = create([wrap.call])
const expected = 'b invoked'

runtime(generator)
expect(output).toEqual(expected)
})

it('call control with error', () => {
let output
const func = () => { throw 'error' }
const generator = function* () {
try {
output = yield invoke(func)
} catch (err) {
output = err
}
}
const runtime = create([wrap.call])
const expected = 'error'

runtime(generator)
expect(output).toEqual(expected)
})

it('cps control', () => {
let output
const func = (input, callback) => {
callback(false, input)
}
const generator = function* () {
output = yield cps(func, 'invoked')
}
const runtime = create([wrap.cps])
const expected = 'invoked'

runtime(generator)
expect(output).toEqual(expected)
})

it('cps control with error', () => {
let output
const func = (input, callback) => {
callback('error', input)
}
const generator = function* () {
try {
output = yield cps(func, 'invoked')
} catch (err) {
output = err
}
}
const runtime = create([wrap.cps])
const expected = 'error'

runtime(generator)
expect(output).toEqual(expected)
})
})

0 comments on commit 74e4020

Please sign in to comment.