// Copyright (c) 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. /** * @fileoverview Assertion support. */ /** * Verify |condition| is truthy and return |condition| if so. * @template T * @param {T} condition A condition to check for truthiness. Note that this * may be used to test whether a value is defined or not, and we don't want * to force a cast to Boolean. * @param {string=} opt_message A message to show on failure. * @return {T} A non-null |condition|. * @closurePrimitive {asserts.truthy} * @suppress {reportUnknownTypes} because T is not sufficiently constrained. */ /* #export */ function assert(condition, opt_message) { if (!condition) { let message = 'Assertion failed'; if (opt_message) { message = message + ': ' + opt_message; } const error = new Error(message); const global = function() { const thisOrSelf = this || self; /** @type {boolean} */ thisOrSelf.traceAssertionsForTesting; return thisOrSelf; }(); if (global.traceAssertionsForTesting) { console.warn(error.stack); } throw error; } return condition; } /** * Call this from places in the code that should never be reached. * * For example, handling all the values of enum with a switch() like this: * * function getValueFromEnum(enum) { * switch (enum) { * case ENUM_FIRST_OF_TWO: * return first * case ENUM_LAST_OF_TWO: * return last; * } * assertNotReached(); * return document; * } * * This code should only be hit in the case of serious programmer error or * unexpected input. * * @param {string=} opt_message A message to show when this is hit. * @closurePrimitive {asserts.fail} */ /* #export */ function assertNotReached(opt_message) { assert(false, opt_message || 'Unreachable code hit'); } /** * @param {*} value The value to check. * @param {function(new: T, ...)} type A user-defined constructor. * @param {string=} opt_message A message to show when this is hit. * @return {T} * @template T */ /* #export */ function assertInstanceof(value, type, opt_message) { // We don't use assert immediately here so that we avoid constructing an error // message if we don't have to. if (!(value instanceof type)) { assertNotReached( opt_message || 'Value ' + value + ' is not a[n] ' + (type.name || typeof type)); } return value; }