Skip to content

Commit

Permalink
Fix TypeErrors when under 'use strict' code
Browse files Browse the repository at this point in the history
fixes #17
  • Loading branch information
dougwilson committed Apr 7, 2015
1 parent 318bbbe commit ec0a6a6
Show file tree
Hide file tree
Showing 4 changed files with 181 additions and 3 deletions.
1 change: 1 addition & 0 deletions History.md
@@ -1,6 +1,7 @@
unreleased
==========

* Fix `TypeError`s when under `'use strict'` code
* Fix useless type name on auto-generated messages
* Support io.js 1.x
* Support Node.js 0.12
Expand Down
6 changes: 4 additions & 2 deletions index.js
Expand Up @@ -280,21 +280,23 @@ function callSiteLocation(callSite) {
function defaultMessage(site) {
var callSite = site.callSite
var funcName = site.name
var typeName = callSite.getTypeName()

// make useful anonymous name
if (!funcName) {
funcName = '<anonymous@' + formatLocation(site) + '>'
}

var context = callSite.getThis()
var typeName = context && callSite.getTypeName()

// ignore useless type name
if (typeName === 'Object') {
typeName = undefined
}

// make useful type name
if (typeName === 'Function') {
typeName = callSite.getThis().name || typeName
typeName = context.name || typeName
}

return typeName && callSite.getMethodName()
Expand Down
51 changes: 51 additions & 0 deletions test/fixtures/strict-lib.js
@@ -0,0 +1,51 @@

'use strict'

var deprecate = require('../..')('strict-lib')

exports.old = function () {
deprecate('old')
}

exports.oldfn = deprecate.function(fn, 'oldfn')

exports.oldfnauto = deprecate.function(fn)

exports.oldfnautoanon = deprecate.function(function () {})

exports.propa = 'thingie'
exports.propauto = 'thingie'

deprecate.property(exports, 'propa', 'propa gone')
deprecate.property(exports, 'propauto')

exports.automsg = function () {
deprecate()
}

exports.automsgnamed = function automsgnamed() {
deprecate()
}

exports.automsganon = function () {
(function () { deprecate() }())
}

exports.fnprop = function thefn() {}
exports.fnprop.propa = 'thingie'
exports.fnprop.propautomsg = 'thingie'

deprecate.property(exports.fnprop, 'propa', 'fn propa gone')
deprecate.property(exports.fnprop, 'propautomsg')

exports.layerfn = function () {
exports.oldfn()
}

exports.layerprop = function () {
exports.propa
}

function fn(a1, a2) {
return a2
}
126 changes: 125 additions & 1 deletion test/test.js
Expand Up @@ -7,6 +7,7 @@ var mylib = require('./fixtures/my-lib')
var path = require('path')
var script = path.join(__dirname, 'fixtures', 'script.js')
var spawn = require('child_process').spawn
var strictlib = require('./fixtures/strict-lib')

describe('depd(namespace)', function () {
it('creates deprecated function', function () {
Expand Down Expand Up @@ -41,6 +42,13 @@ describe('deprecate(message)', function () {
assert.ok(/\.js:[0-9]+:[0-9]+/.test(stderr))
})

it('should log call site from strict lib', function () {
function callold() { strictlib.old() }
var stderr = captureStderr(callold)
assert.ok(stderr.indexOf(basename(__filename)) !== -1)
assert.ok(/\.js:[0-9]+:[0-9]+/.test(stderr))
})

it('should log call site regardless of Error.stackTraceLimit', function () {
function callold() { mylib.old() }
var limit = Error.stackTraceLimit
Expand All @@ -62,6 +70,13 @@ describe('deprecate(message)', function () {
assert.ok(/\.js:[0-9]+:[0-9]+/.test(stderr))
})

it('should log call site within strict', function () {
function callold() { 'use strict'; mylib.old() }
var stderr = captureStderr(callold)
assert.ok(stderr.indexOf(basename(__filename)) !== -1)
assert.ok(/\.js:[0-9]+:[0-9]+/.test(stderr))
})

it('should only warn once per call site', function () {
function callold() {
for (var i = 0; i < 5; i++) {
Expand Down Expand Up @@ -147,6 +162,54 @@ describe('deprecate(message)', function () {
assert.ok(stderr.indexOf('deprecated') !== -1)
assert.ok(/ exports\.automsganon | <anonymous@[^:]+:[0-9]+:[0-9]+> /.test(stderr))
})

describe('in strict mode library', function () {
it('should generate message for method call on named function', function () {
function callold() { strictlib.automsgnamed() }
var stderr = captureStderr(callold)
assert.ok(stderr.indexOf(basename(__filename)) !== -1)
assert.ok(stderr.indexOf('deprecated') !== -1)
assert.ok(stderr.indexOf(' automsgnamed ') !== -1)
})

it('should generate message for function call on named function', function () {
function callold() {
var fn = strictlib.automsgnamed
fn()
}
var stderr = captureStderr(callold)
assert.ok(stderr.indexOf(basename(__filename)) !== -1)
assert.ok(stderr.indexOf('deprecated') !== -1)
assert.ok(stderr.indexOf(' automsgnamed ') !== -1)
})

it('should generate message for method call on unnamed function', function () {
function callold() { strictlib.automsg() }
var stderr = captureStderr(callold)
assert.ok(stderr.indexOf(basename(__filename)) !== -1)
assert.ok(stderr.indexOf('deprecated') !== -1)
assert.ok(stderr.indexOf(' exports.automsg ') !== -1)
})

it('should generate message for function call on unnamed function', function () {
function callold() {
var fn = strictlib.automsg
fn()
}
var stderr = captureStderr(callold)
assert.ok(stderr.indexOf(basename(__filename)) !== -1)
assert.ok(stderr.indexOf('deprecated') !== -1)
assert.ok(stderr.indexOf(' exports.automsg ') !== -1)
})

it('should generate message for function call on anonymous function', function () {
function callold() { strictlib.automsganon() }
var stderr = captureStderr(callold)
assert.ok(stderr.indexOf(basename(__filename)) !== -1)
assert.ok(stderr.indexOf('deprecated') !== -1)
assert.ok(/ exports\.automsganon | <anonymous@[^:]+:[0-9]+:[0-9]+> /.test(stderr))
})
})
})

describe('when output supports colors', function () {
Expand Down Expand Up @@ -215,7 +278,7 @@ describe('deprecate(message)', function () {
})

describe('deprecate.function(fn, message)', function () {
it('should thrown when not given function', function () {
it('should throw when not given function', function () {
var deprecate = depd('test')
assert.throws(deprecate.function.bind(deprecate, 2), /fn.*function/)
})
Expand Down Expand Up @@ -243,6 +306,13 @@ describe('deprecate.function(fn, message)', function () {
assert.ok(/test.js:[0-9]+:[0-9]+/.test(stderr))
})

it('should show call site outside scope from strict lib', function () {
function callold() { strictlib.layerfn() }
var stderr = captureStderr(callold)
assert.ok(stderr.indexOf(' oldfn ') !== -1)
assert.ok(/test.js:[0-9]+:[0-9]+/.test(stderr))
})

it('should only warn once per call site', function () {
function callold() {
for (var i = 0; i < 5; i++) {
Expand Down Expand Up @@ -297,6 +367,26 @@ describe('deprecate.function(fn, message)', function () {
assert.ok(/ <anonymous@[^:]+my-lib\.js:[0-9]+:[0-9]+> /.test(stderr))
assert.ok(/ at [^:]+test\.js:/.test(stderr))
})

describe('in strict mode library', function () {
it('should generate message for method call on named function', function () {
function callold() { strictlib.oldfnauto() }
var stderr = captureStderr(callold)
assert.ok(stderr.indexOf(basename(__filename)) !== -1)
assert.ok(stderr.indexOf('deprecated') !== -1)
assert.ok(stderr.indexOf(' fn ') !== -1)
assert.ok(/ at [^:]+test\.js:/.test(stderr))
})

it('should generate message for method call on anonymous function', function () {
function callold() { strictlib.oldfnautoanon() }
var stderr = captureStderr(callold)
assert.ok(stderr.indexOf(basename(__filename)) !== -1)
assert.ok(stderr.indexOf('deprecated') !== -1)
assert.ok(/ <anonymous@[^:]+strict-lib\.js:[0-9]+:[0-9]+> /.test(stderr))
assert.ok(/ at [^:]+test\.js:/.test(stderr))
})
})
})
})

Expand Down Expand Up @@ -369,6 +459,13 @@ describe('deprecate.property(obj, prop, message)', function () {
assert.ok(/test.js:[0-9]+:[0-9]+/.test(stderr))
})

it('should show call site outside scope from strict lib', function () {
function callold() { strictlib.layerprop() }
var stderr = captureStderr(callold)
assert.ok(stderr.indexOf(' propa ') !== -1)
assert.ok(/test.js:[0-9]+:[0-9]+/.test(stderr))
})

describe('when obj is a function', function () {
it('should log on access to property on function', function () {
function callprop() { mylib.fnprop.propa }
Expand All @@ -383,6 +480,22 @@ describe('deprecate.property(obj, prop, message)', function () {
assert.ok(stderr.indexOf(' deprecated ') !== -1)
assert.ok(stderr.indexOf(' thefn.propautomsg ') !== -1)
})

describe('in strict mode library', function () {
it('should log on access to property on function', function () {
function callprop() { strictlib.fnprop.propa }
var stderr = captureStderr(callprop)
assert.ok(stderr.indexOf(' deprecated ') !== -1)
assert.ok(stderr.indexOf(' fn propa gone ') !== -1)
})

it('should generate message on named function', function () {
function callprop() { strictlib.fnprop.propautomsg }
var stderr = captureStderr(callprop)
assert.ok(stderr.indexOf(' deprecated ') !== -1)
assert.ok(stderr.indexOf(' thefn.propautomsg ') !== -1)
})
})
})

describe('when value descriptor', function () {
Expand Down Expand Up @@ -429,6 +542,17 @@ describe('deprecate.property(obj, prop, message)', function () {
assert.ok(stderr.indexOf(' propauto ') !== -1)
assert.ok(/ at [^:]+test\.js:/.test(stderr))
})

describe('in strict mode library', function () {
it('should generate message for method call on named function', function () {
function callold() { strictlib.propauto }
var stderr = captureStderr(callold)
assert.ok(stderr.indexOf(basename(__filename)) !== -1)
assert.ok(stderr.indexOf('deprecated') !== -1)
assert.ok(stderr.indexOf(' propauto ') !== -1)
assert.ok(/ at [^:]+test\.js:/.test(stderr))
})
})
})
})

Expand Down

0 comments on commit ec0a6a6

Please sign in to comment.