Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / test / data / webui / mock_controller.js
blob378fdc353967085027d07a0cb999b4ff059158af
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 /**
6  * Create a mock function that records function calls and validates against
7  * expectations.
8  * @constructor.
9  */
10 function MockMethod() {
11   var fn = function() {
12     var args = Array.prototype.slice.call(arguments);
13     fn.recordCall(args);
14     return this.returnValue;
15   };
17   /**
18    * List of signatures for fucntion calls.
19    * @type {!Array.<!Array>}
20    * @private
21    */
22   fn.calls_ = [];
24   /**
25    * List of expected call signatures.
26    * @type {!Array.<!Array>}
27    * @private
28    */
29   fn.expectations_ = [];
31   /**
32    * Value returned from call to function.
33    * @type {*}
34    */
35   fn.returnValue = undefined;
37   fn.__proto__ = MockMethod.prototype;
38   return fn;
41 MockMethod.prototype = {
42   /**
43    * Adds an expected call signature.
44    * @param {...}  var_args Expected arguments for the function call.
45    */
46   addExpectation: function() {
47     var args = Array.prototype.slice.call(arguments);
48     this.expectations_.push(args);
49   },
51   /**
52    * Adds a call signature.
53    * @param {!Array} args.
54    */
55   recordCall: function(args) {
56     this.calls_.push(args);
57   },
59   /**
60    * Verifies that the function is called the expected number of times and with
61    * the correct signature for each call.
62    */
63   verifyMock: function() {
64     var errorMessage =  'Number of method calls did not match expectation.';
65     if (this.functionName)
66       errorMessage = 'Error in ' + this.functionName + ':\n' + errorMessage;
67     assertEquals(this.expectations_.length,
68                  this.calls_.length,
69                  errorMessage);
70     for (var i = 0; i < this.expectations_.length; i++) {
71       this.validateCall(i, this.expectations_[i], this.calls_[i]);
72     }
73   },
75   /**
76    * Verifies that the observed function arguments match expectations.
77    * Override if strict equality is not required.
78    * @param {number} index Canonical index of the function call. Unused in the
79    *     base implementation, but provides context that may be useful for
80    *     overrides.
81    * @param {!Array} expected The expected arguments.
82    * @parma {!Array} observed The observed arguments.
83    */
84   validateCall: function(index, expected, observed) {
85     assertDeepEquals(expected, observed);
86   },
89 /**
90  * Controller for mocking methods. Tracks calls to mocked methods and verifies
91  * that call signatures match expectations.
92  * @constructor.
93  */
94 function MockController() {
95   /**
96    * Original functions implementations, which are restored when |reset| is
97    * called.
98    * @type {!Array.<!Object>}
99    * @private
100    */
101   this.overrides_ = [];
103   /**
104    * List of registered mocks.
105    * @type {!Array.<!MockMethod>}
106    * @private
107    */
108   this.mocks_ = [];
111 MockController.prototype = {
112   /**
113    * Creates a mock function.
114    * @param {Object=} opt_parent Optional parent object for the function.
115    * @param {string=} opt_functionName Optional name of the function being
116    *     mocked. If the parent and function name are both provided, the
117    *     mock is automatically substituted for the original and replaced on
118    *     reset.
119    */
120   createFunctionMock: function(opt_parent, opt_functionName) {
121     var fn = new MockMethod();
123     // Register mock.
124     if (opt_parent && opt_functionName) {
125       this.overrides_.push({
126         parent: opt_parent,
127         functionName: opt_functionName,
128         originalFunction: opt_parent[opt_functionName]
129       });
130       opt_parent[opt_functionName] = fn;
131       fn.functionName = opt_functionName;
132     }
133     this.mocks_.push(fn);
135     return fn;
136   },
138   /**
139    * Validates all mocked methods. An exception is thrown if the
140    * expected and actual calls to a mocked function to not align.
141    */
142   verifyMocks: function() {
143     for (var i = 0; i < this.mocks_.length; i++) {
144       this.mocks_[i].verifyMock();
145     }
146   },
148   /**
149    * Discard mocks reestoring default behavior.
150    */
151   reset: function() {
152     for (var i = 0; i < this.overrides_.length; i++) {
153       var override = this.overrides_[i];
154       override.parent[override.functionName] = override.originalFunction;
155     }
156   },