feat(cli): gonext plugin test — in-process fake host + conformance suite#461
Merged
Conversation
…ests Adds a new packages/go/plugins/fakehost package that mirrors each host ABI (gn_db_*, gn_kv_*, gn_cache_invalidate, gn_http_fetch, gn_media_read, gn_users_read, gn_secrets_get, gn_audit_emit, gn_cron_register, gn_log, gn_time_ms, gn_i18n_translate, gn_metric_observe, gn_event_emit, gn_span_event, gn_panic, http.serve). Every call is recorded as a typed Event so the upcoming `gonext plugin test --suite=conformance` (issue #247) can assert what the plugin actually did. Includes deterministic clock, capability denial gating, KV quotas, scripted HTTP responses, and a secrets bag that deliberately never echoes values into the recorded trace. Refs #247. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: Claude (for tayebmokni) <tayeb.mokni@gmail.com>
Adds packages/go/plugins/conformance implementing the suite invoked by `gonext plugin test --suite=conformance`. Each Scenario receives a parsed manifest + a fresh fakehost.Host and returns a ScenarioResult. The built-ins assert: capabilities are in the v1 vocabulary, declared capabilities cover the plugin's registered hooks (statically — dynamic dispatch awaits the WASM runner), hook names are non-empty, jobs are namespaced under the plugin slug, init+teardown is idempotent, and the synthetic 1s job respects its budget. The runner accepts both directory bundles and .gnplugin/.zip archives, parses v1 and legacy manifests, recovers panics, and optionally records per-scenario JSON fixtures. A LoadFixtureScenarios helper round-trips user-supplied fixtures from tests/conformance/fixtures. Smoke-tested against examples/plugins/seo's manifest. Refs #247. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: Tayeb Mokni <tayeb.mokni@gmail.com>
Wires the conformance suite (issue #247) into the existing `gonext plugin test` subcommand: gonext plugin test --suite=conformance [--json] [--record-fixtures=DIR] <bundle> The default suite (no --suite or --suite=default) continues to run the plugintest contract checks unchanged — marketplace ingest stays on the stable shape. --suite=conformance switches to packages/go/plugins/conformance.NewSuite, which parses the manifest (v1 OR legacy), runs the built-in scenarios against an in-memory fakehost.Host, and optionally writes one JSON fixture per scenario via --record-fixtures. Includes a tests/conformance/fixtures/README + a seo_init.json template showing the fixture format. Smoke-tested end-to-end against examples/plugins/seo (TestRunTest_Conformance_SEOExample passes green). Refs #247. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: Tayeb Mokni <tayeb.mokni@gmail.com>
tayebmokni
pushed a commit
that referenced
this pull request
May 25, 2026
Closes #242. packages/ts/sdk-plugin: TypeScript SDK for GoNext plugin authors via Javy (JavaScript → WASM). - pluginInit + registerAction / registerFilter - Typed wrappers over every gn_* host ABI through globalThis - JSON envelope codec - Manifest builder mirroring the Go side - bin/gonext-sdk-build.js wraps esbuild + javy compile - cli/gonext/templates/typescript + 'gonext plugin init --template=typescript' - examples/plugins/sdk-ts-hello working example - 54 Vitest tests (codec + manifest + dispatch) This PR was rebased onto main after #460/#461/#462 landed; the runInit dispatch now switches on template name and embeds both templates/go and templates/typescript via the single templatesFS. Signed-off-by: Tayeb Mokni <tayeb.mokni@gmail.com>
tayebmokni
pushed a commit
that referenced
this pull request
May 25, 2026
Closes #239. packages/rust/gonext-sdk + packages/rust/gonext-sdk-macros: Cargo crates for Rust plugin authors. - plugin_init! proc-macro generates gn_alloc/gn_free/_start/gn_handle_hook exports - Safe typed wrappers over every gn_* host ABI (env, env_net, gonext_data, env_platform) - JSON envelope codec via serde_json - Manifest builder mirroring the Go side - cli/gonext/cmd/plugin/templates/rust + 'gonext plugin init --template=rust' - examples/plugins/sdk-rust-hello: working example (action + filter + kv.set + audit.emit) Rebased onto main after #460/#461/#462 landed; init.go now switches on template name. TestRunInitUnknownTemplate updated to use a clearly-not-real template name so it stays robust as new templates land. Signed-off-by: Tayeb Mokni <tayeb.mokni@gmail.com>
tayebmokni
pushed a commit
that referenced
this pull request
May 25, 2026
Closes #242. packages/ts/sdk-plugin: TypeScript SDK for GoNext plugin authors via Javy (JavaScript → WASM). - pluginInit + registerAction / registerFilter - Typed wrappers over every gn_* host ABI through globalThis - JSON envelope codec - Manifest builder mirroring the Go side - bin/gonext-sdk-build.js wraps esbuild + javy compile - cli/gonext/templates/typescript + 'gonext plugin init --template=typescript' - examples/plugins/sdk-ts-hello working example - 54 Vitest tests (codec + manifest + dispatch) This PR was rebased onto main after #460/#461/#462 landed; the runInit dispatch now switches on template name and embeds both templates/go and templates/typescript via the single templatesFS. Signed-off-by: Tayeb Mokni <tayeb.mokni@gmail.com>
tayebmokni
pushed a commit
that referenced
this pull request
May 26, 2026
Closes #242. packages/ts/sdk-plugin: TypeScript SDK for GoNext plugin authors via Javy (JavaScript → WASM). - pluginInit + registerAction / registerFilter - Typed wrappers over every gn_* host ABI through globalThis - JSON envelope codec - Manifest builder mirroring the Go side - bin/gonext-sdk-build.js wraps esbuild + javy compile - cli/gonext/templates/typescript + 'gonext plugin init --template=typescript' - examples/plugins/sdk-ts-hello working example - 54 Vitest tests (codec + manifest + dispatch) This PR was rebased onto main after #460/#461/#462 landed; the runInit dispatch now switches on template name and embeds both templates/go and templates/typescript via the single templatesFS. Signed-off-by: Tayeb Mokni <tayeb.mokni@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #247.
Adds an offline conformance harness so plugin authors can test their
plugins against an in-memory fake host without standing up Postgres /
Redis / the wazero runtime.
What ships
packages/go/plugins/fakehost/— in-memory implementations of everyhost ABI (gn_db_, gn_kv_, gn_cache_invalidate, gn_http_fetch,
gn_media_read, gn_users_read, gn_secrets_get, gn_audit_emit,
gn_cron_register, gn_log, gn_time_ms, gn_i18n_translate,
gn_metric_observe, gn_event_emit, gn_span_event, gn_panic,
http.serve). Every call is recorded as a typed
Eventwith adeterministic clock the test can advance. Capability denial, KV
quotas, scripted HTTP responses, and a secrets bag that never echoes
values into the trace are all wired.
packages/go/plugins/conformance/— scenario runner driving thefake host. Built-in scenarios assert: declared capabilities are in
the v1 vocabulary (plus legacy
hooks.subscribe/jobs.enqueue),capabilities cover the manifest's hook registrations
(
save_post/publish_postneedposts.write), hook names arenon-empty, jobs are namespaced under the plugin slug,
init+teardown is idempotent, and a synthetic 1s budget is
respected. Parses both the v1 manifest schema and the legacy
apiVersion-form (so the existing
examples/plugins/seobundlepasses without modification).
cli/gonext/cmd/plugin/test.go— extended with--suite=conformanceand
--record-fixtures=DIR. The default suite (no flag, or--suite=default) continues to run the existing plugintestcontract checks unchanged — marketplace ingest stays on the stable
shape.
tests/conformance/fixtures/— README + aseo_init.jsonsamplefixture demonstrating the JSON format. The runner's
LoadFixtureScenarioshelper picks*.jsonfiles upautomatically; round-tripping
--record-fixtures→ load iscovered by tests.
Tests
capability gating, secret-trace hiding, scripted HTTP, concurrent
safety).
gonext plugin test --suite=conformance examples/plugins/seoruns end-to-end and reportsconformance PASS — 6 scenarios (0 failed, 1 skipped). (The oneskip is
limits.budget, which reports reasonwasm-not-wired— itupgrades to a real meter check when the runtime is wired to
conformance in a follow-up.)
TestRunTest_Conformance_SEOExamplesmoke-tests the end-to-endpath against
examples/plugins/seofrom the CLI test suite.Out of scope
(driving a plugin's WASM
initfrom the conformance runner). Theconformance package is structured so this drops in as the body of
driveSyntheticInitonce the runtime integration lands.--record-fixturesemits andwhat authors paste back; YAML can be added in a follow-up if
demand materialises.
Run locally:
🤖 Generated with Claude Code