test.js
/*!
* rename-function <https://github.com/tunnckoCore/rename-function>
*
* Copyright (c) 2016 Charlike Mike Reagent <@tunnckoCore> (http://www.tunnckocore.tk)
* Released under the MIT license.
*/
/* jshint asi:true */
'use strict'
var inspect = require('util').inspect
var test = require('assertit')
var renameFunction = require('./index')
var getName = require('get-fn-name')
var toString = require('clean-tostring')
var isIstanbul = process.env.running_under_istanbul
test('should throw TypeError if `fn` not a function', function (done) {
function fixture () {
renameFunction(123)
}
test.throws(fixture, TypeError)
test.throws(fixture, /expect `fn` be function/)
done()
})
test('should namify `name` if reserved word', function (done) {
function foo () {}
var fn = renameFunction(foo, 'class')
test.strictEqual(getName(fn), '_class')
done()
})
test('should have correct, actual and updated result of `.toString`', function (done) {
function bar () { return 123 }
var qux = renameFunction(bar, 'qux')
/* istanbul ignore next */
if (isIstanbul) {
test.strictEqual(toString(bar), 'function bar() {return 123;}')
test.strictEqual(toString(qux), 'function qux() {return 123;}')
} else {
test.strictEqual(toString(bar), 'function bar() { return 123 }')
test.strictEqual(toString(qux), 'function qux() { return 123 }')
}
done()
})
test('should allow optionally passing a context as third argument', function (done) {
function qux () { return this.foo }
var actual = renameFunction(qux, 'abc', {foo: 'bar'})
test.strictEqual(actual(), 'bar')
done()
})
test('should be able to pass context by bind/call/apply renameFunction', function (done) {
function fox () { return this.cat }
var fn = renameFunction.call({cat: 'abc'}, fox, 'cat')
test.strictEqual(fn(), 'abc')
test.strictEqual(getName(fn), 'cat')
done()
})
test('should work for anonymous function', function (done) {
var anonymous = renameFunction(function () { return this || 1 })
test.strictEqual(anonymous.name, '')
test.strictEqual(getName(anonymous), null)
test.strictEqual(anonymous(), 1)
var named = renameFunction(function named () { return this || 2 })
test.strictEqual(named.name, 'named')
test.strictEqual(getName(named), 'named')
test.strictEqual(named(), 2)
done()
})
test('should work to pass context to anonymous function', function (done) {
var anonymous = renameFunction(function () { return this.x }, null, {x: 'y'})
test.strictEqual(anonymous(), 'y')
done()
})
test('should be able to pass only `fn` and `ctx` and preserve name', function (done) {
var anonymous = renameFunction(function () { return this || 1 }, {foo: 'bar'})
var named = renameFunction(function named () { return this || 2 }, {bar: 'qux'})
test.deepEqual(anonymous(), {foo: 'bar'})
test.deepEqual(named(), {bar: 'qux'})
done()
})
test('should return earlier without modifications if `name` is same as original', function (done) {
var fn = renameFunction(function zzz () {}, 'zzz')
var actual = toString(fn)
var expected = 'function zzz() {}'
test.strictEqual(actual, expected)
test.strictEqual(fn.name, 'zzz')
test.strictEqual(getName(fn), 'zzz')
done()
})
test('should respect first context when nested binds (same as native bind behavior)', function (done) {
function zoopark () { return this.foo }
var boundOne = renameFunction(zoopark, {foo: 'one'})
var boundTwo = renameFunction(boundOne, {foo: 'two'})
var boundZzz = renameFunction(boundTwo, {foo: 'zzz'})
test.strictEqual(boundOne(), 'one')
test.strictEqual(boundTwo(), 'one')
test.strictEqual(boundZzz(), 'one')
test.strictEqual(inspect(zoopark), inspect(boundOne))
test.strictEqual(inspect(boundOne), inspect(boundTwo))
test.strictEqual(inspect(boundTwo), inspect(boundZzz))
test.strictEqual(inspect(zoopark), inspect(boundZzz))
done()
})
test('should not have problems to rename bound functions and use the bounded context', function (done) {
function zoopark () { return this.foo }
var bound = renameFunction(zoopark.bind({foo: 'bar'}), 'qux', {foo: 'zzz'})
test.strictEqual(bound.name, 'qux')
test.strictEqual(getName(bound), 'qux')
test.strictEqual(bound(), 'bar')
done()
})