diff --git a/addon/index.js b/addon/index.js index 5b1e2a0..a30a345 100644 --- a/addon/index.js +++ b/addon/index.js @@ -1 +1,17 @@ -export { default } from 'ember-debug-logger/utils/debug-logger'; +import { + overrideLoggers, + debugLogger, + infoLogger, + warnLogger, + errorLogger +} from 'ember-debug-logger/utils/debug-logger'; + +export { + overrideLoggers, + debugLogger, + infoLogger, + warnLogger, + errorLogger +}; + +export default debugLogger; diff --git a/addon/instance-initializers/debug-logger.js b/addon/instance-initializers/debug-logger.js index 745655e..927c803 100644 --- a/addon/instance-initializers/debug-logger.js +++ b/addon/instance-initializers/debug-logger.js @@ -1,4 +1,4 @@ -import debugLogger from 'ember-debug-logger/utils/debug-logger'; +import {debugLogger, errorLogger} from 'ember-debug-logger/utils/debug-logger'; export function initialize(instance) { // In 1.13, the app instance exposes the registry; in 2.x, it proxies it instead @@ -6,9 +6,11 @@ export function initialize(instance) { let inject = registry.inject || registry.injection; registry.register('debug-logger:main', debugLogger(), { instantiate: false }); + registry.register('error-logger:main', errorLogger(), { instantiate: false }); ['route', 'component', 'controller', 'service'].forEach(function(type) { inject.call(registry, type, 'debug', 'debug-logger:main'); + inject.call(registry, type, 'error', 'error-logger:main'); }); } diff --git a/addon/utils/debug-logger.js b/addon/utils/debug-logger.js index 77d7630..2a24e1d 100644 --- a/addon/utils/debug-logger.js +++ b/addon/utils/debug-logger.js @@ -13,25 +13,90 @@ * Logging preferences are persisted in local storage, and you'll need to reload * the page for changes to take effect. */ -export default function debugLogger(key) { - return key ? window.debug(key) : instanceLogger; + +/** + * The default logging functions + * @type {{debug: *, info: *, warn: *, error: *}} + */ +let LOGGERS = { + 'debug': console.log.bind(console), + 'info' : console.info.bind(console), + 'warn' : console.warn.bind(console), + 'error': console.error.bind(console) +}; + +/** + * These functions wrap the loggers, so we can perform runtime lookups + * of the loggers, and change them on the fly. + * @type {{debug: (function(): *), info: (function(): *), warn: (function(): *), error: (function(): *)}} + */ +const WRAPPERS = { + 'debug': (...args) => LOGGERS['debug'](...args), + 'info' : (...args) => LOGGERS['info'](...args), + 'warn' : (...args) => LOGGERS['warn'](...args), + 'error': (...args) => LOGGERS['error'](...args) +}; + +/** + * Replaces the logging function for the various log types. + * Expects an object with keys of: debug, info, warn, or error + * The values should be a function. + * + * @function overrideLoggers + * @param {Object} loggers a hash as described above + */ +export function overrideLoggers(loggers) { + LOGGERS = loggers; + for (const type of Object.keys(loggers)) { + LOGGERS[type] = loggers[type]; + } } -const LOGGER = '_debugLoggerInstance'; +/** + * Creates an instance logger of type, type + * @param type + * @returns {Function} + */ +function createInstanceLogger(type) { + return function () { + let logger = this && this[`${type}InstanceLogger`]; + + if (!logger) { + const loggerKey = this && this._debugContainerKey; + if (!loggerKey) { + throw new Error('On non-container-managed objects, debug-logger requires an explicit key.'); + } -export function instanceLogger() { - let logger = this && this[LOGGER]; + logger = window.debug(loggerKey); + logger.log = WRAPPERS[type]; - if (!logger) { - const loggerKey = this && this._debugContainerKey; - if (!loggerKey) { - throw new Error('On non-container-managed objects, debug-logger requires an explicit key.'); + Object.defineProperty(this, type, { value: logger }); } - logger = window.debug(loggerKey); + return logger.apply(this, arguments); + }; +} + +const instanceDebugLogger = createInstanceLogger('debug'); +const instanceInfoLogger = createInstanceLogger('info'); +const instanceWarnLogger = createInstanceLogger('warn'); +const instanceErrorLogger = createInstanceLogger('error'); - Object.defineProperty(this, LOGGER, { value: logger }); - } +export function debugLogger(key) { + return key ? window.debug(key) : instanceDebugLogger; +} - return logger.apply(this, arguments); + +export function infoLogger() { + return instanceInfoLogger; +} + +export function warnLogger() { + return instanceWarnLogger; } + +export function errorLogger() { + return instanceErrorLogger; +} + +export default debugLogger; diff --git a/tests/acceptance/container-keys-test.js b/tests/acceptance/container-keys-test.js index 5341bf3..0fb98e6 100644 --- a/tests/acceptance/container-keys-test.js +++ b/tests/acceptance/container-keys-test.js @@ -3,9 +3,12 @@ import Ember from 'ember'; import { test } from 'qunit'; import moduleForAcceptance from 'dummy/tests/helpers/module-for-acceptance'; +import {overrideLoggers} from 'ember-debug-logger'; const { Service, Route } = Ember; +let logger = null; + moduleForAcceptance('Acceptance | logging from container-managed objects', { beforeEach: function() { this.application.register('route:application', Route); @@ -13,11 +16,15 @@ moduleForAcceptance('Acceptance | logging from container-managed objects', { this.container = this.container || this.application.__container__; debug.enable('route:*, service:*'); - sinon.stub(console, 'log'); + + logger = sinon.stub(); + + overrideLoggers({ + debug: logger + }); }, afterEach: function() { - console.log.restore(); debug.disable(); } }); @@ -29,13 +36,13 @@ test('it automatically finds keys when attached to container-managed objects', f const appRoute = this.container.lookup('route:application'); appRoute.debug('test message from the application route'); - let [routeMessage] = console.log.lastCall.args; + let [routeMessage] = logger.lastCall.args; assert.ok(/route:application/.test(routeMessage), 'Route message should include its container key'); const testService = this.container.lookup('service:my/test/module'); testService.debug('test message from the mysterious service'); - let [serviceMessage] = console.log.lastCall.args; + let [serviceMessage] = logger.lastCall.args; assert.ok(/service:my\/test\/module/.test(serviceMessage), 'Service message should include its container key'); }); }); diff --git a/tests/unit/utils/debug-logger-test.js b/tests/unit/utils/debug-logger-test.js index 47d52c2..73fbbdc 100644 --- a/tests/unit/utils/debug-logger-test.js +++ b/tests/unit/utils/debug-logger-test.js @@ -1,7 +1,7 @@ /* global sinon, debug */ import Ember from 'ember'; -import debugLogger from 'ember-debug-logger'; +import { debugLogger } from 'ember-debug-logger'; import { module, test } from 'qunit'; const { A } = Ember;