diff --git a/packages/ember-debug/lib/deprecate.js b/packages/ember-debug/lib/deprecate.js index 19f95ae7d9f..42222a883dc 100644 --- a/packages/ember-debug/lib/deprecate.js +++ b/packages/ember-debug/lib/deprecate.js @@ -1,4 +1,5 @@ /*global __fail__*/ +import { DEBUG } from 'ember-env-flags'; import EmberError from './error'; import Logger from 'ember-console'; @@ -7,6 +8,11 @@ import { ENV } from 'ember-environment'; import { registerHandler as genericRegisterHandler, invoke } from './handlers'; +/** +@module ember +@submodule ember-debug +*/ + /** Allows for runtime registration of handler functions that override the default deprecation behavior. Deprecations are invoked by calls to [Ember.deprecate](http://emberjs.com/api/classes/Ember.html#method_deprecate). @@ -42,150 +48,159 @@ import { registerHandler as genericRegisterHandler, invoke } from './handlers'; @param handler {Function} A function to handle deprecation calls. @since 2.1.0 */ -export function registerHandler(handler) { - genericRegisterHandler('deprecate', handler); -} +let registerHandler = () => {}; +let missingOptionsDeprecation, missingOptionsIdDeprecation, missingOptionsUntilDeprecation, deprecate; -function formatMessage(_message, options) { - let message = _message; - - if (options && options.id) { - message = message + ` [deprecation id: ${options.id}]`; - } - - if (options && options.url) { - message += ` See ${options.url} for more details.`; +if (DEBUG) { + registerHandler = function registerHandler(handler) { + genericRegisterHandler('deprecate', handler); } - return message; -} - -registerHandler(function logDeprecationToConsole(message, options) { - let updatedMessage = formatMessage(message, options); + let formatMessage = function formatMessage(_message, options) { + let message = _message; - Logger.warn(`DEPRECATION: ${updatedMessage}`); -}); + if (options && options.id) { + message = message + ` [deprecation id: ${options.id}]`; + } -let captureErrorForStack; + if (options && options.url) { + message += ` See ${options.url} for more details.`; + } -if (new Error().stack) { - captureErrorForStack = () => new Error(); -} else { - captureErrorForStack = () => { - try { __fail__.fail(); } catch (e) { return e; } - }; -} + return message; + } -registerHandler(function logDeprecationStackTrace(message, options, next) { - if (ENV.LOG_STACKTRACE_ON_DEPRECATION) { - let stackStr = ''; - let error = captureErrorForStack(); - let stack; - - if (error.stack) { - if (error['arguments']) { - // Chrome - stack = error.stack.replace(/^\s+at\s+/gm, ''). - replace(/^([^\(]+?)([\n$])/gm, '{anonymous}($1)$2'). - replace(/^Object.\s*\(([^\)]+)\)/gm, '{anonymous}($1)').split('\n'); - stack.shift(); - } else { - // Firefox - stack = error.stack.replace(/(?:\n@:0)?\s+$/m, ''). - replace(/^\(/gm, '{anonymous}(').split('\n'); - } + registerHandler(function logDeprecationToConsole(message, options) { + let updatedMessage = formatMessage(message, options); - stackStr = `\n ${stack.slice(2).join('\n ')}`; - } + Logger.warn(`DEPRECATION: ${updatedMessage}`); + }); - let updatedMessage = formatMessage(message, options); + let captureErrorForStack; - Logger.warn(`DEPRECATION: ${updatedMessage}${stackStr}`); + if (new Error().stack) { + captureErrorForStack = () => new Error(); } else { - next(...arguments); + captureErrorForStack = () => { + try { __fail__.fail(); } catch (e) { return e; } + }; } -}); -registerHandler(function raiseOnDeprecation(message, options, next) { - if (ENV.RAISE_ON_DEPRECATION) { - let updatedMessage = formatMessage(message); + registerHandler(function logDeprecationStackTrace(message, options, next) { + if (ENV.LOG_STACKTRACE_ON_DEPRECATION) { + let stackStr = ''; + let error = captureErrorForStack(); + let stack; + + if (error.stack) { + if (error['arguments']) { + // Chrome + stack = error.stack.replace(/^\s+at\s+/gm, ''). + replace(/^([^\(]+?)([\n$])/gm, '{anonymous}($1)$2'). + replace(/^Object.\s*\(([^\)]+)\)/gm, '{anonymous}($1)').split('\n'); + stack.shift(); + } else { + // Firefox + stack = error.stack.replace(/(?:\n@:0)?\s+$/m, ''). + replace(/^\(/gm, '{anonymous}(').split('\n'); + } + + stackStr = `\n ${stack.slice(2).join('\n ')}`; + } + + let updatedMessage = formatMessage(message, options); - throw new EmberError(updatedMessage); - } else { - next(...arguments); - } -}); + Logger.warn(`DEPRECATION: ${updatedMessage}${stackStr}`); + } else { + next(...arguments); + } + }); -export let missingOptionsDeprecation = 'When calling `Ember.deprecate` you ' + - 'must provide an `options` hash as the third parameter. ' + - '`options` should include `id` and `until` properties.'; -export let missingOptionsIdDeprecation = 'When calling `Ember.deprecate` you must provide `id` in options.'; -export let missingOptionsUntilDeprecation = 'When calling `Ember.deprecate` you must provide `until` in options.'; + registerHandler(function raiseOnDeprecation(message, options, next) { + if (ENV.RAISE_ON_DEPRECATION) { + let updatedMessage = formatMessage(message); -/** -@module ember -@submodule ember-debug -*/ + throw new EmberError(updatedMessage); + } else { + next(...arguments); + } + }); -/** - Display a deprecation warning with the provided message and a stack trace - (Chrome and Firefox only). - - * In a production build, this method is defined as an empty function (NOP). - Uses of this method in Ember itself are stripped from the ember.prod.js build. - - @method deprecate - @param {String} message A description of the deprecation. - @param {Boolean} test A boolean. If falsy, the deprecation will be displayed. - @param {Object} options - @param {String} options.id A unique id for this deprecation. The id can be - used by Ember debugging tools to change the behavior (raise, log or silence) - for that specific deprecation. The id should be namespaced by dots, e.g. - "view.helper.select". - @param {string} options.until The version of Ember when this deprecation - warning will be removed. - @param {String} [options.url] An optional url to the transition guide on the - emberjs.com website. - @for Ember - @public - @since 1.0.0 -*/ -export default function deprecate(message, test, options) { - if (!options || (!options.id && !options.until)) { - deprecate( - missingOptionsDeprecation, - false, - { - id: 'ember-debug.deprecate-options-missing', - until: '3.0.0', - url: 'http://emberjs.com/deprecations/v2.x/#toc_ember-debug-function-options' - } - ); - } + missingOptionsDeprecation = 'When calling `Ember.deprecate` you ' + + 'must provide an `options` hash as the third parameter. ' + + '`options` should include `id` and `until` properties.'; + missingOptionsIdDeprecation = 'When calling `Ember.deprecate` you must provide `id` in options.'; + missingOptionsUntilDeprecation = 'When calling `Ember.deprecate` you must provide `until` in options.'; + + /** + Display a deprecation warning with the provided message and a stack trace + (Chrome and Firefox only). + + * In a production build, this method is defined as an empty function (NOP). + Uses of this method in Ember itself are stripped from the ember.prod.js build. + + @method deprecate + @param {String} message A description of the deprecation. + @param {Boolean} test A boolean. If falsy, the deprecation will be displayed. + @param {Object} options + @param {String} options.id A unique id for this deprecation. The id can be + used by Ember debugging tools to change the behavior (raise, log or silence) + for that specific deprecation. The id should be namespaced by dots, e.g. + "view.helper.select". + @param {string} options.until The version of Ember when this deprecation + warning will be removed. + @param {String} [options.url] An optional url to the transition guide on the + emberjs.com website. + @for Ember + @public + @since 1.0.0 + */ + deprecate = function deprecate(message, test, options) { + if (!options || (!options.id && !options.until)) { + deprecate( + missingOptionsDeprecation, + false, + { + id: 'ember-debug.deprecate-options-missing', + until: '3.0.0', + url: 'http://emberjs.com/deprecations/v2.x/#toc_ember-debug-function-options' + } + ); + } - if (options && !options.id) { - deprecate( - missingOptionsIdDeprecation, - false, - { - id: 'ember-debug.deprecate-id-missing', - until: '3.0.0', - url: 'http://emberjs.com/deprecations/v2.x/#toc_ember-debug-function-options' - } - ); - } + if (options && !options.id) { + deprecate( + missingOptionsIdDeprecation, + false, + { + id: 'ember-debug.deprecate-id-missing', + until: '3.0.0', + url: 'http://emberjs.com/deprecations/v2.x/#toc_ember-debug-function-options' + } + ); + } - if (options && !options.until) { - deprecate( - missingOptionsUntilDeprecation, - options && options.until, - { - id: 'ember-debug.deprecate-until-missing', - until: '3.0.0', - url: 'http://emberjs.com/deprecations/v2.x/#toc_ember-debug-function-options' - } - ); + if (options && !options.until) { + deprecate( + missingOptionsUntilDeprecation, + options && options.until, + { + id: 'ember-debug.deprecate-until-missing', + until: '3.0.0', + url: 'http://emberjs.com/deprecations/v2.x/#toc_ember-debug-function-options' + } + ); + } + + invoke('deprecate', ...arguments); } +} + +export default deprecate; - invoke('deprecate', ...arguments); +export { + registerHandler, + missingOptionsDeprecation, + missingOptionsIdDeprecation, + missingOptionsUntilDeprecation } diff --git a/packages/ember-debug/lib/handlers.js b/packages/ember-debug/lib/handlers.js index 7bee3032a7e..6cf6e15e9ae 100644 --- a/packages/ember-debug/lib/handlers.js +++ b/packages/ember-debug/lib/handlers.js @@ -1,19 +1,31 @@ +import { DEBUG } from 'ember-env-flags'; + export let HANDLERS = { }; -export function registerHandler(type, callback) { - let nextHandler = HANDLERS[type] || (() => { }); +let registerHandler = () => {}; +let invoke = () => {}; - HANDLERS[type] = (message, options) => { - callback(message, options, nextHandler); - }; -} +if (DEBUG) { + registerHandler = function registerHandler(type, callback) { + let nextHandler = HANDLERS[type] || (() => { }); + + HANDLERS[type] = (message, options) => { + callback(message, options, nextHandler); + }; + } -export function invoke(type, message, test, options) { - if (test) { return; } + invoke = function invoke(type, message, test, options) { + if (test) { return; } - let handlerForType = HANDLERS[type]; + let handlerForType = HANDLERS[type]; - if (handlerForType) { - handlerForType(message, options); + if (handlerForType) { + handlerForType(message, options); + } } } + +export { + registerHandler, + invoke +} diff --git a/packages/ember-debug/lib/index.js b/packages/ember-debug/lib/index.js index e6a76e0b322..b65fdc94079 100644 --- a/packages/ember-debug/lib/index.js +++ b/packages/ember-debug/lib/index.js @@ -1,3 +1,4 @@ +import { DEBUG } from 'ember-env-flags' import { ENV, environment } from 'ember-environment'; import Logger from 'ember-console'; import { isTesting } from './testing'; @@ -14,16 +15,50 @@ export { default as isFeatureEnabled } from './features'; export { default as Error } from './error'; export { isTesting, setTesting } from './testing'; -export let debugFunctions = { - assert() {}, - info() {}, - warn() {}, - debug() {}, - deprecate() {}, - deprecateFunc(...args) { return args[args.length - 1]; }, - debugSeal() {}, - debugFreeze() {} -}; +// These are the default production build versions: +let assert = () => {}; +let info = () => {}; +let warn = () => {}; +let debug = () => {}; +let deprecate = () => {}; +let debugSeal = () => {}; +let debugFreeze = () => {}; +let runInDebug = () => {}; + +let deprecateFunc = function() { return arguments[arguments.length - 1]; }; + +let setDebugFunction = () => {}; +let getDebugFunction = () => {}; + +if (DEBUG) { + setDebugFunction = function(type, callback) { + switch (type) { + case 'assert': return assert = callback; + case 'info': return info = callback; + case 'warn': return warn = callback; + case 'debug': return debug = callback; + case 'deprecate': return deprecate = callback; + case 'debugSeal': return debugSeal = callback; + case 'debugFreeze': return debugFreeze = callback; + case 'runInDebug': return runInDebug = callback; + case 'deprecateFunc': return deprecateFunc = callback; + } + }; + + getDebugFunction = function(type) { + switch (type) { + case 'assert': return assert; + case 'info': return info; + case 'warn': return warn; + case 'debug': return debug; + case 'deprecate': return deprecate; + case 'debugSeal': return debugSeal; + case 'debugFreeze': return debugFreeze; + case 'runInDebug': return runInDebug; + case 'deprecateFunc': return deprecateFunc; + } + }; +} /** @module ember @@ -35,166 +70,169 @@ export let debugFunctions = { @public */ +if (DEBUG) { + /** + Define an assertion that will throw an exception if the condition is not met. + + * In a production build, this method is defined as an empty function (NOP). + Uses of this method in Ember itself are stripped from the ember.prod.js build. + + ```javascript + // Test for truthiness + Ember.assert('Must pass a valid object', obj); + + // Fail unconditionally + Ember.assert('This code path should never be run'); + ``` + + @method assert + @param {String} desc A description of the assertion. This will become + the text of the Error thrown if the assertion fails. + @param {Boolean} test Must be truthy for the assertion to pass. If + falsy, an exception will be thrown. + @public + @since 1.0.0 + */ + setDebugFunction('assert', function assert(desc, test) { + if (!test) { + throw new EmberError(`Assertion Failed: ${desc}`); + } + }); -/** - Define an assertion that will throw an exception if the condition is not met. - - * In a production build, this method is defined as an empty function (NOP). - Uses of this method in Ember itself are stripped from the ember.prod.js build. - - ```javascript - // Test for truthiness - Ember.assert('Must pass a valid object', obj); - - // Fail unconditionally - Ember.assert('This code path should never be run'); - ``` - - @method assert - @param {String} desc A description of the assertion. This will become - the text of the Error thrown if the assertion fails. - @param {Boolean} test Must be truthy for the assertion to pass. If - falsy, an exception will be thrown. - @public - @since 1.0.0 -*/ -setDebugFunction('assert', function assert(desc, test) { - if (!test) { - throw new EmberError(`Assertion Failed: ${desc}`); - } -}); - -/** - Display a debug notice. - - * In a production build, this method is defined as an empty function (NOP). - Uses of this method in Ember itself are stripped from the ember.prod.js build. - - ```javascript - Ember.debug('I\'m a debug notice!'); - ``` + /** + Display a debug notice. - @method debug - @param {String} message A debug message to display. - @public -*/ -setDebugFunction('debug', function debug(message) { - Logger.debug(`DEBUG: ${message}`); -}); + * In a production build, this method is defined as an empty function (NOP). + Uses of this method in Ember itself are stripped from the ember.prod.js build. -/** - Display an info notice. + ```javascript + Ember.debug('I\'m a debug notice!'); + ``` - * In a production build, this method is defined as an empty function (NOP). - Uses of this method in Ember itself are stripped from the ember.prod.js build. + @method debug + @param {String} message A debug message to display. + @public + */ + setDebugFunction('debug', function debug(message) { + Logger.debug(`DEBUG: ${message}`); + }); - @method info - @private -*/ -setDebugFunction('info', function info() { - Logger.info.apply(undefined, arguments); -}); + /** + Display an info notice. -/** - Alias an old, deprecated method with its new counterpart. + * In a production build, this method is defined as an empty function (NOP). + Uses of this method in Ember itself are stripped from the ember.prod.js build. - Display a deprecation warning with the provided message and a stack trace - (Chrome and Firefox only) when the assigned method is called. + @method info + @private + */ + setDebugFunction('info', function info() { + Logger.info.apply(undefined, arguments); + }); - * In a production build, this method is defined as an empty function (NOP). + /** + Alias an old, deprecated method with its new counterpart. + + Display a deprecation warning with the provided message and a stack trace + (Chrome and Firefox only) when the assigned method is called. + + * In a production build, this method is defined as an empty function (NOP). + + ```javascript + Ember.oldMethod = Ember.deprecateFunc('Please use the new, updated method', Ember.newMethod); + ``` + + @method deprecateFunc + @param {String} message A description of the deprecation. + @param {Object} [options] The options object for Ember.deprecate. + @param {Function} func The new function called to replace its deprecated counterpart. + @return {Function} A new function that wraps the original function with a deprecation warning + @private + */ + setDebugFunction('deprecateFunc', function deprecateFunc(...args) { + if (args.length === 3) { + let [message, options, func] = args; + return function() { + deprecate(message, false, options); + return func.apply(this, arguments); + }; + } else { + let [message, func] = args; + return function() { + deprecate(message); + return func.apply(this, arguments); + }; + } + }); - ```javascript - Ember.oldMethod = Ember.deprecateFunc('Please use the new, updated method', Ember.newMethod); - ``` - @method deprecateFunc - @param {String} message A description of the deprecation. - @param {Object} [options] The options object for Ember.deprecate. - @param {Function} func The new function called to replace its deprecated counterpart. - @return {Function} A new function that wraps the original function with a deprecation warning - @private -*/ -setDebugFunction('deprecateFunc', function deprecateFunc(...args) { - if (args.length === 3) { - let [message, options, func] = args; - return function() { - deprecate(message, false, options); - return func.apply(this, arguments); - }; - } else { - let [message, func] = args; - return function() { - deprecate(message); - return func.apply(this, arguments); - }; - } -}); + /** + Run a function meant for debugging. + * In a production build, this method is defined as an empty function (NOP). + Uses of this method in Ember itself are stripped from the ember.prod.js build. -/** - Run a function meant for debugging. + ```javascript + Ember.runInDebug(() => { + Ember.Component.reopen({ + didInsertElement() { + console.log("I'm happy"); + } + }); + }); + ``` + + @method runInDebug + @param {Function} func The function to be executed. + @since 1.5.0 + @public + */ + setDebugFunction('runInDebug', function runInDebug(func) { + func(); + }); - * In a production build, this method is defined as an empty function (NOP). - Uses of this method in Ember itself are stripped from the ember.prod.js build. + setDebugFunction('debugSeal', function debugSeal(obj) { + Object.seal(obj); + }); - ```javascript - Ember.runInDebug(() => { - Ember.Component.reopen({ - didInsertElement() { - console.log("I'm happy"); - } - }); + setDebugFunction('debugFreeze', function debugFreeze(obj) { + Object.freeze(obj); }); - ``` - @method runInDebug - @param {Function} func The function to be executed. - @since 1.5.0 - @public -*/ -setDebugFunction('runInDebug', function runInDebug(func) { - func(); -}); + setDebugFunction('deprecate', _deprecate); -setDebugFunction('debugSeal', function debugSeal(obj) { - Object.seal(obj); -}); + setDebugFunction('warn', _warn); +} -setDebugFunction('debugFreeze', function debugFreeze(obj) { - Object.freeze(obj); -}); +let _warnIfUsingStrippedFeatureFlags; -setDebugFunction('deprecate', _deprecate); +if (DEBUG && !isTesting()) { + /** + Will call `Ember.warn()` if ENABLE_OPTIONAL_FEATURES or + any specific FEATURES flag is truthy. -setDebugFunction('warn', _warn); + This method is called automatically in debug canary builds. -/** - Will call `Ember.warn()` if ENABLE_OPTIONAL_FEATURES or - any specific FEATURES flag is truthy. + @private + @method _warnIfUsingStrippedFeatureFlags + @return {void} + */ + _warnIfUsingStrippedFeatureFlags = function _warnIfUsingStrippedFeatureFlags(FEATURES, knownFeatures, featuresWereStripped) { + if (featuresWereStripped) { + warn('Ember.ENV.ENABLE_OPTIONAL_FEATURES is only available in canary builds.', !ENV.ENABLE_OPTIONAL_FEATURES, { id: 'ember-debug.feature-flag-with-features-stripped' }); - This method is called automatically in debug canary builds. + let keys = Object.keys(FEATURES || {}); + for (let i = 0; i < keys.length; i++) { + let key = keys[i]; + if (key === 'isEnabled' || !(key in knownFeatures)) { + continue; + } - @private - @method _warnIfUsingStrippedFeatureFlags - @return {void} -*/ -export function _warnIfUsingStrippedFeatureFlags(FEATURES, knownFeatures, featuresWereStripped) { - if (featuresWereStripped) { - warn('Ember.ENV.ENABLE_OPTIONAL_FEATURES is only available in canary builds.', !ENV.ENABLE_OPTIONAL_FEATURES, { id: 'ember-debug.feature-flag-with-features-stripped' }); - - let keys = Object.keys(FEATURES || {}); - for (let i = 0; i < keys.length; i++) { - let key = keys[i]; - if (key === 'isEnabled' || !(key in knownFeatures)) { - continue; + warn(`FEATURE["${key}"] is set as enabled, but FEATURE flags are only available in canary builds.`, !FEATURES[key], { id: 'ember-debug.feature-flag-with-features-stripped' }); } - - warn(`FEATURE["${key}"] is set as enabled, but FEATURE flags are only available in canary builds.`, !FEATURES[key], { id: 'ember-debug.feature-flag-with-features-stripped' }); } - } -} + }; -if (!isTesting()) { // Complain if they're using FEATURE flags in builds other than canary FEATURES['features-stripped-test'] = true; let featuresWereStripped = true; @@ -240,46 +278,17 @@ if (runningNonEmberDebugJS) { warn('Please use `ember.debug.js` instead of `ember.js` for development and debugging.'); } -export function getDebugFunction(name) { - return debugFunctions[name]; -} - -export function setDebugFunction(name, fn) { - debugFunctions[name] = fn; -} - -export function assert() { - return debugFunctions.assert.apply(undefined, arguments); -} - -export function info() { - return debugFunctions.info.apply(undefined, arguments); -} - -export function warn() { - return debugFunctions.warn.apply(undefined, arguments); -} - -export function debug() { - return debugFunctions.debug.apply(undefined, arguments); -} - -export function deprecate() { - return debugFunctions.deprecate.apply(undefined, arguments); +export { + assert, + info, + warn, + debug, + deprecate, + debugSeal, + debugFreeze, + runInDebug, + deprecateFunc, + setDebugFunction, + getDebugFunction, + _warnIfUsingStrippedFeatureFlags } - -export function deprecateFunc() { - return debugFunctions.deprecateFunc.apply(undefined, arguments); -} - -export function runInDebug() { - return debugFunctions.runInDebug.apply(undefined, arguments); -} - -export function debugSeal() { - return debugFunctions.debugSeal.apply(undefined, arguments); -} - -export function debugFreeze() { - return debugFunctions.debugFreeze.apply(undefined, arguments); -} \ No newline at end of file diff --git a/packages/ember-debug/lib/run-in-debug.js b/packages/ember-debug/lib/run-in-debug.js deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/packages/ember-debug/lib/warn.js b/packages/ember-debug/lib/warn.js index 19a8f271c67..fe599c040cb 100644 --- a/packages/ember-debug/lib/warn.js +++ b/packages/ember-debug/lib/warn.js @@ -1,102 +1,117 @@ +import { DEBUG } from 'ember-env-flags'; + import Logger from 'ember-console'; import deprecate from './deprecate'; import { registerHandler as genericRegisterHandler, invoke } from './handlers'; -/** - Allows for runtime registration of handler functions that override the default warning behavior. - Warnings are invoked by calls made to [Ember.warn](http://emberjs.com/api/classes/Ember.html#method_warn). - The following example demonstrates its usage by registering a handler that does nothing overriding Ember's - default warning behavior. - - ```javascript - // next is not called, so no warnings get the default behavior - Ember.Debug.registerWarnHandler(() => {}); - ``` - - The handler function takes the following arguments: - - - - @public - @static - @method registerWarnHandler - @param handler {Function} A function to handle warnings. - @since 2.1.0 -*/ -export function registerHandler(handler) { - genericRegisterHandler('warn', handler); -} - -registerHandler(function logWarning(message, options) { - Logger.warn(`WARNING: ${message}`); - if ('trace' in Logger) { - Logger.trace(); - } -}); - -export let missingOptionsDeprecation = 'When calling `Ember.warn` you ' + - 'must provide an `options` hash as the third parameter. ' + - '`options` should include an `id` property.'; -export let missingOptionsIdDeprecation = 'When calling `Ember.warn` you must provide `id` in options.'; +let registerHandler = () => {}; +let warn = () => {}; +let missingOptionsDeprecation, missingOptionsIdDeprecation; /** @module ember @submodule ember-debug */ -/** - Display a warning with the provided message. - - * In a production build, this method is defined as an empty function (NOP). - Uses of this method in Ember itself are stripped from the ember.prod.js build. - - @method warn - @param {String} message A warning to display. - @param {Boolean} test An optional boolean. If falsy, the warning - will be displayed. - @param {Object} options An object that can be used to pass a unique - `id` for this warning. The `id` can be used by Ember debugging tools - to change the behavior (raise, log, or silence) for that specific warning. - The `id` should be namespaced by dots, e.g. "ember-debug.feature-flag-with-features-stripped" - @for Ember - @public - @since 1.0.0 -*/ -export default function warn(message, test, options) { - if (arguments.length === 2 && typeof test === 'object') { - options = test; - test = false; - } - if (!options) { - deprecate( - missingOptionsDeprecation, - false, - { - id: 'ember-debug.warn-options-missing', - until: '3.0.0', - url: 'http://emberjs.com/deprecations/v2.x/#toc_ember-debug-function-options' - } - ); +if (DEBUG) { + /** + Allows for runtime registration of handler functions that override the default warning behavior. + Warnings are invoked by calls made to [Ember.warn](http://emberjs.com/api/classes/Ember.html#method_warn). + The following example demonstrates its usage by registering a handler that does nothing overriding Ember's + default warning behavior. + + ```javascript + // next is not called, so no warnings get the default behavior + Ember.Debug.registerWarnHandler(() => {}); + ``` + + The handler function takes the following arguments: + + + + @public + @static + @method registerWarnHandler + @param handler {Function} A function to handle warnings. + @since 2.1.0 + */ + registerHandler = function registerHandler(handler) { + genericRegisterHandler('warn', handler); } - if (options && !options.id) { - deprecate( - missingOptionsIdDeprecation, - false, - { - id: 'ember-debug.warn-id-missing', - until: '3.0.0', - url: 'http://emberjs.com/deprecations/v2.x/#toc_ember-debug-function-options' - } - ); + registerHandler(function logWarning(message, options) { + Logger.warn(`WARNING: ${message}`); + if ('trace' in Logger) { + Logger.trace(); + } + }); + + missingOptionsDeprecation = 'When calling `Ember.warn` you ' + + 'must provide an `options` hash as the third parameter. ' + + '`options` should include an `id` property.'; + missingOptionsIdDeprecation = 'When calling `Ember.warn` you must provide `id` in options.'; + + /** + Display a warning with the provided message. + + * In a production build, this method is defined as an empty function (NOP). + Uses of this method in Ember itself are stripped from the ember.prod.js build. + + @method warn + @param {String} message A warning to display. + @param {Boolean} test An optional boolean. If falsy, the warning + will be displayed. + @param {Object} options An object that can be used to pass a unique + `id` for this warning. The `id` can be used by Ember debugging tools + to change the behavior (raise, log, or silence) for that specific warning. + The `id` should be namespaced by dots, e.g. "ember-debug.feature-flag-with-features-stripped" + @for Ember + @public + @since 1.0.0 + */ + warn = function warn(message, test, options) { + if (arguments.length === 2 && typeof test === 'object') { + options = test; + test = false; + } + if (!options) { + deprecate( + missingOptionsDeprecation, + false, + { + id: 'ember-debug.warn-options-missing', + until: '3.0.0', + url: 'http://emberjs.com/deprecations/v2.x/#toc_ember-debug-function-options' + } + ); + } + + if (options && !options.id) { + deprecate( + missingOptionsIdDeprecation, + false, + { + id: 'ember-debug.warn-id-missing', + until: '3.0.0', + url: 'http://emberjs.com/deprecations/v2.x/#toc_ember-debug-function-options' + } + ); + } + + invoke('warn', message, test, options); } +} - invoke('warn', message, test, options); +export default warn; +export { + registerHandler, + missingOptionsIdDeprecation, + missingOptionsDeprecation } diff --git a/packages/ember/lib/index.js b/packages/ember/lib/index.js index b32c85b6955..1bd30ea1d6d 100644 --- a/packages/ember/lib/index.js +++ b/packages/ember/lib/index.js @@ -35,7 +35,6 @@ Ember.Registry = Registry; // flag plugin works properly import * as EmberDebug from 'ember-debug'; import { deprecate, deprecateFunc } from 'ember-debug'; -import { DEBUG } from 'ember-env-flags'; const computed = metal.computed; computed.alias = metal.alias; @@ -46,12 +45,6 @@ Ember.cacheFor = metal.cacheFor; Ember.assert = EmberDebug.assert; Ember.warn = EmberDebug.warn; Ember.debug = EmberDebug.debug; -Ember.deprecate = function () { }; -Ember.deprecateFunc = function() { }; -if (DEBUG) { - Ember.deprecate = EmberDebug.deprecate; - Ember.deprecateFunc = EmberDebug.deprecateFunc; -} Ember.deprecateFunc = EmberDebug.deprecateFunc; Ember.runInDebug = EmberDebug.runInDebug; /** diff --git a/packages/ember/tests/production_build_test.js b/packages/ember/tests/production_build_test.js new file mode 100644 index 00000000000..da40e3cebcb --- /dev/null +++ b/packages/ember/tests/production_build_test.js @@ -0,0 +1,27 @@ +import { DEBUG } from 'ember-env-flags' +import { + assert as emberAssert, + runInDebug +} from 'ember-debug'; + +QUnit.module('production builds'); + +if (!DEBUG) { + QUnit.test('assert does not throw in production builds', function(assert) { + assert.expect(1); + + try { + emberAssert('Should not throw'); + assert.ok(true, 'Ember.assert did not throw'); + } catch (e) { + assert.ok(false, `Expected assert not to throw but it did: ${e.message}`); + } + }); + + QUnit.test('runInDebug does not run the callback in production builds', function(assert) { + let fired = false; + runInDebug(() => fired = true); + + assert.equal(fired, false, 'runInDebug callback should not be ran'); + }); +}