| OLD | NEW |
| 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 |assert_selection(sample, tester, expectedText)| assertion | 7 // This file provides |assert_selection(sample, tester, expectedText)| assertion |
| 8 // to W3C test harness to write editing test cases easier. | 8 // to W3C test harness to write editing test cases easier. |
| 9 // | 9 // |
| 10 // |sample| is an HTML fragment text which is inserted as |innerHTML|. It should | 10 // |sample| is an HTML fragment text which is inserted as |innerHTML|. It should |
| (...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 serialize() { | 573 serialize() { |
| 574 /** @type {!SampleSelection} */ | 574 /** @type {!SampleSelection} */ |
| 575 const selection = SampleSelection.fromDOMSelection(this.selection_); | 575 const selection = SampleSelection.fromDOMSelection(this.selection_); |
| 576 /** @type {!Serializer} */ | 576 /** @type {!Serializer} */ |
| 577 const serializer = new Serializer(selection); | 577 const serializer = new Serializer(selection); |
| 578 return serializer.serialize(this.document_); | 578 return serializer.serialize(this.document_); |
| 579 } | 579 } |
| 580 } | 580 } |
| 581 | 581 |
| 582 function assembleDescription() { | 582 function assembleDescription() { |
| 583 const RE_TEST_FUNCTION = | |
| 584 new RegExp('at Object.test \\(.*?([^/]+?):(\\d+):(\\d+)\\)'); | |
| 585 function getStack() { | 583 function getStack() { |
| 586 let stack; | 584 let stack; |
| 587 try { | 585 try { |
| 588 throw new Error('get line number'); | 586 throw new Error('get line number'); |
| 589 } catch (error) { | 587 } catch (error) { |
| 590 stack = error.stack.split('\n').slice(1); | 588 stack = error.stack.split('\n').slice(1); |
| 591 } | 589 } |
| 592 return stack | 590 return stack |
| 593 } | 591 } |
| 592 |
| 593 const RE_IN_ASSERT_SELECTION = new RegExp('assert_selection\\.js'); |
| 594 for (const line of getStack()) { | 594 for (const line of getStack()) { |
| 595 const match = RE_TEST_FUNCTION.exec(line); | 595 const match = RE_IN_ASSERT_SELECTION.exec(line); |
| 596 if (!match) | 596 if (!match) { |
| 597 continue; | 597 const RE_LAYOUTTESTS = new RegExp('LayoutTests.*'); |
| 598 return `${match[1]}(${match[2]})`; | 598 return RE_LAYOUTTESTS.exec(line); |
| 599 } |
| 599 } | 600 } |
| 600 return ''; | 601 return ''; |
| 601 } | 602 } |
| 602 | 603 |
| 603 /** | 604 /** |
| 604 * @param {string} expectedText | 605 * @param {string} expectedText |
| 605 */ | 606 */ |
| 606 function checkExpectedText(expectedText) { | 607 function checkExpectedText(expectedText) { |
| 607 /** @type {number} */ | 608 /** @type {number} */ |
| 608 const anchorOffset = expectedText.indexOf('^'); | 609 const anchorOffset = expectedText.indexOf('^'); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 621 `You should have a focus marker "|" in "${expectedText}".`); | 622 `You should have a focus marker "|" in "${expectedText}".`); |
| 622 } | 623 } |
| 623 if (anchorOffset >= 0 && focusOffset >= 0 && | 624 if (anchorOffset >= 0 && focusOffset >= 0 && |
| 624 (anchorOffset + 1 === focusOffset || anchorOffset - 1 === focusOffset)) { | 625 (anchorOffset + 1 === focusOffset || anchorOffset - 1 === focusOffset)) { |
| 625 throw new Error( | 626 throw new Error( |
| 626 `You should have focus marker and should not have anchor marker if and o
nly if selection is a caret in "${expectedText}".`); | 627 `You should have focus marker and should not have anchor marker if and o
nly if selection is a caret in "${expectedText}".`); |
| 627 } | 628 } |
| 628 } | 629 } |
| 629 | 630 |
| 630 /** | 631 /** |
| 632 * @param {string} str1 |
| 633 * @param {string} str2 |
| 634 * @return {string} |
| 635 */ |
| 636 function commonPrefixOf(str1, str2) { |
| 637 for (let index = 0; index < str1.length; ++index) { |
| 638 if (str1[index] !== str2[index]) |
| 639 return str1.substr(0, index); |
| 640 } |
| 641 return str1; |
| 642 } |
| 643 |
| 644 /** |
| 631 * @param {string} inputText | 645 * @param {string} inputText |
| 632 * @param {function(!Selection)|string} | 646 * @param {function(!Selection)|string} |
| 633 * @param {string} expectedText | 647 * @param {string} expectedText |
| 634 * @param {string=} opt_description | 648 * @param {string=} opt_description |
| 635 */ | 649 */ |
| 636 function assertSelection( | 650 function assertSelection( |
| 637 inputText, tester, expectedText, opt_description = '') { | 651 inputText, tester, expectedText, opt_description = '') { |
| 638 /** @type {string} */ | 652 /** @type {string} */ |
| 639 const description = | 653 const description = |
| 640 opt_description === '' ? assembleDescription() : opt_description; | 654 opt_description === '' ? assembleDescription() : opt_description; |
| 641 checkExpectedText(expectedText); | 655 checkExpectedText(expectedText); |
| 642 const sample = new Sample(inputText); | 656 const sample = new Sample(inputText); |
| 643 if (typeof(tester) === 'function') { | 657 if (typeof(tester) === 'function') { |
| 644 tester.call(window, sample.selection); | 658 tester.call(window, sample.selection); |
| 645 } else if (typeof(tester) === 'string') { | 659 } else if (typeof(tester) === 'string') { |
| 646 const strings = tester.split(' '); | 660 const strings = tester.split(' '); |
| 647 sample.document.execCommand(strings[0], false, strings[1]); | 661 sample.document.execCommand(strings[0], false, strings[1]); |
| 648 } else { | 662 } else { |
| 649 throw new Error(`Invalid tester: ${tester}`); | 663 throw new Error(`Invalid tester: ${tester}`); |
| 650 } | 664 } |
| 651 /** @type {string} */ | 665 /** @type {string} */ |
| 652 const actualText = sample.serialize(); | 666 const actualText = sample.serialize(); |
| 653 // We keep sample HTML when assertion is false for ease of debugging test | 667 // We keep sample HTML when assertion is false for ease of debugging test |
| 654 // case. | 668 // case. |
| 655 if (actualText === expectedText) | 669 if (actualText === expectedText) { |
| 656 sample.remove(); | 670 sample.remove(); |
| 657 assert_equals(actualText, expectedText, description); | 671 return; |
| 672 } |
| 673 throw new Error(`${description}\n` + |
| 674 `\t expected ${expectedText},\n` + |
| 675 `\t but got ${actualText},\n` + |
| 676 `\t sameupto ${commonPrefixOf(expectedText, actualText)}`); |
| 658 } | 677 } |
| 659 | 678 |
| 660 // Export symbols | 679 // Export symbols |
| 661 window.Sample = Sample; | 680 window.Sample = Sample; |
| 662 window.assert_selection = assertSelection; | 681 window.assert_selection = assertSelection; |
| 663 })(); | 682 })(); |
| OLD | NEW |