summaryrefslogtreecommitdiff
path: root/test/macos_e2e.swift
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-08-16 15:49:12 -0300
committerGabriel Schneider <[email protected]>2026-08-18 23:44:42 -0300
commit1551e409c31992437cb2fa864f576d45c8433801 (patch)
treee2fae8451f87b735a1360c7c2e383fdc40165789 /test/macos_e2e.swift
parentbe2a9957708cbf0c478ca861c4a1f0f227bbfe10 (diff)
downloadpardes-1551e409c31992437cb2fa864f576d45c8433801.tar.gz
pardes-1551e409c31992437cb2fa864f576d45c8433801.zip
big slow change: prebuilt shaders (SPIR-V/Metal), core gui reflow, docs, web + snapshot refresh
Diffstat (limited to 'test/macos_e2e.swift')
-rw-r--r--test/macos_e2e.swift69
1 files changed, 68 insertions, 1 deletions
diff --git a/test/macos_e2e.swift b/test/macos_e2e.swift
index 16992271..93019403 100644
--- a/test/macos_e2e.swift
+++ b/test/macos_e2e.swift
@@ -91,6 +91,7 @@ private final class Driver: PardesViewDelegate {
private var booted = false
private var observer: NSObjectProtocol?
private var output = ""
+ private var nextAnimationFrame: Date?
/// The script's own file name, for error messages.
private let scriptName: String
@@ -201,6 +202,9 @@ private final class Driver: PardesViewDelegate {
// seeded below are the core's only notion of cell size.
view.delegate = self
pardesViewDidResize(view)
+ // The resize pump adopts a startup-config Font before this report.
+ // Match the app's ordering so Config sees the actual initial face.
+ view.reportEffectiveFont()
}
func shutdown() {
@@ -266,6 +270,19 @@ private final class Driver: PardesViewDelegate {
/// without which run(until:) returns instantly and this becomes a spin.
private func idle() {
RunLoop.current.run(until: Date().addingTimeInterval(pollInterval))
+ let now = Date()
+ guard pardes_animating() else {
+ nextAnimationFrame = nil
+ return
+ }
+ guard let due = nextAnimationFrame else {
+ nextAnimationFrame = now.addingTimeInterval(1.0 / 60.0)
+ return
+ }
+ guard now >= due else { return }
+ _ = pardes_animation_tick()
+ nextAnimationFrame = now.addingTimeInterval(1.0 / 60.0)
+ pump()
}
// MARK: - waiting
@@ -496,6 +513,16 @@ private final class Driver: PardesViewDelegate {
throw ScriptError(message: "wearing \(view.faceName.debugDescription), wanted \(rest.debugDescription)")
}
+ // The host-owned half of Config's font tuple. Unlike a grid snapshot,
+ // this observes the point size CoreText is actually wearing and catches
+ // a zoom which resized cells but forgot to acknowledge runtime state.
+ case "font-size":
+ let view = try live()
+ let want = try double(args, 0, "font-size points")
+ guard abs(Double(view.effectivePointSize) - want) < 0.005 else {
+ throw ScriptError(message: "wearing \(view.effectivePointSize)pt, wanted \(want)pt")
+ }
+
// Cmd+ / Cmd- / Cmd+0, minus the menu. What the grid does afterwards
// is the assertion: a bigger cell fits fewer columns in the same
// window, so a zoom that changed nothing shows up as a golden that
@@ -641,7 +668,8 @@ private final class Driver: PardesViewDelegate {
// by the RELEASE SPEED, and a script that could only turn the dial
// could never throw it — NSEvent phases have no public constructor, so
// this entry point is the only way the momentum path is reachable at
- // all. The coast is then spent by the pump, at one fixed step per tick.
+ // all. The coast is then spent by idle's display clock, at one fixed
+ // step per animation frame; ordinary pumps do not move it.
case "rotate_end":
let view = try live()
view.rotateEnd()
@@ -723,6 +751,45 @@ private final class Driver: PardesViewDelegate {
guard !rest.isEmpty else { throw ScriptError(message: "draw needs a label") }
try draw(rest)
+ case "draw-effect":
+ let view = try live()
+ guard !rest.isEmpty else { throw ScriptError(message: "draw-effect needs a label") }
+ try draw(rest)
+ guard view.lastFrameUsedPostprocessor else {
+ throw ScriptError(message: "draw-effect \(rest): runtime Metal postprocess was bypassed or failed")
+ }
+
+ // Snapshot and validate the plain panel-track ABI. A subsequent draw
+ // drives those exact records through the runtime-compiled Metal kernel.
+ case "tracks":
+ _ = try live()
+ _ = pardes_frame()
+ let count = Int(pardes_frame_panel_tracks())
+ guard count == args.count else {
+ throw ScriptError(message: "got \(count) panel tracks, wanted \(args.count): \(rest)")
+ }
+ guard count == 0 || pardes_frame_panel_track_list() != nil else {
+ throw ScriptError(message: "panel track count is \(count), but its list is nil")
+ }
+ if let list = pardes_frame_panel_track_list() {
+ for i in 0..<count {
+ let track = list[i]
+ let phase = track.phase == UInt8(PARDES_PANEL_MOVING) ? "moving" :
+ track.phase == UInt8(PARDES_PANEL_OPENING) ? "opening" : "unknown"
+ let effect: String = switch track.effect {
+ case UInt8(PARDES_PANEL_SLIDE): "slide"
+ case UInt8(PARDES_PANEL_ZOOM): "zoom"
+ case UInt8(PARDES_PANEL_DISSOLVE): "dissolve"
+ case UInt8(PARDES_PANEL_ASCII): "ascii"
+ default: "off"
+ }
+ let got = "\(phase):\(effect)"
+ guard got == args[i] else {
+ throw ScriptError(message: "track \(i) is \(got), wanted \(args[i])")
+ }
+ }
+ }
+
default:
throw ScriptError(message: "unknown command \(cmd)")
}