Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
seleniumhq
GitHub Repository: seleniumhq/selenium
Path: blob/trunk/third_party/closure/goog/testing/strictmock.js
4506 views
1
/**
2
* @license
3
* Copyright The Closure Library Authors.
4
* SPDX-License-Identifier: Apache-2.0
5
*/
6
7
/**
8
* @fileoverview This file defines a strict mock implementation.
9
*/
10
11
goog.setTestOnly('goog.testing.StrictMock');
12
goog.provide('goog.testing.StrictMock');
13
14
goog.require('goog.array');
15
goog.require('goog.asserts');
16
goog.require('goog.testing.Mock');
17
goog.requireType('goog.testing.MockExpectation');
18
19
20
21
/**
22
* This is a mock that verifies that methods are called in the order that they
23
* are specified during the recording phase. Since it verifies order, it
24
* follows 'fail fast' semantics. If it detects a deviation from the
25
* expectations, it will throw an exception and not wait for verify to be
26
* called.
27
* @param {Object|Function} objectToMock The object that should be mocked, or
28
* the constructor of an object to mock.
29
* @param {boolean=} opt_mockStaticMethods An optional argument denoting that
30
* a mock should be constructed from the static functions of a class.
31
* @param {boolean=} opt_createProxy An optional argument denoting that
32
* a proxy for the target mock should be created.
33
* @constructor
34
* @extends {goog.testing.Mock}
35
* @final
36
*/
37
goog.testing.StrictMock = function(
38
objectToMock, opt_mockStaticMethods, opt_createProxy) {
39
'use strict';
40
goog.testing.Mock.call(
41
this, objectToMock, opt_mockStaticMethods, opt_createProxy);
42
43
/**
44
* An array of MockExpectations.
45
* @type {!Array<!goog.testing.MockExpectation>}
46
* @private
47
*/
48
this.$expectations_ = [];
49
50
/** @private {!Set<!goog.testing.MockExpectation>} */
51
this.awaitingExpectations_ = new Set();
52
};
53
goog.inherits(goog.testing.StrictMock, goog.testing.Mock);
54
55
56
/** @override */
57
goog.testing.StrictMock.prototype.$recordExpectation = function() {
58
'use strict';
59
if (this.$pendingExpectation) {
60
this.$expectations_.push(this.$pendingExpectation);
61
this.awaitingExpectations_.add(this.$pendingExpectation);
62
}
63
};
64
65
66
/** @override */
67
goog.testing.StrictMock.prototype.$recordCall = function(name, args) {
68
'use strict';
69
if (this.$expectations_.length == 0) {
70
this.$throwCallException(name, args);
71
}
72
73
// If the current expectation has a different name, make sure it was called
74
// enough and then discard it. We're through with it.
75
var currentExpectation = this.$expectations_[0];
76
while (!this.$verifyCall(currentExpectation, name, args)) {
77
// This might be an item which has passed its min, and we can now
78
// look past it, or it might be below its min and generate an error.
79
if (currentExpectation.actualCalls < currentExpectation.minCalls) {
80
this.$throwCallException(name, args, currentExpectation);
81
}
82
83
this.$expectations_.shift();
84
this.awaitingExpectations_.delete(currentExpectation);
85
this.maybeFinishedWithExpectations_();
86
if (this.$expectations_.length < 1) {
87
// Nothing left, but this may be a failed attempt to call the previous
88
// item on the list, which may have been between its min and max.
89
this.$throwCallException(name, args, currentExpectation);
90
}
91
currentExpectation = this.$expectations_[0];
92
}
93
94
if (currentExpectation.maxCalls == 0) {
95
this.$throwCallException(name, args);
96
}
97
98
currentExpectation.actualCalls++;
99
// If we hit the max number of calls for this expectation, we're finished
100
// with it.
101
if (currentExpectation.actualCalls == currentExpectation.maxCalls) {
102
this.$expectations_.shift();
103
}
104
if (currentExpectation.actualCalls >= currentExpectation.minCalls) {
105
this.awaitingExpectations_.delete(currentExpectation);
106
this.maybeFinishedWithExpectations_();
107
}
108
109
return this.$do(currentExpectation, args);
110
};
111
112
113
/** @override */
114
goog.testing.StrictMock.prototype.$reset = function() {
115
'use strict';
116
goog.testing.StrictMock.superClass_.$reset.call(this);
117
118
goog.array.clear(this.$expectations_);
119
this.awaitingExpectations_.clear();
120
};
121
122
123
/** @override */
124
goog.testing.StrictMock.prototype.$waitAndVerify = function() {
125
'use strict';
126
for (var i = 0; i < this.$expectations_.length; i++) {
127
var expectation = this.$expectations_[i];
128
goog.asserts.assert(
129
!isFinite(expectation.maxCalls) ||
130
expectation.minCalls == expectation.maxCalls,
131
'Mock expectations cannot have a loose number of expected calls to ' +
132
'use $waitAndVerify.');
133
}
134
var promise = goog.testing.StrictMock.base(this, '$waitAndVerify');
135
this.maybeFinishedWithExpectations_();
136
return promise;
137
};
138
139
/**
140
* @private
141
*/
142
goog.testing.StrictMock.prototype.maybeFinishedWithExpectations_ = function() {
143
'use strict';
144
var unresolvedExpectations =
145
this.$expectations_
146
.filter(function(expectation) {
147
'use strict';
148
return expectation.actualCalls < expectation.minCalls;
149
})
150
.length;
151
if (this.waitingForExpectations && !unresolvedExpectations) {
152
this.waitingForExpectations.resolve();
153
}
154
};
155
156
157
/** @override */
158
goog.testing.StrictMock.prototype.$verify = function() {
159
'use strict';
160
goog.testing.StrictMock.superClass_.$verify.call(this);
161
162
while (this.$expectations_.length > 0) {
163
var expectation = this.$expectations_[0];
164
if (expectation.actualCalls < expectation.minCalls) {
165
this.$throwException(
166
'Missing a call to ' + expectation.name + '\nExpected: ' +
167
expectation.minCalls + ' but was: ' + expectation.actualCalls);
168
169
} else {
170
// Don't need to check max, that's handled when the call is made
171
this.$expectations_.shift();
172
}
173
}
174
};
175
176