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 <gr-autocomplete
id="parentInput" id="parentInput"
query="[[_query]]" query="[[_query]]"
no-debounce
text="{{_inputText}}" text="{{_inputText}}"
on-tap="_handleEnterChangeNumberTap" on-tap="_handleEnterChangeNumberTap"
on-commit="_handleBaseSelected" on-commit="_handleBaseSelected"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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