// Licensed to the Software Freedom Conservancy (SFC) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The SFC licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. goog.provide('webdriver.test.testutil'); goog.provide('webdriver.test.testutil.StubError'); goog.require('goog.array'); goog.require('goog.debug.Error'); goog.require('goog.string'); goog.require('goog.testing.recordFunction'); goog.require('webdriver.stacktrace'); /** * A custom error used for testing. * @param {string=} opt_msg The error message to use. * @constructor * @extends {goog.debug.Error} * @final */ webdriver.test.testutil.StubError = function(opt_msg) { webdriver.test.testutil.StubError.base(this, 'constructor', opt_msg); }; goog.inherits(webdriver.test.testutil.StubError, goog.debug.Error); /** @override */ webdriver.test.testutil.StubError.prototype.name = 'StubError'; /** @type {Array.} */ webdriver.test.testutil.messages = []; webdriver.test.testutil.getStackTrace = function() { return webdriver.stacktrace.get(); }; webdriver.test.testutil.throwStubError = function() { throw new webdriver.test.testutil.StubError; }; webdriver.test.testutil.assertIsStubError = function(error) { assertTrue(error + ' is not an instanceof StubError', error instanceof webdriver.test.testutil.StubError); }; /** * Asserts the contents of the {@link webdriver.test.testutil.messages} array * are as expected. * @param {...*} var_args The expected contents. */ webdriver.test.testutil.assertMessages = function(var_args) { var args = Array.prototype.slice.call(arguments, 0); assertArrayEquals(args, webdriver.test.testutil.messages); }; /** * Wraps a call to {@link webdriver.test.testutil.assertMessages} so it can * be passed as a callback. * @param {...*} var_args The expected contents. * @return {!Function} The wrapped function. */ webdriver.test.testutil.assertingMessages = function(var_args) { var args = goog.array.slice(arguments, 0); return function() { return webdriver.test.testutil.assertMessages.apply(null, args); }; }; /** * Asserts an object is a promise. * @param {*} obj The object to check. */ webdriver.test.testutil.assertIsPromise = function(obj) { assertTrue('Value is not a promise: ' + goog.typeOf(obj), webdriver.promise.isPromise(obj)); }; /** * Asserts an object is not a promise. * @param {*} obj The object to check. */ webdriver.test.testutil.assertNotPromise = function(obj) { assertFalse(webdriver.promise.isPromise(obj)); }; /** * Wraps a function. The wrapped function will have several utility functions: * * @param {Function=} opt_fn The function to wrap; defaults to * goog.nullFunction. * @return {!Function} The wrapped function. * @see goog.testing.recordFunction */ webdriver.test.testutil.callbackHelper = function(opt_fn) { var callback = goog.testing.recordFunction(opt_fn); callback.getExpectedCallCountMessage = function(n, opt_prefix, opt_noJoin) { var message = []; if (opt_prefix) message.push(opt_prefix); var calls = callback.getCalls(); message.push( 'Expected to be called ' + n + ' times.', ' was called ' + calls.length + ' times:'); goog.array.forEach(calls, function(call) { var e = call.getError(); if (e) { throw e; } }); return opt_noJoin ? message : message.join('\n'); }; callback.assertCalled = function(opt_message) { assertEquals(callback.getExpectedCallCountMessage(1, opt_message), 1, callback.getCallCount()); }; callback.assertNotCalled = function(opt_message) { assertEquals(callback.getExpectedCallCountMessage(0, opt_message), 0, callback.getCallCount()); }; return callback; }; /** * Creates a utility for managing a pair of callbacks, capable of asserting only * one of the pair was ever called. * * @param {Function=} opt_callback The callback to manage. * @param {Function=} opt_errback The errback to manage. */ webdriver.test.testutil.callbackPair = function(opt_callback, opt_errback) { var pair = { callback: webdriver.test.testutil.callbackHelper(opt_callback), errback: webdriver.test.testutil.callbackHelper(opt_errback) }; /** @param {string=} opt_message Optional failure message. */ pair.assertEither = function(opt_message) { if (!pair.callback.getCallCount() && !pair.errback.getCallCount()) { var message = ['Neither callback nor errback has been called']; if (opt_message) goog.array.insertAt(message, opt_message); fail(message.join('\n')); } }; /** @param {string=} opt_message Optional failure message. */ pair.assertNeither = function(opt_message) { var message = (opt_message || '') + 'Did not expect callback or errback'; pair.callback.assertNotCalled(message); pair.errback.assertNotCalled(message); }; /** @param {string=} opt_message Optional failure message. */ pair.assertCallback = function(opt_message) { var message = opt_message ? (opt_message + ': ') : ''; pair.errback.assertNotCalled(message + 'Expected callback, not errback'); pair.callback.assertCalled(message + 'Callback not called'); }; /** @param {string=} opt_message Optional failure message. */ pair.assertErrback = function(opt_message) { var message = opt_message ? (opt_message + ': ') : ''; pair.callback.assertNotCalled(message + 'Expected errback, not callback'); pair.errback.assertCalled(message + 'Errback not called'); }; pair.reset = function() { pair.callback.reset(); pair.errback.reset(); }; return pair; }; webdriver.test.testutil.assertObjectEquals = function(expected, actual) { assertObjectEquals( 'Expected: ' + JSON.stringify(expected) + '\n' + 'Actual: ' + JSON.stringify(actual), expected, actual); };