mirror of
https://github.com/discourse/discourse.git
synced 2024-11-27 08:53:38 +08:00
DEV: Implement DeferredTrackedSet
(#27372)
For cases where you'd be using a TrackedSet to render something and then modifying that set throughout the same render cycle. (specifically it will be used in #27365)
This commit is contained in:
parent
ffec8163b0
commit
46ab4f0c4a
|
@ -1,4 +1,6 @@
|
|||
import { tracked } from "@glimmer/tracking";
|
||||
import { next } from "@ember/runloop";
|
||||
import { TrackedSet } from "@ember-compat/tracked-built-ins";
|
||||
|
||||
/**
|
||||
* Define a tracked property on an object without needing to use the @tracked decorator.
|
||||
|
@ -120,3 +122,57 @@ export function dedupeTracked(target, key, desc) {
|
|||
},
|
||||
};
|
||||
}
|
||||
|
||||
export class DeferredTrackedSet {
|
||||
#set;
|
||||
|
||||
constructor(value) {
|
||||
this.#set = new TrackedSet(value);
|
||||
}
|
||||
|
||||
has(value) {
|
||||
return this.#set.has(value);
|
||||
}
|
||||
|
||||
entries() {
|
||||
return this.#set.entries();
|
||||
}
|
||||
|
||||
keys() {
|
||||
return this.#set.keys();
|
||||
}
|
||||
|
||||
values() {
|
||||
return this.#set.values();
|
||||
}
|
||||
|
||||
forEach(fn) {
|
||||
return this.#set.forEach(fn);
|
||||
}
|
||||
|
||||
get size() {
|
||||
return this.#set.size;
|
||||
}
|
||||
|
||||
[Symbol.iterator]() {
|
||||
return this.#set[Symbol.iterator]();
|
||||
}
|
||||
|
||||
get [Symbol.toStringTag]() {
|
||||
return this.#set[Symbol.toStringTag];
|
||||
}
|
||||
|
||||
add(value) {
|
||||
next(() => this.#set.add(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
delete(value) {
|
||||
next(() => this.#set.delete(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
clear() {
|
||||
next(() => this.#set.clear());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { cached } from "@glimmer/tracking";
|
||||
import { run } from "@ember/runloop";
|
||||
import { settled } from "@ember/test-helpers";
|
||||
import { module, test } from "qunit";
|
||||
import { dedupeTracked } from "discourse/lib/tracked-tools";
|
||||
import { dedupeTracked, DeferredTrackedSet } from "discourse/lib/tracked-tools";
|
||||
|
||||
module("Unit | tracked-tools", function () {
|
||||
test("@dedupeTracked", async function (assert) {
|
||||
|
@ -45,4 +47,73 @@ module("Unit | tracked-tools", function () {
|
|||
"Initials getter re-evaluated"
|
||||
);
|
||||
});
|
||||
|
||||
test("DeferredTrackedSet", async function (assert) {
|
||||
class Player {
|
||||
evaluationsCount = 0;
|
||||
|
||||
letters = new DeferredTrackedSet();
|
||||
|
||||
@cached
|
||||
get score() {
|
||||
this.evaluationsCount++;
|
||||
return this.letters.size;
|
||||
}
|
||||
}
|
||||
|
||||
const player = new Player();
|
||||
assert.strictEqual(player.score, 0, "score is correct");
|
||||
assert.strictEqual(player.evaluationsCount, 1, "getter evaluated once");
|
||||
|
||||
run(() => {
|
||||
player.letters.add("a");
|
||||
|
||||
assert.strictEqual(player.score, 0, "score does not change");
|
||||
assert.strictEqual(
|
||||
player.evaluationsCount,
|
||||
1,
|
||||
"getter does not evaluate"
|
||||
);
|
||||
|
||||
player.letters.add("b");
|
||||
player.letters.add("c");
|
||||
|
||||
assert.strictEqual(player.score, 0, "score still does not change");
|
||||
assert.strictEqual(
|
||||
player.evaluationsCount,
|
||||
1,
|
||||
"getter still does not evaluate"
|
||||
);
|
||||
});
|
||||
await settled();
|
||||
|
||||
assert.strictEqual(player.score, 3, "score is correct");
|
||||
assert.strictEqual(player.evaluationsCount, 2, "getter evaluated again");
|
||||
|
||||
run(() => {
|
||||
player.letters.add("d");
|
||||
});
|
||||
await settled();
|
||||
|
||||
assert.strictEqual(player.score, 4, "score is correct");
|
||||
assert.strictEqual(player.evaluationsCount, 3, "getter evaluated again");
|
||||
|
||||
run(() => {
|
||||
player.letters.add("e");
|
||||
|
||||
assert.strictEqual(player.score, 4, "score is correct");
|
||||
assert.strictEqual(
|
||||
player.evaluationsCount,
|
||||
3,
|
||||
"getter does not evaluate"
|
||||
);
|
||||
|
||||
player.letters.add("f");
|
||||
});
|
||||
await settled();
|
||||
|
||||
assert.strictEqual(player.score, 6, "score is correct");
|
||||
assert.strictEqual(player.evaluationsCount, 4, "getter evaluated");
|
||||
assert.deepEqual([...player.letters], ["a", "b", "c", "d", "e", "f"]);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue
Block a user