write tests for AsyncMappedList
This commit is contained in:
parent
1fc1d2c79b
commit
81f06f565e
3 changed files with 76 additions and 43 deletions
|
@ -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});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Reference in a new issue