Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace function constructor with defineProperty #42

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
55 changes: 32 additions & 23 deletions index.js
Expand Up @@ -64,20 +64,6 @@ function convertDataDescriptorToAccessor (obj, prop, message) {
return descriptor
}

/**
* Create arguments string to keep arity.
*/

function createArgumentsString (arity) {
var str = ''

for (var i = 0; i < arity; i++) {
str += ', arg' + i
}

return str.substr(2)
}

/**
* Create stack string from stack.
*/
Expand Down Expand Up @@ -374,6 +360,20 @@ function formatLocation (callSite) {
':' + callSite[2]
}

/**
* Create arguments string to keep arity.
*/

function createArgumentsString (arity) {
var str = ''

for (var i = 0; i < arity; i++) {
str += ', arg' + i
}

return str.substr(2)
}

/**
* Get the stack as array of call sites.
*/
Expand Down Expand Up @@ -415,20 +415,29 @@ function wrapfunction (fn, message) {
throw new TypeError('argument fn must be a function')
}

var args = createArgumentsString(fn.length)
var deprecate = this
var stack = getStack()
var site = callSiteLocation(stack[1])

site.name = fn.name

// eslint-disable-next-line no-new-func
var deprecatedfn = new Function('fn', 'log', 'deprecate', 'message', 'site',
'"use strict"\n' +
'return function (' + args + ') {' +
'log.call(deprecate, message, site)\n' +
'return fn.apply(this, arguments)\n' +
'}')(fn, log, this, message, site)

var deprecatedfn = function () {
log.call(deprecate, message, site)
return fn.apply(this, arguments)
}
try {
Object.defineProperty(deprecatedfn, 'length', { value: fn.length })
} catch (e) {
// Fallback for NodeJS 2.5 and below
var args = createArgumentsString(fn.length)
// eslint-disable-next-line no-new-func
deprecatedfn = new Function('fn', 'log', 'deprecate', 'message', 'site',
'"use strict"\n' +
'return function (' + args + ') {' +
'log.call(deprecate, message, site)\n' +
'return fn.apply(this, arguments)\n' +
'}')(fn, log, this, message, site)
}
return deprecatedfn
}

Expand Down
8 changes: 8 additions & 0 deletions test/fixtures/basic.js
@@ -0,0 +1,8 @@

var deprecate = require('../..')('basic')

var object = { foo: 'bar' }
deprecate.property(object, 'foo')

function fn () {}
deprecate.function(fn)
29 changes: 26 additions & 3 deletions test/test.js
Expand Up @@ -10,6 +10,16 @@ var script = path.join(__dirname, 'fixtures', 'script.js')
var spawn = require('child_process').spawn
var strictlib = libs.strict

function isNodeVersionGE (required) {
var nodeVersion = process.version.substr(1).split('.')
for (var i = 0; i < required.length; i++) {
if (+nodeVersion[i] < required[i]) {
return false
}
}
return true
}

describe('depd(namespace)', function () {
it('creates deprecated function', function () {
assert.strictEqual(typeof depd('test'), 'function')
Expand Down Expand Up @@ -730,9 +740,9 @@ describe('node script.js', function () {
;(function () {
// --*-deprecation switches are 0.8+
// no good way to feature detect this sync
var describe = /^v0\.6\./.test(process.version)
? global.describe.skip
: global.describe
var describe = isNodeVersionGE([0, 8])
? global.describe
: global.describe.skip

describe('node --no-deprecation script.js', function () {
it('should suppress deprecation message', function (done) {
Expand All @@ -755,6 +765,19 @@ describe('node script.js', function () {
})
}())

describe('node --disallow-code-generation-from-strings script.js', function () {
it('should run without error', function (done) {
if (!isNodeVersionGE([9])) this.skip() // --disallow-code-generation-from-strings is 9+

var basic = path.join(__dirname, 'fixtures', 'basic.js')
captureChildStderr(basic, ['--disallow-code-generation-from-strings'], function (err, stderr) {
if (err) return done(err)
assert.strictEqual(stderr, '')
done()
})
})
})

function captureChildStderr (script, opts, callback) {
var chunks = []
var env = { PATH: process.env.PATH }
Expand Down