Debounce autocomplete queries by default

Bug: Issue 8149
Change-Id: If93a5850cf5e8b7996237fd53e1f201f552966c7
This commit is contained in:
Wyatt Allen
2018-03-14 11:53:45 -07:00
parent 76af81ab09
commit c7de1f198b
7 changed files with 35 additions and 26 deletions

View File

@@ -104,6 +104,7 @@ limitations under the License.
<gr-autocomplete
id="parentInput"
query="[[_query]]"
no-debounce
text="{{_inputText}}"
on-tap="_handleEnterChangeNumberTap"
on-commit="_handleBaseSelected"

View File

@@ -165,6 +165,7 @@ limitations under the License.
test('input text change triggers function', () => {
sandbox.spy(element, '_getRecentChanges');
element.$.parentInput.noDebounce = true;
element._inputText = '1';
assert.isTrue(element._getRecentChanges.calledOnce);
element._inputText = '12';

View File

@@ -47,7 +47,6 @@ limitations under the License.
id="searchInput"
text="{{_inputVal}}"
query="[[query]]"
debounce-wait="200"
on-commit="_handleInputCommit"
allow-non-suggested-values
multi

View File

@@ -60,12 +60,14 @@ suite('gr-edit-controls tests', () => {
suite('edit button CUJ', () => {
let navStubs;
let openAutoCcmplete;
setup(() => {
navStubs = [
sandbox.stub(Gerrit.Nav, 'getEditUrlForDiff'),
sandbox.stub(Gerrit.Nav, 'navigateToRelativeUrl'),
];
openAutoCcmplete = element.$.openDialog.querySelector('gr-autocomplete');
});
test('_isValidPath', () => {
@@ -83,8 +85,8 @@ suite('gr-edit-controls tests', () => {
assert.isTrue(element._hideAllDialogs.called);
assert.isTrue(element.$.openDialog.disabled);
assert.isFalse(queryStub.called);
element.$.openDialog.querySelector('gr-autocomplete').text =
'src/test.cpp';
openAutoCcmplete.noDebounce = true;
openAutoCcmplete.text = 'src/test.cpp';
assert.isTrue(queryStub.called);
assert.isFalse(element.$.openDialog.disabled);
MockInteractions.tap(element.$.openDialog.$$('gr-button[primary]'));
@@ -99,8 +101,8 @@ suite('gr-edit-controls tests', () => {
MockInteractions.tap(element.$$('#open'));
return showDialogSpy.lastCall.returnValue.then(() => {
assert.isTrue(element.$.openDialog.disabled);
element.$.openDialog.querySelector('gr-autocomplete').text =
'src/test.cpp';
openAutoCcmplete.noDebounce = true;
openAutoCcmplete.text = 'src/test.cpp';
assert.isFalse(element.$.openDialog.disabled);
MockInteractions.tap(element.$.openDialog.$$('gr-button'));
for (const stub of navStubs) { assert.isFalse(stub.called); }
@@ -113,10 +115,13 @@ suite('gr-edit-controls tests', () => {
suite('delete button CUJ', () => {
let navStub;
let deleteStub;
let deleteAutocomplete;
setup(() => {
navStub = sandbox.stub(Gerrit.Nav, 'navigateToChange');
deleteStub = sandbox.stub(element.$.restAPI, 'deleteFileInChangeEdit');
deleteAutocomplete =
element.$.deleteDialog.querySelector('gr-autocomplete');
});
test('delete', () => {
@@ -125,8 +130,8 @@ suite('gr-edit-controls tests', () => {
return showDialogSpy.lastCall.returnValue.then(() => {
assert.isTrue(element.$.deleteDialog.disabled);
assert.isFalse(queryStub.called);
element.$.deleteDialog.querySelector('gr-autocomplete').text =
'src/test.cpp';
deleteAutocomplete.noDebounce = true;
deleteAutocomplete.text = 'src/test.cpp';
assert.isTrue(queryStub.called);
assert.isFalse(element.$.deleteDialog.disabled);
MockInteractions.tap(element.$.deleteDialog.$$('gr-button[primary]'));
@@ -148,8 +153,8 @@ suite('gr-edit-controls tests', () => {
return showDialogSpy.lastCall.returnValue.then(() => {
assert.isTrue(element.$.deleteDialog.disabled);
assert.isFalse(queryStub.called);
element.$.deleteDialog.querySelector('gr-autocomplete').text =
'src/test.cpp';
deleteAutocomplete.noDebounce = true;
deleteAutocomplete.text = 'src/test.cpp';
assert.isTrue(queryStub.called);
assert.isFalse(element.$.deleteDialog.disabled);
MockInteractions.tap(element.$.deleteDialog.$$('gr-button[primary]'));
@@ -182,10 +187,13 @@ suite('gr-edit-controls tests', () => {
suite('rename button CUJ', () => {
let navStub;
let renameStub;
let renameAutocomplete;
setup(() => {
navStub = sandbox.stub(Gerrit.Nav, 'navigateToChange');
renameStub = sandbox.stub(element.$.restAPI, 'renameFileInChangeEdit');
renameAutocomplete =
element.$.renameDialog.querySelector('gr-autocomplete');
});
test('rename', () => {
@@ -194,8 +202,8 @@ suite('gr-edit-controls tests', () => {
return showDialogSpy.lastCall.returnValue.then(() => {
assert.isTrue(element.$.renameDialog.disabled);
assert.isFalse(queryStub.called);
element.$.renameDialog.querySelector('gr-autocomplete').text =
'src/test.cpp';
renameAutocomplete.noDebounce = true;
renameAutocomplete.text = 'src/test.cpp';
assert.isTrue(queryStub.called);
assert.isTrue(element.$.renameDialog.disabled);
@@ -222,8 +230,8 @@ suite('gr-edit-controls tests', () => {
return showDialogSpy.lastCall.returnValue.then(() => {
assert.isTrue(element.$.renameDialog.disabled);
assert.isFalse(queryStub.called);
element.$.renameDialog.querySelector('gr-autocomplete').text =
'src/test.cpp';
renameAutocomplete.noDebounce = true;
renameAutocomplete.text = 'src/test.cpp';
assert.isTrue(queryStub.called);
assert.isTrue(element.$.renameDialog.disabled);

View File

@@ -95,7 +95,6 @@ limitations under the License.
<th>
<gr-autocomplete
id="newProject"
debounce-wait="200"
query="[[_query]]"
threshold="1"
placeholder="Project"></gr-autocomplete>

View File

@@ -15,6 +15,7 @@
'use strict';
const TOKENIZE_REGEX = /(?:[^\s"]+|"[^"]*")+/g;
const DEBOUNCE_WAIT_MS = 200;
Polymer({
is: 'gr-autocomplete',
@@ -130,12 +131,11 @@
},
/**
* The number of milliseconds to use as the debounce wait time. If null,
* no debouncing is used.
* When true, querying for suggestions is not debounced w/r/t keypresses
*/
debounceWait: {
type: Number,
value: null,
noDebounce: {
type: Boolean,
value: false,
},
/** @type {?} */
@@ -173,6 +173,7 @@
detached() {
this.unlisten(document.body, 'tap', '_handleBodyTap');
this.cancelDebouncer('update-suggestions');
},
get focusStart() {
@@ -255,10 +256,10 @@
});
};
if (this.debounceWait) {
this.debounce('update-suggestions', update, this.debounceWait);
} else {
if (this.noDebounce) {
update();
} else {
this.debounce('update-suggestions', update, DEBOUNCE_WAIT_MS);
}
},

View File

@@ -27,7 +27,7 @@ limitations under the License.
<test-fixture id="basic">
<template>
<gr-autocomplete></gr-autocomplete>
<gr-autocomplete no-debounce></gr-autocomplete>
</template>
</test-fixture>
@@ -235,7 +235,7 @@ limitations under the License.
assert.isTrue(queryStub.called);
});
test('debounceWait debounces the query', () => {
test('noDebounce=false debounces the query', () => {
const queryStub = sandbox.spy(() => {
return Promise.resolve([]);
});
@@ -243,11 +243,11 @@ limitations under the License.
const debounceStub = sandbox.stub(element, 'debounce',
(name, cb) => { callback = cb; });
element.query = queryStub;
element.debounceWait = 100;
element.noDebounce = false;
element.text = 'a';
assert.isFalse(queryStub.called);
assert.isTrue(debounceStub.called);
assert.equal(debounceStub.lastCall.args[2], 100);
assert.equal(debounceStub.lastCall.args[2], 200);
assert.isFunction(callback);
callback();
assert.isTrue(queryStub.called);