1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)/**
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * @fileoverview Assertion support.
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) */
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)/**
1003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * Verify |condition| is truthy and return |condition| if so.
1103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @template T
1203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @param {T} condition A condition to check for truthiness.  Note that this
1303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) *     may be used to test whether a value is defined or not, and we don't want
1403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) *     to force a cast to Boolean.
1503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @param {string=} opt_message A message to show on failure.
1603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @return {T} A non-null |condition|.
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) */
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)function assert(condition, opt_message) {
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  'use strict';
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!condition) {
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    var msg = 'Assertion failed';
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (opt_message)
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      msg = msg + ': ' + opt_message;
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    throw new Error(msg);
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
2603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return condition;
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)/**
305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * Call this from places in the code that should never be reached.
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *
325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * For example, handling all the values of enum with a switch() like this:
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *   function getValueFromEnum(enum) {
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *     switch (enum) {
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *       case ENUM_FIRST_OF_TWO:
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *         return first
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *       case ENUM_LAST_OF_TWO:
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *         return last;
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *     }
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *     assertNotReached();
425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *     return document;
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *   }
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * This code should only be hit in the case of serious programmer error or
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * unexpected input.
475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * @param {string=} opt_message A message to show when this is hit.
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) */
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)function assertNotReached(opt_message) {
5103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  throw new Error(opt_message || 'Unreachable code hit');
5203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
5303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
5403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)/**
5503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @param {*} value The value to check.
5603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @param {function(new: T, ...)} type A user-defined constructor.
5703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @return {T}
5803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @template T
5903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */
6003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)function assertInstanceof(value, type) {
6103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!(value instanceof type))
6203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    throw new Error(value + ' is not a[n] ' + (type.name || typeof type));
6303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return value;
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
65