chore: mesurer la forme du tableau au lieu de la supposer, et retirer les any
La branche tableau se decide sur `typeof cible.length === "number"`, ce qui est une question posee a un proxy : mesure contre le vrai `@ng-org/alien-deepsignals`, `deepSignal(new Set(...)).length` vaut `undefined` et ses `Object.keys` sont vides, tandis que `deepSignal([...]).length` est un nombre. La forme ensemble n-entre donc jamais dans cette branche, et c-est aussi celle qui ne porte aucune cle nommant un objet. Les trois `as any` des tests ajoutes et le `Iterable<any>` du harness sont types.
This commit is contained in:
@@ -1088,9 +1088,11 @@ const identity = new IdentityStore(
|
|||||||
// `data` - the member its own example destructures first, and one of the three that
|
// `data` - the member its own example destructures first, and one of the three that
|
||||||
// used to come back unfiltered.
|
// used to come back unfiltered.
|
||||||
const read = (): string[] =>
|
const read = (): string[] =>
|
||||||
[...(libUseShape(wsShape("urn:e2e:caps:Item"), EVERYTHING).data as Iterable<any>)].map(
|
[
|
||||||
(i) => i.v,
|
...(libUseShape(wsShape("urn:e2e:caps:Item"), EVERYTHING).data as Iterable<
|
||||||
);
|
{ v: string }
|
||||||
|
>),
|
||||||
|
].map((i) => i.v);
|
||||||
setCurrentUser("owner-O");
|
setCurrentUser("owner-O");
|
||||||
getCaps().open("did:ng:o:protdoc", "protected");
|
getCaps().open("did:ng:o:protdoc", "protected");
|
||||||
const link = getCaps().open("did:ng:o:pubdoc", "public");
|
const link = getCaps().open("did:ng:o:pubdoc", "public");
|
||||||
|
|||||||
@@ -213,6 +213,12 @@ export function makeReadFilteredView<S extends object>(set: S, caps: CapRegistry
|
|||||||
* `DeepSignal<ReadOnlyArray>` instead of a `DeepSignalSet`, and an array is addressed by
|
* `DeepSignal<ReadOnlyArray>` instead of a `DeepSignalSet`, and an array is addressed by
|
||||||
* INDEX and counts itself with `length`. Decided from the target once, so the view never
|
* INDEX and counts itself with `length`. Decided from the target once, so the view never
|
||||||
* grows a member the collection it wraps does not have.
|
* grows a member the collection it wraps does not have.
|
||||||
|
*
|
||||||
|
* MEASURED against the real `@ng-org/alien-deepsignals` rather than assumed, because the
|
||||||
|
* collection is itself a proxy and what it answers for a key it does not carry is its
|
||||||
|
* business: `deepSignal(new Set(...)).length` is `undefined` and its `Object.keys` is
|
||||||
|
* empty, while `deepSignal([...]).length` is a number. So the set form never enters this
|
||||||
|
* branch, and the set form is also the one with no key naming an item to project.
|
||||||
*/
|
*/
|
||||||
const arrayLike = typeof (set as { length?: unknown }).length === "number";
|
const arrayLike = typeof (set as { length?: unknown }).length === "number";
|
||||||
/** The index a key names, or `null` when it names no position in this collection. */
|
/** The index a key names, or `null` when it names no position in this collection. */
|
||||||
|
|||||||
@@ -149,10 +149,10 @@ test("forEach is filtered too", () => {
|
|||||||
// hatch included, which `get` refuses by name. Everything built on that call goes the same
|
// hatch included, which `get` refuses by name. Everything built on that call goes the same
|
||||||
// way: `Object.keys`, `Object.entries`, a spread, `JSON.stringify`, a console inspection.
|
// way: `Object.keys`, `Object.entries`, a spread, `JSON.stringify`, a console inspection.
|
||||||
test("a descriptor cannot answer what reading the member refuses", () => {
|
test("a descriptor cannot answer what reading the member refuses", () => {
|
||||||
const set = new Set<Item>([MINE]) as any;
|
const set: Set<Item> & { __raw__?: unknown } = new Set<Item>([MINE]);
|
||||||
set.__raw__ = set;
|
set.__raw__ = set;
|
||||||
const { caps, become } = setup("alice");
|
const { caps, become } = setup("alice");
|
||||||
const view = makeReadFilteredView(set, caps) as any;
|
const view = makeReadFilteredView(set, caps);
|
||||||
become("bob");
|
become("bob");
|
||||||
expect(() => Object.getOwnPropertyDescriptor(view, "__raw__")).toThrow(/raw collection/i);
|
expect(() => Object.getOwnPropertyDescriptor(view, "__raw__")).toThrow(/raw collection/i);
|
||||||
});
|
});
|
||||||
@@ -163,9 +163,9 @@ test("a descriptor cannot answer what reading the member refuses", () => {
|
|||||||
// count of what a holder may NOT read came back out through the other three, and the
|
// count of what a holder may NOT read came back out through the other three, and the
|
||||||
// descriptor handed back the items themselves.
|
// descriptor handed back the items themselves.
|
||||||
test("the array form counts and addresses the readable items, by every route", () => {
|
test("the array form counts and addresses the readable items, by every route", () => {
|
||||||
const items = [MINE, FOREIGN, LINKED];
|
const items: Item[] = [MINE, FOREIGN, LINKED];
|
||||||
const { caps, become } = setup("alice");
|
const { caps, become } = setup("alice");
|
||||||
const view = makeReadFilteredView(items, caps) as any;
|
const view = makeReadFilteredView(items, caps);
|
||||||
become("bob"); // holds nothing of the three documents
|
become("bob"); // holds nothing of the three documents
|
||||||
|
|
||||||
expect(view.length).toBe(0);
|
expect(view.length).toBe(0);
|
||||||
@@ -178,9 +178,9 @@ test("the array form counts and addresses the readable items, by every route", (
|
|||||||
become("alice"); // holds her own document and the one she published
|
become("alice"); // holds her own document and the one she published
|
||||||
expect(view.length).toBe(2);
|
expect(view.length).toBe(2);
|
||||||
expect(Object.keys(view)).toEqual(["0", "1"]);
|
expect(Object.keys(view)).toEqual(["0", "1"]);
|
||||||
expect(view[0].id).toBe("a");
|
expect(view[0]).toBe(MINE);
|
||||||
expect(view[1].id).toBe("p");
|
expect(view[1]).toBe(LINKED);
|
||||||
expect(Object.getOwnPropertyDescriptor(view, "1")?.value.id).toBe("p");
|
expect(Object.getOwnPropertyDescriptor(view, "1")?.value).toBe(LINKED);
|
||||||
expect(2 in view).toBe(false);
|
expect(2 in view).toBe(false);
|
||||||
// `length` is the array's own key and is never hidden - a proxy may not drop a key the
|
// `length` is the array's own key and is never hidden - a proxy may not drop a key the
|
||||||
// target cannot configure away - but it is not a position and does not enumerate.
|
// target cannot configure away - but it is not a position and does not enumerate.
|
||||||
|
|||||||
Reference in New Issue
Block a user