-
-
Notifications
You must be signed in to change notification settings - Fork 0
rescue: INT-02 / INT-09 / INT-11 — recover stranded feature work from a deleted checkout #708
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| #!/usr/bin/env bash | ||
| # SPDX-License-Identifier: MPL-2.0 | ||
| # End-to-end runtime test for the CadreRouter JS wrapper. | ||
|
|
||
| set -uo pipefail | ||
| cd "$(dirname "$0")" | ||
| REPO="$(cd ../.. && pwd)" | ||
| BIN="${AFFINESCRIPT_BIN:-$REPO/_build/default/bin/main.exe}" | ||
|
|
||
| if [ ! -x "$BIN" ]; then | ||
|
Check failure on line 10 in affinescript-cadre/e2e/run.sh
|
||
| echo "SKIP: compiler not built ($BIN missing) — run dune build" | ||
| exit 0 | ||
| fi | ||
|
|
||
| command -v node >/dev/null 2>&1 || { echo "SKIP: node not on PATH"; exit 0; } | ||
|
|
||
| TMP="$(mktemp -d)" | ||
| trap 'rm -rf "$TMP"' EXIT | ||
|
|
||
| # Generate the Wasm router module | ||
| "$BIN" router-bridge -o "$TMP/router.wasm" | ||
|
|
||
| # Run the Node test | ||
| node test.mjs "$TMP/router.wasm" | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| // SPDX-License-Identifier: MPL-2.0 | ||
| // e2e test for the CadreRouter JS wrapper. | ||
|
|
||
| import assert from 'node:assert/strict'; | ||
| import { CadreRouter } from '../src/CadreRouter.js'; | ||
|
|
||
| async function main() { | ||
| const wasmPath = process.argv[2] || './router.wasm'; | ||
| const router = await CadreRouter.create(wasmPath, { base: import.meta.url }); | ||
|
|
||
| // Initial State assertions | ||
| assert.equal(router.screenW, 1280, 'Initial screen width should be 1280'); | ||
| assert.equal(router.screenH, 720, 'Initial screen height should be 720'); | ||
| assert.equal(router.stackLen, 0, 'Initial stack should be empty'); | ||
| assert.equal(router.stackTop, -1, 'Initial stack top should be -1'); | ||
| assert.equal(router.popupTag, -1, 'Initial popup tag should be -1'); | ||
|
|
||
| // Push a screen | ||
| router.push(4); // 4 = Game | ||
| assert.equal(router.stackLen, 1, 'Stack length should be 1 after push'); | ||
| assert.equal(router.stackTop, 4, 'Stack top should be 4 (Game)'); | ||
|
|
||
| // Push another screen | ||
| router.push(1); // 1 = CharacterSelect | ||
| assert.equal(router.stackLen, 2, 'Stack length should be 2 after push'); | ||
| assert.equal(router.stackTop, 1, 'Stack top should be 1 (CharacterSelect)'); | ||
|
|
||
| // Resize | ||
| router.resize(1920, 1080); | ||
| assert.equal(router.screenW, 1920, 'Width should be updated to 1920'); | ||
| assert.equal(router.screenH, 1080, 'Height should be updated to 1080'); | ||
|
|
||
| // Pop | ||
| router.pop(); | ||
| assert.equal(router.stackLen, 1, 'Stack length should be 1 after pop'); | ||
| assert.equal(router.stackTop, 4, 'Stack top should be 4 (Game) after pop'); | ||
|
|
||
| // Popup | ||
| router.presentPopup(2); // 2 = Hacking | ||
| assert.equal(router.popupTag, 2, 'Popup tag should be 2 (Hacking)'); | ||
|
|
||
| router.dismissPopup(); | ||
| assert.equal(router.popupTag, -1, 'Popup tag should be -1 after dismiss'); | ||
|
|
||
| console.log('ALL ASSERTIONS PASS — CadreRouter ran end-to-end'); | ||
| } | ||
|
|
||
| main().catch((err) => { | ||
|
Check warning on line 48 in affinescript-cadre/e2e/test.mjs
|
||
| console.error(err); | ||
| process.exit(1); | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| { | ||
| "name": "@hyperpolymath/affinescript-cadre", | ||
| "version": "0.1.0", | ||
| "description": "Router and Navigation runtime for AffineScript", | ||
| "type": "module", | ||
| "main": "src/CadreRouter.js", | ||
| "scripts": { | ||
| "test": "./e2e/run.sh" | ||
| }, | ||
| "author": "Jonathan D.A. Jewell", | ||
| "license": "MPL-2.0" | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| // SPDX-License-Identifier: MPL-2.0 | ||
| // Cadre Router runtime wrapping the affine-js loader and tea_router wasm. | ||
|
|
||
| import { readBytes, buildImportObject } from '../../packages/affine-js/loader.js'; | ||
|
|
||
| export class CadreRouter { | ||
| constructor(instance) { | ||
| this.exports = instance.exports; | ||
| } | ||
|
|
||
| /** | ||
| * Initialize a new CadreRouter instance from a WASM module. | ||
| * @param {string | URL} wasmSource | ||
| * @param {{ base?: string | URL }} options | ||
| */ | ||
| static async create(wasmSource, options = {}) { | ||
| const bytes = await readBytes(wasmSource, options); | ||
| // The router does not have imports, but we use buildImportObject for host parity | ||
| const importObject = buildImportObject({}, options); | ||
| const { instance } = await WebAssembly.instantiate(bytes, importObject); | ||
| const router = new CadreRouter(instance); | ||
| router.exports.affinescript_router_init(); | ||
| return router; | ||
| } | ||
|
|
||
| // --- Actions --- | ||
|
|
||
| push(screenTag) { | ||
| this.exports.affinescript_router_push(screenTag); | ||
| } | ||
|
|
||
| pop() { | ||
| this.exports.affinescript_router_pop(); | ||
| } | ||
|
|
||
| presentPopup(popupTag) { | ||
| this.exports.affinescript_router_present_popup(popupTag); | ||
| } | ||
|
|
||
| dismissPopup() { | ||
| this.exports.affinescript_router_dismiss_popup(); | ||
| } | ||
|
|
||
| resize(w, h) { | ||
| this.exports.affinescript_router_resize(w, h); | ||
| } | ||
|
|
||
| // --- Getters --- | ||
|
|
||
| get screenW() { | ||
| return this.exports.affinescript_router_get_screen_w(); | ||
| } | ||
|
|
||
| get screenH() { | ||
| return this.exports.affinescript_router_get_screen_h(); | ||
| } | ||
|
|
||
| get stackLen() { | ||
| return this.exports.affinescript_router_get_stack_len(); | ||
| } | ||
|
|
||
| get stackTop() { | ||
| return this.exports.affinescript_router_get_stack_top(); | ||
| } | ||
|
|
||
| get popupTag() { | ||
| return this.exports.affinescript_router_get_popup_tag(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| <!DOCTYPE html> | ||
| <html lang="en"> | ||
| <head> | ||
| <meta charset="UTF-8"> | ||
| <title>AffineScript DOM Reconciler - Browser Test</title> | ||
| <style> | ||
| body { font-family: system-ui, sans-serif; padding: 2rem; } | ||
| #status { font-weight: bold; padding: 1rem; border-radius: 4px; } | ||
| .success { background: #d4edda; color: #155724; } | ||
| .error { background: #f8d7da; color: #721c24; } | ||
| pre { background: #f8f9fa; padding: 1rem; overflow-x: auto; } | ||
| </style> | ||
| </head> | ||
| <body> | ||
| <h1>AffineScript DOM Reconciler E2E Test</h1> | ||
| <div id="status">Running tests...</div> | ||
|
|
||
| <h3>Logs</h3> | ||
| <pre id="logs"></pre> | ||
|
|
||
| <script type="module"> | ||
| const statusEl = document.getElementById('status'); | ||
| const logsEl = document.getElementById('logs'); | ||
|
|
||
| // Capture console.log to show on page | ||
| const originalLog = console.log; | ||
| console.log = (...args) => { | ||
| originalLog(...args); | ||
| logsEl.textContent += args.join(' ') + '\n'; | ||
| }; | ||
|
|
||
| try { | ||
| // Import the host-agnostic mjs script | ||
| await import('./dom_host.mjs'); | ||
| statusEl.textContent = '✅ ALL ASSERTIONS PASS — reconciler ran end-to-end in the browser!'; | ||
| statusEl.className = 'success'; | ||
| } catch (err) { | ||
| console.error(err); | ||
| statusEl.textContent = '❌ TEST FAILED: ' + err.message; | ||
| statusEl.className = 'error'; | ||
| } | ||
| </script> | ||
| </body> | ||
| </html> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| #!/usr/bin/env bash | ||
| # SPDX-License-Identifier: MPL-2.0 | ||
| # Manual browser host parity test (INT-11). | ||
| # Compiles the reconciler and serves browser_test.html locally. | ||
|
|
||
| set -uo pipefail | ||
| cd "$(dirname "$0")" | ||
| REPO="$(cd ../.. && pwd)" | ||
| BIN="${AFFINESCRIPT_BIN:-$REPO/_build/default/bin/main.exe}" | ||
|
|
||
| if [ ! -x "$BIN" ]; then | ||
|
Check failure on line 11 in affinescript-dom/e2e/run_browser.sh
|
||
| echo "ERROR: compiler not built ($BIN missing) — run dune build first." | ||
|
Check warning on line 12 in affinescript-dom/e2e/run_browser.sh
|
||
| exit 1 | ||
| fi | ||
|
|
||
| echo "Compiling reconciler to WASM..." | ||
| cat ../src/dom.affine driver_main.affine > dom_drive.affine | ||
| "$BIN" compile dom_drive.affine -o dom_drive.wasm | ||
| rm dom_drive.affine | ||
|
|
||
| echo "" | ||
| echo "==========================================================" | ||
| echo "WASM compiled successfully. Starting local HTTP server..." | ||
| echo "Please open your browser to: http://localhost:8080/browser_test.html" | ||
| echo "Check the page to verify ALL ASSERTIONS PASS." | ||
| echo "Press Ctrl+C to stop the server and clean up." | ||
| echo "==========================================================" | ||
| echo "" | ||
|
|
||
| # Cleanup wasm on exit | ||
| trap 'rm -f dom_drive.wasm' EXIT | ||
|
|
||
| python3 -m http.server 8080 | ||
Uh oh!
There was an error while loading. Please reload this page.