# 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 * @struct38 * @implements {goog.labs.testing.Matcher}39 * @final40 */41goog.labs.testing.AllOfMatcher = function(matchers) {42  /**43   * @type {!Array.<!goog.labs.testing.Matcher>}44   * @private45   */46  this.matchers_ = matchers;47};484950/**51 * Determines if all of the matchers match the input value.52 *53 * @override54 */55goog.labs.testing.AllOfMatcher.prototype.matches = function(actualValue) {56  return goog.array.every(this.matchers_, function(matcher) {57    return matcher.matches(actualValue);58  });59};606162/**63 * Describes why the matcher failed. The returned string is a concatenation of64 * all the failed matchers' error strings.65 *66 * @override67 */68goog.labs.testing.AllOfMatcher.prototype.describe =69    function(actualValue) {70  // TODO(user) : Optimize this to remove duplication with matches ?71  var errorString = '';72  goog.array.forEach(this.matchers_, function(matcher) {73    if (!matcher.matches(actualValue)) {74      errorString += matcher.describe(actualValue) + '\n';75    }76  });77  return errorString;78};79808182/**83 * The AnyOf matcher.84 *85 * @param {!Array.<!goog.labs.testing.Matcher>} matchers Input matchers.86 *87 * @constructor88 * @struct89 * @implements {goog.labs.testing.Matcher}90 * @final91 */92goog.labs.testing.AnyOfMatcher = function(matchers) {93  /**94   * @type {!Array.<!goog.labs.testing.Matcher>}95   * @private96   */97  this.matchers_ = matchers;98};99100101/**102 * Determines if any of the matchers matches the input value.103 *104 * @override105 */106goog.labs.testing.AnyOfMatcher.prototype.matches = function(actualValue) {107  return goog.array.some(this.matchers_, function(matcher) {108    return matcher.matches(actualValue);109  });110};111112113/**114 * Describes why the matcher failed.115 *116 * @override117 */118goog.labs.testing.AnyOfMatcher.prototype.describe =119    function(actualValue) {120  // TODO(user) : Optimize this to remove duplication with matches ?121  var errorString = '';122  goog.array.forEach(this.matchers_, function(matcher) {123    if (!matcher.matches(actualValue)) {124      errorString += matcher.describe(actualValue) + '\n';125    }126  });127  return errorString;128};129130131132/**133 * The IsNot matcher.134 *135 * @param {!goog.labs.testing.Matcher} matcher The matcher to negate.136 *137 * @constructor138 * @struct139 * @implements {goog.labs.testing.Matcher}140 * @final141 */142goog.labs.testing.IsNotMatcher = function(matcher) {143  /**144   * @type {!goog.labs.testing.Matcher}145   * @private146   */147  this.matcher_ = matcher;148};149150151/**152 * Determines if the input value doesn't satisfy a matcher.153 *154 * @override155 */156goog.labs.testing.IsNotMatcher.prototype.matches = function(actualValue) {157  return !this.matcher_.matches(actualValue);158};159160161/**162 * Describes why the matcher failed.163 *164 * @override165 */166goog.labs.testing.IsNotMatcher.prototype.describe =167    function(actualValue) {168  return 'The following is false: ' + this.matcher_.describe(actualValue);169};170171172/**173 * Creates a matcher that will succeed only if all of the given matchers174 * succeed.175 *176 * @param {...goog.labs.testing.Matcher} var_args The matchers to test177 *     against.178 *179 * @return {!goog.labs.testing.AllOfMatcher} The AllOf matcher.180 */181function allOf(var_args) {182  var matchers = goog.array.toArray(arguments);183  return new goog.labs.testing.AllOfMatcher(matchers);184}185186187/**188 * Accepts a set of matchers and returns a matcher which matches189 * values which satisfy the constraints of any of the given matchers.190 *191 * @param {...goog.labs.testing.Matcher} var_args The matchers to test192 *     against.193 *194 * @return {!goog.labs.testing.AnyOfMatcher} The AnyOf matcher.195 */196function anyOf(var_args) {197  var matchers = goog.array.toArray(arguments);198  return new goog.labs.testing.AnyOfMatcher(matchers);199}200201202/**203 * Returns a matcher that negates the input matcher. The returned204 * matcher matches the values not matched by the input matcher and vice-versa.205 *206 * @param {!goog.labs.testing.Matcher} matcher The matcher to test against.207 *208 * @return {!goog.labs.testing.IsNotMatcher} The IsNot matcher.209 */210function isNot(matcher) {211  return new goog.labs.testing.IsNotMatcher(matcher);212}