[Pkg-javascript-commits] [node-depd] 02/06: Imported Upstream version 0.4.4
Andrew Kelley
andrewrk-guest at moszumanska.debian.org
Tue Sep 9 17:20:11 UTC 2014
This is an automated email from the git hooks/post-receive script.
andrewrk-guest pushed a commit to branch master
in repository node-depd.
commit f8cfd1b8502b53ead9384146b933740d3bcc625a
Author: Andrew Kelley <superjoe30 at gmail.com>
Date: Tue Sep 9 17:16:37 2014 +0000
Imported Upstream version 0.4.4
---
History.md | 29 +++++
Readme.md | 29 ++++-
files/message.png | Bin 2733 -> 2857 bytes
index.js | 104 +++++++++++++++---
package.json | 4 +-
test/fixtures/my-lib.js | 15 +++
test/fixtures/old-lib.js | 5 +
test/fixtures/script.js | 8 ++
test/fixtures/thing-lib.js | 6 +
test/fixtures/{old-lib.js => trace-lib.js} | 4 +-
test/test.js | 171 +++++++++++++++++++++++++++++
11 files changed, 350 insertions(+), 25 deletions(-)
diff --git a/History.md b/History.md
index b9d1c6d..ba1af12 100644
--- a/History.md
+++ b/History.md
@@ -1,3 +1,32 @@
+0.4.4 / 2014-07-27
+==================
+
+ * Work-around v8 generating empty stack traces
+
+0.4.3 / 2014-07-26
+==================
+
+ * Fix exception when global `Error.stackTraceLimit` is too low
+
+0.4.2 / 2014-07-19
+==================
+
+ * Correct call site for wrapped functions and properties
+
+0.4.1 / 2014-07-19
+==================
+
+ * Improve automatic message generation for function properties
+
+0.4.0 / 2014-07-19
+==================
+
+ * Add `TRACE_DEPRECATION` environment variable
+ * Remove non-standard grey color from color output
+ * Support `--no-deprecation` argument
+ * Support `--trace-deprecation` argument
+ * Support `deprecate.property(fn, prop, message)`
+
0.3.0 / 2014-06-16
==================
diff --git a/Readme.md b/Readme.md
index 872a8b4..47a53a1 100644
--- a/Readme.md
+++ b/Readme.md
@@ -3,6 +3,7 @@
[![NPM version](https://badge.fury.io/js/depd.svg)](http://badge.fury.io/js/depd)
[![Build Status](https://travis-ci.org/dougwilson/nodejs-depd.svg?branch=master)](https://travis-ci.org/dougwilson/nodejs-depd)
[![Coverage Status](https://img.shields.io/coveralls/dougwilson/nodejs-depd.svg?branch=master)](https://coveralls.io/r/dougwilson/nodejs-depd)
+[![Gittip](http://img.shields.io/gittip/dougwilson.svg)](https://www.gittip.com/dougwilson/)
Deprecate all the things
@@ -17,8 +18,7 @@ $ npm install depd
## API
```js
-var depd = require('depd')
-var deprecate = depd('my-module')
+var deprecate = require('depd')('my-module')
```
This library allows you to display deprecation messages to your users.
@@ -114,9 +114,32 @@ This will suppress deprecations from being output for "my-module" and "othermod"
The value is a list of comma-separated namespaces. To suppress every warning
across all namespaces, use the value `*` for a namespace.
+Providing the argument `--no-deprecation` to the `node` executable will suppress
+all deprecations.
+
**NOTE** This will not suppress the deperecations given to any "deprecation"
event listeners, just the output to STDERR.
+### process.env.TRACE_DEPRECATION
+
+As a user of modules that are deprecated, the environment variable `TRACE_DEPRECATION`
+is provided as a solution to getting more detailed location information in deprecation
+warnings by including the entire stack trace. The format of this is the same as
+`NO_DEPRECATION`:
+
+```sh
+$ TRACE_DEPRECATION=my-module,othermod node app.js
+```
+
+This will include stack traces for deprecations being output for "my-module" and
+"othermod". The value is a list of comma-separated namespaces. To trace every
+warning across all namespaces, use the value `*` for a namespace.
+
+Providing the argument `--trace-deprecation` to the `node` executable will trace
+all deprecations.
+
+**NOTE** This will not trace the deperecations silenced by `NO_DEPRECATION`.
+
## Display
![message](files/message.png)
@@ -127,7 +150,7 @@ and layout to the `debug` module):
```
bright cyan bright yellow
-| | grey cyan
+| | reset cyan
| | | |
▼ ▼ ▼ ▼
my-cool-module deprecated oldfunction [eval]-wrapper:6:22
diff --git a/files/message.png b/files/message.png
index 21dc881..bc0cf79 100644
Binary files a/files/message.png and b/files/message.png differ
diff --git a/index.js b/index.js
index f42aa07..a6fb372 100644
--- a/index.js
+++ b/index.js
@@ -32,6 +32,27 @@ var eventListenerCount = EventEmitter.listenerCount
|| function (emitter, type) { return emitter.listeners(type).length }
/**
+ * Determine if namespace is contained in the string.
+ */
+
+function containsNamespace(str, namespace) {
+ var val = str.split(/[ ,]+/)
+
+ namespace = String(namespace).toLowerCase()
+
+ for (var i = 0 ; i < val.length; i++) {
+ if (!(str = val[i])) continue;
+
+ // namespace contained
+ if (str === '*' || str.toLowerCase() === namespace) {
+ return true
+ }
+ }
+
+ return false
+}
+
+/**
* Convert a data descriptor to accessor descriptor.
*/
@@ -106,6 +127,7 @@ function depd(namespace) {
deprecate._file = file
deprecate._ignored = isignored(namespace)
deprecate._namespace = namespace
+ deprecate._traced = istraced(namespace)
deprecate._warned = Object.create(null)
deprecate.function = wrapfunction
@@ -119,21 +141,33 @@ function depd(namespace) {
*/
function isignored(namespace) {
+ /* istanbul ignore next: tested in a child processs */
+ if (process.noDeprecation) {
+ // --no-deprecation support
+ return true
+ }
+
var str = process.env.NO_DEPRECATION || ''
- var val = str.split(/[ ,]+/)
- namespace = String(namespace).toLowerCase()
+ // namespace ignored
+ return containsNamespace(str, namespace)
+}
- for (var i = 0 ; i < val.length; i++) {
- if (!(str = val[i])) continue;
+/**
+ * Determine if namespace is traced.
+ */
- // namespace ignored
- if (str === '*' || str.toLowerCase() === namespace) {
- return true
- }
+function istraced(namespace) {
+ /* istanbul ignore next: tested in a child processs */
+ if (process.traceDeprecation) {
+ // --trace-deprecation support
+ return true
}
- return false
+ var str = process.env.TRACE_DEPRECATION || ''
+
+ // namespace traced
+ return containsNamespace(str, namespace)
}
/**
@@ -149,6 +183,7 @@ function log(message, site) {
}
var caller
+ var callFile
var callSite
var i = 0
var seen = false
@@ -170,9 +205,12 @@ function log(message, site) {
// get caller of deprecated thing in relation to file
for (; i < stack.length; i++) {
caller = callSiteLocation(stack[i])
+ callFile = caller[0]
- if (caller[0] === file) {
+ if (callFile === file) {
seen = true
+ } else if (callFile === this._file) {
+ file = this._file
} else if (seen) {
break
}
@@ -207,7 +245,7 @@ function log(message, site) {
var format = process.stderr.isTTY
? formatColor
: formatPlain
- var msg = format.call(this, message, caller)
+ var msg = format.call(this, message, caller, stack.slice(i))
process.stderr.write(msg + '\n', 'utf8')
return
@@ -241,14 +279,20 @@ 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) + '>'
}
+ // make useful type name
+ if (typeName === 'Function') {
+ typeName = callSite.getThis().name || typeName
+ }
+
return callSite.getMethodName()
- ? callSite.getTypeName() + '.' + funcName
+ ? typeName + '.' + funcName
: funcName
}
@@ -256,13 +300,22 @@ function defaultMessage(site) {
* Format deprecation message without color.
*/
-function formatPlain(msg, caller) {
+function formatPlain(msg, caller, stack) {
var timestamp = new Date().toUTCString()
var formatted = timestamp
+ ' ' + this._namespace
+ ' deprecated ' + msg
+ // add stack trace
+ if (this._traced) {
+ for (var i = 0; i < stack.length; i++) {
+ formatted += '\n at ' + stack[i].toString()
+ }
+
+ return formatted
+ }
+
if (caller) {
formatted += ' at ' + formatLocation(caller)
}
@@ -274,10 +327,19 @@ function formatPlain(msg, caller) {
* Format deprecation message with color.
*/
-function formatColor(msg, caller) {
+function formatColor(msg, caller, stack) {
var formatted = '\x1b[36;1m' + this._namespace + '\x1b[22;39m' // bold cyan
+ ' \x1b[33;1mdeprecated\x1b[22;39m' // bold yellow
- + ' \x1b[90m' + msg + '\x1b[39m' // grey
+ + ' \x1b[0m' + msg + '\x1b[39m' // reset
+
+ // add stack trace
+ if (this._traced) {
+ for (var i = 0; i < stack.length; i++) {
+ formatted += '\n \x1b[36mat ' + stack[i].toString() + '\x1b[39m' // cyan
+ }
+
+ return formatted
+ }
if (caller) {
formatted += ' \x1b[36m' + formatLocation(caller) + '\x1b[39m' // cyan
@@ -301,15 +363,21 @@ function formatLocation(callSite) {
*/
function getStack() {
+ var limit = Error.stackTraceLimit
var obj = {}
var prep = Error.prepareStackTrace
Error.prepareStackTrace = prepareObjectStackTrace
- Error.captureStackTrace(obj, getStack)
+ Error.stackTraceLimit = Math.max(10, limit)
+
+ // capture the stack
+ Error.captureStackTrace(obj)
- var stack = obj.stack
+ // slice this function off the top
+ var stack = obj.stack.slice(1)
Error.prepareStackTrace = prep
+ Error.stackTraceLimit = limit
return stack
}
@@ -351,7 +419,7 @@ function wrapfunction(fn, message) {
*/
function wrapproperty(obj, prop, message) {
- if (!obj || typeof obj !== 'object') {
+ if (!obj || (typeof obj !== 'object' && typeof obj !== 'function')) {
throw new TypeError('argument obj must be object')
}
diff --git a/package.json b/package.json
index bc62cf5..5623078 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "depd",
"description": "Deprecate all the things",
- "version": "0.3.0",
+ "version": "0.4.4",
"author": "Douglas Christopher Wilson <doug at somethingdoug.com>",
"license": "MIT",
"keywords": [
@@ -10,7 +10,7 @@
],
"repository": "dougwilson/nodejs-depd",
"devDependencies": {
- "istanbul": "0.2.10",
+ "istanbul": "0.3.0",
"mocha": "~1.20.1",
"should": "~4.0.4"
},
diff --git a/test/fixtures/my-lib.js b/test/fixtures/my-lib.js
index fa096cc..1b1821f 100644
--- a/test/fixtures/my-lib.js
+++ b/test/fixtures/my-lib.js
@@ -59,6 +59,21 @@ 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
}
diff --git a/test/fixtures/old-lib.js b/test/fixtures/old-lib.js
index fc33744..44dcf11 100644
--- a/test/fixtures/old-lib.js
+++ b/test/fixtures/old-lib.js
@@ -1,6 +1,7 @@
var deprecate1 = require('../..')('old-lib')
var deprecate2 = require('../..')('old-lib-other')
+var deprecate3 = require('../..')('my-cool-module')
exports.old = function () {
deprecate1('old')
@@ -9,3 +10,7 @@ exports.old = function () {
exports.old2 = function () {
deprecate2('old2')
}
+
+exports.oldfunction = function () {
+ deprecate3('oldfunction')
+}
diff --git a/test/fixtures/script.js b/test/fixtures/script.js
new file mode 100644
index 0000000..db149b6
--- /dev/null
+++ b/test/fixtures/script.js
@@ -0,0 +1,8 @@
+
+var oldlib = require('./old-lib')
+
+run()
+
+function run() {
+ oldlib.oldfunction()
+}
diff --git a/test/fixtures/thing-lib.js b/test/fixtures/thing-lib.js
new file mode 100644
index 0000000..6d757a6
--- /dev/null
+++ b/test/fixtures/thing-lib.js
@@ -0,0 +1,6 @@
+
+var deprecate = require('../..')('thing-lib')
+
+exports.old = function () {
+ deprecate('old')
+}
diff --git a/test/fixtures/old-lib.js b/test/fixtures/trace-lib.js
similarity index 51%
copy from test/fixtures/old-lib.js
copy to test/fixtures/trace-lib.js
index fc33744..89c04d7 100644
--- a/test/fixtures/old-lib.js
+++ b/test/fixtures/trace-lib.js
@@ -1,6 +1,6 @@
-var deprecate1 = require('../..')('old-lib')
-var deprecate2 = require('../..')('old-lib-other')
+var deprecate1 = require('../..')('trace-lib')
+var deprecate2 = require('../..')('trace-lib-other')
exports.old = function () {
deprecate1('old')
diff --git a/test/test.js b/test/test.js
index 50882d0..02fcfaf 100644
--- a/test/test.js
+++ b/test/test.js
@@ -2,7 +2,10 @@
var basename = require('path').basename
var depd = require('..')
var mylib = require('./fixtures/my-lib')
+var path = require('path')
+var script = path.join(__dirname, 'fixtures', 'script.js')
var should = require('should')
+var spawn = require('child_process').spawn
describe('depd(namespace)', function () {
it('creates deprecated function', function () {
@@ -37,6 +40,19 @@ describe('deprecate(message)', function () {
stderr.should.match(/\.js:[0-9]+:[0-9]+/)
})
+ it('should log call site regardless of Error.stackTraceLimit', function () {
+ function callold() { mylib.old() }
+ var limit = Error.stackTraceLimit
+ try {
+ Error.stackTraceLimit = 1
+ var stderr = captureStderr(callold)
+ stderr.should.containEql(basename(__filename))
+ stderr.should.match(/\.js:[0-9]+:[0-9]+/)
+ } finally {
+ Error.stackTraceLimit = limit
+ }
+ })
+
it('should log call site within eval', function () {
function callold() { eval('mylib.old()') }
var stderr = captureStderr(callold)
@@ -219,6 +235,13 @@ describe('deprecate.function(fn, message)', function () {
ret.should.equal(2)
})
+ it('should show call site outside scope', function () {
+ function callold() { mylib.layerfn() }
+ var stderr = captureStderr(callold)
+ stderr.should.containEql(' oldfn ')
+ stderr.should.match(/test.js:[0-9]+:[0-9]+/)
+ })
+
it('should only warn once per call site', function () {
function callold() {
for (var i = 0; i < 5; i++) {
@@ -232,6 +255,17 @@ describe('deprecate.function(fn, message)', function () {
stderr.split('invoke').should.have.length(6)
})
+ it('should handle rapid calling of deprecated thing', function () {
+ function callold() {
+ for (var i = 0; i < 10000; i++) {
+ mylib.oldfn()
+ }
+ }
+
+ var stderr = captureStderr(callold)
+ stderr.split('deprecated').should.have.length(2)
+ })
+
it('should warn for different calls on same line', function () {
function callold() {
mylib.oldfn(), mylib.oldfn()
@@ -327,6 +361,29 @@ describe('deprecate.property(obj, prop, message)', function () {
stderr.split(fileline[0]).should.have.length(3)
})
+ it('should show call site outside scope', function () {
+ function callold() { mylib.layerprop() }
+ var stderr = captureStderr(callold)
+ stderr.should.containEql(' propa ')
+ stderr.should.match(/test.js:[0-9]+:[0-9]+/)
+ })
+
+ describe('when obj is a function', function () {
+ it('should log on access to property on function', function () {
+ function callprop() { mylib.fnprop.propa }
+ var stderr = captureStderr(callprop)
+ stderr.should.containEql(' deprecated ')
+ stderr.should.containEql(' fn propa gone ')
+ })
+
+ it('should generate message on named function', function () {
+ function callprop() { mylib.fnprop.propautomsg }
+ var stderr = captureStderr(callprop)
+ stderr.should.containEql(' deprecated ')
+ stderr.should.containEql(' thefn.propautomsg ')
+ })
+ })
+
describe('when value descriptor', function () {
it('should log on access and set', function () {
function callold() { mylib.propa }
@@ -440,6 +497,14 @@ describe('process.env.NO_DEPRECATION', function () {
var error
function ondeprecation(err) { error = err }
+ beforeEach(function () {
+ error = null
+ })
+
+ afterEach(function () {
+ process.removeListener('deprecation', ondeprecation)
+ })
+
after(function () {
process.env.NO_DEPRECATION = ''
})
@@ -464,6 +529,14 @@ describe('process.env.NO_DEPRECATION', function () {
captureStderr(newlib.old).should.be.empty
})
+ it('should emit "deprecation" events anyway', function () {
+ process.env.NO_DEPRECATION = 'thing-lib'
+ var thinglib = require('./fixtures/thing-lib')
+ process.on('deprecation', ondeprecation)
+ captureStderr(thinglib.old).should.be.empty
+ error.namespace.should.equal('thing-lib')
+ })
+
describe('when *', function () {
it('should suppress any namespace', function () {
process.env.NO_DEPRECATION = '*'
@@ -474,6 +547,104 @@ describe('process.env.NO_DEPRECATION', function () {
})
})
+describe('process.env.TRACE_DEPRECATION', function () {
+ before(function () {
+ process.env.TRACE_DEPRECATION = 'trace-lib'
+ })
+
+ after(function () {
+ process.env.TRACE_DEPRECATION = ''
+ })
+
+ it('should trace given namespace', function () {
+ var tracelib = require('./fixtures/trace-lib')
+ function callold() { tracelib.old() }
+ captureStderr(callold).should.containEql(' trace-lib deprecated old\n at callold (')
+ })
+
+ it('should not trace non-given namespace', function () {
+ var tracelib = require('./fixtures/trace-lib')
+ function callold() { tracelib.old2() }
+ captureStderr(callold).should.containEql(' trace-lib-other deprecated old2 at ')
+ })
+
+ describe('when output supports colors', function () {
+ var stderr
+ before(function () {
+ var tracelib = require('./fixtures/trace-lib')
+ function callold() { tracelib.old() }
+ stderr = captureStderr(callold, true)
+ })
+
+ it('should log in color', function () {
+ stderr.should.not.be.empty
+ stderr.should.containEql('\x1b[')
+ })
+
+ it('should log namespace', function () {
+ stderr.should.containEql('trace-lib')
+ })
+
+ it('should log call site in color', function () {
+ stderr.should.containEql(basename(__filename))
+ stderr.should.match(/\x1b\[\d+mat callold \(/)
+ })
+ })
+})
+
+describe('node script.js', function () {
+ it('should display deprecation message', function (done) {
+ captureChildStderr([script], function (err, stderr) {
+ if (err) return done(err)
+ var filename = path.relative(process.cwd(), script)
+ stderr = stderr.replace(/\w+, \d+ \w+ \d+ \d+:\d+:\d+ \w+/, '__timestamp__')
+ stderr.should.equal('__timestamp__ my-cool-module deprecated oldfunction at ' + filename + ':7:10\n')
+ done()
+ })
+ })
+})
+
+describe('node --no-deprecation script.js', function () {
+ it('should suppress deprecation message', function (done) {
+ captureChildStderr(['--no-deprecation', script], function (err, stderr) {
+ if (err) return done(err)
+ stderr.should.be.empty
+ done()
+ })
+ })
+})
+
+describe('node --trace-deprecation script.js', function () {
+ it('should suppress deprecation message', function (done) {
+ captureChildStderr(['--trace-deprecation', script], function (err, stderr) {
+ if (err) return done(err)
+ stderr = stderr.replace(/\w+, \d+ \w+ \d+ \d+:\d+:\d+ \w+/, '__timestamp__')
+ stderr.should.startWith('__timestamp__ my-cool-module deprecated oldfunction\n at run (' + script + ':7:10)\n at')
+ done()
+ })
+ })
+})
+
+function captureChildStderr(args, callback) {
+ var chunks = []
+ var env = {PATH: process.env.PATH}
+ var exec = process.argv[0]
+ var proc = spawn(exec, args, {
+ env: env
+ })
+
+ proc.stdout.resume()
+ proc.stderr.on('data', function ondata(chunk) {
+ chunks.push(chunk)
+ })
+
+ proc.on('error', callback)
+ proc.on('exit', function () {
+ var stderr = Buffer.concat(chunks).toString('utf8')
+ callback(null, stderr)
+ })
+}
+
function captureStderr(fn, color) {
var chunks = []
var isTTY = process.stderr.isTTY
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-depd.git
More information about the Pkg-javascript-commits
mailing list