# lib/goog/labs/testing/logicmatcher.js

    1// Copyright 2012 The Closure Library Authors. All Rights Reserved.2//3// Licensed under the Apache License, Version 2.0 (the "License");4// you may not use this file except in compliance with the License.5// You may obtain a copy of the License at6//7//      http://www.apache.org/licenses/LICENSE-2.08//9// Unless required by applicable law or agreed to in writing, software10// distributed under the License is distributed on an "AS-IS" BASIS,11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12// See the License for the specific language governing permissions and13// limitations under the License.1415/**16 * @fileoverview Provides the built-in logic matchers: anyOf, allOf, and isNot.17 *18 */192021goog.provide('goog.labs.testing.AllOfMatcher');22goog.provide('goog.labs.testing.AnyOfMatcher');23goog.provide('goog.labs.testing.IsNotMatcher');242526goog.require('goog.array');27goog.require('goog.labs.testing.Matcher');28293031/**32 * The AllOf matcher.33 *34 * @param {!Array.<!goog.labs.testing.Matcher>} matchers Input matchers.35 *36 * @constructor37 * @implements {goog.labs.testing.Matcher}38 */39goog.labs.testing.AllOfMatcher = function(matchers) {40  /**41   * @type {!Array.<!goog.labs.testing.Matcher>}42   * @private43   */44  this.matchers_ = matchers;45};464748/**49 * Determines if all of the matchers match the input value.50 *51 * @override52 */53goog.labs.testing.AllOfMatcher.prototype.matches = function(actualValue) {54  return goog.array.every(this.matchers_, function(matcher) {55    return matcher.matches(actualValue);56  });57};585960/**61 * Describes why the matcher failed. The returned string is a concatenation of62 * all the failed matchers' error strings.63 *64 * @override65 */66goog.labs.testing.AllOfMatcher.prototype.describe =67    function(actualValue) {68  // TODO(user) : Optimize this to remove duplication with matches ?69  var errorString = '';70  goog.array.forEach(this.matchers_, function(matcher) {71    if (!matcher.matches(actualValue)) {72      errorString += matcher.describe(actualValue) + '\n';73    }74  });75  return errorString;76};77787980/**81 * The AnyOf matcher.82 *83 * @param {!Array.<!goog.labs.testing.Matcher>} matchers Input matchers.84 *85 * @constructor86 * @implements {goog.labs.testing.Matcher}87 */88goog.labs.testing.AnyOfMatcher = function(matchers) {89  /**90   * @type {!Array.<!goog.labs.testing.Matcher>}91   * @private92   */93  this.matchers_ = matchers;94};959697/**98 * Determines if any of the matchers matches the input value.99 *100 * @override101 */102goog.labs.testing.AnyOfMatcher.prototype.matches = function(actualValue) {103  return goog.array.some(this.matchers_, function(matcher) {104    return matcher.matches(actualValue);105  });106};107108109/**110 * Describes why the matcher failed.111 *112 * @override113 */114goog.labs.testing.AnyOfMatcher.prototype.describe =115    function(actualValue) {116  // TODO(user) : Optimize this to remove duplication with matches ?117  var errorString = '';118  goog.array.forEach(this.matchers_, function(matcher) {119    if (!matcher.matches(actualValue)) {120      errorString += matcher.describe(actualValue) + '\n';121    }122  });123  return errorString;124};125126127128/**129 * The IsNot matcher.130 *131 * @param {!goog.labs.testing.Matcher} matcher The matcher to negate.132 *133 * @constructor134 * @implements {goog.labs.testing.Matcher}135 */136goog.labs.testing.IsNotMatcher = function(matcher) {137  /**138   * @type {!goog.labs.testing.Matcher}139   * @private140   */141  this.matcher_ = matcher;142};143144145/**146 * Determines if the input value doesn't satisfy a matcher.147 *148 * @override149 */150goog.labs.testing.IsNotMatcher.prototype.matches = function(actualValue) {151  return !this.matcher_.matches(actualValue);152};153154155/**156 * Describes why the matcher failed.157 *158 * @override159 */160goog.labs.testing.IsNotMatcher.prototype.describe =161    function(actualValue) {162  return 'The following is false: ' + this.matcher_.describe(actualValue);163};164165166/**167 * Creates a matcher that will succeed only if all of the given matchers168 * succeed.169 *170 * @param {...goog.labs.testing.Matcher} var_args The matchers to test171 *     against.172 *173 * @return {!goog.labs.testing.AllOfMatcher} The AllOf matcher.174 */175function allOf(var_args) {176  var matchers = goog.array.toArray(arguments);177  return new goog.labs.testing.AllOfMatcher(matchers);178}179180181/**182 * Accepts a set of matchers and returns a matcher which matches183 * values which satisfy the constraints of any of the given matchers.184 *185 * @param {...goog.labs.testing.Matcher} var_args The matchers to test186 *     against.187 *188 * @return {!goog.labs.testing.AnyOfMatcher} The AnyOf matcher.189 */190function anyOf(var_args) {191  var matchers = goog.array.toArray(arguments);192  return new goog.labs.testing.AnyOfMatcher(matchers);193}194195196/**197 * Returns a matcher that negates the input matcher. The returned198 * matcher matches the values not matched by the input matcher and vice-versa.199 *200 * @param {!goog.labs.testing.Matcher} matcher The matcher to test against.201 *202 * @return {!goog.labs.testing.IsNotMatcher} The IsNot matcher.203 */204function isNot(matcher) {205  return new goog.labs.testing.IsNotMatcher(matcher);206}