From a14c5ee871db11fa9664e1d36a585e4683fefce3 Mon Sep 17 00:00:00 2001 From: "g. nicholas d'andrea" Date: Sun, 12 Jul 2026 16:57:04 -0400 Subject: [PATCH] web/playground: source BUG examples from @ethdebug/bugc/examples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both playgrounds showed BUG programs that were maintained separately from the canonical `.bug` files under packages/bugc/examples: the docs BugPlayground had no example picker at all, and the standalone playground reached across packages with a Vite `import.meta.glob(... ?raw)` that only works under Vite. Neither stayed in step with the sources bugc actually tests. Both now import the shared `@ethdebug/bugc/examples` map, which ships the canonical sources as inlined string literals so webpack (docs) and Vite (playground) consume them without a filesystem glob. Each consumer keeps a small curated list — which examples to show, their labels, and (for the playground) their category — and applies `stripTestAnnotations` so the editor shows clean source without bugc's inline `@test`/`@expect` directives. - docs BugPlayground: add an example selector (curated trio: an owned counter, functions, arrays & loops), shown when the embed hasn't pinned a specific program via `initialCode`. - standalone playground: drop `import.meta.glob`; keep the same curated, categorized set, now keyed by canonical example path. - unit coverage that the curated sets resolve to real sources, strip clean, and compile to bytecode. --- packages/bugc-react/src/examples.test.ts | 59 ++++++++++++ packages/bugc-react/src/examples.ts | 52 +++++++++++ packages/bugc-react/src/index.ts | 3 + packages/bugc-react/vitest.config.ts | 13 +++ .../playground/src/playground/examples.ts | 68 ++++++++------ .../src/theme/BugcExample/BugPlayground.css | 6 +- .../src/theme/BugcExample/BugPlayground.tsx | 90 +++++++++++++------ 7 files changed, 233 insertions(+), 58 deletions(-) create mode 100644 packages/bugc-react/src/examples.test.ts create mode 100644 packages/bugc-react/src/examples.ts create mode 100644 packages/bugc-react/vitest.config.ts diff --git a/packages/bugc-react/src/examples.test.ts b/packages/bugc-react/src/examples.test.ts new file mode 100644 index 000000000..bda50ae69 --- /dev/null +++ b/packages/bugc-react/src/examples.test.ts @@ -0,0 +1,59 @@ +/** + * The curated example set is sourced from `@ethdebug/bugc/examples` + * (the canonical `.bug` files), sliced down and stripped for display. + * These guards ensure the selection stays valid and editor-clean: the + * strings ship verbatim into the docs playground editor. + */ +import { describe, it, expect } from "vitest"; +import { compile } from "@ethdebug/bugc"; +import { exampleSources } from "@ethdebug/bugc/examples"; +import { bugExamples } from "./examples.js"; + +describe("bugExamples", () => { + it("is the curated trio (counter, functions, arrays)", () => { + expect(bugExamples.map((e) => e.name)).toEqual([ + "counter", + "functions", + "arrays", + ]); + }); + + it("gives every example a display name and non-empty source", () => { + for (const ex of bugExamples) { + expect(ex.displayName.trim().length).toBeGreaterThan(0); + expect(ex.code.trim().length).toBeGreaterThan(0); + } + }); + + it("draws its sources from the canonical bugc examples", () => { + // Sanity: the raw sources the curation selects really exist + // upstream, so the selection can't silently drift to empty. + expect( + Object.prototype.hasOwnProperty.call( + exampleSources, + "intermediate/owner-counter.bug", + ), + ).toBe(true); + expect(bugExamples.length).toBeGreaterThan(0); + }); + + it("strips bugc's inline test annotations for display", () => { + for (const ex of bugExamples) { + expect(ex.code).not.toContain("@test"); + expect(ex.code).not.toContain("@expect"); + } + }); + + // Each curated source must compile cleanly to bytecode — this is + // the guard that matters, since these ship straight to the editor. + for (const ex of bugExamples) { + it(`compiles ${ex.name} to bytecode without errors`, async () => { + const result = await compile({ + to: "bytecode", + source: ex.code, + optimizer: { level: 0 }, + }); + expect(result.success).toBe(true); + }); + } +}); diff --git a/packages/bugc-react/src/examples.ts b/packages/bugc-react/src/examples.ts new file mode 100644 index 000000000..80dc840fe --- /dev/null +++ b/packages/bugc-react/src/examples.ts @@ -0,0 +1,52 @@ +/** + * Curated BUG examples for the docs playground's example selector. + * + * The sources are the canonical `.bug` files shipped by + * `@ethdebug/bugc/examples` — the same files bugc's behavioral tests + * compile — so the playground never drifts from a hand-maintained copy. + * We select a small subset, label it for display, and strip bugc's + * inline test annotations so the editor shows clean source. + */ + +import { exampleSources, stripTestAnnotations } from "@ethdebug/bugc/examples"; + +/** A named, display-labelled BUG source for the example selector. */ +export interface BugExample { + /** Stable identifier (used as the