Skip to content

docs/feat: sealed routes can't be enumerated at runtime — document the testing impact #72

Description

@Mastersam07

This is the honest cost of being codegen-free rather than a bug, but it changes how apps test and is currently undocumented.

With a route table (auto_route, go_router) you can walk it at runtime and assert over every route: "these N are auth-protected", "these are the analytics names", "no route is unreachable". With sealed types, Dart cannot enumerate a sealed types subtypes at runtime, so those invariants have nowhere typed to iterate.

What apps end up doing

Both such tests in one migration became regex passes over the route source files:

final routeFiles = Directory(lib/.../routes).listSync().whereType<File>();
RegExp("String get routeName => ([A-Za-z0-9_]+)")
    .allMatches(file.readAsStringSync());

That catches drift, but a text search is standing in for a type-level property.

It bites hardest on safety-critical invariants. An "is this screen reachable while locked?" classification is a switch over route types with a default. Verifying it exhaustively needs an instance of every route — and routes carrying domain objects cannot be cheaply constructed in a test. In that app only 28 of 41 relevant routes could be instantiated; the rest had to be covered by grepping the classifications own source.

What already works

Exhaustiveness is fully solved for anything that dispatches on a route — page builders, codecs, transition wrappers all get compile-time totality from switch. The gap is specifically invariants over the set of routes.

Suggestion

At minimum, document the trade-off and the source-level testing pattern so teams do not discover it when writing their first whole-table test.

Optionally, endorse a convention the compiler can help with:

sealed class AppRoute extends KaiselRoute {
  const AppRoute();
  static const all = <AppRoute>[Home(), Settings(), /* ... */];
}

Hand-maintained, but usable by whole-table tests, and drift is at least visible in review. A lint (pkg:kaisel_lint) that flags a route variant missing from such a list would make it reliable.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentationenhancementNew feature or requestpkg:kaisel_corePure-Dart core

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions