summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorisaacs <i@izs.me>2013-05-21 15:22:05 -0700
committerisaacs <i@izs.me>2013-05-21 16:39:50 -0700
commit896b2aa7074fc886efd7dd0a397d694763cac7ce (patch)
tree10142a9e81afb77b762098b138caa50911e7a578
parent0fefcc1690f65593aba768b78e1b97b925f8caad (diff)
downloadandroid-node-v8-896b2aa7074fc886efd7dd0a397d694763cac7ce.tar.gz
android-node-v8-896b2aa7074fc886efd7dd0a397d694763cac7ce.tar.bz2
android-node-v8-896b2aa7074fc886efd7dd0a397d694763cac7ce.zip
util: Add debuglog, deprecate console lookalikes
-rw-r--r--doc/api/util.markdown111
-rw-r--r--lib/_http_client.js4
-rw-r--r--lib/_http_common.js7
-rw-r--r--lib/module.js7
-rw-r--r--lib/net.js15
-rw-r--r--lib/timers.js15
-rw-r--r--lib/tls.js28
-rw-r--r--lib/util.js167
-rw-r--r--test/message/stack_overflow.js4
-rw-r--r--test/message/throw_custom_error.js4
-rw-r--r--test/message/throw_in_line_with_tabs.js4
-rw-r--r--test/message/throw_non_error.js4
-rw-r--r--test/message/undefined_reference_in_new_context.js4
-rw-r--r--test/simple/test-deprecation-flags.js2
-rw-r--r--test/simple/test-http-proxy.js18
-rw-r--r--test/simple/test-util-debug.js87
16 files changed, 296 insertions, 185 deletions
diff --git a/doc/api/util.markdown b/doc/api/util.markdown
index 8b34ba6658..a1bfdb0f69 100644
--- a/doc/api/util.markdown
+++ b/doc/api/util.markdown
@@ -2,9 +2,46 @@
Stability: 5 - Locked
-These functions are in the module `'util'`. Use `require('util')` to access
-them.
+These functions are in the module `'util'`. Use `require('util')` to
+access them.
+The `util` module is primarily designed to support the needs of Node's
+internal APIs. Many of these utilities are useful for your own
+programs. If you find that these functions are lacking for your
+purposes, however, you are encouraged to write your own utilities. We
+are not interested in any future additions to the `util` module that
+are unnecessary for Node's internal functionality.
+
+## util.debuglog(section)
+
+* `section` {String} The section of the program to be debugged
+* Returns: {Function} The logging function
+
+This is used to create a function which conditionally writes to stderr
+based on the existence of a `NODE_DEBUG` environment variable. If the
+`section` name appears in that environment variable, then the returned
+function will be similar to `console.error()`. If not, then the
+returned function is a no-op.
+
+For example:
+
+```javascript
+var debuglog = util.debuglog('foo');
+
+var bar = 123;
+debuglog('hello from foo [%d]', bar);
+```
+
+If this program is run with `NODE_DEBUG=foo` in the environment, then
+it will output something like:
+
+ FOO 3245: hello from foo [123]
+
+where `3245` is the process id. If it is not run with that
+environment variable set, then it will not print anything.
+
+You may separate multiple `NODE_DEBUG` environment variables with a
+comma. For example, `NODE_DEBUG=fs,net,tls`.
## util.format(format, [...])
@@ -37,35 +74,12 @@ Each argument is converted to a string with `util.inspect()`.
util.format(1, 2, 3); // '1 2 3'
-## util.debug(string)
-
-A synchronous output function. Will block the process and
-output `string` immediately to `stderr`.
-
- require('util').debug('message on stderr');
-
-## util.error([...])
-
-Same as `util.debug()` except this will output all arguments immediately to
-`stderr`.
-
-## util.puts([...])
-
-A synchronous output function. Will block the process and output all arguments
-to `stdout` with newlines after each argument.
-
-## util.print([...])
-
-A synchronous output function. Will block the process, cast each argument to a
-string then output to `stdout`. Does not place newlines after each argument.
-
## util.log(string)
Output with timestamp on `stdout`.
require('util').log('Timestamped message.');
-
## util.inspect(object, [options])
Return a string representation of `object`, which is useful for debugging.
@@ -94,6 +108,8 @@ Example of inspecting all properties of the `util` object:
### Customizing `util.inspect` colors
+<!-- type=misc -->
+
Color output (if enabled) of `util.inspect` is customizable globally
via `util.inspect.styles` and `util.inspect.colors` objects.
@@ -116,6 +132,8 @@ There are also `bold`, `italic`, `underline` and `inverse` codes.
### Custom `inspect()` function on Objects
+<!-- type=misc -->
+
Objects also may define their own `inspect(depth)` function which `util.inspect()`
will invoke and use the result of when inspecting the object:
@@ -198,17 +216,6 @@ Returns `true` if the given "object" is an `Error`. `false` otherwise.
// false
-## util.pump(readableStream, writableStream, [callback])
-
- Stability: 0 - Deprecated: Use readableStream.pipe(writableStream)
-
-Read the data from `readableStream` and send it to the `writableStream`.
-When `writableStream.write(data)` returns `false` `readableStream` will be
-paused until the `drain` event occurs on the `writableStream`. `callback` gets
-an error as its only argument and is called when `writableStream` is closed or
-when an error occurs.
-
-
## util.inherits(constructor, superConstructor)
Inherit the prototype methods from one
@@ -241,3 +248,35 @@ through the `constructor.super_` property.
console.log('Received data: "' + data + '"');
})
stream.write("It works!"); // Received data: "It works!"
+
+
+## util.debug(string)
+
+ Stability: 0 - Deprecated: use console.error() instead.
+
+Deprecated predecessor of `console.error`.
+
+## util.error([...])
+
+ Stability: 0 - Deprecated: Use console.error() instead.
+
+Deprecated predecessor of `console.error`.
+
+## util.puts([...])
+
+ Stability: 0 - Deprecated: Use console.log() instead.
+
+Deprecated predecessor of `console.log`.
+
+## util.print([...])
+
+ Stability: 0 - Deprecated: Use `console.log` instead.
+
+Deprecated predecessor of `console.log`.
+
+
+## util.pump(readableStream, writableStream, [callback])
+
+ Stability: 0 - Deprecated: Use readableStream.pipe(writableStream)
+
+Deprecated predecessor of `stream.pipe()`.
diff --git a/lib/_http_client.js b/lib/_http_client.js
index 71f5c335d0..339a5c785d 100644
--- a/lib/_http_client.js
+++ b/lib/_http_client.js
@@ -205,7 +205,7 @@ function socketErrorListener(err) {
var socket = this;
var parser = socket.parser;
var req = socket._httpMessage;
- debug('HTTP SOCKET ERROR: ' + err.message + '\n' + err.stack);
+ debug('SOCKET ERROR:', err.message, err.stack);
if (req) {
req.emit('error', err);
@@ -325,7 +325,7 @@ function parserOnIncomingClient(res, shouldKeepAlive) {
// to the content-length of the entity-body had the request
// been a GET.
var isHeadResponse = req.method == 'HEAD';
- debug('AGENT isHeadResponse ' + isHeadResponse);
+ debug('AGENT isHeadResponse', isHeadResponse);
if (res.statusCode == 100) {
// restart the parser, as this is a continue message.
diff --git a/lib/_http_common.js b/lib/_http_common.js
index 8c97886272..1ed8abc8c6 100644
--- a/lib/_http_common.js
+++ b/lib/_http_common.js
@@ -28,12 +28,7 @@ var readStart = incoming.readStart;
var readStop = incoming.readStop;
-var debug;
-if (process.env.NODE_DEBUG && /http/.test(process.env.NODE_DEBUG)) {
- debug = function(x) { console.error('HTTP: %s', x); };
-} else {
- debug = function() { };
-}
+var debug = require('util').debuglog('http');
exports.debug = debug;
exports.CRLF = '\r\n';
diff --git a/lib/module.js b/lib/module.js
index f98a42610f..d34ce10f15 100644
--- a/lib/module.js
+++ b/lib/module.js
@@ -62,12 +62,7 @@ Module.wrap = NativeModule.wrap;
var path = NativeModule.require('path');
-Module._debug = function() {};
-if (process.env.NODE_DEBUG && /module/.test(process.env.NODE_DEBUG)) {
- Module._debug = function(x) {
- console.error(x);
- };
-}
+Module._debug = NativeModule.require('util').debuglog('module');
// We use this alias for the preprocessor that filters it out
diff --git a/lib/net.js b/lib/net.js
index c1d9bb6c0a..e248bdfb3c 100644
--- a/lib/net.js
+++ b/lib/net.js
@@ -51,20 +51,7 @@ function createHandle(fd) {
}
-var debug;
-if (process.env.NODE_DEBUG && /net/.test(process.env.NODE_DEBUG)) {
- var pid = process.pid;
- debug = function(x) {
- // if console is not set up yet, then skip this.
- if (!console.error)
- return;
- console.error('NET: %d', pid,
- util.format.apply(util, arguments).slice(0, 500));
- };
-} else {
- debug = function() { };
-}
-
+var debug = util.debuglog('net');
function isPipeName(s) {
return typeof s === 'string' && toNumber(s) === false;
diff --git a/lib/timers.js b/lib/timers.js
index 708f0af16e..2b0745c5a4 100644
--- a/lib/timers.js
+++ b/lib/timers.js
@@ -26,12 +26,7 @@ var assert = require('assert').ok;
// Timeout values > TIMEOUT_MAX are set to 1.
var TIMEOUT_MAX = 2147483647; // 2^31-1
-var debug;
-if (process.env.NODE_DEBUG && /timer/.test(process.env.NODE_DEBUG)) {
- debug = function() { require('util').error.apply(this, arguments); };
-} else {
- debug = function() { };
-}
+var debug = require('util').debuglog('timer');
// IDLE TIMEOUTS
@@ -78,17 +73,17 @@ function listOnTimeout() {
var msecs = this.msecs;
var list = this;
- debug('timeout callback ' + msecs);
+ debug('timeout callback %d', msecs);
var now = Date.now();
- debug('now: ' + now);
+ debug('now: %s', now);
var first;
while (first = L.peek(list)) {
var diff = now - first._idleStart;
if (diff < msecs) {
list.start(msecs - diff, 0);
- debug(msecs + ' list wait because diff is ' + diff);
+ debug('%d list wait because diff is %d', msecs, diff);
return;
} else {
L.remove(first);
@@ -121,7 +116,7 @@ function listOnTimeout() {
}
}
- debug(msecs + ' list empty');
+ debug('%d list empty', msecs);
assert(L.isEmpty(list));
list.close();
delete lists[msecs];
diff --git a/lib/tls.js b/lib/tls.js
index c0b59d99b7..3af078a966 100644
--- a/lib/tls.js
+++ b/lib/tls.js
@@ -52,13 +52,7 @@ exports.getCiphers = function() {
};
-var debug;
-if (process.env.NODE_DEBUG && /tls/.test(process.env.NODE_DEBUG)) {
- debug = function(a) { console.error('TLS:', a); };
-} else {
- debug = function() { };
-}
-
+var debug = util.debuglog('tls');
var Connection = null;
try {
@@ -328,10 +322,10 @@ CryptoStream.prototype._write = function write(data, encoding, cb) {
// Write current buffer now
var written;
if (this === this.pair.cleartext) {
- debug('cleartext.write called with ' + data.length + ' bytes');
+ debug('cleartext.write called with %d bytes', data.length);
written = this.pair.ssl.clearIn(data, 0, data.length);
} else {
- debug('encrypted.write called with ' + data.length + ' bytes');
+ debug('encrypted.write called with %d bytes', data.length);
written = this.pair.ssl.encIn(data, 0, data.length);
}
@@ -354,9 +348,9 @@ CryptoStream.prototype._write = function write(data, encoding, cb) {
// Whole buffer was written
if (written === data.length) {
if (this === this.pair.cleartext) {
- debug('cleartext.write succeed with ' + data.length + ' bytes');
+ debug('cleartext.write succeed with %d bytes', data.length);
} else {
- debug('encrypted.write succeed with ' + data.length + ' bytes');
+ debug('encrypted.write succeed with %d bytes', data.length);
}
return cb(null);
@@ -375,9 +369,9 @@ CryptoStream.prototype._write = function write(data, encoding, cb) {
this._pendingCallback = cb;
if (this === this.pair.cleartext) {
- debug('cleartext.write queued with ' + data.length + ' bytes');
+ debug('cleartext.write queued with %d bytes', data.length);
} else {
- debug('encrypted.write queued with ' + data.length + ' bytes');
+ debug('encrypted.write queued with %d bytes', data.length);
}
};
@@ -404,10 +398,10 @@ CryptoStream.prototype._read = function read(size) {
var out;
if (this === this.pair.cleartext) {
- debug('cleartext.read called with ' + size + ' bytes');
+ debug('cleartext.read called with %d bytes', size);
out = this.pair.ssl.clearOut;
} else {
- debug('encrypted.read called with ' + size + ' bytes');
+ debug('encrypted.read called with %d bytes', size);
out = this.pair.ssl.encOut;
}
@@ -437,9 +431,9 @@ CryptoStream.prototype._read = function read(size) {
assert(bytesRead >= 0);
if (this === this.pair.cleartext) {
- debug('cleartext.read succeed with ' + bytesRead + ' bytes');
+ debug('cleartext.read succeed with %d bytes', bytesRead);
} else {
- debug('encrypted.read succeed with ' + bytesRead + ' bytes');
+ debug('encrypted.read succeed with %d bytes', bytesRead);
}
// Try writing pending data
diff --git a/lib/util.js b/lib/util.js
index 58c7312c95..4f9d06943e 100644
--- a/lib/util.js
+++ b/lib/util.js
@@ -81,29 +81,22 @@ exports.deprecate = function(fn, msg) {
};
-exports.print = function() {
- for (var i = 0, len = arguments.length; i < len; ++i) {
- process.stdout.write(String(arguments[i]));
- }
-};
-
-
-exports.puts = function() {
- for (var i = 0, len = arguments.length; i < len; ++i) {
- process.stdout.write(arguments[i] + '\n');
- }
-};
-
-
-exports.debug = function(x) {
- process.stderr.write('DEBUG: ' + x + '\n');
-};
-
-
-var error = exports.error = function(x) {
- for (var i = 0, len = arguments.length; i < len; ++i) {
- process.stderr.write(arguments[i] + '\n');
+var debugs = {};
+var debugEnviron = process.env.NODE_DEBUG || '';
+exports.debuglog = function(set) {
+ set = set.toUpperCase();
+ if (!debugs[set]) {
+ if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
+ var pid = process.pid;
+ debugs[set] = function() {
+ var msg = exports.format.apply(exports, arguments);
+ console.error('%s %d: %s', set, pid, msg);
+ };
+ } else {
+ debugs[set] = function() {};
+ }
}
+ return debugs[set];
};
@@ -466,13 +459,6 @@ function objectToString(o) {
}
-exports.p = exports.deprecate(function() {
- for (var i = 0, len = arguments.length; i < len; ++i) {
- error(exports.inspect(arguments[i]));
- }
-}, 'util.p: Use console.error() instead.');
-
-
function pad(n) {
return n < 10 ? '0' + n.toString(10) : n.toString(10);
}
@@ -497,51 +483,6 @@ exports.log = function() {
};
-exports.exec = exports.deprecate(function() {
- return require('child_process').exec.apply(this, arguments);
-}, 'util.exec is now called `child_process.exec`.');
-
-
-function pump(readStream, writeStream, callback) {
- var callbackCalled = false;
-
- function call(a, b, c) {
- if (callback && !callbackCalled) {
- callback(a, b, c);
- callbackCalled = true;
- }
- }
-
- readStream.addListener('data', function(chunk) {
- if (writeStream.write(chunk) === false) readStream.pause();
- });
-
- writeStream.addListener('drain', function() {
- readStream.resume();
- });
-
- readStream.addListener('end', function() {
- writeStream.end();
- });
-
- readStream.addListener('close', function() {
- call();
- });
-
- readStream.addListener('error', function(err) {
- writeStream.end();
- call(err);
- });
-
- writeStream.addListener('error', function(err) {
- readStream.destroy();
- call(err);
- });
-}
-exports.pump = exports.deprecate(pump,
- 'util.pump() is deprecated. Use readableStream.pipe() instead.');
-
-
/**
* Inherit the prototype methods from one constructor into another.
*
@@ -582,3 +523,81 @@ exports._extend = function(origin, add) {
function hasOwnProperty(obj, prop) {
return Object.prototype.hasOwnProperty.call(obj, prop);
}
+
+
+// Deprecated old stuff.
+
+exports.p = exports.deprecate(function() {
+ for (var i = 0, len = arguments.length; i < len; ++i) {
+ console.error(exports.inspect(arguments[i]));
+ }
+}, 'util.p: Use console.error() instead');
+
+
+exports.exec = exports.deprecate(function() {
+ return require('child_process').exec.apply(this, arguments);
+}, 'util.exec is now called `child_process.exec`.');
+
+
+exports.print = exports.deprecate(function() {
+ for (var i = 0, len = arguments.length; i < len; ++i) {
+ process.stdout.write(String(arguments[i]));
+ }
+}, 'util.print: Use console.log instead');
+
+
+exports.puts = exports.deprecate(function() {
+ for (var i = 0, len = arguments.length; i < len; ++i) {
+ process.stdout.write(arguments[i] + '\n');
+ }
+}, 'util.puts: Use console.log instead');
+
+
+exports.debug = exports.deprecate(function(x) {
+ process.stderr.write('DEBUG: ' + x + '\n');
+}, 'util.debug: Use console.error instead');
+
+
+exports.error = exports.deprecate(function(x) {
+ for (var i = 0, len = arguments.length; i < len; ++i) {
+ process.stderr.write(arguments[i] + '\n');
+ }
+}, 'util.error: Use console.error instead');
+
+
+exports.pump = exports.deprecate(function(readStream, writeStream, callback) {
+ var callbackCalled = false;
+
+ function call(a, b, c) {
+ if (callback && !callbackCalled) {
+ callback(a, b, c);
+ callbackCalled = true;
+ }
+ }
+
+ readStream.addListener('data', function(chunk) {
+ if (writeStream.write(chunk) === false) readStream.pause();
+ });
+
+ writeStream.addListener('drain', function() {
+ readStream.resume();
+ });
+
+ readStream.addListener('end', function() {
+ writeStream.end();
+ });
+
+ readStream.addListener('close', function() {
+ call();
+ });
+
+ readStream.addListener('error', function(err) {
+ writeStream.end();
+ call(err);
+ });
+
+ writeStream.addListener('error', function(err) {
+ readStream.destroy();
+ call(err);
+ });
+}, 'util.pump(): Use readableStream.pipe() instead');
diff --git a/test/message/stack_overflow.js b/test/message/stack_overflow.js
index 0066313084..166cf1adc3 100644
--- a/test/message/stack_overflow.js
+++ b/test/message/stack_overflow.js
@@ -27,7 +27,7 @@ var assert = require('assert');
Error.stackTraceLimit = 0;
-common.error('before');
+console.error('before');
// stack overflow
function stackOverflow() {
@@ -35,4 +35,4 @@ function stackOverflow() {
}
stackOverflow();
-common.error('after');
+console.error('after');
diff --git a/test/message/throw_custom_error.js b/test/message/throw_custom_error.js
index b92298d864..eab8499e9b 100644
--- a/test/message/throw_custom_error.js
+++ b/test/message/throw_custom_error.js
@@ -25,9 +25,9 @@
var common = require('../common');
var assert = require('assert');
-common.error('before');
+console.error('before');
// custom error throwing
throw ({ name: 'MyCustomError', message: 'This is a custom message' });
-common.error('after');
+console.error('after');
diff --git a/test/message/throw_in_line_with_tabs.js b/test/message/throw_in_line_with_tabs.js
index f01bc0e2c4..80be3f56fc 100644
--- a/test/message/throw_in_line_with_tabs.js
+++ b/test/message/throw_in_line_with_tabs.js
@@ -25,11 +25,11 @@
var common = require('../common');
var assert = require('assert');
-common.error('before');
+console.error('before');
(function () {
// these lines should contain tab!
throw ({ foo: 'bar' });
})();
-common.error('after');
+console.error('after');
diff --git a/test/message/throw_non_error.js b/test/message/throw_non_error.js
index defa0791e6..a3de7ad64a 100644
--- a/test/message/throw_non_error.js
+++ b/test/message/throw_non_error.js
@@ -25,9 +25,9 @@
var common = require('../common');
var assert = require('assert');
-common.error('before');
+console.error('before');
// custom error throwing
throw ({ foo: 'bar' });
-common.error('after');
+console.error('after');
diff --git a/test/message/undefined_reference_in_new_context.js b/test/message/undefined_reference_in_new_context.js
index 90cf43549b..3da10b0bb2 100644
--- a/test/message/undefined_reference_in_new_context.js
+++ b/test/message/undefined_reference_in_new_context.js
@@ -25,7 +25,7 @@
var common = require('../common');
var assert = require('assert');
-common.error('before');
+console.error('before');
var Script = process.binding('evals').NodeScript;
@@ -33,4 +33,4 @@ var Script = process.binding('evals').NodeScript;
var script = new Script('foo.bar = 5;');
script.runInNewContext();
-common.error('after');
+console.error('after');
diff --git a/test/simple/test-deprecation-flags.js b/test/simple/test-deprecation-flags.js
index 81605da21f..71e43d8ddb 100644
--- a/test/simple/test-deprecation-flags.js
+++ b/test/simple/test-deprecation-flags.js
@@ -33,7 +33,7 @@ execFile(node, normal, function(er, stdout, stderr) {
console.error('normal: show deprecation warning');
assert.equal(er, null);
assert.equal(stdout, '');
- assert.equal(stderr, 'util.p: Use console.error() instead.\n\'This is deprecated\'\n');
+ assert.equal(stderr, 'util.p: Use console.error() instead\n\'This is deprecated\'\n');
console.log('normal ok');
});
diff --git a/test/simple/test-http-proxy.js b/test/simple/test-http-proxy.js
index 099afb9d0a..b531f1a8ab 100644
--- a/test/simple/test-http-proxy.js
+++ b/test/simple/test-http-proxy.js
@@ -37,20 +37,20 @@ var headers = {'content-type': 'text/plain',
'hello': 'world' };
var backend = http.createServer(function(req, res) {
- common.debug('backend request');
+ console.error('backend request');
res.writeHead(200, headers);
res.write('hello world\n');
res.end();
});
var proxy = http.createServer(function(req, res) {
- common.debug('proxy req headers: ' + JSON.stringify(req.headers));
+ console.error('proxy req headers: ' + JSON.stringify(req.headers));
var proxy_req = http.get({
port: BACKEND_PORT,
path: url.parse(req.url).pathname
}, function(proxy_res) {
- common.debug('proxy res headers: ' + JSON.stringify(proxy_res.headers));
+ console.error('proxy res headers: ' + JSON.stringify(proxy_res.headers));
assert.equal('world', proxy_res.headers['hello']);
assert.equal('text/plain', proxy_res.headers['content-type']);
@@ -64,7 +64,7 @@ var proxy = http.createServer(function(req, res) {
proxy_res.on('end', function() {
res.end();
- common.debug('proxy res');
+ console.error('proxy res');
});
});
});
@@ -80,7 +80,7 @@ function startReq() {
port: PROXY_PORT,
path: '/test'
}, function(res) {
- common.debug('got res');
+ console.error('got res');
assert.equal(200, res.statusCode);
assert.equal('world', res.headers['hello']);
@@ -92,16 +92,16 @@ function startReq() {
res.on('end', function() {
proxy.close();
backend.close();
- common.debug('closed both');
+ console.error('closed both');
});
});
- common.debug('client req');
+ console.error('client req');
}
-common.debug('listen proxy');
+console.error('listen proxy');
proxy.listen(PROXY_PORT, startReq);
-common.debug('listen backend');
+console.error('listen backend');
backend.listen(BACKEND_PORT, startReq);
process.on('exit', function() {
diff --git a/test/simple/test-util-debug.js b/test/simple/test-util-debug.js
new file mode 100644
index 0000000000..1506e1af80
--- /dev/null
+++ b/test/simple/test-util-debug.js
@@ -0,0 +1,87 @@
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+var common = require('../common');
+var assert = require('assert');
+
+if (process.argv[2] === 'child')
+ child();
+else
+ parent();
+
+function parent() {
+ test('foo,tud,bar', true);
+ test('foo,tud', true);
+ test('tud,bar', true);
+ test('tud', true);
+ test('foo,bar', false);
+ test('', false);
+}
+
+function test(environ, shouldWrite) {
+ var expectErr = '';
+ if (shouldWrite) {
+ expectErr = 'TUD %PID%: this { is: \'a\' } /debugging/\n' +
+ 'TUD %PID%: number=1234 string=asdf obj={"foo":"bar"}\n';
+ }
+ var expectOut = 'ok\n';
+ var didTest = false;
+
+ var spawn = require('child_process').spawn;
+ var child = spawn(process.execPath, [__filename, 'child'], {
+ env: { NODE_DEBUG: environ }
+ });
+
+ expectErr = expectErr.split('%PID%').join(child.pid);
+
+ var err = '';
+ child.stderr.setEncoding('utf8');
+ child.stderr.on('data', function(c) {
+ err += c;
+ });
+
+ var out = '';
+ child.stdout.setEncoding('utf8');
+ child.stdout.on('data', function(c) {
+ out += c;
+ });
+
+ child.on('close', function(c) {
+ assert(!c);
+ assert.equal(err, expectErr);
+ assert.equal(out, expectOut);
+ didTest = true;
+ console.log('ok %j %j', environ, shouldWrite);
+ });
+
+ process.on('exit', function() {
+ assert(didTest);
+ });
+}
+
+
+function child() {
+ var util = require('util');
+ var debug = util.debug('tud');
+ debug('this', { is: 'a' }, /debugging/);
+ debug('number=%d string=%s obj=%j', 1234, 'asdf', { foo: 'bar' });
+ console.log('ok');
+}