1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2008 The Closure Library Authors. All Rights Reserved. 2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// 3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Licensed under the Apache License, Version 2.0 (the "License"); 4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// you may not use this file except in compliance with the License. 5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// You may obtain a copy of the License at 6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// 7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// http://www.apache.org/licenses/LICENSE-2.0 8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// 9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Unless required by applicable law or agreed to in writing, software 10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// distributed under the License is distributed on an "AS-IS" BASIS, 11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// See the License for the specific language governing permissions and 13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// limitations under the License. 14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @fileoverview Utilities to check the preconditions, postconditions and 17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * invariants runtime. 18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * 19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Methods in this package should be given special treatment by the compiler 20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * for type-inference. For example, <code>goog.asserts.assert(foo)</code> 21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * will restrict <code>foo</code> to a truthy value. 22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * 23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * The compiler has an option to disable asserts. So code like: 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * <code> 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * var x = goog.asserts.assert(foo()); goog.asserts.assert(bar()); 26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * </code> 27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * will be transformed into: 28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * <code> 29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * var x = foo(); 30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * </code> 31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * The compiler will leave in foo() (because its return value is used), 32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * but it will remove bar() because it assumes it does not have side-effects. 33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * 34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.provide('goog.asserts'); 37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.provide('goog.asserts.AssertionError'); 38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.require('goog.debug.Error'); 40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.require('goog.dom.NodeType'); 41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.require('goog.string'); 42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @define {boolean} Whether to strip out asserts or to leave them in. 46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.define('goog.asserts.ENABLE_ASSERTS', goog.DEBUG); 48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Error object for failed assertions. 53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {string} messagePattern The pattern that was used to form message. 54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {!Array.<*>} messageArgs The items to substitute into the pattern. 55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @constructor 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @extends {goog.debug.Error} 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @final 58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.asserts.AssertionError = function(messagePattern, messageArgs) { 60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) messageArgs.unshift(messagePattern); 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) goog.debug.Error.call(this, goog.string.subs.apply(null, messageArgs)); 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Remove the messagePattern afterwards to avoid permenantly modifying the 63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // passed in array. 64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) messageArgs.shift(); 65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /** 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * The message pattern used to format the error message. Error handlers can 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * use this to uniquely identify the assertion. 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @type {string} 70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.messagePattern = messagePattern; 72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.inherits(goog.asserts.AssertionError, goog.debug.Error); 74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** @override */ 77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.asserts.AssertionError.prototype.name = 'AssertionError'; 78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Throws an exception with the given message and "Assertion failed" prefixed 82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * onto it. 83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {string} defaultMessage The message to use if givenMessage is empty. 84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {Array.<*>} defaultArgs The substitution arguments for defaultMessage. 85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {string|undefined} givenMessage Message supplied by the caller. 86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {Array.<*>} givenArgs The substitution arguments for givenMessage. 87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @throws {goog.asserts.AssertionError} When the value is not a number. 88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @private 89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.asserts.doAssertFailure_ = 91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) function(defaultMessage, defaultArgs, givenMessage, givenArgs) { 92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var message = 'Assertion failed'; 93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (givenMessage) { 94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) message += ': ' + givenMessage; 95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var args = givenArgs; 96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else if (defaultMessage) { 97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) message += ': ' + defaultMessage; 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) args = defaultArgs; 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // The '' + works around an Opera 10 bug in the unit tests. Without it, 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // a stack trace is added to var message above. With this, a stack trace is 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // not added until this line (it causes the extra garbage to be added after 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // the assertion message instead of in the middle of it). 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) throw new goog.asserts.AssertionError('' + message, args || []); 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Checks if the condition evaluates to true if goog.asserts.ENABLE_ASSERTS is 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * true. 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @template T 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {T} condition The condition to check. 113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {string=} opt_message Error message in case of failure. 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {...*} var_args The items to substitute into the failure message. 115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @return {T} The value of the condition. 116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @throws {goog.asserts.AssertionError} When the condition evaluates to false. 117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.asserts.assert = function(condition, opt_message, var_args) { 119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (goog.asserts.ENABLE_ASSERTS && !condition) { 120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) goog.asserts.doAssertFailure_('', null, opt_message, 121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Array.prototype.slice.call(arguments, 2)); 122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return condition; 124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Fails if goog.asserts.ENABLE_ASSERTS is true. This function is useful in case 129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * when we want to add a check in the unreachable area like switch-case 130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * statement: 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * <pre> 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * switch(type) { 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * case FOO: doSomething(); break; 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * case BAR: doSomethingElse(); break; 136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * default: goog.assert.fail('Unrecognized type: ' + type); 137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * // We have only 2 types - "default:" section is unreachable code. 138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * } 139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * </pre> 140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * 141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {string=} opt_message Error message in case of failure. 142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {...*} var_args The items to substitute into the failure message. 143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @throws {goog.asserts.AssertionError} Failure. 144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.asserts.fail = function(opt_message, var_args) { 146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (goog.asserts.ENABLE_ASSERTS) { 147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) throw new goog.asserts.AssertionError( 148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'Failure' + (opt_message ? ': ' + opt_message : ''), 149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Array.prototype.slice.call(arguments, 1)); 150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Checks if the value is a number if goog.asserts.ENABLE_ASSERTS is true. 156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {*} value The value to check. 157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {string=} opt_message Error message in case of failure. 158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {...*} var_args The items to substitute into the failure message. 159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @return {number} The value, guaranteed to be a number when asserts enabled. 160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @throws {goog.asserts.AssertionError} When the value is not a number. 161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.asserts.assertNumber = function(value, opt_message, var_args) { 163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (goog.asserts.ENABLE_ASSERTS && !goog.isNumber(value)) { 164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) goog.asserts.doAssertFailure_('Expected number but got %s: %s.', 165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) [goog.typeOf(value), value], opt_message, 166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Array.prototype.slice.call(arguments, 2)); 167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return /** @type {number} */ (value); 169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Checks if the value is a string if goog.asserts.ENABLE_ASSERTS is true. 174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {*} value The value to check. 175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {string=} opt_message Error message in case of failure. 176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {...*} var_args The items to substitute into the failure message. 177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @return {string} The value, guaranteed to be a string when asserts enabled. 178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @throws {goog.asserts.AssertionError} When the value is not a string. 179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.asserts.assertString = function(value, opt_message, var_args) { 181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (goog.asserts.ENABLE_ASSERTS && !goog.isString(value)) { 182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) goog.asserts.doAssertFailure_('Expected string but got %s: %s.', 183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) [goog.typeOf(value), value], opt_message, 184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Array.prototype.slice.call(arguments, 2)); 185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return /** @type {string} */ (value); 187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Checks if the value is a function if goog.asserts.ENABLE_ASSERTS is true. 192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {*} value The value to check. 193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {string=} opt_message Error message in case of failure. 194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {...*} var_args The items to substitute into the failure message. 195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @return {!Function} The value, guaranteed to be a function when asserts 196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * enabled. 197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @throws {goog.asserts.AssertionError} When the value is not a function. 198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.asserts.assertFunction = function(value, opt_message, var_args) { 200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (goog.asserts.ENABLE_ASSERTS && !goog.isFunction(value)) { 201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) goog.asserts.doAssertFailure_('Expected function but got %s: %s.', 202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) [goog.typeOf(value), value], opt_message, 203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Array.prototype.slice.call(arguments, 2)); 204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return /** @type {!Function} */ (value); 206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Checks if the value is an Object if goog.asserts.ENABLE_ASSERTS is true. 211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {*} value The value to check. 212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {string=} opt_message Error message in case of failure. 213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {...*} var_args The items to substitute into the failure message. 214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @return {!Object} The value, guaranteed to be a non-null object. 215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @throws {goog.asserts.AssertionError} When the value is not an object. 216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.asserts.assertObject = function(value, opt_message, var_args) { 218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (goog.asserts.ENABLE_ASSERTS && !goog.isObject(value)) { 219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) goog.asserts.doAssertFailure_('Expected object but got %s: %s.', 220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) [goog.typeOf(value), value], 221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) opt_message, Array.prototype.slice.call(arguments, 2)); 222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return /** @type {!Object} */ (value); 224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Checks if the value is an Array if goog.asserts.ENABLE_ASSERTS is true. 229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {*} value The value to check. 230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {string=} opt_message Error message in case of failure. 231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {...*} var_args The items to substitute into the failure message. 232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @return {!Array} The value, guaranteed to be a non-null array. 233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @throws {goog.asserts.AssertionError} When the value is not an array. 234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.asserts.assertArray = function(value, opt_message, var_args) { 236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (goog.asserts.ENABLE_ASSERTS && !goog.isArray(value)) { 237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) goog.asserts.doAssertFailure_('Expected array but got %s: %s.', 238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) [goog.typeOf(value), value], opt_message, 239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Array.prototype.slice.call(arguments, 2)); 240cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 241cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return /** @type {!Array} */ (value); 242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Checks if the value is a boolean if goog.asserts.ENABLE_ASSERTS is true. 247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {*} value The value to check. 248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {string=} opt_message Error message in case of failure. 249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {...*} var_args The items to substitute into the failure message. 250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @return {boolean} The value, guaranteed to be a boolean when asserts are 251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * enabled. 252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @throws {goog.asserts.AssertionError} When the value is not a boolean. 253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.asserts.assertBoolean = function(value, opt_message, var_args) { 255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (goog.asserts.ENABLE_ASSERTS && !goog.isBoolean(value)) { 256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) goog.asserts.doAssertFailure_('Expected boolean but got %s: %s.', 257cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) [goog.typeOf(value), value], opt_message, 258cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Array.prototype.slice.call(arguments, 2)); 259cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return /** @type {boolean} */ (value); 261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Checks if the value is a DOM Element if goog.asserts.ENABLE_ASSERTS is true. 266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {*} value The value to check. 267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {string=} opt_message Error message in case of failure. 268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {...*} var_args The items to substitute into the failure message. 269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @return {!Element} The value, likely to be a DOM Element when asserts are 270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * enabled. 271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @throws {goog.asserts.AssertionError} When the value is not a boolean. 272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.asserts.assertElement = function(value, opt_message, var_args) { 274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (goog.asserts.ENABLE_ASSERTS && (!goog.isObject(value) || 275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) value.nodeType != goog.dom.NodeType.ELEMENT)) { 276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) goog.asserts.doAssertFailure_('Expected Element but got %s: %s.', 277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) [goog.typeOf(value), value], opt_message, 278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Array.prototype.slice.call(arguments, 2)); 279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return /** @type {!Element} */ (value); 281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Checks if the value is an instance of the user-defined type if 286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * goog.asserts.ENABLE_ASSERTS is true. 287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * 288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * The compiler may tighten the type returned by this function. 289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * 290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {*} value The value to check. 291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {function(new: T, ...)} type A user-defined constructor. 292cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {string=} opt_message Error message in case of failure. 293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {...*} var_args The items to substitute into the failure message. 294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @throws {goog.asserts.AssertionError} When the value is not an instance of 295cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * type. 296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @return {!T} 297cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @template T 298cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 299cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.asserts.assertInstanceof = function(value, type, opt_message, var_args) { 300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (goog.asserts.ENABLE_ASSERTS && !(value instanceof type)) { 301cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) goog.asserts.doAssertFailure_('instanceof check failed.', null, 302cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) opt_message, Array.prototype.slice.call(arguments, 3)); 303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return value; 305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 306cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 307cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 308cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 309cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Checks that no enumerable keys are present in Object.prototype. Such keys 310cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * would break most code that use {@code for (var ... in ...)} loops. 311cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 312cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.asserts.assertObjectPrototypeIsIntact = function() { 313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (var key in Object.prototype) { 314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) goog.asserts.fail(key + ' should not be enumerable in Object.prototype.'); 315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 316cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 317