OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * Create a mock function that records function calls and validates against | 6 * Create a mock function that records function calls and validates against |
7 * expectations. | 7 * expectations. |
8 * @constructor. | 8 * @constructor. |
9 */ | 9 */ |
10 function MockMethod() { | 10 function MockMethod() { |
11 var fn = function() { | 11 var fn = function() { |
12 var args = Array.prototype.slice.call(arguments); | 12 var args = Array.prototype.slice.call(arguments); |
13 var callbacks = | |
14 args.filter(function(arg) { return (typeof arg == 'function'); }); | |
15 | |
16 if (callbacks.length > 1) { | |
17 console.error('Only support mocking function with at most one callback.'); | |
18 return; | |
19 } | |
20 | |
21 fn.recordCall(args); | 13 fn.recordCall(args); |
22 if (callbacks.length == 1) { | 14 return this.returnValue; |
23 callbacks[0].apply(undefined, fn.callbackData); | |
24 return; | |
25 } | |
26 return fn.returnValue; | |
27 }; | 15 }; |
28 | 16 |
29 /** | 17 /** |
30 * List of signatures for fucntion calls. | 18 * List of signatures for fucntion calls. |
31 * @type {!Array.<!Array>} | 19 * @type {!Array.<!Array>} |
32 * @private | 20 * @private |
33 */ | 21 */ |
34 fn.calls_ = []; | 22 fn.calls_ = []; |
35 | 23 |
36 /** | 24 /** |
37 * List of expected call signatures. | 25 * List of expected call signatures. |
38 * @type {!Array.<!Array>} | 26 * @type {!Array.<!Array>} |
39 * @private | 27 * @private |
40 */ | 28 */ |
41 fn.expectations_ = []; | 29 fn.expectations_ = []; |
42 | 30 |
43 /** | 31 /** |
44 * Value returned from call to function. | 32 * Value returned from call to function. |
45 * @type {*} | 33 * @type {*} |
46 */ | 34 */ |
47 fn.returnValue = undefined; | 35 fn.returnValue = undefined; |
48 | 36 |
49 /** | |
50 * List of arguments for callback function. | |
51 * @type {!Array.<!Array>} | |
52 */ | |
53 fn.callbackData = []; | |
54 | |
55 fn.__proto__ = MockMethod.prototype; | 37 fn.__proto__ = MockMethod.prototype; |
56 return fn; | 38 return fn; |
57 } | 39 } |
58 | 40 |
59 MockMethod.prototype = { | 41 MockMethod.prototype = { |
60 /** | 42 /** |
61 * Adds an expected call signature. | 43 * Adds an expected call signature. |
62 * @param {...} var_args Expected arguments for the function call. | 44 * @param {...} var_args Expected arguments for the function call. |
63 */ | 45 */ |
64 addExpectation: function() { | 46 addExpectation: function() { |
65 var args = Array.prototype.slice.call(arguments); | 47 var args = Array.prototype.slice.call(arguments); |
66 this.expectations_.push(args.filter(this.notFunction_)); | 48 this.expectations_.push(args); |
67 }, | 49 }, |
68 | 50 |
69 /** | 51 /** |
70 * Adds a call signature. | 52 * Adds a call signature. |
71 * @param {!Array} args. | 53 * @param {!Array} args. |
72 */ | 54 */ |
73 recordCall: function(args) { | 55 recordCall: function(args) { |
74 this.calls_.push(args.filter(this.notFunction_)); | 56 this.calls_.push(args); |
75 }, | 57 }, |
76 | 58 |
77 /** | 59 /** |
78 * Verifies that the function is called the expected number of times and with | 60 * Verifies that the function is called the expected number of times and with |
79 * the correct signature for each call. | 61 * the correct signature for each call. |
80 */ | 62 */ |
81 verifyMock: function() { | 63 verifyMock: function() { |
82 var errorMessage = 'Number of method calls did not match expectation.'; | 64 var errorMessage = 'Number of method calls did not match expectation.'; |
83 if (this.functionName) | 65 if (this.functionName) |
84 errorMessage = 'Error in ' + this.functionName + ':\n' + errorMessage; | 66 errorMessage = 'Error in ' + this.functionName + ':\n' + errorMessage; |
(...skipping 10 matching lines...) Expand all Loading... |
95 * Override if strict equality is not required. | 77 * Override if strict equality is not required. |
96 * @param {number} index Canonical index of the function call. Unused in the | 78 * @param {number} index Canonical index of the function call. Unused in the |
97 * base implementation, but provides context that may be useful for | 79 * base implementation, but provides context that may be useful for |
98 * overrides. | 80 * overrides. |
99 * @param {!Array} expected The expected arguments. | 81 * @param {!Array} expected The expected arguments. |
100 * @parma {!Array} observed The observed arguments. | 82 * @parma {!Array} observed The observed arguments. |
101 */ | 83 */ |
102 validateCall: function(index, expected, observed) { | 84 validateCall: function(index, expected, observed) { |
103 assertDeepEquals(expected, observed); | 85 assertDeepEquals(expected, observed); |
104 }, | 86 }, |
105 | |
106 /** | |
107 * Test if arg is a function. | |
108 * @param {*} arg The argument to test. | |
109 * @return True if arg is not function type. | |
110 */ | |
111 notFunction_: function(arg) { | |
112 return typeof arg != 'function'; | |
113 } | |
114 }; | 87 }; |
115 | 88 |
116 /** | 89 /** |
117 * Controller for mocking methods. Tracks calls to mocked methods and verifies | 90 * Controller for mocking methods. Tracks calls to mocked methods and verifies |
118 * that call signatures match expectations. | 91 * that call signatures match expectations. |
119 * @constructor. | 92 * @constructor. |
120 */ | 93 */ |
121 function MockController() { | 94 function MockController() { |
122 /** | 95 /** |
123 * Original functions implementations, which are restored when |reset| is | 96 * Original functions implementations, which are restored when |reset| is |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 * Discard mocks reestoring default behavior. | 149 * Discard mocks reestoring default behavior. |
177 */ | 150 */ |
178 reset: function() { | 151 reset: function() { |
179 for (var i = 0; i < this.overrides_.length; i++) { | 152 for (var i = 0; i < this.overrides_.length; i++) { |
180 var override = this.overrides_[i]; | 153 var override = this.overrides_[i]; |
181 override.parent[override.functionName] = override.originalFunction; | 154 override.parent[override.functionName] = override.originalFunction; |
182 } | 155 } |
183 }, | 156 }, |
184 | 157 |
185 }; | 158 }; |
OLD | NEW |