write tests for AsyncMappedList

This commit is contained in:
Bruno Windels 2021-06-21 17:26:08 +02:00
parent 1fc1d2c79b
commit 81f06f565e
3 changed files with 76 additions and 43 deletions

View file

@ -16,67 +16,46 @@ limitations under the License.
export class ListObserver {
constructor() {
this._queuesPerType = new Map();
this._queue = [];
this._backlog = [];
}
_nextEvent(type) {
let queue = this._queuesPerType.get(type);
if (!queue) {
queue = [];
this._queuesPerType.set(type, queue);
next() {
if (this._backlog.length) {
return Promise.resolve(this._backlog.shift());
} else {
return new Promise(resolve => {
this._queue.push(resolve);
});
}
return new Promise(resolve => {
queue.push(resolve);
});
}
nextAdd() {
return this._nextEvent("add");
}
nextUpdate() {
return this._nextEvent("update");
}
nextRemove() {
return this._nextEvent("remove");
}
nextMove() {
return this._nextEvent("move");
}
nextReset() {
return this._nextEvent("reset");
}
_popQueue(type) {
const queue = this._queuesPerType.get(type);
return queue?.unshift();
_fullfillNext(value) {
if (this._queue.length) {
const resolve = this._queue.shift();
resolve(value);
} else {
this._backlog.push(value);
}
}
onReset() {
const resolve = this._popQueue("reset");
resolve && resolve();
this._fullfillNext({type: "reset"});
}
onAdd(index, value) {
const resolve = this._popQueue("add");
resolve && resolve({index, value});
this._fullfillNext({type: "add", index, value});
}
onUpdate(index, value, params) {
const resolve = this._popQueue("update");
resolve && resolve({index, value, params});
this._fullfillNext({type: "update", index, value, params});
}
onRemove(index, value) {
const resolve = this._popQueue("remove");
resolve && resolve({index, value});
this._fullfillNext({type: "remove", index, value});
}
onMove(fromIdx, toIdx, value) {
const resolve = this._popQueue("move");
resolve && resolve({fromIdx, toIdx, value});
this._fullfillNext({type: "move", fromIdx, toIdx, value});
}
}

View file

@ -143,8 +143,55 @@ class ResetEvent {
}
}
import {ObservableArray} from "./ObservableArray.js";
import {ListObserver} from "../../mocks/ListObserver.js";
export function tests() {
return {
"events are emitted in order": async assert => {
const double = n => n * n;
const source = new ObservableArray();
const mapper = new AsyncMappedList(source, async n => {
await new Promise(r => setTimeout(r, n));
return {n: double(n)};
}, (o, params, n) => {
o.n = double(n);
});
const observer = new ListObserver();
mapper.subscribe(observer);
source.append(2); // will sleep this amount, so second append would take less time
source.append(1);
source.update(0, 7, "lucky seven")
source.remove(0);
{
const {type, index, value} = await observer.next();
assert.equal(mapper.length, 1);
assert.equal(type, "add");
assert.equal(index, 0);
assert.equal(value.n, 4);
}
{
const {type, index, value} = await observer.next();
assert.equal(mapper.length, 2);
assert.equal(type, "add");
assert.equal(index, 1);
assert.equal(value.n, 1);
}
{
const {type, index, value, params} = await observer.next();
assert.equal(mapper.length, 2);
assert.equal(type, "update");
assert.equal(index, 0);
assert.equal(value.n, 49);
assert.equal(params, "lucky seven");
}
{
const {type, index, value} = await observer.next();
assert.equal(mapper.length, 1);
assert.equal(type, "remove");
assert.equal(index, 0);
assert.equal(value.n, 49);
}
}
}
}

View file

@ -44,6 +44,13 @@ export class ObservableArray extends BaseObservableList {
this.emitAdd(idx, item);
}
update(idx, item, params = null) {
if (idx < this._items.length) {
this._items[idx] = item;
this.emitUpdate(idx, item, params);
}
}
get array() {
return this._items;
}