Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(42)

Side by Side Diff: chrome/browser/resources/chromeos/chromevox/testing/mock_feedback.js

Issue 1319093003: Use new earcons in ChromeVox Next. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@automation_node_id_fix_2
Patch Set: Rebase Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 * @fileoverview This file contains the |MockFeedback| class which is a 6 * @fileoverview This file contains the |MockFeedback| class which is
7 * combined mock class for speech and braille feedback. A test that uses 7 * a combined mock class for speech, braille, and earcon feedback. A
8 * this class may add expectations for speech utterances and braille display 8 * test that uses this class may add expectations for speech
9 * content to be output. The |install| method sets appropriate mock classes 9 * utterances, braille display content to be output, and earcons
10 * as the |cvox.ChromeVox.tts| and |cvox.ChromeVox.braille| objects, 10 * played (by name). The |install| method sets appropriate mock
11 * respectively. Output sent to those objects will then be collected in 11 * classes as the |cvox.ChromeVox.tts|, |cvox.ChromeVox.braille| and
12 * an internal queue. 12 * |cvox.ChromeVox.earcons| objects, respectively. Output sent to
13 * those objects will then be collected in an internal queue.
13 * 14 *
14 * Expectations can be added using the |expectSpeech| and |expectBraille| 15 * Expectations can be added using the |expectSpeech|,
15 * methods. These methods take either strings or regular expressions to match 16 * |expectBraille|, and |expectEarcon| methods. These methods take
16 * against. Strings must match a full utterance (or display content) exactly, 17 * either strings or regular expressions to match against. Strings
17 * while a regular expression must match a substring (use anchor operators if 18 * must match a full utterance (or display content) exactly, while a
19 * regular expression must match a substring (use anchor operators if
18 * needed). 20 * needed).
19 * 21 *
20 * Function calls may be inserted in the stream of expectations using the 22 * Function calls may be inserted in the stream of expectations using the
21 * |call| method. Such callbacks are called after all preceding expectations 23 * |call| method. Such callbacks are called after all preceding expectations
22 * have been met, and before any further expectations are matched. Callbacks 24 * have been met, and before any further expectations are matched. Callbacks
23 * are called in the order they were added to the mock. 25 * are called in the order they were added to the mock.
24 * 26 *
25 * The |replay| method starts processing any pending utterances and braille 27 * The |replay| method starts processing any pending utterances,
26 * display content and will try to match expectations as new feedback enters 28 * braille display content, and earcons and will try to match
27 * the queue asynchronously. When all expectations have been met and callbacks 29 * expectations as new feedback enters the queue asynchronously. When
28 * called, the finish callback, if any was provided to the constructor, is 30 * all expectations have been met and callbacks called, the finish
29 * called. 31 * callback, if any was provided to the constructor, is called.
30 * 32 *
31 * This mock class is lean, meaning that feedback that doesn't match 33 * This mock class is lean, meaning that feedback that doesn't match
32 * any expectations is silently ignored. 34 * any expectations is silently ignored.
33 * 35 *
34 * NOTE: for asynchronous tests, the processing will never finish if there 36 * NOTE: for asynchronous tests, the processing will never finish if there
35 * are unmet expectations. To help debugging in such situations, the mock 37 * are unmet expectations. To help debugging in such situations, the mock
36 * will output its pending state if there are pending expectations and no 38 * will output its pending state if there are pending expectations and no
37 * output is received within a few seconds. 39 * output is received within a few seconds.
38 * 40 *
39 * See mock_feedback_test.js for example usage of this class. 41 * See mock_feedback_test.js for example usage of this class.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 * @private 77 * @private
76 */ 78 */
77 this.pendingUtterances_ = []; 79 this.pendingUtterances_ = [];
78 /** 80 /**
79 * Pending braille output. 81 * Pending braille output.
80 * @type {Array<{text: string, callback: (function|undefined)}>} 82 * @type {Array<{text: string, callback: (function|undefined)}>}
81 * @private 83 * @private
82 */ 84 */
83 this.pendingBraille_ = []; 85 this.pendingBraille_ = [];
84 /** 86 /**
87 * Pending earcons.
88 * @type {Array<{text: string, callback: (function|undefined)}>}
89 * @private
90 */
91 this.pendingEarcons_ = [];
92 /**
85 * Handle for the timeout set for debug logging. 93 * Handle for the timeout set for debug logging.
86 * @type {number} 94 * @type {number}
87 * @private 95 * @private
88 */ 96 */
89 this.logTimeoutId_ = 0; 97 this.logTimeoutId_ = 0;
90 /** 98 /**
91 * @type {cvox.NavBraille} 99 * @type {cvox.NavBraille}
92 * @private 100 * @private
93 */ 101 */
94 this.lastMatchedBraille_ = null; 102 this.lastMatchedBraille_ = null;
(...skipping 16 matching lines...) Expand all
111 119
112 cvox.ChromeVox.tts = new MockTts(); 120 cvox.ChromeVox.tts = new MockTts();
113 121
114 var MockBraille = function() {}; 122 var MockBraille = function() {};
115 MockBraille.prototype = { 123 MockBraille.prototype = {
116 __proto__: cvox.BrailleInterface.prototype, 124 __proto__: cvox.BrailleInterface.prototype,
117 write: this.addBraille_.bind(this) 125 write: this.addBraille_.bind(this)
118 }; 126 };
119 127
120 cvox.ChromeVox.braille = new MockBraille(); 128 cvox.ChromeVox.braille = new MockBraille();
129
130 var MockEarcons = function() {};
131 MockEarcons.prototype = {
132 __proto__: cvox.AbstractEarcons.prototype,
133 playEarcon: this.addEarcon_.bind(this)
134 };
135
136 // cvox.ChromeVox.earcons is a getter that switches between Classic and
137 // Next; replace it with MockEarcons.
138 delete cvox.ChromeVox.earcons;
139 cvox.ChromeVox.earcons = new MockEarcons();
121 }, 140 },
122 141
123 /** 142 /**
124 * Adds an expectation for one or more spoken utterances. 143 * Adds an expectation for one or more spoken utterances.
125 * @param {...(string|RegExp)} var_args One or more utterance to add as 144 * @param {...(string|RegExp)} var_args One or more utterance to add as
126 * expectations. 145 * expectations.
127 * @return {MockFeedback} |this| for chaining 146 * @return {MockFeedback} |this| for chaining
128 */ 147 */
129 expectSpeech: function() { 148 expectSpeech: function() {
130 assertFalse(this.replaying_); 149 assertFalse(this.replaying_);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 return !!match; 209 return !!match;
191 }.bind(this), 210 }.bind(this),
192 toString: function() { 211 toString: function() {
193 return 'Braille \'' + text + '\' ' + JSON.stringify(props); 212 return 'Braille \'' + text + '\' ' + JSON.stringify(props);
194 } 213 }
195 }); 214 });
196 return this; 215 return this;
197 }, 216 },
198 217
199 /** 218 /**
219 * Adds an expectation for a played earcon.
220 * @param {string} earconName The name of the earcon.
221 * @return {MockFeedback} |this| for chaining
222 */
223 expectEarcon: function(earconName, opt_props) {
224 assertFalse(this.replaying_);
225 this.pendingActions_.push({
226 perform: function() {
227 var match = MockFeedback.matchAndConsume_(
228 earconName, {}, this.pendingEarcons_);
229 return !!match;
230 }.bind(this),
231 toString: function() {
232 return 'Earcon \'' + earconName + '\'';
233 }
234 });
235 return this;
236 },
237
238 /**
200 * Arranges for a callback to be invoked when all expectations that were 239 * Arranges for a callback to be invoked when all expectations that were
201 * added before this call have been met. Callbacks are called in the 240 * added before this call have been met. Callbacks are called in the
202 * order they are added. 241 * order they are added.
203 * @param {Function} callback 242 * @param {Function} callback
204 * @return {MockFeedback} |this| for chaining 243 * @return {MockFeedback} |this| for chaining
205 */ 244 */
206 call: function(callback) { 245 call: function(callback) {
207 assertFalse(this.replaying_); 246 assertFalse(this.replaying_);
208 this.pendingActions_.push({ 247 this.pendingActions_.push({
209 perform: function() { 248 perform: function() {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 callback: callback}); 302 callback: callback});
264 this.process_(); 303 this.process_();
265 }, 304 },
266 305
267 /** @private */ 306 /** @private */
268 addBraille_: function(navBraille) { 307 addBraille_: function(navBraille) {
269 this.pendingBraille_.push(navBraille); 308 this.pendingBraille_.push(navBraille);
270 this.process_(); 309 this.process_();
271 }, 310 },
272 311
312 /** @private */
313 addEarcon_: function(earconName) {
314 this.pendingEarcons_.push({text: earconName});
315 this.process_();
316 },
317
273 /*** @private */ 318 /*** @private */
274 process_: function() { 319 process_: function() {
275 if (!this.replaying_ || this.inProcess_) 320 if (!this.replaying_ || this.inProcess_)
276 return; 321 return;
277 try { 322 try {
278 this.inProcess_ = true; 323 this.inProcess_ = true;
279 while (this.pendingActions_.length > 0) { 324 while (this.pendingActions_.length > 0) {
280 var action = this.pendingActions_[0]; 325 var action = this.pendingActions_[0];
281 if (action.perform()) { 326 if (action.perform()) {
282 this.pendingActions_.shift(); 327 this.pendingActions_.shift();
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 var ret = '\'' + i.text + '\''; 362 var ret = '\'' + i.text + '\'';
318 if ('startIndex' in i) 363 if ('startIndex' in i)
319 ret += ' startIndex=' + i.startIndex; 364 ret += ' startIndex=' + i.startIndex;
320 if ('endIndex' in i) 365 if ('endIndex' in i)
321 ret += ' endIndex=' + i.endIndex; 366 ret += ' endIndex=' + i.endIndex;
322 return ret; 367 return ret;
323 }).join('\n ') + '\n '); 368 }).join('\n ') + '\n ');
324 } 369 }
325 logPending('speech utterances', this.pendingUtterances_); 370 logPending('speech utterances', this.pendingUtterances_);
326 logPending('braille', this.pendingBraille_); 371 logPending('braille', this.pendingBraille_);
372 logPending('earcons', this.pendingEarcons_);
327 this.logTimeoutId_ = 0; 373 this.logTimeoutId_ = 0;
328 }, 374 },
329 }; 375 };
330 376
331 /** 377 /**
332 * @param {string} text 378 * @param {string} text
333 * @param {Object} props 379 * @param {Object} props
334 * @param {Array<{text: (string|RegExp), callback: (function|undefined)}>} 380 * @param {Array<{text: (string|RegExp), callback: (function|undefined)}>}
335 * pending 381 * pending
336 * @return {Object} 382 * @return {Object}
337 * @private 383 * @private
338 */ 384 */
339 MockFeedback.matchAndConsume_ = function(text, props, pending) { 385 MockFeedback.matchAndConsume_ = function(text, props, pending) {
340 for (var i = 0, candidate; candidate = pending[i]; ++i) { 386 for (var i = 0, candidate; candidate = pending[i]; ++i) {
341 var candidateText = candidate.text.toString(); 387 var candidateText = candidate.text;
388 if (typeof(candidateText) != 'string')
389 candidateText = candidateText.toString();
390
342 if (text === candidateText || 391 if (text === candidateText ||
343 (text instanceof RegExp && text.test(candidateText))) { 392 (text instanceof RegExp && text.test(candidateText))) {
344 var matched = true; 393 var matched = true;
345 for (prop in props) { 394 for (prop in props) {
346 if (candidate[prop] !== props[prop]) { 395 if (candidate[prop] !== props[prop]) {
347 matched = false; 396 matched = false;
348 break; 397 break;
349 } 398 }
350 } 399 }
351 if (matched) 400 if (matched)
352 break; 401 break;
353 } 402 }
354 } 403 }
355 if (candidate) { 404 if (candidate) {
356 var consumed = pending.splice(0, i + 1); 405 var consumed = pending.splice(0, i + 1);
357 consumed.forEach(function(item) { 406 consumed.forEach(function(item) {
358 if (item.callback) 407 if (item.callback)
359 item.callback(); 408 item.callback();
360 }); 409 });
361 } 410 }
362 return candidate; 411 return candidate;
363 }; 412 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698