Skip to content

Add showcase and invalid examples, pinned by golden-file tests - #20

Merged
milyin merged 2 commits into
mainfrom
feature/examples
Aug 6, 2026
Merged

Add showcase and invalid examples, pinned by golden-file tests#20
milyin merged 2 commits into
mainfrom
feature/examples

Conversation

@milyin

@milyin milyin commented Aug 6, 2026

Copy link
Copy Markdown
Owner

Two runnable examples, and a test that runs each and compares its output against
a stored file.

cargo run --example showcase   # every construct the model can emit
cargo run --example invalid    # a broken model, and what the validator says

showcase

A small but complete generator — it builds KtFile fragments, merges them so
each package collapses to one file, and renders every construct the model has:
classes with each modifier, objects, an enum with a constructor its entries
call, data and value classes, a sealed interface with nested alternatives,
interfaces, fun interfaces, type aliases, properties with accessors and
delegates, external natives, raw blocks, and every KtCode block form
(blk, blk_with, try_finally, wline, raw_reindent, import). It ends
with the identifier helpers.

The output is real, compilable-looking Kotlin across four files, including a
width-broken signature and a width-broken call — so the layout rules are
visible rather than described.

invalid

Shows the two ways a mistake surfaces, which are caught at different moments:

  • The validator reports one case of each of its ten checks, with the scope
    path locating each (io.example.broken/My-Class/object). Then the same model
    under warn_all(), and under a policy with one check downgraded and one
    switched off.
  • The builder simply refuses the shapes Part A made unrepresentable. The
    last section catches those panics so the example can print what the author
    would see:
object Foo(x: Int)  — an object has no primary constructor
    -> `object` has no primary constructor to add parameter `x` to
class A : B(x), C(y)  — Kotlin constructs at most one superclass
    -> class `A` already extends `B`; Kotlin allows only one superclass (use `implements` for interfaces)

Why golden files

The examples are the crate's documentation, so they have to keep working — and
because their output is generated Kotlin, pinning it turns them into readable
regression tests: a diff shows the change in the emitted source, not in a
builder call. UPDATE_GOLDEN=1 cargo test --test examples rewrites them.

the_invalid_example_demonstrates_every_check is pinned separately against
Check::ALL rather than only by the golden file, because that is the property
that matters — adding a check without demonstrating it should fail with an
explanation, not look like golden noise.

Two things the examples turned up

A real bug: merge_files silently dropped a fragment's banner override.
The merged file is rebuilt from scratch and never copied it, so a per-package
banner was lost the moment anything was merged. The first fragment of a package
to set one now wins, with a test.

A wrong assumption of mine: the test originally located example binaries
under target/<profile>/examples/. That works for cargo test but not for
cargo test --test examples — cargo does not build example targets for the
latter, so the test passed or failed depending on how the suite was started. It
now invokes cargo to build and run them, which behaves the same either way at
the cost of a no-op build.

Verification

107 unit tests, 3 example tests, 10 doctests. cargo clippy --all-targets -- --deny warnings and CI's exact rustfmt invocation both clean. cargo package --list confirms the examples and golden files ship with the crate.

Two runnable examples and a test that runs each and compares its output
against a stored file.

`showcase` is a small but complete generator: it builds KtFile
fragments, merges them so each package collapses to one file, and
renders every construct the model can emit — classes with each modifier,
objects, enums with a constructor their entries call, data and value
classes, a sealed interface with nested alternatives, interfaces,
`fun interface`s, type aliases, properties with accessors and delegates,
`external` natives, raw blocks, and every KtCode block form. It ends
with the identifier helpers.

`invalid` shows the two ways a mistake surfaces. The validator reports
one case of each of its ten checks, and the last section catches the
builder panics for the shapes the model refuses to construct at all —
`object Foo(x: Int)`, two constructed superclasses, `external` as a
modifier.

The examples are the crate's documentation, so pinning their output
keeps them working; and because the output *is* generated Kotlin, a diff
shows the change in the emitted source rather than in a builder call.
`UPDATE_GOLDEN=1` rewrites the stored files.

`the_invalid_example_demonstrates_every_check` is pinned separately
against `Check::ALL`, so adding a check without an example fails with an
explanation instead of looking like golden noise.

Two things the examples turned up:

  * `merge_files` silently dropped a fragment's `banner` override — the
    merged file is rebuilt from scratch and never copied it. The first
    fragment of a package to set one now wins.
  * The test cannot locate example binaries under `target/`: cargo does
    not build example targets for `cargo test --test examples`. It
    invokes cargo instead, so it behaves the same however it is run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds two runnable examples (showcase, invalid) to serve as executable documentation for the Kotlin model/renderer/validator, and introduces golden-file tests that run those examples and pin their stdout. Also fixes merge_files_with to preserve KtFile::banner overrides during merges.

Changes:

  • Add examples/showcase.rs (comprehensive generator demo) and examples/invalid.rs (validator + builder refusal demo), with pinned golden outputs.
  • Add tests/examples.rs integration test to run examples via cargo run --example ... and compare stdout to tests/golden/*.txt (with UPDATE_GOLDEN=1 update path).
  • Fix merge_files_with to carry the first KtFile::banner override forward into the merged file, plus a unit test for it.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/golden/showcase.txt Golden output pinned for the showcase example’s generated Kotlin + identifier helper output.
tests/golden/invalid.txt Golden output pinned for the invalid example’s diagnostics, merge refusal, warn policy behavior, and builder-refusal messages.
tests/examples.rs New test harness that runs examples through Cargo and compares stdout to golden files; includes a completeness check for Check::ALL.
src/tests.rs Adds a regression test asserting banner overrides survive merge_files and that “first override wins.”
src/file.rs Updates merge logic to preserve KtFile::banner overrides while merging fragments of the same package.
README.md Documents the new examples and how to update golden files.
examples/showcase.rs New example generating a broad set of Kotlin constructs and printing merged rendered output.
examples/invalid.rs New example demonstrating validator diagnostics, merge refusal, policy tuning, and builder-rejected shapes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread examples/invalid.rs Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@milyin
milyin merged commit 7e139e4 into main Aug 6, 2026
2 checks passed
@milyin milyin mentioned this pull request Aug 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants