diff --git a/Makefile b/Makefile index 19716b29..fe9c7f6a 100644 --- a/Makefile +++ b/Makefile @@ -43,6 +43,7 @@ lint: .FORCE eslint debug.js test: .FORCE - mocha - + mocha test/server/**.js + karma start --single-run + .PHONY: all install clean distclean diff --git a/bower.json b/bower.json index 073ecfcf..ad6589ef 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "visionmedia-debug", - "main": "./debug.js", + "main": "./src/debug.js", "homepage": "https://github.com/visionmedia/debug", "authors": [ "TJ Holowaychuk ", diff --git a/component.json b/component.json index 765066b4..32d5c388 100644 --- a/component.json +++ b/component.json @@ -8,10 +8,10 @@ "log", "debugger" ], - "main": "browser.js", + "main": "src/browser.js", "scripts": [ - "browser.js", - "debug.js" + "src/browser.js", + "src/debug.js" ], "dependencies": { "rauchg/ms.js": "0.7.1" diff --git a/dist/debug.js b/dist/debug.js index 18105c34..a57f060e 100644 --- a/dist/debug.js +++ b/dist/debug.js @@ -1,4 +1,337 @@ -(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.debug = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 1) { + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + } + queue.push(new Item(fun, args)); + if (queue.length === 1 && !draining) { + runTimeout(drainQueue); + } +}; + +// v8 likes predictible objects +function Item(fun, array) { + this.fun = fun; + this.array = array; +} +Item.prototype.run = function () { + this.fun.apply(null, this.array); +}; +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; +process.version = ''; // empty string to avoid regexp issues +process.versions = {}; + +function noop() {} + +process.on = noop; +process.addListener = noop; +process.once = noop; +process.off = noop; +process.removeListener = noop; +process.removeAllListeners = noop; +process.emit = noop; + +process.binding = function (name) { + throw new Error('process.binding is not supported'); +}; + +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; +process.umask = function() { return 0; }; + +},{}],2:[function(require,module,exports){ +/** + * Helpers. + */ + +var s = 1000 +var m = s * 60 +var h = m * 60 +var d = h * 24 +var y = d * 365.25 + +/** + * Parse or format the given `val`. + * + * Options: + * + * - `long` verbose formatting [false] + * + * @param {String|Number} val + * @param {Object} options + * @throws {Error} throw an error if val is not a non-empty string or a number + * @return {String|Number} + * @api public + */ + +module.exports = function (val, options) { + options = options || {} + var type = typeof val + if (type === 'string' && val.length > 0) { + return parse(val) + } else if (type === 'number' && isNaN(val) === false) { + return options.long ? + fmtLong(val) : + fmtShort(val) + } + throw new Error('val is not a non-empty string or a valid number. val=' + JSON.stringify(val)) +} + +/** + * Parse the given `str` and return milliseconds. + * + * @param {String} str + * @return {Number} + * @api private + */ + +function parse(str) { + str = String(str) + if (str.length > 10000) { + return + } + var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str) + if (!match) { + return + } + var n = parseFloat(match[1]) + var type = (match[2] || 'ms').toLowerCase() + switch (type) { + case 'years': + case 'year': + case 'yrs': + case 'yr': + case 'y': + return n * y + case 'days': + case 'day': + case 'd': + return n * d + case 'hours': + case 'hour': + case 'hrs': + case 'hr': + case 'h': + return n * h + case 'minutes': + case 'minute': + case 'mins': + case 'min': + case 'm': + return n * m + case 'seconds': + case 'second': + case 'secs': + case 'sec': + case 's': + return n * s + case 'milliseconds': + case 'millisecond': + case 'msecs': + case 'msec': + case 'ms': + return n + default: + return undefined + } +} + +/** + * Short format for `ms`. + * + * @param {Number} ms + * @return {String} + * @api private + */ + +function fmtShort(ms) { + if (ms >= d) { + return Math.round(ms / d) + 'd' + } + if (ms >= h) { + return Math.round(ms / h) + 'h' + } + if (ms >= m) { + return Math.round(ms / m) + 'm' + } + if (ms >= s) { + return Math.round(ms / s) + 's' + } + return ms + 'ms' +} + +/** + * Long format for `ms`. + * + * @param {Number} ms + * @return {String} + * @api private + */ + +function fmtLong(ms) { + return plural(ms, d, 'day') || + plural(ms, h, 'hour') || + plural(ms, m, 'minute') || + plural(ms, s, 'second') || + ms + ' ms' +} + +/** + * Pluralization helper. + */ + +function plural(ms, n, name) { + if (ms < n) { + return + } + if (ms < n * 1.5) { + return Math.floor(ms / n) + ' ' + name + } + return Math.ceil(ms / n) + ' ' + name + 's' +} + +},{}],3:[function(require,module,exports){ /** * This is the common logic for both the Node.js and web browser @@ -7,7 +340,7 @@ * Expose `debug()` as the module. */ -exports = module.exports = debug.debug = debug; +exports = module.exports = createDebug.debug = createDebug.default = createDebug; exports.coerce = coerce; exports.disable = disable; exports.enable = enable; @@ -24,17 +357,11 @@ exports.skips = []; /** * Map of special "%n" handling functions, for the debug "format" argument. * - * Valid key names are a single, lowercased letter, i.e. "n". + * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N". */ exports.formatters = {}; -/** - * Previously assigned color. - */ - -var prevColor = 0; - /** * Previous log timestamp. */ @@ -43,13 +370,20 @@ var prevTime; /** * Select a color. - * + * @param {String} namespace * @return {Number} * @api private */ -function selectColor() { - return exports.colors[prevColor++ % exports.colors.length]; +function selectColor(namespace) { + var hash = 0, i; + + for (i in namespace) { + hash = ((hash << 5) - hash) + namespace.charCodeAt(i); + hash |= 0; // Convert to 32bit integer + } + + return exports.colors[Math.abs(hash) % exports.colors.length]; } /** @@ -60,17 +394,13 @@ function selectColor() { * @api public */ -function debug(namespace) { +function createDebug(namespace) { - // define the `disabled` version - function disabled() { - } - disabled.enabled = false; + function debug() { + // disabled? + if (!debug.enabled) return; - // define the `enabled` version - function enabled() { - - var self = enabled; + var self = debug; // set `diff` timestamp var curr = +new Date(); @@ -80,22 +410,22 @@ function debug(namespace) { self.curr = curr; prevTime = curr; - // add the `color` if not set - if (null == self.useColors) self.useColors = exports.useColors(); - if (null == self.color && self.useColors) self.color = selectColor(); - - var args = Array.prototype.slice.call(arguments); + // turn the `arguments` into a proper Array + var args = new Array(arguments.length); + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i]; + } args[0] = exports.coerce(args[0]); if ('string' !== typeof args[0]) { - // anything else let's inspect with %o - args = ['%o'].concat(args); + // anything else let's inspect with %O + args.unshift('%O'); } // apply any `formatters` transformations var index = 0; - args[0] = args[0].replace(/%([a-z%])/g, function(match, format) { + args[0] = args[0].replace(/%([a-zA-Z%])/g, function(match, format) { // if we encounter an escaped % then don't increase the array index if (match === '%%') return match; index++; @@ -111,19 +441,24 @@ function debug(namespace) { return match; }); - if ('function' === typeof exports.formatArgs) { - args = exports.formatArgs.apply(self, args); - } + // apply env-specific formatting (colors, etc.) + exports.formatArgs.call(self, args); + var logFn = enabled.log || exports.log || console.log.bind(console); logFn.apply(self, args); } - enabled.enabled = true; - var fn = exports.enabled(namespace) ? enabled : disabled; + debug.namespace = namespace; + debug.enabled = exports.enabled(namespace); + debug.useColors = exports.useColors(); + debug.color = selectColor(namespace); - fn.namespace = namespace; + // env-specific initialization logic for debug instances + if ('function' === typeof exports.init) { + exports.init(debug); + } - return fn; + return debug; } /** @@ -197,135 +532,8 @@ function coerce(val) { return val; } -},{"ms":2}],2:[function(require,module,exports){ -/** - * Helpers. - */ - -var s = 1000; -var m = s * 60; -var h = m * 60; -var d = h * 24; -var y = d * 365.25; - -/** - * Parse or format the given `val`. - * - * Options: - * - * - `long` verbose formatting [false] - * - * @param {String|Number} val - * @param {Object} options - * @return {String|Number} - * @api public - */ - -module.exports = function(val, options){ - options = options || {}; - if ('string' == typeof val) return parse(val); - return options.long - ? long(val) - : short(val); -}; - -/** - * Parse the given `str` and return milliseconds. - * - * @param {String} str - * @return {Number} - * @api private - */ - -function parse(str) { - str = '' + str; - if (str.length > 10000) return; - var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str); - if (!match) return; - var n = parseFloat(match[1]); - var type = (match[2] || 'ms').toLowerCase(); - switch (type) { - case 'years': - case 'year': - case 'yrs': - case 'yr': - case 'y': - return n * y; - case 'days': - case 'day': - case 'd': - return n * d; - case 'hours': - case 'hour': - case 'hrs': - case 'hr': - case 'h': - return n * h; - case 'minutes': - case 'minute': - case 'mins': - case 'min': - case 'm': - return n * m; - case 'seconds': - case 'second': - case 'secs': - case 'sec': - case 's': - return n * s; - case 'milliseconds': - case 'millisecond': - case 'msecs': - case 'msec': - case 'ms': - return n; - } -} - -/** - * Short format for `ms`. - * - * @param {Number} ms - * @return {String} - * @api private - */ - -function short(ms) { - if (ms >= d) return Math.round(ms / d) + 'd'; - if (ms >= h) return Math.round(ms / h) + 'h'; - if (ms >= m) return Math.round(ms / m) + 'm'; - if (ms >= s) return Math.round(ms / s) + 's'; - return ms + 'ms'; -} - -/** - * Long format for `ms`. - * - * @param {Number} ms - * @return {String} - * @api private - */ - -function long(ms) { - return plural(ms, d, 'day') - || plural(ms, h, 'hour') - || plural(ms, m, 'minute') - || plural(ms, s, 'second') - || ms + ' ms'; -} - -/** - * Pluralization helper. - */ - -function plural(ms, n, name) { - if (ms < n) return; - if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name; - return Math.ceil(ms / n) + ' ' + name + 's'; -} - -},{}],3:[function(require,module,exports){ - +},{"ms":2}],4:[function(require,module,exports){ +(function (process){ /** * This is the web browser implementation of `debug()`. * @@ -366,12 +574,15 @@ exports.colors = [ function useColors() { // is webkit? http://stackoverflow.com/a/16459606/376773 - return ('WebkitAppearance' in document.documentElement.style) || + // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 + return (typeof document !== 'undefined' && 'WebkitAppearance' in document.documentElement.style) || // is firebug? http://stackoverflow.com/a/398120/376773 - (window.console && (console.firebug || (console.exception && console.table))) || + (typeof window !== 'undefined' && window.console && (console.firebug || (console.exception && console.table))) || // is firefox >= v31? // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages - (navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31); + (navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) || + // double check webkit in userAgent just in case we are in a worker + (navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)); } /** @@ -381,7 +592,7 @@ function useColors() { exports.formatters.j = function(v) { try { return JSON.stringify(v); - }catch( err){ + } catch (err) { return '[UnexpectedJSONParseError]: ' + err.message; } }; @@ -393,8 +604,7 @@ exports.formatters.j = function(v) { * @api public */ -function formatArgs() { - var args = arguments; +function formatArgs(args) { var useColors = this.useColors; args[0] = (useColors ? '%c' : '') @@ -404,10 +614,10 @@ function formatArgs() { + (useColors ? '%c ' : ' ') + '+' + exports.humanize(this.diff); - if (!useColors) return args; + if (!useColors) return; var c = 'color: ' + this.color; - args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1)); + args.splice(1, 0, c, 'color: inherit') // the final "%c" is somewhat tricky, because there could be other // arguments passed either before or after the %c, so we need to @@ -425,7 +635,6 @@ function formatArgs() { }); args.splice(lastC, 0, c); - return args; } /** @@ -470,9 +679,13 @@ function save(namespaces) { function load() { var r; try { - r = exports.storage.debug; + return exports.storage.debug; } catch(e) {} - return r; + + // If debug isn't set in LS, and we're in Electron, try to load $DEBUG + if (typeof process !== 'undefined' && 'env' in process) { + return process.env.DEBUG; + } } /** @@ -492,11 +705,16 @@ exports.enable(load()); * @api private */ -function localstorage(){ +function localstorage() { try { return window.localStorage; } catch (e) {} } -},{"./debug":1}]},{},[3])(3) -}); \ No newline at end of file +/** Attach to Window*/ +if (window) { + window.debug = exports; +} + +}).call(this,require('_process')) +},{"./debug":3,"_process":1}]},{},[4]); diff --git a/karma.conf.js b/karma.conf.js new file mode 100644 index 00000000..58b700d5 --- /dev/null +++ b/karma.conf.js @@ -0,0 +1,70 @@ +// Karma configuration +// Generated on Fri Dec 16 2016 13:09:51 GMT+0000 (UTC) + +module.exports = function(config) { + config.set({ + + // base path that will be used to resolve all patterns (eg. files, exclude) + basePath: '', + + + // frameworks to use + // available frameworks: https://npmjs.org/browse/keyword/karma-adapter + frameworks: ['mocha', 'browserify'], + + + // list of files / patterns to load in the browser + files: [ + 'dist/debug.js', + 'test/client/*spec.js' + ], + + + // list of files to exclude + exclude: [ + 'src/node.js' + ], + + + // preprocess matching files before serving them to the browser + // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor + preprocessors: { + }, + + // test results reporter to use + // possible values: 'dots', 'progress' + // available reporters: https://npmjs.org/browse/keyword/karma-reporter + reporters: ['progress'], + + + // web server port + port: 9876, + + + // enable / disable colors in the output (reporters and logs) + colors: true, + + + // level of logging + // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG + logLevel: config.LOG_INFO, + + + // enable / disable watching file and executing tests whenever any file changes + autoWatch: true, + + + // start these browsers + // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher + browsers: ['PhantomJS'], + + + // Continuous Integration mode + // if true, Karma captures browsers, runs the tests and exits + singleRun: false, + + // Concurrency level + // how many browser should be started simultaneous + concurrency: Infinity + }) +} diff --git a/package.json b/package.json index 96f1a686..890e4ac7 100644 --- a/package.json +++ b/package.json @@ -34,8 +34,8 @@ "mocha": "^3.2.0", "sinon": "^1.17.6" }, - "main": "./index.js", - "browser": "./browser.js", + "main": "./src/index.js", + "browser": "./src/browser.js", "component": { "scripts": { "debug/index.js": "browser.js", diff --git a/browser.js b/src/browser.js similarity index 98% rename from browser.js rename to src/browser.js index bee8b0b7..f49434fc 100644 --- a/browser.js +++ b/src/browser.js @@ -174,3 +174,8 @@ function localstorage() { return window.localStorage; } catch (e) {} } + +/** Attach to Window*/ +if (window) { + window.debug = exports; +} diff --git a/debug.js b/src/debug.js similarity index 100% rename from debug.js rename to src/debug.js diff --git a/index.js b/src/index.js similarity index 100% rename from index.js rename to src/index.js diff --git a/node.js b/src/node.js similarity index 100% rename from node.js rename to src/node.js diff --git a/test/client/debug_spec.js b/test/client/debug_spec.js new file mode 100644 index 00000000..8b007eb0 --- /dev/null +++ b/test/client/debug_spec.js @@ -0,0 +1,8 @@ +describe('debug', function () { + describe('sanity check', function () { + it('passes', function () { + const log = debug('test'); + log('hello world'); + }); + }); +}); \ No newline at end of file diff --git a/test/debug_spec.js b/test/debug_spec.js deleted file mode 100644 index b0339218..00000000 --- a/test/debug_spec.js +++ /dev/null @@ -1,12 +0,0 @@ -import { expect } from 'chai'; - -import debug from '../index'; - -describe('debug', () => { - describe('sanity check', () => { - it('passes', () => { - const log = debug('test'); - log('hello world'); - }); - }); -}) diff --git a/test/mocha.opts b/test/mocha.opts deleted file mode 100644 index 6b233a1c..00000000 --- a/test/mocha.opts +++ /dev/null @@ -1 +0,0 @@ ---compilers js:babel-register diff --git a/test/server/debug_spec.js b/test/server/debug_spec.js new file mode 100644 index 00000000..82144e20 --- /dev/null +++ b/test/server/debug_spec.js @@ -0,0 +1,12 @@ +const expect = require('chai').expect + +const debug = require('../../src/index'); + +describe('debug', function () { + describe('sanity check', function () { + it('passes', function () { + const log = debug('test'); + log('hello world'); + }); + }); +})