import bind from '../bind'
describe('bind', () => {
function Foo(x) {
this.x = x
}
function add(x) {
return this.x + x
}
class Bar {
constructor(x, y) {
this.x = x
this.y = y
}
getX() {
return 'prototype getX'
}
}
Bar.prototype = new Foo()
it('returns a function', () => {
eq(typeof bind(add, Foo), 'function')
})
it('returns a function bound to the specified context object', () => {
const f = new Foo(12)
function isFoo() {
return this instanceof Foo
}
const isFooBound = bind(isFoo, f)
eq(isFoo(), false)
eq(isFooBound(), true)
})
it('works with built-in types', () => {
const abc = bind(String.prototype.toLowerCase, 'ABCDEFG')
eq(typeof abc, 'function')
eq(abc(), 'abcdefg')
})
it('works with user-defined types', () => {
const f = new Foo(12)
function getX() {
return this.x
}
const getXFooBound = bind(getX, f)
eq(getXFooBound(), 12)
})
it('works with plain objects', () => {
const pojso = {
x: 100,
}
function incThis() {
return this.x + 1
}
const incPojso = bind(incThis, pojso)
eq(typeof incPojso, 'function')
eq(incPojso(), 101)
})
it('does not interfere with existing object methods', () => {
const b = new Bar('a', 'b')
function getX() {
return this.x
}
const getXBarBound = bind(getX, b)
eq(b.getX(), 'prototype getX')
eq(getXBarBound(), 'a')
})
it('is curried', () => {
const f = new Foo(1)
eq(bind(add)(f)(10), 11)
})
it('preserves arity', () => {
const f0 = () => 0
const f1 = a => a
const f2 = (a, b) => a + b
const f3 = (a, b, c) => a + b + c
eq(bind(f0, {}).length, 0)
eq(bind(f1, {}).length, 1)
eq(bind(f2, {}).length, 2)
eq(bind(f3, {}).length, 3)
})
})