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

Side by Side Diff: third_party/WebKit/LayoutTests/editing/spelling/spellcheck_test.js

Issue 2727673005: Better spellcheck_test (Closed)
Patch Set: more minor fix Created 3 years, 9 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 'use strict'; 5 'use strict';
6 6
7 // This file provides 7 // This file provides
8 // |spellcheck_test(sample, tester, expectedText, opt_title)| asynchronous test 8 // |spellcheck_test(sample, tester, expectedText, opt_title)| asynchronous test
9 // to W3C test harness for easier writing of spellchecker test cases. 9 // to W3C test harness for easier writing of spellchecker test cases.
10 // 10 //
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 */ 268 */
269 serializeInternal(node) { 269 serializeInternal(node) {
270 if (isElement(node)) 270 if (isElement(node))
271 return this.handleElementNode(node); 271 return this.handleElementNode(node);
272 if (isCharacterData(node)) 272 if (isCharacterData(node))
273 return this.handleCharacterData(node); 273 return this.handleCharacterData(node);
274 throw new Error(`Unexpected node ${node}`); 274 throw new Error(`Unexpected node ${node}`);
275 } 275 }
276 } 276 }
277 277
278 /**
279 * @param {!Document} document
280 * @return {boolean}
281 */
282 function hasPendingSpellCheckRequest(document) {
283 return internals.lastSpellCheckRequestSequence(document) !==
284 internals.lastSpellCheckProcessedSequence(document);
285 }
286
278 /** @type {string} */ 287 /** @type {string} */
279 const kTitle = 'title'; 288 const kTitle = 'title';
280 /** @type {string} */ 289 /** @type {string} */
281 const kCallback = 'callback'; 290 const kCallback = 'callback';
282 /** @type {string} */ 291 /** @type {string} */
283 const kIsSpellcheckTest = 'isSpellcheckTest'; 292 const kIsSpellcheckTest = 'isSpellcheckTest';
284 293
285 /**
286 * @param {!Test} testObject
287 * @param {!Sample} sample
288 * @param {string} expectedText
289 * @param {number} remainingRetry
290 * @param {number} retryInterval
291 */
292 function verifyMarkers(
293 testObject, sample, expectedText, remainingRetry, retryInterval) {
294 assert_not_equals(
295 window.internals, undefined,
296 'window.internals is required for running automated spellcheck tests.');
297
298 /** @type {!MarkerSerializer} */
299 const serializer = new MarkerSerializer({
300 spelling: '#',
301 grammar: '~'});
302
303 try {
304 assert_equals(serializer.serialize(sample.document), expectedText);
305 testObject.done();
306 } catch (error) {
307 if (remainingRetry <= 0)
308 throw error;
309
310 // Force invoking idle time spellchecker in case it has not been run yet.
311 if (window.testRunner)
312 window.testRunner.runIdleTasks(() => {});
313
314 // TODO(xiaochengh): We should make SpellCheckRequester::didCheck trigger
315 // something in JavaScript (e.g., a |Promise|), so that we can actively
316 // know the completion of spellchecking instead of passively waiting for
317 // markers to appear or disappear.
318 testObject.step_timeout(
319 () => verifyMarkers(testObject, sample, expectedText,
320 remainingRetry - 1, retryInterval),
321 retryInterval);
322 }
323 }
324
325 // Spellchecker gets triggered not only by text and selection change, but also 294 // Spellchecker gets triggered not only by text and selection change, but also
326 // by focus change. For example, misspelling markers in <INPUT> disappear when 295 // by focus change. For example, misspelling markers in <INPUT> disappear when
327 // the window loses focus, even though the selection does not change. 296 // the window loses focus, even though the selection does not change.
328 // Therefore, we disallow spellcheck tests from running simultaneously to 297 // Therefore, we disallow spellcheck tests from running simultaneously to
329 // prevent interference among them. If we call spellcheck_test while another 298 // prevent interference among them. If we call spellcheck_test while another
330 // test is running, the new test will be added into testQueue waiting for the 299 // test is running, the new test will be added into testQueue waiting for the
331 // completion of the previous test. 300 // completion of the previous test.
332 301
333 /** @type {boolean} */ 302 /** @type {boolean} */
334 var spellcheckTestRunning = false; 303 var spellcheckTestRunning = false;
335 /** @type {!Array<!Object>} */ 304 /** @type {!Array<!Object>} */
336 const testQueue = []; 305 const testQueue = [];
337 306
307 /** @type {?Function} */
308 var verificationForCurrentTest = null;
yosin_UTC9 2017/03/03 04:44:59 nit: s/var/let/
Xiaocheng 2017/03/03 18:56:41 Done.
309
338 /** 310 /**
339 * @param {!Test} testObject 311 * @param {!Test} testObject
340 * @param {!Sample|string} input 312 * @param {!Sample|string} input
341 * @param {function(!Document)|string} tester 313 * @param {function(!Document)|string} tester
342 * @param {string} expectedText 314 * @param {string} expectedText
343 */ 315 */
344 function invokeSpellcheckTest(testObject, input, tester, expectedText) { 316 function invokeSpellcheckTest(testObject, input, tester, expectedText) {
345 spellcheckTestRunning = true; 317 spellcheckTestRunning = true;
346 318
347 testObject.step(() => { 319 testObject.step(() => {
348 // TODO(xiaochengh): Merge the following part with |assert_selection|. 320 // TODO(xiaochengh): Merge the following part with |assert_selection|.
349 /** @type {!Sample} */ 321 /** @type {!Sample} */
350 const sample = typeof(input) === 'string' ? new Sample(input) : input; 322 const sample = typeof(input) === 'string' ? new Sample(input) : input;
351 testObject.sample = sample; 323 testObject.sample = sample;
352 324
353 if (typeof(tester) === 'function') { 325 if (typeof(tester) === 'function') {
354 tester.call(window, sample.document); 326 tester.call(window, sample.document);
355 } else if (typeof(tester) === 'string') { 327 } else if (typeof(tester) === 'string') {
356 const strings = tester.split(/ (.+)/); 328 const strings = tester.split(/ (.+)/);
357 sample.document.execCommand(strings[0], false, strings[1]); 329 sample.document.execCommand(strings[0], false, strings[1]);
358 } else { 330 } else {
359 assert_unreached(`Invalid tester: ${tester}`); 331 assert_unreached(`Invalid tester: ${tester}`);
360 } 332 }
361 333
362 /** @type {number} */ 334 assert_not_equals(
363 const kMaxRetry = 10; 335 window.testRunner, undefined,
364 /** @type {number} */ 336 'window.testRunner is required for automated spellcheck tests.');
365 const kRetryInterval = 50; 337 assert_not_equals(
338 window.internals, undefined,
339 'window.internals is required for automated spellcheck tests.');
366 340
367 // TODO(xiaochengh): We should make SpellCheckRequester::didCheck trigger 341 assert_equals(
368 // something in JavaScript (e.g., a |Promise|), so that we can actively know 342 verificationForCurrentTest, null,
369 // the completion of spellchecking instead of passively waiting for markers 343 'Internal error: previous test not verified yet');
370 // to appear or disappear. 344
371 testObject.step_timeout( 345 verificationForCurrentTest = () => {
372 () => verifyMarkers(testObject, sample, expectedText, 346 if (hasPendingSpellCheckRequest(sample.document))
373 kMaxRetry, kRetryInterval), 347 return;
374 kRetryInterval); 348
349 testObject.step(() => {
350 /** @type {!MarkerSerializer} */
351 const serializer = new MarkerSerializer({
352 spelling: '#',
353 grammar: '~'});
354
355 assert_equals(serializer.serialize(sample.document), expectedText);
356 testObject.done();
357 });
358 };
359
360 if (internals.idleTimeSpellCheckerState !== undefined) {
361 if (internals.idleTimeSpellCheckerState(sample.document) === 'hot-mode-req uested')
yosin_UTC9 2017/03/03 04:44:59 nit: We can use just one if-statement. if (intern
Xiaocheng 2017/03/03 18:56:41 Done.
362 internals.runIdleTimeSpellChecker(sample.document);
363 }
364
365 // For a test that does not create new spell check request, a synchronous
366 // verification finishes everything.
367 verificationForCurrentTest();
375 }); 368 });
376 } 369 }
377 370
378 add_result_callback(testObj => { 371 add_result_callback(testObj => {
379 if (!testObj.properties[kIsSpellcheckTest]) 372 if (!testObj.properties[kIsSpellcheckTest])
380 return; 373 return;
381 374
375 verificationForCurrentTest = null;
376
382 /** @type {boolean} */ 377 /** @type {boolean} */
383 var shouldRemoveSample = false; 378 var shouldRemoveSample = false;
384 if (testObj.status === testObj.PASS) { 379 if (testObj.status === testObj.PASS) {
385 if (testObj.properties[kCallback]) 380 if (testObj.properties[kCallback])
386 testObj.properties[kCallback](testObj.sample); 381 testObj.properties[kCallback](testObj.sample);
387 else 382 else
388 shouldRemoveSample = true; 383 shouldRemoveSample = true;
389 } else { 384 } else {
390 if (window.testRunner) 385 if (window.testRunner)
391 shouldRemoveSample = true; 386 shouldRemoveSample = true;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 return args; 420 return args;
426 } 421 }
427 422
428 /** 423 /**
429 * @param {!Sample|string} input 424 * @param {!Sample|string} input
430 * @param {function(!Document)|string} tester 425 * @param {function(!Document)|string} tester
431 * @param {string} expectedText 426 * @param {string} expectedText
432 * @param {Object=} opt_args 427 * @param {Object=} opt_args
433 */ 428 */
434 function spellcheckTest(input, tester, expectedText, opt_args) { 429 function spellcheckTest(input, tester, expectedText, opt_args) {
435 if (window.testRunner)
436 window.testRunner.setMockSpellCheckerEnabled(true);
437
438 /** @type {!Object} */ 430 /** @type {!Object} */
439 const args = getTestArguments(opt_args); 431 const args = getTestArguments(opt_args);
440 /** @type {!Test} */ 432 /** @type {!Test} */
441 const testObject = async_test(args[kTitle], args); 433 const testObject = async_test(args[kTitle], args);
442 434
443 if (spellcheckTestRunning) { 435 if (spellcheckTestRunning) {
444 testQueue.push({ 436 testQueue.push({
445 testObject: testObject, input: input, 437 testObject: testObject, input: input,
446 tester: tester, expectedText: expectedText}); 438 tester: tester, expectedText: expectedText});
447 return; 439 return;
448 } 440 }
449 441
450 invokeSpellcheckTest(testObject, input, tester, expectedText); 442 invokeSpellcheckTest(testObject, input, tester, expectedText);
451 } 443 }
452 444
445 if (window.testRunner) {
446 window.testRunner.setMockSpellCheckerEnabled(true);
447 window.testRunner.setSpellCheckResolvedCallback(() => {
448 if (verificationForCurrentTest)
449 verificationForCurrentTest();
450 });
451 }
452
453 // Export symbols 453 // Export symbols
454 window.spellcheck_test = spellcheckTest; 454 window.spellcheck_test = spellcheckTest;
455 })(); 455 })();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698