From ad249a27691d2cf464e6a48e29a2742333dc9675 Mon Sep 17 00:00:00 2001 From: Josep M Sobrepere Date: Tue, 18 Oct 2022 11:48:23 +0200 Subject: [PATCH] context-state: fix `route-state` broken tests --- .../src/internal/detached-node.ts | 11 +++++++++-- packages/context-state/src/route-state.test.ts | 4 +++- packages/context-state/src/route-state.ts | 18 +++++++++++++++++- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/packages/context-state/src/internal/detached-node.ts b/packages/context-state/src/internal/detached-node.ts index fb6a2de..99b01d9 100644 --- a/packages/context-state/src/internal/detached-node.ts +++ b/packages/context-state/src/internal/detached-node.ts @@ -106,7 +106,9 @@ export const detachedNode = ( if (isParentLoaded) { // an actual change of context - const hasPreviousValue = instance && instance.currentValue !== EMPTY_VALUE + let previousValue = instance ? instance.currentValue : EMPTY_VALUE + const hasPreviousValue = previousValue !== EMPTY_VALUE + if (!instance) { instance = { subject: new ReplaySubject(1), @@ -154,7 +156,10 @@ export const detachedNode = ( actualInstance.subscription = observable?.subscribe({ next(value) { - let prevValue = actualInstance.currentValue + let prevValue = + previousValue !== EMPTY_VALUE + ? previousValue + : actualInstance.currentValue actualInstance.currentValue = value const prevPromise = actualInstance.promise actualInstance.promise = null @@ -186,6 +191,8 @@ export const detachedNode = ( runChildren(key, true, false) prevSubect?.complete() } + + previousValue = EMPTY_VALUE return } diff --git a/packages/context-state/src/route-state.test.ts b/packages/context-state/src/route-state.test.ts index ac94fd6..bf2b3cc 100644 --- a/packages/context-state/src/route-state.test.ts +++ b/packages/context-state/src/route-state.test.ts @@ -40,7 +40,9 @@ describe("routeState", () => { ) root.run() - expect(() => key.getValue()).toThrow() // TODO which error? + expect(() => key.getValue()).toThrow( + 'Invalid Route. Received "c" while valid keys are: "a, b"', + ) }) it("errors if the selector throws an error", () => { diff --git a/packages/context-state/src/route-state.ts b/packages/context-state/src/route-state.ts index a805cfb..ae77480 100644 --- a/packages/context-state/src/route-state.ts +++ b/packages/context-state/src/route-state.ts @@ -10,6 +10,17 @@ import { of } from "rxjs" import { substate } from "./substate" import { StateNode, Ctx } from "./types" +export class InvalidRouteError extends Error { + constructor(key: string, keys: string[]) { + super( + `Invalid Route. Received "${key}" while valid keys are: "${keys.join( + ", ", + )}"`, + ) + this.name = "InvalidRouteError" + } +} + export const routeState = < T, O extends { [P in keyof any]: ((value: T) => any) | null }, @@ -25,7 +36,12 @@ export const routeState = < routes: O, selector: (value: T, ctx: Ctx) => keyof O, ): [StateNode, OT] => { - const keyState = substate(parent, (ctx) => of(selector(ctx(parent), ctx))) + const keys = new Set(Object.keys(routes)) + const keyState = substate(parent, (ctx) => { + const key = selector(ctx(parent), ctx) as string + if (!keys.has(key)) throw new InvalidRouteError(key, [...keys]) + return of(key) + }) const routedState = mapRecord(routes, (mapper) => { const result = detachedNode((ctx) => {