Skip to content

Headless rendering CLI and snapshot-test pattern #62

@hugithordarson

Description

@hugithordarson

A command-line entry point for rendering ng-objects components without an HTTP server, plus a snapshot-style test pattern that uses it.

Motivation

Template-heavy frameworks have a particularly bad iteration cycle for visual/structural changes: change template → restart server → reload page → look at it → describe what you see. The verification step is human-mediated, and when AI is involved in proposing changes the round-trip cost compounds — every iteration needs the human to apply, restart, navigate, observe, describe.

A headless render that produces HTML from a component + data, with no HTTP server in the loop, eliminates the slow verification step for the cases where output can be evaluated by reading the HTML (which is most cases). This is valuable for:

  • AI-assisted development (the AI can render, evaluate, iterate without human eyes in the loop)
  • Snapshot testing (catch unintentional rendering changes in CI)
  • Quick iteration on template changes by humans
  • Component-level debugging without standing up an app

Proposed shape

CLI

```bash
ng render --component MyPage --data testdata.json
```

Output: rendered HTML to stdout, or stack trace (using the enriched format from #61) on error.

Optional flags:

  • `--bindings key=value` for inline binding data
  • `--diff path/to/expected.html` to compare against a known-good output
  • `--strict` to fail on any rendering warnings

Programmatic API

```java
NGRenderHarness harness = NGRenderHarness.forFramework();
String html = harness.render(MyPage.class, testData);
```

Snapshot test pattern

```java
@test
void rendersCorrectly() {
NGRenderHarness harness = NGRenderHarness.forFramework();
String html = harness.render(MyPage.class, testData);
assertSnapshotMatches(html, "MyPage.expected.html");
}
```

The framework provides the harness; the snapshot-matching utility can be a thin layer over an existing JVM snapshot library or rolled small.

What this requires

  • An `NGApplication`-like driver that initializes the framework without depending on the HTTP adaptor
  • A synthetic minimal request/context to feed into rendering
  • Binding evaluation against provided test data (component class + data → rendered HTML)
  • Error handling that surfaces the enriched render exceptions from Enrich exceptions thrown during rendering with positional context #61

Scope

The CLI + programmatic harness is the core. Snapshot-test conventions can follow. `--diff` and other CLI niceties are nice-to-have.

Likely a few days of focused work for v1. Most of the rendering machinery already exists; the work is mostly building a non-HTTP entry point and a clean test-friendly API around it.

Why this is M2-shippable

  • Small and contained
  • Improves framework testability (M2 nice-to-have, already on the punch list)
  • Composes well with Enrich exceptions thrown during rendering with positional context #61 (enriched render exceptions) and Template validation #28 (template binding validation) — together these make the framework dramatically easier to develop with
  • Signals that the framework takes developer-time seriously, which is a good conference message
  • Useful for the framework's own internal testing as it matures

Composability with future work

  • When template compilation (Compile templates to Java classes #60) lands, the harness uses compiled templates automatically
  • When the AI-assisted development workflow (`docs/ai-assisted-development-workflow.md`) develops further, this is the foundation it builds on

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions