Skip to content

Commit adb2479

Browse files
AndrewAltimitAI Agent BotclaudeAI Review Agent
authored
refactor: backend extension traits, test coverage, JS events, ASAN fix (#54)
* test: add demux error path, streaming throttle, seek interpolation tests Add 49 new pure-logic tests across two crates (PR 6 from refactor plan): demux_lite.rs (21 new tests): - Truncated/empty box headers, invalid box sizes, extended size errors - Zero-size box (extends to EOF), oversized box skipping - Missing moov/empty moov, parse_moov_tracks edge cases - Empty stts/stsc/stsz/stco tables, sample offset/PTS edge cases - AVCC→Annex B: empty data, NAL exceeds bounds, invalid NAL length size - read_desc_len: single/multi/empty, ctts negative offset clamping - find_keyframe_before/find_sample_at with empty tables tv_controller.rs (28 new tests): - should_throttle: extract pure function, test all 12 boundary cases (decoder=0 ± moov ± buf threshold, decoder>0 ± lookahead boundary) - linear_seek_interpolation: extract pure function, test 8 cases (zero/half/full/beyond duration, zero/negative duration, small/large files) - parse_moov_duration: v0, zero timescale, missing mvhd, too short - maybe_evict: 5 tests (small buffer, large buffer, disabled, cursor at start, preserves data near cursor) Also refactors inline seek interpolation formulas to use the extracted linear_seek_interpolation() helper for consistency and testability. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * test: add input mapping + color conversion unit tests across backends Add ~85 pure-logic unit tests covering: SDL backend (lib.rs): key_up edge cases (Backspace/F11 not mapped), F-key coverage, letter-key selectivity, wheel delta sign inversion, mouse coordinate truncation, frect/fpoint conversion helpers. WASM backend (input.rs): Extract scale_point_math() pure function from scale_point() for testable letterbox coordinate scaling. 19 tests cover identity, 2x scaling, horizontal/vertical letterboxing, clamping, aspect ratio variations, zero-size elements, fractional coords, DPI. PSP backend (input.rs): Extract analog_to_cursor_delta(), clamp_cursor(), apply_deadzone() helpers. 15 tests for deadzone threshold, cursor speed, boundary clamping, button/trigger map completeness, constant values. PSP backend (lib.rs): Add from_abgr() decode function and 20 tests for RGBA-to-ABGR encode, decode, and round-trip for all primary colors, transparent, arbitrary values, min/max channels. UE5 backend (input.rs): 8 additional tests for coordinate passthrough, boundary values, multiple poll drain cycles, all-button round-trip. UE5 backend (renderer.rs): 28 tests for lerp_u8 endpoints/midpoint/ zero-denominator, lerp_color, intersect_clip, RGBA buffer layout for all primary colors, alpha blending, transparency, out-of-bounds pixel safety, and RGBA encode/decode round-trip. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: backend extension traits, 200+ tests, JS event dispatch, ASAN fix Backend trait surface area: - Split SdiBackend (48 methods) into 8 focused extension traits (SdiShapes, SdiGradients, SdiAlpha, SdiText, SdiTextures, SdiClipTransform, SdiVector, SdiBatch) with blanket impls - Remove dead code: draw_text_weighted (never overridden) - Existing SdiBackend kept intact for backwards compat (Phase 1) Test coverage (~200 new tests): - Input mapping: SDL (13), WASM (19), PSP (15), UE5 (8) tests - Color/pixel conversion: PSP ABGR (20), UE5 RGBA/lerp/clip (28) tests - Video demux: 21 error path tests (truncated headers, missing atoms, empty sample tables, AVCC edge cases) - Streaming: 28 tests (throttle logic, seek interpolation, moov parsing, buffer eviction) with extracted pure helper functions Browser JS runtime: - Retain JsEngine beyond page load (stored in BrowserWidget) - Event bubbling via __oasis_dispatch_with_bubbling (target→root) - stopPropagation, preventDefault, target/currentTarget support - Hit-test clicks through layout tree to dispatch to JS listeners - 8 new JS event dispatch tests CI fixes: - Fix ASAN "incompatible runtimes" by removing CFLAGS=-fsanitize=address (SDL3 C code conflicted with Rust's ASan runtime) - Expand memory-ci PR trigger paths (oasis-app, backend-sdl, backend-ue5, oasis-types, Cargo.toml/lock) - Add advisory nightly clippy step to PR validation pipeline - Fix unused_comparisons warning in oasis-vector anim.rs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: update backend method counts (30→39), JS runtime, plan status - CLAUDE.md: SdiBackend 39 methods + 8 extension traits, JS event dispatch - design.md: update method counts in 2 locations - ADR 003: update method counts, document extension traits - AGENTS.md: update method count - Plan doc: mark Phase 1 as implemented Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * ci: disable benchmarks in PR validation pipeline Benchmarks add significant time to PR validation without blocking value. They can be run manually or in main-ci instead. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * ci: use if conditional for benchmarks instead of comment block Benchmarks now only run on workflow_dispatch, skipped for PRs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: SdiVector defaults use triangle fan + line segments, not bounding boxes Change SdiVector supertrait from SdiCore to SdiShapes so defaults can use ext_fill_triangle (triangle fan decomposition) for polygons/arcs and ext_draw_line for stroke outlines instead of crude fill_rect bounding boxes. Addresses Gemini review feedback on PR #54. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: address AI review feedback (iteration 2) Automated fix by Claude in response to Gemini/Codex review. Iteration: 2/5 Co-Authored-By: AI Review Agent <noreply@anthropic.com> * fix: auto-format + update pre-commit to run cargo fmt on commit - Fix formatting in SdiVector extension trait defaults - Update pre-commit config: cargo fmt auto-fixes on commit (local, not Docker), clippy runs on pre-push only (too slow per commit) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: AI Agent Bot <ai-agent@localhost> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: AI Review Agent <ai-review-agent@localhost>
1 parent 227b6db commit adb2479

File tree

23 files changed

+3420
-182
lines changed

23 files changed

+3420
-182
lines changed

.github/workflows/memory-ci.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ on:
88
paths:
99
- 'crates/oasis-video/**'
1010
- 'crates/oasis-core/**'
11+
- 'crates/oasis-app/**'
12+
- 'crates/oasis-backend-sdl/**'
13+
- 'crates/oasis-backend-ue5/**'
14+
- 'crates/oasis-types/**'
15+
- 'Cargo.toml'
16+
- 'Cargo.lock'
1117
- '.github/workflows/memory-ci.yml'
1218
workflow_dispatch:
1319

@@ -54,7 +60,6 @@ jobs:
5460
set -o pipefail
5561
docker compose --profile ci run --rm \
5662
-e RUSTFLAGS="-Zsanitizer=address" \
57-
-e CFLAGS="-fsanitize=address" \
5863
-e ASAN_OPTIONS="detect_leaks=1:halt_on_error=0:print_summary=1" \
5964
-e SDL_VIDEODRIVER=dummy \
6065
rust-ci bash -c "

.github/workflows/pr-validation.yml

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,14 @@ jobs:
7272
- name: Clippy
7373
run: docker compose --profile ci run --rm rust-ci cargo clippy --workspace -- -D warnings
7474

75+
# -- Nightly Warnings Check (advisory) -----------------------------------
76+
- name: Nightly warnings check
77+
continue-on-error: true
78+
run: >
79+
docker compose --profile ci run --rm rust-ci
80+
cargo +nightly clippy --workspace -- -D warnings
81+
-W unused-comparisons
82+
7583
# -- Documentation ------------------------------------------------------
7684
- name: Doc build
7785
run: >
@@ -128,8 +136,9 @@ jobs:
128136
- name: cargo-deny
129137
run: docker compose --profile ci run --rm rust-ci cargo deny check
130138

131-
# -- Benchmarks --------------------------------------------------------
139+
# -- Benchmarks (disabled by default, enable via workflow_dispatch) ------
132140
- name: Benchmarks
141+
if: github.event_name == 'workflow_dispatch'
133142
run: |
134143
set -o pipefail
135144
docker compose --profile ci run --rm rust-ci \
@@ -139,7 +148,7 @@ jobs:
139148
echo "::endgroup::"
140149
141150
- name: Upload benchmark results
142-
if: always()
151+
if: github.event_name == 'workflow_dispatch'
143152
uses: actions/upload-artifact@v4
144153
with:
145154
name: benchmark-results

.pre-commit-config.yaml

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,20 +37,21 @@ repos:
3737
types: [shell]
3838
args: [-x]
3939

40-
# Rust formatting and linting (containerized)
40+
# Rust formatting (auto-fix, runs locally for speed)
4141
- repo: local
4242
hooks:
43-
# oasis_os workspace (stable toolchain)
4443
- id: rust-fmt-oasis
4544
name: Rust format oasis_os
46-
entry: docker compose --profile ci run --rm rust-ci cargo fmt --all -- --check
45+
entry: bash -c 'source "$HOME/.cargo/env" 2>/dev/null || true; cargo fmt --all'
4746
language: system
48-
files: '^crates/.*\.rs$'
47+
files: '\.rs$'
4948
pass_filenames: false
5049

50+
# Clippy on pre-push only (too slow for every commit)
5151
- id: rust-clippy-oasis
5252
name: Rust lint oasis_os
53-
entry: docker compose --profile ci run --rm rust-ci cargo clippy --workspace -- -D warnings
53+
entry: bash -c 'source "$HOME/.cargo/env" 2>/dev/null || true; cargo clippy --workspace -- -D warnings'
5454
language: system
55-
files: '^crates/.*\.rs$'
55+
files: '\.rs$'
5656
pass_filenames: false
57+
stages: [pre-push]

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ oasis-types (foundation: Color, Button, InputEvent, backend traits, error ty
9393

9494
`oasis-types/src/backend.rs` defines the only abstraction between core and platform (re-exported by `oasis-core`):
9595
- `SdiCore` -- required rendering (13 methods: init, clear, blit, fill_rect, draw_text, swap_buffers, load_texture, destroy_texture, set_clip_rect, reset_clip_rect, measure_text, read_pixels, shutdown)
96-
- `SdiBackend` -- extends `SdiCore` with 30 optional accelerated primitives (shapes, gradients, text styling, batching)
96+
- `SdiBackend` -- extends `SdiCore` with 39 optional accelerated primitives (shapes, gradients, text styling, vector graphics, batching)
9797
- `InputBackend` -- input polling (returns `Vec<InputEvent>`)
9898
- `NetworkBackend` -- TCP networking
9999
- `AudioBackend` -- audio playback

CLAUDE.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ cargo run -p oasis-app --bin oasis-screenshot
6060

6161
## CI Pipeline Order
6262

63-
format check -> clippy -> doc build -> markdown link check -> test -> release build -> screenshot regression -> cargo-deny -> benchmarks -> PSP EBOOT build -> PPSSPP headless test -> code coverage -> GitHub Pages deploy (WASM)
63+
format check -> clippy -> nightly clippy (advisory) -> doc build -> markdown link check -> test -> release build -> screenshot regression -> cargo-deny -> PSP EBOOT build -> PPSSPP headless test -> code coverage -> GitHub Pages deploy (WASM)
6464

6565
All steps run via `docker compose --profile ci run --rm rust-ci`.
6666

@@ -130,7 +130,7 @@ TV Guide on desktop uses in-process progressive streaming via `StreamingBuffer`
130130

131131
`oasis-types/src/backend.rs` defines the only abstraction boundary between core and platform (re-exported by `oasis-core`):
132132
- `SdiCore` -- required rendering (13 methods: init, clear, blit, fill_rect, draw_text, swap_buffers, load_texture, destroy_texture, set_clip_rect, reset_clip_rect, measure_text, read_pixels, shutdown)
133-
- `SdiBackend` -- extends `SdiCore` with 30+ optional accelerated primitives (shapes, gradients, text styling, batching, vector graphics path operations)
133+
- `SdiBackend` -- extends `SdiCore` with 39 optional accelerated primitives (shapes, gradients, text styling, batching, vector graphics path operations). Also split into 8 focused extension traits: `SdiShapes`, `SdiGradients`, `SdiAlpha`, `SdiText`, `SdiTextures`, `SdiClipTransform`, `SdiVector`, `SdiBatch`
134134
- `InputBackend` -- input polling (returns `Vec<InputEvent>`)
135135
- `NetworkBackend` -- TCP networking
136136
- `AudioBackend` -- audio playback
@@ -145,7 +145,7 @@ The framework is split into 20 workspace crates. Each module below is its own cr
145145
- **oasis-sdi** -- Scene Display Interface: named objects with position, size, color, texture, text, z-order, gradients, rounded corners, shadows
146146
- **oasis-skin** -- Data-driven TOML skin system with 18 skins (12 external TOML in `skins/`, 18 built-in). Theme derivation from 9 base colors.
147147
- **oasis-browser** -- Embeddable HTML/CSS/Gemini rendering engine: DOM parser, CSS cascade, block/inline/table layout, link navigation, reader mode, JavaScript DOM bindings
148-
- **oasis-js** -- JavaScript engine wrapping QuickJS-NG via rquickjs: `console` API (log/warn/error/info), inline `<script>` execution, DOM manipulation (`document.getElementById`, `createElement`, `textContent`, attributes). Feature-gated (`javascript`)
148+
- **oasis-js** -- JavaScript engine wrapping QuickJS-NG via rquickjs: `console` API (log/warn/error/info), inline `<script>` execution, DOM manipulation (`document.getElementById`, `createElement`, `textContent`, attributes), retained engine with event dispatch (click bubbling via `__oasis_dispatch_with_bubbling`, `stopPropagation`/`preventDefault`). Feature-gated (`javascript`)
149149
- **oasis-ui** -- 27 reusable widgets: Button, Card, TabBar, Panel, TextField, ListView, ScrollView, ProgressBar, Toggle, NinePatch, flex layout, Accordion, Avatar, Badge, Checkbox, Dropdown, Modal, Slider, Spinner, Toast, Tooltip, TreeView, and more
150150
- **oasis-vfs** -- Virtual file system: `MemoryVfs` (in-RAM), `RealVfs` (disk), `GameAssetVfs` (UE5 with overlay writes)
151151
- **oasis-terminal** -- Command interpreter with 90+ commands across 17 modules (core, text, file, system, dev, fun, security, doc, audio, network, skin, UI, plus agent/plugin/script/transfer/update registered by oasis-core). Shell features: variable expansion, glob expansion, aliases, history, piping

0 commit comments

Comments
 (0)