Skip to content

Commit

Permalink
Add test for async combobox initSelection order preservation
Browse files Browse the repository at this point in the history
  • Loading branch information
volkanceylan committed Oct 10, 2024
1 parent 566fbb5 commit b8fefda
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 9 deletions.
62 changes: 62 additions & 0 deletions packages/corelib/src/ui/editors/comboboxeditor.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { ComboboxSearchQuery, ComboboxSearchResult } from "./combobox";
import { ComboboxEditor } from "./comboboxeditor";

describe("ComboboxEditor async behavior", () => {

type TestItem = {
ID: string,
}

class ReverseAsyncCombo extends ComboboxEditor<{ filter?: (x: string) => boolean }, TestItem> {
protected override hasAsyncSource(): boolean {
return true;
}

protected override isMultiple() {
return true;
}

protected override getIdField() {
return "ID";
}

protected asyncSearch(query: ComboboxSearchQuery): PromiseLike<ComboboxSearchResult<TestItem>> {
if (query.initSelection) {
return Promise.resolve({
items: query.idList.slice().reverse().filter(this.props.filter ?? (() => true)).map(id => ({
ID: id,
Name: "Name" + id
})),
more: false
});
}

throw "Not Implemented";
}
}

it("should preserve order for async initSelection", async () => {
var combo = new ReverseAsyncCombo({
});
combo.values = ["3", "2", "1"];
expect(combo.values).toStrictEqual(["3", "2", "1"]);
await Promise.resolve();
expect(combo.values).toStrictEqual(["3", "2", "1"]);
});

it("should preserve order when some items not found for async initSelection", async () => {
jest.useFakeTimers();
try {
var combo = new ReverseAsyncCombo({
filter: x => x !== "2"
});
combo.values = ["3", "2", "1"];
expect(combo.values).toStrictEqual(["3", "2", "1"]);
await jest.runAllTimersAsync();
expect(combo.values).toStrictEqual(["3", "1"]);
}
finally {
jest.useRealTimers();
}
});
});
21 changes: 12 additions & 9 deletions packages/corelib/src/ui/editors/comboboxeditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -172,12 +172,13 @@ export class ComboboxEditor<P, TItem> extends Widget<P> implements
if (this.hasAsyncSource()) {
opt.search = query => this.asyncSearch(query).then(result => {
let items = this.mapItems(result.items || []);
this._itemById ??= {};
for (var x of items)
this._itemById[x.id] = x;


if (query.initSelection) {
const newItems = (query.idList || []).map(id => this._itemById[id] || items.find(z => z.id == id)).filter(x => x != null);
const itemById: typeof this._itemById = {};
for (var x of items) {
itemById[x.id] = x;
}
const newItems = (query.idList || []).map(id => itemById[id]).filter(x => x != null);
if (items.length == newItems.length) {
// if length is not equal, might be a case sensitivity issue, ignore ordering otherwise
items = newItems;
Expand All @@ -193,16 +194,18 @@ export class ComboboxEditor<P, TItem> extends Widget<P> implements
items.length < query.idList.length) {
for (var v of query.idList) {
if (!items.some(z => z.id == v)) {
var item = {
items.push({
id: v,
text: v
};
items.push(item);
this._itemById[x.id] = x;
});
}
}
}

this._itemById ??= {};
for (var x of items)
this._itemById[x.id] = x;

return mappedResult;
});
}
Expand Down

0 comments on commit b8fefda

Please sign in to comment.