test(conformance): reference-app RUN-conformance harness for web apps#103
Merged
Conversation
…apps Prove rbgo can *run* real Ruby web apps end-to-end (run, not just parse) by driving the Rack call(env) contract directly with a synthetic Rack env — no TCP socket, no network. scripts/conformance/webapp/ stages real .rb apps through the public ruby.Run API and asserts the deterministic response: Stage 1 Pure Rack lambda -> GREEN Stage 2 Rack + ERB view -> GREEN Stage 3 Sinatra DSL (require sinatra/base) -> GAP (no sinatra binding) Stage 4 sqlite3 + ERB/JSON data route -> GREEN Stage 4b ActiveRecord ORM data route -> GAP (go-ruby-activerecord, PR #102) A data-backed route (in-memory sqlite3 seed + query + ERB/JSON render) is servable through rbgo today via the raw sqlite3 binding (stage 4). The Sinatra and ActiveRecord stages feature-detect the require: they assert the real response when the binding is present and otherwise record the exact missing feature, so the suite stays green now and lights up automatically when the binding lands. Test-only package: no new production code, so the 100%-coverage gate (coverpkg=./internal/...) is unaffected. Apps embedded via go:embed so the suite is CWD-independent under the coverage job, on Windows, and under qemu on every 64-bit target. Deterministic and TZ-independent. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…require PR #102 landed the go-ruby-activerecord binding on main, so `require "active_record"` now succeeds — but the binding does not yet implement `ActiveRecord::Schema.define`, so stage 4b's route hard-failed with `NoMethodError: undefined method 'define' for Module`. Feature-detect the specific ORM capability the route uses, mirroring the skip-until-present pattern of the Sinatra stage: a Ruby probe runs the exact chain (establish_connection + Schema.define + create! + where(...).order.to_a) inside a rescue and reports "READY" only when it all runs clean, else "GAP: <ExceptionClass>: <message>". Stage 4b skips-with-gap when the ORM path is incomplete and flips to a hard assertion automatically once the binding gains the methods. Recorded gap: NoMethodError: undefined method 'define' for Module (ActiveRecord::Schema lacks .define). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.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.
What
A reference-app RUN-conformance harness for rbgo — the proof that the embedded interpreter can actually run real Ruby web apps end-to-end (run, not merely parse). It drives the Rack
call(env)contract directly with a synthetic Rack environment (no TCP socket, no network), so it exercises routing → handler → model → view → response entirely through the pure-Go VM.scripts/conformance/webapp/stages real.rbapps through the publicruby.RunAPI and asserts the deterministic response each app prints.Staged results
->(env){[200,…,["hello #{PATH_INFO}"]]}hello /xrequire "erb",ERB.new(…).result(binding))require "sinatra/base",get('/hi'){…})LoadError: cannot load such file -- sinatra/baseLoadError: cannot load such file -- active_record(PR #102 /bind/batch7)A data-backed route is servable through rbgo today via the raw
sqlite3binding (stage 4): an in-memory SQLite DB seeded, queried per request, and rendered as both HTML (ERB) and JSON. The idiomatic ActiveRecord ORM form (stage 4b) is the only piece still missing, pending thego-ruby-activerecordbinding.Gap list for full Sinatra/Rack run-conformance
sinatra/base: need ago-ruby-sinatrabinding (Sinatra::Base, theget/postclass-DSL,params, and the Rack#calladapter).active_record: thego-ruby-activerecordbinding (PR Bind go-ruby-grape, go-ruby-rubocop, go-ruby-xslt and go-ruby-activerecord into rbgo as native modules #102) suppliesActiveRecord::Base/establish_connection/Schema.define/ query interface; stage 4b flips to a hard assertion automatically once it lands.require "rack"itself is aLoadError(rack is not a provided feature); the harness deliberately does not need it — the Rack contract is exercised in plain Ruby.Design
requirefirst — they assert the real response when the binding is present and otherwise record the exact missing feature andt.Skip. The suite is green today and lights up automatically when a binding lands.coverpkg=./internal/...) is unaffected.go:embed(CWD-independent under the coverage job, on Windows, and under qemu on every 64-bit arch); deterministic and TZ-independent.gofmt/go vetclean; fullvmsuite green underTZ=UTC.Do not merge — this is an exploratory baseline for review.
🤖 Generated with Claude Code