123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457 |
- // 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.PlainTextSpellCheckerTest');
- goog.setTestOnly('goog.ui.PlainTextSpellCheckerTest');
- goog.require('goog.Timer');
- goog.require('goog.dom');
- goog.require('goog.events.KeyCodes');
- goog.require('goog.spell.SpellCheck');
- goog.require('goog.testing.events');
- goog.require('goog.testing.jsunit');
- goog.require('goog.ui.PlainTextSpellChecker');
- var missspelling = 'missspelling';
- var iggnore = 'iggnore';
- var vocabulary = ['test', 'words', 'a', 'few', missspelling, iggnore];
- // We don't use Math.random() to make test predictable. Math.random is not
- // repeatable, so a success on the dev machine != success in the lab (or on
- // other dev machines). This is the same pseudorandom logic that CRT rand()
- // uses.
- var rseed = 1;
- function random(range) {
- rseed = (rseed * 1103515245 + 12345) & 0xffffffff;
- return ((rseed >> 16) & 0x7fff) % range;
- }
- 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;
- // Last two words are considered misspellings
- for (var j = 0; j < vocabulary.length - 2; ++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, ['foo', 'bar']]);
- }
- }
- callback.call(spellChecker, results);
- }
- function generateRandomSpace() {
- var string = '';
- var nSpace = 1 + random(4);
- for (var i = 0; i < nSpace; ++i) {
- string += ' ';
- }
- return string;
- }
- function generateRandomString(maxWords, doQuotes) {
- var x = random(10);
- var string = '';
- if (doQuotes) {
- if (x == 0) {
- string = 'On xxxxx yyyy wrote:\n> ';
- } else if (x < 3) {
- string = '> ';
- }
- }
- var nWords = 1 + random(maxWords);
- for (var i = 0; i < nWords; ++i) {
- string += vocabulary[random(vocabulary.length)];
- string += generateRandomSpace();
- }
- return string;
- }
- var timerQueue = [];
- function processTimerQueue() {
- while (timerQueue.length > 0) {
- var fn = timerQueue.shift();
- fn();
- }
- }
- function localTimer(fn, delay, obj) {
- if (obj) {
- fn = goog.bind(fn, obj);
- }
- timerQueue.push(fn);
- return timerQueue.length;
- }
- function testPlainTextSpellCheckerNoQuotes() {
- var handler = new goog.spell.SpellCheck(localSpellCheckingFunction);
- var s = new goog.ui.PlainTextSpellChecker(handler);
- s.asyncWordsPerBatch_ = 100;
- var el = document.getElementById('test1');
- s.decorate(el);
- var text = '';
- for (var i = 0; i < 10; ++i) {
- text += generateRandomString(10, false) + '\n';
- }
- el.value = text;
- // Yes this looks bizarre. This is for '\n' processing.
- // They get converted to CRLF as part of the above statement.
- text = el.value;
- var timerSav = goog.Timer.callOnce;
- goog.Timer.callOnce = localTimer;
- s.check();
- processTimerQueue();
- s.ignoreWord(iggnore);
- processTimerQueue();
- s.check();
- processTimerQueue();
- s.resume();
- processTimerQueue();
- goog.Timer.callOnce = timerSav;
- assertEquals(
- 'Spell checker run should not change the underlying element.', text,
- el.value);
- s.dispose();
- }
- function testPlainTextSpellCheckerWithQuotes() {
- var handler = new goog.spell.SpellCheck(localSpellCheckingFunction);
- var s = new goog.ui.PlainTextSpellChecker(handler);
- s.asyncWordsPerBatch_ = 100;
- var el = document.getElementById('test2');
- s.decorate(el);
- var text = '';
- for (var i = 0; i < 10; ++i) {
- text += generateRandomString(10, true) + '\n';
- }
- el.value = text;
- // Yes this looks bizarre. This is for '\n' processing.
- // They get converted to CRLF as part of the above statement.
- text = el.value;
- var timerSav = goog.Timer.callOnce;
- goog.Timer.callOnce = localTimer;
- s.setExcludeMarker(new RegExp('\nOn .* wrote:\n(> .*\n)+|\n(> .*\n)', 'g'));
- s.check();
- processTimerQueue();
- s.ignoreWord(iggnore);
- processTimerQueue();
- s.check();
- processTimerQueue();
- s.resume();
- processTimerQueue();
- goog.Timer.callOnce = timerSav;
- assertEquals(
- 'Spell checker run should not change the underlying element.', text,
- el.value);
- s.dispose();
- }
- function testPlainTextSpellCheckerWordReplacement() {
- var handler = new goog.spell.SpellCheck(localSpellCheckingFunction);
- var s = new goog.ui.PlainTextSpellChecker(handler);
- s.asyncWordsPerBatch_ = 100;
- var el = document.getElementById('test3');
- s.decorate(el);
- var text = '';
- for (var i = 0; i < 10; ++i) {
- text += generateRandomString(10, false) + '\n';
- }
- el.value = text;
- var timerSav = goog.Timer.callOnce;
- goog.Timer.callOnce = localTimer;
- s.check();
- processTimerQueue();
- var container = s.overlay_;
- var wordEl = container.firstChild;
- while (wordEl) {
- if (goog.dom.getTextContent(wordEl) == missspelling) {
- break;
- }
- wordEl = wordEl.nextSibling;
- }
- if (!wordEl) {
- assertTrue(
- 'Cannot find the world that should have been here.' +
- 'Please revise the test',
- false);
- return;
- }
- s.activeWord_ = missspelling;
- s.activeElement_ = wordEl;
- var suggestions = s.getSuggestions_();
- s.replaceWord(wordEl, missspelling, 'foo');
- assertEquals(
- 'Should have set the original word attribute!',
- wordEl.getAttribute(goog.ui.AbstractSpellChecker.ORIGINAL_),
- missspelling);
- s.activeWord_ = goog.dom.getTextContent(wordEl);
- s.activeElement_ = wordEl;
- var newSuggestions = s.getSuggestions_();
- assertEquals(
- 'Suggestion list should still be present even if the word ' +
- 'is now correct!',
- suggestions, newSuggestions);
- s.resume();
- processTimerQueue();
- goog.Timer.callOnce = timerSav;
- s.dispose();
- }
- function testPlainTextSpellCheckerKeyboardNavigateNext() {
- var handler = new goog.spell.SpellCheck(localSpellCheckingFunction);
- var s = new goog.ui.PlainTextSpellChecker(handler);
- var el = document.getElementById('test4');
- s.decorate(el);
- var text = 'a unit test for keyboard test';
- el.value = text;
- var keyEventProperties = {};
- keyEventProperties.ctrlKey = true;
- keyEventProperties.shiftKey = false;
- var timerSav = goog.Timer.callOnce;
- goog.Timer.callOnce = localTimer;
- s.check();
- processTimerQueue();
- var container = s.overlay_;
- // First call just moves focus to first misspelled word.
- goog.testing.events.fireKeySequence(
- container, goog.events.KeyCodes.RIGHT, keyEventProperties);
- // Test moving from first to second misspelled word.
- var defaultExecuted = goog.testing.events.fireKeySequence(
- container, goog.events.KeyCodes.RIGHT, keyEventProperties);
- assertFalse(
- 'The default action should be prevented for the key event',
- defaultExecuted);
- assertEquals(
- 'The second misspelled word should have focus.', document.activeElement,
- container.children[1]);
- s.resume();
- processTimerQueue();
- goog.Timer.callOnce = timerSav;
- s.dispose();
- }
- function testPlainTextSpellCheckerKeyboardNavigateNextOnLastWord() {
- var handler = new goog.spell.SpellCheck(localSpellCheckingFunction);
- var s = new goog.ui.PlainTextSpellChecker(handler);
- var el = document.getElementById('test5');
- s.decorate(el);
- var text = 'a unit test for keyboard test';
- el.value = text;
- var keyEventProperties = {};
- keyEventProperties.ctrlKey = true;
- keyEventProperties.shiftKey = false;
- var timerSav = goog.Timer.callOnce;
- goog.Timer.callOnce = localTimer;
- s.check();
- processTimerQueue();
- var container = s.overlay_;
- // First call just moves focus to first misspelled word.
- goog.testing.events.fireKeySequence(
- container, goog.events.KeyCodes.RIGHT, keyEventProperties);
- goog.testing.events.fireKeySequence(
- container, goog.events.KeyCodes.RIGHT, keyEventProperties);
- goog.testing.events.fireKeySequence(
- container, goog.events.KeyCodes.RIGHT, keyEventProperties);
- // Test moving to the next invalid word.
- var defaultExecuted = goog.testing.events.fireKeySequence(
- container, goog.events.KeyCodes.RIGHT, keyEventProperties);
- assertFalse(
- 'The default action should be prevented for the key event',
- defaultExecuted);
- assertEquals(
- 'The third/last misspelled word should have focus.',
- document.activeElement, container.children[2]);
- s.resume();
- processTimerQueue();
- goog.Timer.callOnce = timerSav;
- s.dispose();
- }
- function testPlainTextSpellCheckerKeyboardNavigateOpenSuggestions() {
- var handler = new goog.spell.SpellCheck(localSpellCheckingFunction);
- var s = new goog.ui.PlainTextSpellChecker(handler);
- var el = document.getElementById('test6');
- s.decorate(el);
- var text = 'unit';
- el.value = text;
- var keyEventProperties = {};
- keyEventProperties.ctrlKey = true;
- keyEventProperties.shiftKey = false;
- var timerSav = goog.Timer.callOnce;
- goog.Timer.callOnce = localTimer;
- s.check();
- processTimerQueue();
- var container = s.overlay_;
- var suggestionMenu = s.getMenu();
- goog.testing.events.fireKeySequence(
- container, 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(
- container, 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());
- s.resume();
- processTimerQueue();
- goog.Timer.callOnce = timerSav;
- s.dispose();
- }
- function testPlainTextSpellCheckerKeyboardNavigatePrevious() {
- var handler = new goog.spell.SpellCheck(localSpellCheckingFunction);
- var s = new goog.ui.PlainTextSpellChecker(handler);
- var el = document.getElementById('test7');
- s.decorate(el);
- var text = 'a unit test for keyboard test';
- el.value = text;
- var keyEventProperties = {};
- keyEventProperties.ctrlKey = true;
- keyEventProperties.shiftKey = false;
- var timerSav = goog.Timer.callOnce;
- goog.Timer.callOnce = localTimer;
- s.check();
- processTimerQueue();
- var container = s.overlay_;
- // Move to the third element, so we can test the move back to the second.
- goog.testing.events.fireKeySequence(
- container, goog.events.KeyCodes.RIGHT, keyEventProperties);
- goog.testing.events.fireKeySequence(
- container, goog.events.KeyCodes.RIGHT, keyEventProperties);
- goog.testing.events.fireKeySequence(
- container, goog.events.KeyCodes.RIGHT, keyEventProperties);
- // Test moving from third to second misspelled word.
- var defaultExecuted = goog.testing.events.fireKeySequence(
- container, goog.events.KeyCodes.LEFT, keyEventProperties);
- assertFalse(
- 'The default action should be prevented for the key event',
- defaultExecuted);
- assertEquals(
- 'The second misspelled word should have focus.', document.activeElement,
- container.children[1]);
- s.resume();
- processTimerQueue();
- goog.Timer.callOnce = timerSav;
- s.dispose();
- }
- function testPlainTextSpellCheckerKeyboardNavigatePreviousOnFirstWord() {
- var handler = new goog.spell.SpellCheck(localSpellCheckingFunction);
- var s = new goog.ui.PlainTextSpellChecker(handler);
- var el = document.getElementById('test8');
- s.decorate(el);
- var text = 'a unit test for keyboard test';
- el.value = text;
- var keyEventProperties = {};
- keyEventProperties.ctrlKey = true;
- keyEventProperties.shiftKey = false;
- var timerSav = goog.Timer.callOnce;
- goog.Timer.callOnce = localTimer;
- s.check();
- processTimerQueue();
- var container = s.overlay_;
- // Move to the first invalid word.
- goog.testing.events.fireKeySequence(
- container, goog.events.KeyCodes.RIGHT, keyEventProperties);
- // Test moving to the previous invalid word.
- var defaultExecuted = goog.testing.events.fireKeySequence(
- container, goog.events.KeyCodes.LEFT, keyEventProperties);
- assertFalse(
- 'The default action should be prevented for the key event',
- defaultExecuted);
- assertEquals(
- 'The first misspelled word should have focus.', document.activeElement,
- container.children[0]);
- s.resume();
- processTimerQueue();
- goog.Timer.callOnce = timerSav;
- s.dispose();
- }
|