Adding mapbox-gl branch
This commit is contained in:
@@ -0,0 +1,367 @@
|
||||
// Copyright 2007 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
goog.provide('goog.ui.RichTextSpellCheckerTest');
|
||||
goog.setTestOnly('goog.ui.RichTextSpellCheckerTest');
|
||||
|
||||
goog.require('goog.dom.Range');
|
||||
goog.require('goog.dom.classlist');
|
||||
goog.require('goog.events.KeyCodes');
|
||||
goog.require('goog.object');
|
||||
goog.require('goog.spell.SpellCheck');
|
||||
goog.require('goog.testing.MockClock');
|
||||
goog.require('goog.testing.events');
|
||||
goog.require('goog.testing.jsunit');
|
||||
goog.require('goog.ui.RichTextSpellChecker');
|
||||
|
||||
var VOCABULARY = ['test', 'words', 'a', 'few'];
|
||||
var SUGGESTIONS = ['foo', 'bar'];
|
||||
var EXCLUDED_DATA = ['DIV.goog-quote', 'goog-comment', 'SPAN.goog-note'];
|
||||
|
||||
|
||||
/**
|
||||
* Delay in ms needed for the spell check word lookup to finish. Finishing the
|
||||
* lookup also finishes the spell checking.
|
||||
* @see goog.spell.SpellCheck.LOOKUP_DELAY_
|
||||
*/
|
||||
var SPELL_CHECK_LOOKUP_DELAY = 100;
|
||||
|
||||
var TEST_TEXT1 = 'this test is longer than a few words now';
|
||||
var TEST_TEXT2 = 'test another simple text with misspelled words';
|
||||
var TEST_TEXT3 = 'test another simple text with misspelled words' +
|
||||
'<b class="goog-quote">test another simple text with misspelled words<u> ' +
|
||||
'test another simple text with misspelled words<del class="goog-quote"> ' +
|
||||
'test another simple text with misspelled words<i>this test is longer ' +
|
||||
'than a few words now</i>test another simple text with misspelled words ' +
|
||||
'<i>this test is longer than a few words now</i></del>test another ' +
|
||||
'simple text with misspelled words<del class="goog-quote">test another ' +
|
||||
'simple text with misspelled words<i>this test is longer than a few ' +
|
||||
'words now</i>test another simple text with misspelled words<i>this test ' +
|
||||
'is longer than a few words now</i></del></u>test another simple text ' +
|
||||
'with misspelled words<u>test another simple text with misspelled words' +
|
||||
'<del class="goog-quote">test another simple text with misspelled words' +
|
||||
'<i> thistest is longer than a few words now</i>test another simple text ' +
|
||||
'with misspelled words<i>this test is longer than a few words ' +
|
||||
'now</i></del>test another simple text with misspelled words' +
|
||||
'<del class="goog-quote">test another simple text with misspelled words' +
|
||||
'<i>this test is longer than a few words now</i>test another simple text ' +
|
||||
'with misspelled words<i>this test is longer than a few words ' +
|
||||
'now</i></del></u></b>';
|
||||
|
||||
var spellChecker;
|
||||
var handler;
|
||||
var mockClock;
|
||||
|
||||
function setUp() {
|
||||
mockClock = new goog.testing.MockClock(true /* install */);
|
||||
handler = new goog.spell.SpellCheck(localSpellCheckingFunction);
|
||||
spellChecker = new goog.ui.RichTextSpellChecker(handler);
|
||||
}
|
||||
|
||||
function tearDown() {
|
||||
spellChecker.dispose();
|
||||
handler.dispose();
|
||||
mockClock.dispose();
|
||||
}
|
||||
|
||||
function waitForSpellCheckToFinish() {
|
||||
mockClock.tick(SPELL_CHECK_LOOKUP_DELAY);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {!Array<string><string>>}
|
||||
* @suppress {missingProvide}
|
||||
*/
|
||||
var lookupWordEntry;
|
||||
|
||||
|
||||
/**
|
||||
* Function to use for word lookup by the spell check handler. This function is
|
||||
* supplied as a constructor parameter for the spell check handler.
|
||||
* @param {!Array<string>} words Unknown words that need to be looked up.
|
||||
* @param {!goog.spell.SpellCheck} spellChecker The spell check handler.
|
||||
* @param {function(!Array.)} callback The lookup callback
|
||||
* function.
|
||||
*/
|
||||
function localSpellCheckingFunction(words, spellChecker, callback) {
|
||||
var len = words.length;
|
||||
var results = [];
|
||||
for (var i = 0; i < len; i++) {
|
||||
var word = words[i];
|
||||
var found = false;
|
||||
for (var j = 0; j < VOCABULARY.length; ++j) {
|
||||
if (VOCABULARY[j] == word) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
results.push([word, goog.spell.SpellCheck.WordStatus.VALID]);
|
||||
} else {
|
||||
results.push([word, goog.spell.SpellCheck.WordStatus.INVALID,
|
||||
SUGGESTIONS]);
|
||||
}
|
||||
}
|
||||
callback.call(spellChecker, results);
|
||||
}
|
||||
|
||||
function testDocumentIntegrity() {
|
||||
var el = document.getElementById('test1');
|
||||
spellChecker.decorate(el);
|
||||
el.appendChild(document.createTextNode(TEST_TEXT3));
|
||||
var el2 = el.cloneNode(true);
|
||||
|
||||
spellChecker.setExcludeMarker('goog-quote');
|
||||
spellChecker.check();
|
||||
waitForSpellCheckToFinish();
|
||||
spellChecker.ignoreWord('iggnore');
|
||||
waitForSpellCheckToFinish();
|
||||
spellChecker.check();
|
||||
waitForSpellCheckToFinish();
|
||||
spellChecker.resume();
|
||||
waitForSpellCheckToFinish();
|
||||
|
||||
assertEquals('Spell checker run should not change the underlying element.',
|
||||
el2.innerHTML, el.innerHTML);
|
||||
}
|
||||
|
||||
function testExcludeMarkers() {
|
||||
var el = document.getElementById('test1');
|
||||
spellChecker.decorate(el);
|
||||
spellChecker.setExcludeMarker(
|
||||
['DIV.goog-quote', 'goog-comment', 'SPAN.goog-note']);
|
||||
assertArrayEquals(['goog-quote', 'goog-comment', 'goog-note'],
|
||||
spellChecker.excludeMarker);
|
||||
assertArrayEquals(['DIV', undefined, 'SPAN'],
|
||||
spellChecker.excludeTags);
|
||||
el.innerHTML = '<div class="goog-quote">misspelling</div>' +
|
||||
'<div class="goog-yes">misspelling</div>' +
|
||||
'<div class="goog-note">misspelling</div>' +
|
||||
'<div class="goog-comment">misspelling</div>' +
|
||||
'<span>misspelling<span>';
|
||||
|
||||
spellChecker.check();
|
||||
waitForSpellCheckToFinish();
|
||||
assertEquals(3, spellChecker.getLastIndex());
|
||||
}
|
||||
|
||||
function testBiggerDocument() {
|
||||
var el = document.getElementById('test2');
|
||||
spellChecker.decorate(el);
|
||||
el.appendChild(document.createTextNode(TEST_TEXT3));
|
||||
var el2 = el.cloneNode(true);
|
||||
|
||||
spellChecker.check();
|
||||
waitForSpellCheckToFinish();
|
||||
spellChecker.resume();
|
||||
waitForSpellCheckToFinish();
|
||||
|
||||
assertEquals('Spell checker run should not change the underlying element.',
|
||||
el2.innerHTML, el.innerHTML);
|
||||
}
|
||||
|
||||
function testElementOverflow() {
|
||||
var el = document.getElementById('test3');
|
||||
spellChecker.decorate(el);
|
||||
el.appendChild(document.createTextNode(TEST_TEXT3));
|
||||
|
||||
var el2 = el.cloneNode(true);
|
||||
|
||||
spellChecker.check();
|
||||
waitForSpellCheckToFinish();
|
||||
spellChecker.check();
|
||||
waitForSpellCheckToFinish();
|
||||
spellChecker.resume();
|
||||
waitForSpellCheckToFinish();
|
||||
|
||||
assertEquals('Spell checker run should not change the underlying element.',
|
||||
el2.innerHTML, el.innerHTML);
|
||||
}
|
||||
|
||||
function testKeyboardNavigateNext() {
|
||||
var el = document.getElementById('test4');
|
||||
spellChecker.decorate(el);
|
||||
var text = 'a unit test for keyboard test';
|
||||
el.appendChild(document.createTextNode(text));
|
||||
var keyEventProperties =
|
||||
goog.object.create('ctrlKey', true, 'shiftKey', false);
|
||||
|
||||
spellChecker.check();
|
||||
waitForSpellCheckToFinish();
|
||||
|
||||
// First call just moves focus to first misspelled word.
|
||||
goog.testing.events.fireKeySequence(el, goog.events.KeyCodes.RIGHT,
|
||||
keyEventProperties);
|
||||
|
||||
// Test moving from first to second mispelled word.
|
||||
var defaultExecuted = goog.testing.events.fireKeySequence(el,
|
||||
goog.events.KeyCodes.RIGHT, keyEventProperties);
|
||||
|
||||
assertFalse('The default action should be prevented for the key event',
|
||||
defaultExecuted);
|
||||
assertCursorAtElement(spellChecker.makeElementId(2));
|
||||
|
||||
spellChecker.resume();
|
||||
}
|
||||
|
||||
function testKeyboardNavigateNextOnLastWord() {
|
||||
var el = document.getElementById('test5');
|
||||
spellChecker.decorate(el);
|
||||
var text = 'a unit test for keyboard test';
|
||||
el.appendChild(document.createTextNode(text));
|
||||
var keyEventProperties =
|
||||
goog.object.create('ctrlKey', true, 'shiftKey', false);
|
||||
|
||||
spellChecker.check();
|
||||
waitForSpellCheckToFinish();
|
||||
|
||||
// Move to the last invalid word.
|
||||
goog.testing.events.fireKeySequence(el, goog.events.KeyCodes.RIGHT,
|
||||
keyEventProperties);
|
||||
goog.testing.events.fireKeySequence(el, goog.events.KeyCodes.RIGHT,
|
||||
keyEventProperties);
|
||||
goog.testing.events.fireKeySequence(el, goog.events.KeyCodes.RIGHT,
|
||||
keyEventProperties);
|
||||
|
||||
// Test moving to the next invalid word. Should have no effect.
|
||||
var defaultExecuted = goog.testing.events.fireKeySequence(el,
|
||||
goog.events.KeyCodes.RIGHT, keyEventProperties);
|
||||
|
||||
assertFalse('The default action should be prevented for the key event',
|
||||
defaultExecuted);
|
||||
assertCursorAtElement(spellChecker.makeElementId(3));
|
||||
|
||||
spellChecker.resume();
|
||||
}
|
||||
|
||||
function testKeyboardNavigateOpenSuggestions() {
|
||||
var el = document.getElementById('test6');
|
||||
spellChecker.decorate(el);
|
||||
var text = 'unit';
|
||||
el.appendChild(document.createTextNode(text));
|
||||
var keyEventProperties =
|
||||
goog.object.create('ctrlKey', true, 'shiftKey', false);
|
||||
|
||||
spellChecker.check();
|
||||
waitForSpellCheckToFinish();
|
||||
|
||||
var suggestionMenu = spellChecker.getMenu();
|
||||
|
||||
goog.testing.events.fireKeySequence(el, goog.events.KeyCodes.RIGHT,
|
||||
keyEventProperties);
|
||||
|
||||
assertFalse('The suggestion menu should not be visible yet.',
|
||||
suggestionMenu.isVisible());
|
||||
|
||||
keyEventProperties.ctrlKey = false;
|
||||
var defaultExecuted = goog.testing.events.fireKeySequence(el,
|
||||
goog.events.KeyCodes.DOWN, keyEventProperties);
|
||||
|
||||
assertFalse('The default action should be prevented for the key event',
|
||||
defaultExecuted);
|
||||
assertTrue('The suggestion menu should be visible after the key event.',
|
||||
suggestionMenu.isVisible());
|
||||
|
||||
spellChecker.resume();
|
||||
}
|
||||
|
||||
function testKeyboardNavigatePrevious() {
|
||||
var el = document.getElementById('test7');
|
||||
spellChecker.decorate(el);
|
||||
var text = 'a unit test for keyboard test';
|
||||
el.appendChild(document.createTextNode(text));
|
||||
var keyEventProperties =
|
||||
goog.object.create('ctrlKey', true, 'shiftKey', false);
|
||||
|
||||
spellChecker.check();
|
||||
waitForSpellCheckToFinish();
|
||||
|
||||
// Move to the third element, so we can test the move back to the second.
|
||||
goog.testing.events.fireKeySequence(el, goog.events.KeyCodes.RIGHT,
|
||||
keyEventProperties);
|
||||
goog.testing.events.fireKeySequence(el, goog.events.KeyCodes.RIGHT,
|
||||
keyEventProperties);
|
||||
goog.testing.events.fireKeySequence(el, goog.events.KeyCodes.RIGHT,
|
||||
keyEventProperties);
|
||||
|
||||
var defaultExecuted = goog.testing.events.fireKeySequence(el,
|
||||
goog.events.KeyCodes.LEFT, keyEventProperties);
|
||||
|
||||
assertFalse('The default action should be prevented for the key event',
|
||||
defaultExecuted);
|
||||
assertCursorAtElement(spellChecker.makeElementId(2));
|
||||
|
||||
spellChecker.resume();
|
||||
}
|
||||
|
||||
function testKeyboardNavigatePreviousOnLastWord() {
|
||||
var el = document.getElementById('test8');
|
||||
spellChecker.decorate(el);
|
||||
var text = 'a unit test for keyboard test';
|
||||
el.appendChild(document.createTextNode(text));
|
||||
var keyEventProperties =
|
||||
goog.object.create('ctrlKey', true, 'shiftKey', false);
|
||||
|
||||
spellChecker.check();
|
||||
waitForSpellCheckToFinish();
|
||||
|
||||
// Move to the first invalid word.
|
||||
goog.testing.events.fireKeySequence(el, goog.events.KeyCodes.RIGHT,
|
||||
keyEventProperties);
|
||||
|
||||
// Test moving to the previous invalid word. Should have no effect.
|
||||
var defaultExecuted = goog.testing.events.fireKeySequence(el,
|
||||
goog.events.KeyCodes.LEFT, keyEventProperties);
|
||||
|
||||
assertFalse('The default action should be prevented for the key event',
|
||||
defaultExecuted);
|
||||
assertCursorAtElement(spellChecker.makeElementId(1));
|
||||
|
||||
spellChecker.resume();
|
||||
}
|
||||
|
||||
function assertCursorAtElement(expectedId) {
|
||||
var range = goog.dom.Range.createFromWindow();
|
||||
|
||||
if (isCaret(range)) {
|
||||
if (isMisspelledWordElement(range.getStartNode())) {
|
||||
var focusedElementId = range.getStartNode().id;
|
||||
}
|
||||
|
||||
// In Chrome a cursor at the start of a misspelled word will appear to be at
|
||||
// the end of the text node preceding it.
|
||||
if (isCursorAtEndOfStartNode(range) &&
|
||||
range.getStartNode().nextSibling != null &&
|
||||
isMisspelledWordElement(range.getStartNode().nextSibling)) {
|
||||
var focusedElementId = range.getStartNode().nextSibling.id;
|
||||
}
|
||||
}
|
||||
|
||||
assertEquals('The cursor is not at the expected misspelled word.',
|
||||
expectedId, focusedElementId);
|
||||
}
|
||||
|
||||
function isCaret(range) {
|
||||
return range.getStartNode() == range.getEndNode();
|
||||
}
|
||||
|
||||
function isMisspelledWordElement(element) {
|
||||
return goog.dom.classlist.contains(
|
||||
element, 'goog-spellcheck-word');
|
||||
}
|
||||
|
||||
function isCursorAtEndOfStartNode(range) {
|
||||
return range.getStartNode().length == range.getStartOffset();
|
||||
}
|
||||
Reference in New Issue
Block a user