blob: 359a255d00e95f3aa1c46389fd94fe26d84f387c [file] [log] [blame]
// Copyright 2006 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.ac.AutoCompleteTest');
goog.setTestOnly('goog.ui.ac.AutoCompleteTest');
goog.require('goog.a11y.aria');
goog.require('goog.a11y.aria.Role');
goog.require('goog.dom');
goog.require('goog.events.EventHandler');
goog.require('goog.events.EventTarget');
goog.require('goog.string');
goog.require('goog.testing.MockControl');
goog.require('goog.testing.events');
goog.require('goog.testing.jsunit');
goog.require('goog.testing.mockmatchers');
goog.require('goog.ui.ac.AutoComplete');
goog.require('goog.ui.ac.InputHandler');
goog.require('goog.ui.ac.RenderOptions');
goog.require('goog.ui.ac.Renderer');
/**
* Mock DataStore
* @constructor
*/
function MockDS(opt_autoHilite) {
this.autoHilite_ = opt_autoHilite;
var disabledRow = {
match: function(str) {return this.text.match(str);},
rowDisabled: true,
text: 'hello@u.edu'
};
this.rows_ = [
'"Slartibartfast Theadore" <fjordmaster@magrathea.com>',
'"Zaphod Beeblebrox" <theprez@universe.gov>',
'"Ford Prefect" <ford@theguide.com>',
'"Arthur Dent" <has.no.tea@gmail.com>',
'"Marvin The Paranoid Android" <marv@googlemail.com>',
'the.mice@magrathea.com',
'the.mice@myotherdomain.com',
'hello@a.com',
disabledRow,
'row@u.edu',
'person@a.edu'
];
this.isRowDisabled = function(row) {
return !!row.rowDisabled;
};
}
MockDS.prototype.requestMatchingRows = function(token, maxMatches,
matchHandler) {
var escapedToken = goog.string.regExpEscape(token);
var matcher = new RegExp('(^|\\W+)' + escapedToken);
var matches = [];
for (var i = 0; i < this.rows_.length && matches.length < maxMatches; ++i) {
var row = this.rows_[i];
if (row.match(matcher)) {
matches.push(row);
}
}
if (this.autoHilite_ === undefined) {
matchHandler(token, matches);
} else {
var options = new goog.ui.ac.RenderOptions();
options.setAutoHilite(this.autoHilite_);
matchHandler(token, matches, options);
}
};
/**
* Mock Selection Handler
*/
function MockSelect() {
}
goog.inherits(MockSelect, goog.events.EventTarget);
MockSelect.prototype.selectRow = function(row) {
this.selectedRow = row;
};
/**
* Renderer subclass that exposes additional private members for testing.
* @constructor
*/
function TestRend() {
goog.ui.ac.Renderer.call(this, goog.dom.getElement('test-area'));
}
goog.inherits(TestRend, goog.ui.ac.Renderer);
TestRend.prototype.getRenderedRows = function() {
return this.rows_;
};
TestRend.prototype.getHilitedRowIndex = function() {
return this.hilitedRow_;
};
TestRend.prototype.getHilitedRowDiv = function() {
return this.rowDivs_[this.hilitedRow_];
};
TestRend.prototype.getRowDiv = function(index) {
return this.rowDivs_[index];
};
var handler;
var inputElement;
var mockControl;
function setUp() {
inputElement = goog.dom.createDom('input', {type: 'text'});
handler = new goog.events.EventHandler();
mockControl = new goog.testing.MockControl();
}
function tearDown() {
handler.dispose();
mockControl.$tearDown();
goog.dom.removeChildren(goog.dom.getElement('test-area'));
}
/**
* Make sure results are truncated (or not) by setMaxMatches.
*/
function testMaxMatches() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
ac.setMaxMatches(2);
ac.setToken('the');
assertEquals(2, rend.getRenderedRows().length);
ac.setToken('');
ac.setMaxMatches(3);
ac.setToken('the');
assertEquals(3, rend.getRenderedRows().length);
ac.setToken('');
ac.setMaxMatches(1000);
ac.setToken('the');
assertEquals(4, rend.getRenderedRows().length);
ac.setToken('');
}
function testHiliteViaMouse() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var updates = 0;
var row = null;
var rowNode = null;
handler.listen(rend,
goog.ui.ac.AutoComplete.EventType.ROW_HILITE,
function(evt) {
updates++;
rowNode = evt.rowNode;
});
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
ac.setMaxMatches(4);
ac.setToken('the');
// Need to set the startRenderingRows_ time to something long ago, otherwise
// the mouse event will not be fired. (The autocomplete logic waits for some
// time to pass after rendering before firing mouseover events.)
rend.startRenderingRows_ = -1;
var hilitedRowDiv = rend.getRowDiv(3);
goog.testing.events.fireMouseOverEvent(hilitedRowDiv);
assertEquals(2, updates);
assertTrue(goog.string.contains(rowNode.innerHTML, 'mice@myotherdomain.com'));
}
function testMouseClickBeforeHilite() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
ac.setMaxMatches(4);
ac.setToken('the');
// Need to set the startRenderingRows_ time to something long ago, otherwise
// the mouse event will not be fired. (The autocomplete logic waits for some
// time to pass after rendering before firing mouseover events.)
rend.startRenderingRows_ = -1;
// hilite row 3...
var hilitedRowDiv = rend.getRowDiv(3);
goog.testing.events.fireMouseOverEvent(hilitedRowDiv);
// but click row 2, to simulate mouse getting ahead of focus.
var targetRowDiv = rend.getRowDiv(2);
goog.testing.events.fireClickEvent(targetRowDiv);
assertEquals('the.mice@magrathea.com', select.selectedRow);
}
function testMouseClickOnFirstRowBeforeHilite() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
ac.setAutoHilite(false);
ac.setMaxMatches(4);
ac.setToken('the');
// Click the first row before highlighting it, to simulate mouse getting ahead
// of focus.
var targetRowDiv = rend.getRowDiv(0);
goog.testing.events.fireClickEvent(targetRowDiv);
assertEquals(
'"Zaphod Beeblebrox" <theprez@universe.gov>', select.selectedRow);
}
function testMouseClickOnRowAfterBlur() {
var ds = new MockDS();
var rend = new TestRend();
var ih = new goog.ui.ac.InputHandler();
ih.attachInput(inputElement);
var ac = new goog.ui.ac.AutoComplete(ds, rend, ih);
goog.testing.events.fireFocusEvent(inputElement);
ac.setToken('the');
var targetRowDiv = rend.getRowDiv(0);
// Simulate the user clicking on an autocomplete row in the short time between
// blur and autocomplete dismissal.
goog.testing.events.fireBlurEvent(inputElement);
assertNotThrows(function() {
goog.testing.events.fireClickEvent(targetRowDiv);
});
}
/*
* Send AutoComplete a SELECT event with empty string for the row. We can't
* simulate with a simple mouse click, so we dispatch the event directly.
*/
function testSelectEventEmptyRow() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
ac.setMaxMatches(4);
ac.setToken('the');
rend.startRenderingRows_ = -1;
// hilight row 2 ('the.mice@...')
var hilitedRowDiv = rend.getRowDiv(2);
goog.testing.events.fireMouseOverEvent(hilitedRowDiv);
assertUndefined(select.selectedRow);
// Dispatch an event that does not specify a row.
rend.dispatchEvent({
type: goog.ui.ac.AutoComplete.EventType.SELECT,
row: ''
});
assertEquals('the.mice@magrathea.com', select.selectedRow);
}
function testSuggestionsUpdateEvent() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
var updates = 0;
handler.listen(ac,
goog.ui.ac.AutoComplete.EventType.SUGGESTIONS_UPDATE,
function() {
updates++;
});
ac.setToken('the');
assertEquals(1, updates);
ac.setToken('beeb');
assertEquals(2, updates);
ac.setToken('ford');
assertEquals(3, updates);
ac.dismiss();
assertEquals(4, updates);
ac.setToken('dent');
assertEquals(5, updates);
}
function checkHilitedIndex(renderer, index) {
assertEquals(index, renderer.getHilitedRowIndex());
}
function testGetRowCount() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
assertEquals(0, ac.getRowCount());
ac.setToken('Zaphod');
assertEquals(1, ac.getRowCount());
ac.setMaxMatches(2);
ac.setToken('the');
assertEquals(2, ac.getRowCount());
}
/**
* Try using next and prev to navigate past the ends with default behavior of
* allowFreeSelect_ and wrap_.
*/
function testHiliteNextPrev_default() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
var updates = 0;
handler.listen(rend,
goog.ui.ac.AutoComplete.EventType.ROW_HILITE,
function() {
updates++;
});
// make sure 'next' and 'prev' don't explode before any token is set
ac.hiliteNext();
ac.hilitePrev();
ac.setMaxMatches(4);
assertEquals(0, rend.getRenderedRows().length);
// check a few times
for (var i = 0; i < 3; ++i) {
ac.setToken('');
ac.setToken('the');
assertEquals(4, rend.getRenderedRows().length);
// check to see if we can select the last of the 4 items
checkHilitedIndex(rend, 0);
ac.hiliteNext();
checkHilitedIndex(rend, 1);
ac.hiliteNext();
checkHilitedIndex(rend, 2);
ac.hiliteNext();
checkHilitedIndex(rend, 3);
// try going over the edge
ac.hiliteNext();
checkHilitedIndex(rend, 3);
// go back down
ac.hilitePrev();
checkHilitedIndex(rend, 2);
ac.hilitePrev();
checkHilitedIndex(rend, 1);
ac.hilitePrev();
checkHilitedIndex(rend, 0);
ac.hilitePrev();
checkHilitedIndex(rend, 0);
}
// 21 changes in the loop above (3 * 7)
assertEquals(21, updates);
}
/**
* Try using next and prev to navigate past the ends with default behavior of
* allowFreeSelect_ and wrap_ and with a disabled first row.
*/
function testHiliteNextPrevWithDisabledFirstRow_default() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
var updates = 0;
handler.listen(rend,
goog.ui.ac.AutoComplete.EventType.ROW_HILITE,
function() {
updates++;
});
// make sure 'next' and 'prev' don't explode before any token is set
ac.hiliteNext();
ac.hilitePrev();
ac.setMaxMatches(3);
assertEquals(0, rend.getRenderedRows().length);
// check a few times with disabled first row
for (var i = 0; i < 3; ++i) {
ac.setToken('');
ac.setToken('edu');
assertEquals(3, rend.getRenderedRows().length);
// The first row is disabled, second should be highlighted.
checkHilitedIndex(rend, 1);
ac.hiliteNext();
checkHilitedIndex(rend, 2);
// try going over the edge
ac.hiliteNext();
checkHilitedIndex(rend, 2);
// go back down
ac.hilitePrev();
checkHilitedIndex(rend, 1);
// First row is disabled, make sure we don't highlight it.
ac.hilitePrev();
checkHilitedIndex(rend, 1);
}
// 9 changes in the loop above (3 * 3)
assertEquals(9, updates);
}
/**
* Try using next and prev to navigate past the ends with default behavior of
* allowFreeSelect_ and wrap_ and with a disabled middle row.
*/
function testHiliteNextPrevWithDisabledMiddleRow_default() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
var updates = 0;
handler.listen(rend,
goog.ui.ac.AutoComplete.EventType.ROW_HILITE,
function() {
updates++;
});
// make sure 'next' and 'prev' don't explode before any token is set
ac.hiliteNext();
ac.hilitePrev();
ac.setMaxMatches(3);
assertEquals(0, rend.getRenderedRows().length);
// check a few times with disabled middle row
for (var i = 0; i < 3; ++i) {
ac.setToken('');
ac.setToken('u');
assertEquals(3, rend.getRenderedRows().length);
checkHilitedIndex(rend, 0);
ac.hiliteNext();
// Second row is disabled and should be skipped.
checkHilitedIndex(rend, 2);
// try going over the edge
ac.hiliteNext();
checkHilitedIndex(rend, 2);
// go back down
ac.hilitePrev();
// Second row is disabled, make sure we don't highlight it.
checkHilitedIndex(rend, 0);
ac.hilitePrev();
checkHilitedIndex(rend, 0);
}
// 9 changes in the loop above (3 * 3)
assertEquals(9, updates);
}
/**
* Try using next and prev to navigate past the ends with default behavior of
* allowFreeSelect_ and wrap_ and with a disabled last row.
*/
function testHiliteNextPrevWithDisabledLastRow_default() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
var updates = 0;
handler.listen(rend,
goog.ui.ac.AutoComplete.EventType.ROW_HILITE,
function() {
updates++;
});
// make sure 'next' and 'prev' don't explode before any token is set
ac.hiliteNext();
ac.hilitePrev();
ac.setMaxMatches(3);
assertEquals(0, rend.getRenderedRows().length);
// check a few times with disabled last row
for (var i = 0; i < 3; ++i) {
ac.setToken('');
ac.setToken('h');
assertEquals(3, rend.getRenderedRows().length);
checkHilitedIndex(rend, 0);
ac.hiliteNext();
checkHilitedIndex(rend, 1);
// try going over the edge since last row is disabled
ac.hiliteNext();
checkHilitedIndex(rend, 1);
// go back down
ac.hilitePrev();
checkHilitedIndex(rend, 0);
ac.hilitePrev();
checkHilitedIndex(rend, 0);
}
// 9 changes in the loop above (3 * 3)
assertEquals(9, updates);
}
/**
* Try using next and prev to navigate past the ends with wrap_ off and
* allowFreeSelect_ on.
*/
function testHiliteNextPrev_allowFreeSelect() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
ac.setAllowFreeSelect(true);
// make sure 'next' and 'prev' don't explode before any token is set
ac.hiliteNext();
ac.hilitePrev();
ac.setMaxMatches(4);
assertEquals(0, rend.getRenderedRows().length);
// check a few times
for (var i = 0; i < 3; ++i) {
ac.setToken('');
ac.setToken('the');
assertEquals(4, rend.getRenderedRows().length);
// check to see if we can select the last of the 4 items
checkHilitedIndex(rend, 0);
ac.hiliteNext();
checkHilitedIndex(rend, 1);
ac.hiliteNext();
checkHilitedIndex(rend, 2);
ac.hiliteNext();
checkHilitedIndex(rend, 3);
// try going over the edge. Since allowFreeSelect is on, this will
// deselect the last row.
ac.hiliteNext();
checkHilitedIndex(rend, -1);
// go back down the list
ac.hiliteNext();
checkHilitedIndex(rend, 0);
ac.hiliteNext();
checkHilitedIndex(rend, 1);
// go back up the list.
ac.hilitePrev();
checkHilitedIndex(rend, 0);
// go back above the first, deselects first.
ac.hilitePrev();
checkHilitedIndex(rend, -1);
}
}
/**
* Try using next and prev to navigate past the ends with wrap_ off and
* allowFreeSelect_ on, and a disabled first row.
*/
function testHiliteNextPrevWithDisabledFirstRow_allowFreeSelect() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
ac.setAllowFreeSelect(true);
// make sure 'next' and 'prev' don't explode before any token is set
ac.hiliteNext();
ac.hilitePrev();
ac.setMaxMatches(4);
assertEquals(0, rend.getRenderedRows().length);
// check a few times with disabled first row
for (var i = 0; i < 3; ++i) {
ac.setToken('');
ac.setToken('edu');
assertEquals(3, rend.getRenderedRows().length);
// The first row is disabled, second should be highlighted.
checkHilitedIndex(rend, 1);
ac.hiliteNext();
checkHilitedIndex(rend, 2);
// Try going over the edge. Since allowFreeSelect is on, this will
// deselect the last row.
ac.hiliteNext();
checkHilitedIndex(rend, -1);
// go back down the list, first row is disabled
ac.hiliteNext();
checkHilitedIndex(rend, 1);
ac.hiliteNext();
checkHilitedIndex(rend, 2);
// go back up the list.
ac.hilitePrev();
checkHilitedIndex(rend, 1);
// first is disabled, so deselect the second.
ac.hilitePrev();
checkHilitedIndex(rend, -1);
}
}
/**
* Try using next and prev to navigate past the ends with wrap_ off and
* allowFreeSelect_ on, and a disabled middle row.
*/
function testHiliteNextPrevWithDisabledMiddleRow_allowFreeSelect() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
ac.setAllowFreeSelect(true);
// make sure 'next' and 'prev' don't explode before any token is set
ac.hiliteNext();
ac.hilitePrev();
ac.setMaxMatches(4);
assertEquals(0, rend.getRenderedRows().length);
// check a few times with disabled middle row
for (var i = 0; i < 3; ++i) {
ac.setToken('');
ac.setToken('u');
assertEquals(3, rend.getRenderedRows().length);
checkHilitedIndex(rend, 0);
ac.hiliteNext();
// Second row is disabled and should be skipped.
checkHilitedIndex(rend, 2);
// try going over the edge. Since allowFreeSelect is on, this will
// deselect the last row.
ac.hiliteNext();
checkHilitedIndex(rend, -1);
// go back down the list
ac.hiliteNext();
checkHilitedIndex(rend, 0);
ac.hiliteNext();
checkHilitedIndex(rend, 2);
// go back up the list.
ac.hilitePrev();
checkHilitedIndex(rend, 0);
// go back above the first, deselects first.
ac.hilitePrev();
checkHilitedIndex(rend, -1);
}
}
/**
* Try using next and prev to navigate past the ends with wrap_ off and
* allowFreeSelect_ on, and a disabled last row.
*/
function testHiliteNextPrevWithDisabledLastRow_allowFreeSelect() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
ac.setAllowFreeSelect(true);
// make sure 'next' and 'prev' don't explode before any token is set
ac.hiliteNext();
ac.hilitePrev();
ac.setMaxMatches(4);
assertEquals(0, rend.getRenderedRows().length);
// check a few times with disabled last row
for (var i = 0; i < 3; ++i) {
ac.setToken('');
ac.setToken('h');
assertEquals(3, rend.getRenderedRows().length);
checkHilitedIndex(rend, 0);
ac.hiliteNext();
checkHilitedIndex(rend, 1);
// try going over the edge since last row is disabled. Since allowFreeSelect
// is on, this will deselect the last row.
ac.hiliteNext();
checkHilitedIndex(rend, -1);
// go back down the list
ac.hiliteNext();
checkHilitedIndex(rend, 0);
ac.hiliteNext();
checkHilitedIndex(rend, 1);
// go back up the list.
ac.hilitePrev();
checkHilitedIndex(rend, 0);
// go back above the first, deselects first.
ac.hilitePrev();
checkHilitedIndex(rend, -1);
}
}
/**
* Try using next and prev to navigate past the ends with wrap_ on
* allowFreeSelect_ off.
*/
function testHiliteNextPrev_wrap() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
ac.setWrap(true);
// make sure 'next' and 'prev' don't explode before any token is set
ac.hiliteNext();
ac.hilitePrev();
ac.setMaxMatches(4);
assertEquals(0, rend.getRenderedRows().length);
// check a few times
for (var i = 0; i < 3; ++i) {
ac.setToken('');
ac.setToken('the');
assertEquals(4, rend.getRenderedRows().length);
// check to see if we can select the last of the 4 items
checkHilitedIndex(rend, 0);
ac.hiliteNext();
checkHilitedIndex(rend, 1);
ac.hiliteNext();
checkHilitedIndex(rend, 2);
ac.hiliteNext();
checkHilitedIndex(rend, 3);
// try going over the edge. Since wrap is on, this will go back to 0.
ac.hiliteNext();
checkHilitedIndex(rend, 0);
// go back down the list
ac.hiliteNext();
checkHilitedIndex(rend, 1);
// go back up the list.
ac.hilitePrev();
checkHilitedIndex(rend, 0);
// go back above the first, selects last.
ac.hilitePrev();
checkHilitedIndex(rend, 3);
}
}
/**
* Try using next and prev to navigate past the ends with wrap_ on
* allowFreeSelect_ off and a disabled first row.
*/
function testHiliteNextPrevWithDisabledFirstRow_wrap() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
ac.setWrap(true);
// make sure 'next' and 'prev' don't explode before any token is set
ac.hiliteNext();
ac.hilitePrev();
ac.setMaxMatches(4);
assertEquals(0, rend.getRenderedRows().length);
// check a few times with disabled first row
for (var i = 0; i < 3; ++i) {
ac.setToken('');
ac.setToken('edu');
assertEquals(3, rend.getRenderedRows().length);
// The first row is disabled, second should be highlighted.
checkHilitedIndex(rend, 1);
ac.hiliteNext();
checkHilitedIndex(rend, 2);
// try going over the edge. Since wrap is on and first row is disabled,
// this will go back to 1.
ac.hiliteNext();
checkHilitedIndex(rend, 1);
// go back down the list
ac.hiliteNext();
checkHilitedIndex(rend, 2);
// go back up the list.
ac.hilitePrev();
checkHilitedIndex(rend, 1);
// first is disabled, so wrap and select the last.
ac.hilitePrev();
checkHilitedIndex(rend, 2);
}
}
/**
* Try using next and prev to navigate past the ends with wrap_ on
* allowFreeSelect_ off and a disabled middle row.
*/
function testHiliteNextPrevWithDisabledMiddleRow_wrap() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
ac.setWrap(true);
// make sure 'next' and 'prev' don't explode before any token is set
ac.hiliteNext();
ac.hilitePrev();
ac.setMaxMatches(4);
assertEquals(0, rend.getRenderedRows().length);
// check a few times with disabled middle row
for (var i = 0; i < 3; ++i) {
ac.setToken('');
ac.setToken('u');
assertEquals(3, rend.getRenderedRows().length);
checkHilitedIndex(rend, 0);
ac.hiliteNext();
// Second row is disabled and should be skipped.
checkHilitedIndex(rend, 2);
// try going over the edge. Since wrap is on, this will go back to 0.
ac.hiliteNext();
checkHilitedIndex(rend, 0);
// go back down the list
ac.hiliteNext();
checkHilitedIndex(rend, 2);
// go back up the list.
ac.hilitePrev();
checkHilitedIndex(rend, 0);
// go back above the first, selects last.
ac.hilitePrev();
checkHilitedIndex(rend, 2);
}
}
/**
* Try using next and prev to navigate past the ends with wrap_ on
* allowFreeSelect_ off and a disabled last row.
*/
function testHiliteNextPrevWithDisabledLastRow_wrap() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
ac.setWrap(true);
// make sure 'next' and 'prev' don't explode before any token is set
ac.hiliteNext();
ac.hilitePrev();
ac.setMaxMatches(4);
assertEquals(0, rend.getRenderedRows().length);
// check a few times with disabled last row
for (var i = 0; i < 3; ++i) {
ac.setToken('');
ac.setToken('h');
assertEquals(3, rend.getRenderedRows().length);
checkHilitedIndex(rend, 0);
ac.hiliteNext();
checkHilitedIndex(rend, 1);
// try going over the edge since last row is disabled. Since wrap is on,
// this will go back to 0.
ac.hiliteNext();
checkHilitedIndex(rend, 0);
// go back down the list
ac.hiliteNext();
checkHilitedIndex(rend, 1);
// go back up the list.
ac.hilitePrev();
checkHilitedIndex(rend, 0);
// go back above the first, since wrap is on and last row is disabled, this
// will select the second last.
ac.hilitePrev();
checkHilitedIndex(rend, 1);
}
}
/**
* Try using next and prev to navigate past the ends with wrap_ on
* allowFreeSelect_ on.
*/
function testHiliteNextPrev_wrapAndAllowFreeSelect() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
ac.setWrap(true);
ac.setAllowFreeSelect(true);
// make sure 'next' and 'prev' don't explode before any token is set
ac.hiliteNext();
ac.hilitePrev();
ac.setMaxMatches(4);
assertEquals(0, rend.getRenderedRows().length);
// check a few times
for (var i = 0; i < 3; ++i) {
ac.setToken('');
ac.setToken('the');
assertEquals(4, rend.getRenderedRows().length);
// check to see if we can select the last of the 4 items
checkHilitedIndex(rend, 0);
ac.hiliteNext();
checkHilitedIndex(rend, 1);
ac.hiliteNext();
checkHilitedIndex(rend, 2);
ac.hiliteNext();
checkHilitedIndex(rend, 3);
// try going over the edge. Since free select is on, this should go
// to -1.
ac.hiliteNext();
checkHilitedIndex(rend, -1);
// go back down the list
ac.hiliteNext();
checkHilitedIndex(rend, 0);
ac.hiliteNext();
checkHilitedIndex(rend, 1);
// go back up the list.
ac.hilitePrev();
checkHilitedIndex(rend, 0);
// go back above the first, free select.
ac.hilitePrev();
checkHilitedIndex(rend, -1);
// wrap to last
ac.hilitePrev();
checkHilitedIndex(rend, 3);
}
}
/**
* Try using next and prev to navigate past the ends with wrap_ on
* allowFreeSelect_ on and a disabled first row.
*/
function testHiliteNextPrevWithDisabledFirstRow_wrapAndAllowFreeSelect() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
ac.setWrap(true);
ac.setAllowFreeSelect(true);
// make sure 'next' and 'prev' don't explode before any token is set
ac.hiliteNext();
ac.hilitePrev();
ac.setMaxMatches(4);
assertEquals(0, rend.getRenderedRows().length);
// check a few times with disabled first row
for (var i = 0; i < 3; ++i) {
ac.setToken('');
ac.setToken('edu');
assertEquals(3, rend.getRenderedRows().length);
// The first row is disabled, second should be highlighted.
checkHilitedIndex(rend, 1);
ac.hiliteNext();
checkHilitedIndex(rend, 2);
// try going over the edge. Since free select is on, this should go to -1.
ac.hiliteNext();
checkHilitedIndex(rend, -1);
// go back down the list, fist row is disabled
ac.hiliteNext();
checkHilitedIndex(rend, 1);
ac.hiliteNext();
checkHilitedIndex(rend, 2);
// go back up the list.
ac.hilitePrev();
checkHilitedIndex(rend, 1);
// go back above the first, free select.
ac.hilitePrev();
checkHilitedIndex(rend, -1);
// wrap to last
ac.hilitePrev();
checkHilitedIndex(rend, 2);
}
}
/**
* Try using next and prev to navigate past the ends with wrap_ on
* allowFreeSelect_ on and a disabled middle row.
*/
function testHiliteNextPrevWithDisabledMiddleRow_wrapAndAllowFreeSelect() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
ac.setWrap(true);
ac.setAllowFreeSelect(true);
// make sure 'next' and 'prev' don't explode before any token is set
ac.hiliteNext();
ac.hilitePrev();
ac.setMaxMatches(4);
assertEquals(0, rend.getRenderedRows().length);
// check a few times with disabled middle row
for (var i = 0; i < 3; ++i) {
ac.setToken('');
ac.setToken('u');
assertEquals(3, rend.getRenderedRows().length);
checkHilitedIndex(rend, 0);
ac.hiliteNext();
// Second row is disabled and should be skipped.
checkHilitedIndex(rend, 2);
// try going over the edge. Since free select is on, this should go to -1
ac.hiliteNext();
checkHilitedIndex(rend, -1);
// go back down the list
ac.hiliteNext();
checkHilitedIndex(rend, 0);
ac.hiliteNext();
checkHilitedIndex(rend, 2);
// go back up the list.
ac.hilitePrev();
checkHilitedIndex(rend, 0);
// go back above the first, free select.
ac.hilitePrev();
checkHilitedIndex(rend, -1);
// wrap to last
ac.hilitePrev();
checkHilitedIndex(rend, 2);
}
}
/**
* Try using next and prev to navigate past the ends with wrap_ on
* allowFreeSelect_ on and a disabled last row.
*/
function testHiliteNextPrevWithDisabledLastRow_wrapAndAllowFreeSelect() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
ac.setWrap(true);
ac.setAllowFreeSelect(true);
// make sure 'next' and 'prev' don't explode before any token is set
ac.hiliteNext();
ac.hilitePrev();
ac.setMaxMatches(4);
assertEquals(0, rend.getRenderedRows().length);
// check a few times with disabled last row
for (var i = 0; i < 3; ++i) {
ac.setToken('');
ac.setToken('h');
assertEquals(3, rend.getRenderedRows().length);
checkHilitedIndex(rend, 0);
ac.hiliteNext();
checkHilitedIndex(rend, 1);
// try going over the edge since last row is disabled. Since free select is
// on, this should go to -1
ac.hiliteNext();
checkHilitedIndex(rend, -1);
// go back down the list
ac.hiliteNext();
checkHilitedIndex(rend, 0);
ac.hiliteNext();
checkHilitedIndex(rend, 1);
// go back up the list.
ac.hilitePrev();
checkHilitedIndex(rend, 0);
// go back above the first, free select.
ac.hilitePrev();
checkHilitedIndex(rend, -1);
// wrap to the second last, since last is disabled.
ac.hilitePrev();
checkHilitedIndex(rend, 1);
}
}
/**
* Try using next and prev to navigate past the ends with wrap_ on
* allowFreeSelect_ on AND turn autoHilite_ off.
*/
function testHiliteNextPrev_wrapAndAllowFreeSelectNoAutoHilite() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
ac.setWrap(true);
ac.setAllowFreeSelect(true);
ac.setAutoHilite(false);
// make sure 'next' and 'prev' don't explode before any token is set
ac.hiliteNext();
ac.hilitePrev();
ac.setMaxMatches(4);
assertEquals(0, rend.getRenderedRows().length);
// check a few times
for (var i = 0; i < 3; ++i) {
ac.setToken('');
ac.setToken('the');
assertEquals(4, rend.getRenderedRows().length);
// check to see if we can select the last of the 4 items.
// Initially nothing should be selected since autoHilite_ is off.
checkHilitedIndex(rend, -1);
ac.hilitePrev();
checkHilitedIndex(rend, 3);
ac.hiliteNext();
checkHilitedIndex(rend, -1);
ac.hiliteNext();
checkHilitedIndex(rend, 0);
ac.hiliteNext();
checkHilitedIndex(rend, 1);
ac.hiliteNext();
checkHilitedIndex(rend, 2);
ac.hiliteNext();
checkHilitedIndex(rend, 3);
// try going over the edge. Since free select is on, this should go
// to -1.
ac.hiliteNext();
checkHilitedIndex(rend, -1);
// go back down the list
ac.hiliteNext();
checkHilitedIndex(rend, 0);
ac.hiliteNext();
checkHilitedIndex(rend, 1);
// go back up the list.
ac.hilitePrev();
checkHilitedIndex(rend, 0);
// go back above the first, free select.
ac.hilitePrev();
checkHilitedIndex(rend, -1);
// wrap to last
ac.hilitePrev();
checkHilitedIndex(rend, 3);
}
}
/**
* Try using next and prev to navigate past the ends with wrap_ on
* allowFreeSelect_ on AND turn autoHilite_ off, and a disabled first row.
*/
function testHiliteNextPrevWithDisabledFirstRow_wrapAndAllowFreeSelectNoAutoHilite() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
ac.setWrap(true);
ac.setAllowFreeSelect(true);
ac.setAutoHilite(false);
// make sure 'next' and 'prev' don't explode before any token is set
ac.hiliteNext();
ac.hilitePrev();
ac.setMaxMatches(4);
assertEquals(0, rend.getRenderedRows().length);
// check a few times with disabled first row
for (var i = 0; i < 3; ++i) {
ac.setToken('');
ac.setToken('edu');
assertEquals(3, rend.getRenderedRows().length);
// Initially nothing should be selected since autoHilite_ is off.
checkHilitedIndex(rend, -1);
ac.hilitePrev();
checkHilitedIndex(rend, 2);
ac.hiliteNext();
checkHilitedIndex(rend, -1);
ac.hiliteNext();
// First row is disabled.
checkHilitedIndex(rend, 1);
ac.hiliteNext();
checkHilitedIndex(rend, 2);
// try going over the edge. Since free select is on, this should go to -1
ac.hiliteNext();
checkHilitedIndex(rend, -1);
// go back down the list, first row is disabled
ac.hiliteNext();
checkHilitedIndex(rend, 1);
ac.hiliteNext();
checkHilitedIndex(rend, 2);
// go back up the list.
ac.hilitePrev();
checkHilitedIndex(rend, 1);
// go back above the first, free select.
ac.hilitePrev();
checkHilitedIndex(rend, -1);
// wrap to last
ac.hilitePrev();
checkHilitedIndex(rend, 2);
}
}
/**
* Try using next and prev to navigate past the ends with wrap_ on
* allowFreeSelect_ on AND turn autoHilite_ off, and a disabled middle row.
*/
function testHiliteNextPrevWithDisabledMiddleRow_wrapAndAllowFreeSelectNoAutoHilite() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
ac.setWrap(true);
ac.setAllowFreeSelect(true);
ac.setAutoHilite(false);
// make sure 'next' and 'prev' don't explode before any token is set
ac.hiliteNext();
ac.hilitePrev();
ac.setMaxMatches(4);
assertEquals(0, rend.getRenderedRows().length);
// check a few times with disabled middle row
for (var i = 0; i < 3; ++i) {
ac.setToken('');
ac.setToken('u');
assertEquals(3, rend.getRenderedRows().length);
// Initially nothing should be selected since autoHilite_ is off.
checkHilitedIndex(rend, -1);
ac.hilitePrev();
checkHilitedIndex(rend, 2);
ac.hiliteNext();
checkHilitedIndex(rend, -1);
ac.hiliteNext();
checkHilitedIndex(rend, 0);
ac.hiliteNext();
// Second row is disabled
checkHilitedIndex(rend, 2);
// try going over the edge. Since free select is on, this should go to -1.
ac.hiliteNext();
checkHilitedIndex(rend, -1);
// go back down the list
ac.hiliteNext();
checkHilitedIndex(rend, 0);
ac.hiliteNext();
// Second row is disabled.
checkHilitedIndex(rend, 2);
// go back up the list.
ac.hilitePrev();
checkHilitedIndex(rend, 0);
// go back above the first, free select.
ac.hilitePrev();
checkHilitedIndex(rend, -1);
// wrap to last
ac.hilitePrev();
checkHilitedIndex(rend, 2);
}
}
/**
* Try using next and prev to navigate past the ends with wrap_ on
* allowFreeSelect_ on AND turn autoHilite_ off, and a disabled last row.
*/
function testHiliteNextPrevWithDisabledLastRow_wrapAndAllowFreeSelectNoAutoHilite() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
ac.setWrap(true);
ac.setAllowFreeSelect(true);
ac.setAutoHilite(false);
// make sure 'next' and 'prev' don't explode before any token is set
ac.hiliteNext();
ac.hilitePrev();
ac.setMaxMatches(4);
assertEquals(0, rend.getRenderedRows().length);
// check a few times with disabled last row
for (var i = 0; i < 3; ++i) {
ac.setToken('');
ac.setToken('h');
assertEquals(3, rend.getRenderedRows().length);
// Initially nothing should be selected since autoHilite_ is off.
checkHilitedIndex(rend, -1);
ac.hilitePrev();
// Last row is disabled
checkHilitedIndex(rend, 1);
ac.hiliteNext();
checkHilitedIndex(rend, -1);
ac.hiliteNext();
checkHilitedIndex(rend, 0);
ac.hiliteNext();
checkHilitedIndex(rend, 1);
// try going over the edge. Since free select is on, this should go to -1.
ac.hiliteNext();
checkHilitedIndex(rend, -1);
// go back down the list
ac.hiliteNext();
checkHilitedIndex(rend, 0);
ac.hiliteNext();
checkHilitedIndex(rend, 1);
// go back up the list.
ac.hilitePrev();
checkHilitedIndex(rend, 0);
// go back above the first, free select.
ac.hilitePrev();
checkHilitedIndex(rend, -1);
// wrap to last
ac.hilitePrev();
checkHilitedIndex(rend, 1);
}
}
function testHiliteWithChangingNumberOfRows() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
ac.setAutoHilite(true);
ac.setMaxMatches(4);
ac.setToken('m');
assertEquals(4, rend.getRenderedRows().length);
checkHilitedIndex(rend, 0);
ac.setToken('ma');
assertEquals(3, rend.getRenderedRows().length);
checkHilitedIndex(rend, 0);
// Hilite the second element
var id = rend.getRenderedRows()[1].id;
ac.hiliteId(id);
ac.setToken('mar');
assertEquals(1, rend.getRenderedRows().length);
checkHilitedIndex(rend, 0);
ac.setToken('ma');
assertEquals(3, rend.getRenderedRows().length);
checkHilitedIndex(rend, 0);
// Hilite the second element
var id = rend.getRenderedRows()[1].id;
ac.hiliteId(id);
ac.setToken('m');
assertEquals(4, rend.getRenderedRows().length);
checkHilitedIndex(rend, 0);
}
/**
* Checks that autohilite is disabled when there is no token; this allows the
* user to tab out of an empty autocomplete.
*/
function testNoAutoHiliteWhenTokenIsEmpty() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
ac.setWrap(true);
ac.setAllowFreeSelect(true);
ac.setAutoHilite(true);
ac.setMaxMatches(4);
ac.setToken('');
assertEquals(4, rend.getRenderedRows().length);
// No token; nothing should be hilited.
checkHilitedIndex(rend, -1);
ac.setToken('the');
assertEquals(4, rend.getRenderedRows().length);
// Now there is a token, so the first row should be highlighted.
checkHilitedIndex(rend, 0);
}
/**
* Checks that opt_preserveHilited works.
*/
function testPreserveHilitedWithoutAutoHilite() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
ac.setWrap(true);
ac.setAllowFreeSelect(true);
ac.setMaxMatches(4);
ac.setAutoHilite(false);
ac.setToken('m');
assertEquals(4, rend.getRenderedRows().length);
// No token; nothing should be hilited.
checkHilitedIndex(rend, -1);
// Hilite the second element
var id = rend.getRenderedRows()[1].id;
ac.hiliteId(id);
checkHilitedIndex(rend, 1);
// Re-render and check if the second element is still hilited
ac.renderRows(rend.getRenderedRows(), true /* preserve hilite */);
checkHilitedIndex(rend, 1);
// Re-render without preservation
ac.renderRows(rend.getRenderedRows());
checkHilitedIndex(rend, -1);
}
/**
* Checks that the autohilite argument "true" of the matcher is used.
*/
function testAutoHiliteFromMatcherTrue() {
var ds = new MockDS(true);
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
ac.setWrap(true);
ac.setAllowFreeSelect(true);
ac.setAutoHilite(false); // Will be overruled.
ac.setMaxMatches(4);
ac.setToken('the');
assertEquals(4, rend.getRenderedRows().length);
// The first row should be highlighted.
checkHilitedIndex(rend, 0);
}
/**
* Checks that the autohilite argument "false" of the matcher is used.
*/
function testAutoHiliteFromMatcherFalse() {
var ds = new MockDS(false);
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
ac.setWrap(true);
ac.setAllowFreeSelect(true);
ac.setAutoHilite(true); // Will be overruled.
ac.setMaxMatches(4);
ac.setToken('the');
assertEquals(4, rend.getRenderedRows().length);
// The first row should not be highlighted.
checkHilitedIndex(rend, -1);
}
/**
* Hilite using ids, the way mouse-based hiliting would work.
*/
function testHiliteId() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
// check a few times
for (var i = 0; i < 3; ++i) {
ac.setToken('m');
assertEquals(4, rend.getRenderedRows().length);
// try hiliting all 3
for (var x = 0; x < 4; ++x) {
var id = rend.getRenderedRows()[x].id;
ac.hiliteId(id);
assertEquals(ac.getIdOfIndex_(x), id);
}
}
}
/**
* Test selecting the hilited row
*/
function testSelection() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var ac;
// try with default selection
ac = new goog.ui.ac.AutoComplete(ds, rend, select);
ac.setToken('m');
ac.selectHilited();
assertEquals('"Slartibartfast Theadore" <fjordmaster@magrathea.com>',
select.selectedRow);
// try second item
ac = new goog.ui.ac.AutoComplete(ds, rend, select);
ac.setToken('the');
ac.hiliteNext();
ac.selectHilited();
assertEquals('"Ford Prefect" <ford@theguide.com>',
select.selectedRow);
}
/**
* Dismiss when empty and non-empty
*/
function testDismiss() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
// dismiss empty
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
var dismissed = 0;
handler.listen(ac,
goog.ui.ac.AutoComplete.EventType.DISMISS,
function() {
dismissed++;
});
ac.dismiss();
assertEquals(1, dismissed);
ac = new goog.ui.ac.AutoComplete(ds, rend, select);
ac.setToken('sir not seen in this picture');
ac.dismiss();
// dismiss with contents
ac = new goog.ui.ac.AutoComplete(ds, rend, select);
ac.setToken('t');
ac.dismiss();
}
function testTriggerSuggestionsOnUpdate() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
var dismissCalled = 0;
rend.dismiss = function() {
dismissCalled++;
};
var updateCalled = 0;
select.update = function(opt_force) {
updateCalled++;
};
// Normally, menu is dismissed after selecting row (without updating).
ac.setToken('the');
ac.selectHilited();
assertEquals(1, dismissCalled);
assertEquals(0, updateCalled);
// But not if we re-trigger on update.
ac.setTriggerSuggestionsOnUpdate(true);
ac.setToken('the');
ac.selectHilited();
assertEquals(1, dismissCalled);
assertEquals(1, updateCalled);
}
function testDispose() {
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
ac.setToken('the');
ac.dispose();
}
/**
* Ensure that activedescendant is updated properly.
*/
function testRolesAndStates() {
function checkActiveDescendant(activeDescendant) {
assertNotNull(inputElement);
assertEquals(
goog.a11y.aria.getActiveDescendant(inputElement),
activeDescendant);
}
function checkRole(el, role) {
assertNotNull(el);
assertEquals(goog.a11y.aria.getRole(el), role);
}
var ds = new MockDS();
var rend = new TestRend();
var select = new MockSelect();
var ac = new goog.ui.ac.AutoComplete(ds, rend, select);
ac.setTarget(inputElement);
// initially activedescendant is not set
checkActiveDescendant(null);
// highlight the matching row and check that activedescendant updates
ac.setToken('');
ac.setToken('the');
ac.hiliteNext();
checkActiveDescendant(rend.getHilitedRowDiv());
// highligted row should have a role of 'option'
checkRole(rend.getHilitedRowDiv(), goog.a11y.aria.Role.OPTION);
// closing the autocomplete should clear activedescendant
ac.dismiss();
checkActiveDescendant(null);
}
function testAttachInputWithAnchor() {
var anchorElement = goog.dom.createDom('div', null, inputElement);
var mockRenderer = mockControl.createLooseMock(
goog.ui.ac.Renderer, true);
mockRenderer.setAnchorElement(anchorElement);
var ignore = goog.testing.mockmatchers.ignoreArgument;
mockRenderer.renderRows(ignore, ignore, inputElement);
var mockInputHandler = mockControl.createLooseMock(
goog.ui.ac.InputHandler, true);
mockInputHandler.attachInputs(inputElement);
mockControl.$replayAll();
var autoComplete = new goog.ui.ac.AutoComplete(
null, mockRenderer, mockInputHandler);
autoComplete.attachInputWithAnchor(inputElement, anchorElement);
autoComplete.setTarget(inputElement);
autoComplete.renderRows(['abc', 'def']);
mockControl.$verifyAll();
}
function testDetachInputWithAnchor() {
var mockRenderer = mockControl.createLooseMock(
goog.ui.ac.Renderer, true);
var mockInputHandler = mockControl.createLooseMock(
goog.ui.ac.InputHandler, true);
var anchorElement = goog.dom.createDom('div', null, inputElement);
var inputElement2 = goog.dom.createDom('input', {type: 'text'});
var anchorElement2 = goog.dom.createDom('div', null, inputElement2);
mockControl.$replayAll();
var autoComplete = new goog.ui.ac.AutoComplete(
null, mockRenderer, mockInputHandler);
autoComplete.attachInputWithAnchor(inputElement, anchorElement);
autoComplete.attachInputWithAnchor(inputElement2, anchorElement2);
autoComplete.detachInputs(inputElement, inputElement2);
assertFalse(goog.getUid(inputElement) in autoComplete.inputToAnchorMap_);
assertFalse(goog.getUid(inputElement2) in autoComplete.inputToAnchorMap_);
mockControl.$verifyAll();
}