[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