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 at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// 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 and
13// limitations under the License.
14
15/**
16 * @fileoverview Provides the built-in logic matchers: anyOf, allOf, and isNot.
17 *
18 */
19
20
21goog.provide('goog.labs.testing.AllOfMatcher');
22goog.provide('goog.labs.testing.AnyOfMatcher');
23goog.provide('goog.labs.testing.IsNotMatcher');
24
25
26goog.require('goog.array');
27goog.require('goog.labs.testing.Matcher');
28
29
30
31/**
32 * The AllOf matcher.
33 *
34 * @param {!Array<!goog.labs.testing.Matcher>} matchers Input matchers.
35 *
36 * @constructor
37 * @struct
38 * @implements {goog.labs.testing.Matcher}
39 * @final
40 */
41goog.labs.testing.AllOfMatcher = function(matchers) {
42 /**
43 * @type {!Array<!goog.labs.testing.Matcher>}
44 * @private
45 */
46 this.matchers_ = matchers;
47};
48
49
50/**
51 * Determines if all of the matchers match the input value.
52 *
53 * @override
54 */
55goog.labs.testing.AllOfMatcher.prototype.matches = function(actualValue) {
56 return goog.array.every(this.matchers_, function(matcher) {
57 return matcher.matches(actualValue);
58 });
59};
60
61
62/**
63 * Describes why the matcher failed. The returned string is a concatenation of
64 * all the failed matchers' error strings.
65 *
66 * @override
67 */
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};
79
80
81
82/**
83 * The AnyOf matcher.
84 *
85 * @param {!Array<!goog.labs.testing.Matcher>} matchers Input matchers.
86 *
87 * @constructor
88 * @struct
89 * @implements {goog.labs.testing.Matcher}
90 * @final
91 */
92goog.labs.testing.AnyOfMatcher = function(matchers) {
93 /**
94 * @type {!Array<!goog.labs.testing.Matcher>}
95 * @private
96 */
97 this.matchers_ = matchers;
98};
99
100
101/**
102 * Determines if any of the matchers matches the input value.
103 *
104 * @override
105 */
106goog.labs.testing.AnyOfMatcher.prototype.matches = function(actualValue) {
107 return goog.array.some(this.matchers_, function(matcher) {
108 return matcher.matches(actualValue);
109 });
110};
111
112
113/**
114 * Describes why the matcher failed.
115 *
116 * @override
117 */
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};
129
130
131
132/**
133 * The IsNot matcher.
134 *
135 * @param {!goog.labs.testing.Matcher} matcher The matcher to negate.
136 *
137 * @constructor
138 * @struct
139 * @implements {goog.labs.testing.Matcher}
140 * @final
141 */
142goog.labs.testing.IsNotMatcher = function(matcher) {
143 /**
144 * @type {!goog.labs.testing.Matcher}
145 * @private
146 */
147 this.matcher_ = matcher;
148};
149
150
151/**
152 * Determines if the input value doesn't satisfy a matcher.
153 *
154 * @override
155 */
156goog.labs.testing.IsNotMatcher.prototype.matches = function(actualValue) {
157 return !this.matcher_.matches(actualValue);
158};
159
160
161/**
162 * Describes why the matcher failed.
163 *
164 * @override
165 */
166goog.labs.testing.IsNotMatcher.prototype.describe =
167 function(actualValue) {
168 return 'The following is false: ' + this.matcher_.describe(actualValue);
169};
170
171
172/**
173 * Creates a matcher that will succeed only if all of the given matchers
174 * succeed.
175 *
176 * @param {...goog.labs.testing.Matcher} var_args The matchers to test
177 * 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}
185
186
187/**
188 * Accepts a set of matchers and returns a matcher which matches
189 * values which satisfy the constraints of any of the given matchers.
190 *
191 * @param {...goog.labs.testing.Matcher} var_args The matchers to test
192 * 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}
200
201
202/**
203 * Returns a matcher that negates the input matcher. The returned
204 * 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}