Something went wrong. Try again.
My version of https://github.com/vercel-labs/fx
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187const std = @import("std");const hooks = @import("../hooks/hooks.zig");const notification_contract = @import("../notifications/notification_contract.zig");
pub const Preferences = notification_contract.Preferences;pub const Notification = notification_contract.Notification;const Kind = notification_contract.Kind;const Cue = notification_contract.Cue;const Provider = notification_contract.Provider;
pub fn Runtime( comptime App: type, comptime provider: Provider,) type { return struct { pub fn configure(app: *App) notification_contract.ConfigureError!void { try provider.configure(app); }
pub fn setPreferences(app: *App, next: Preferences) void { provider.set_preferences(app, next); }
pub fn preferences(app: *const App) Preferences { return provider.preferences(app); }
pub fn maxEnabled(app: *const App) bool { return provider.max_enabled(app); }
pub fn queue(app: *App, notification: Notification) void { provider.queue(app, notification); }
pub fn presentationFinished(app: *App) void { provider.presentation_finished(app); }
pub fn flush(app: *App) void { provider.flush(app); }
pub fn playCue(app: *App, cue: Cue) void { provider.play_cue(app, cue); }
pub fn playMaxCue(app: *App, cue: Cue) void { provider.play_max_cue(app, cue); }
pub fn dispatchAttentionRequired( app: *App, turn_id: u64, kind: hooks.AttentionKind, ) void { provider.dispatch_attention_required(app, turn_id, kind); } };}
test "notification runtime routes the full contract through its provider" { const FakeApp = struct { configure_fails: bool = false, configure_count: usize = 0, preferences_value: Preferences = .{}, max_enabled_value: bool = false, queued: ?Notification = null, presentation_finished_count: usize = 0, flush_count: usize = 0, played_cue: ?Cue = null, played_max_cue: ?Cue = null, attention_turn_id: ?u64 = null, attention_kind: ?hooks.AttentionKind = null,
const provider = Provider{ .configure = configureProvider, .set_preferences = setPreferencesProvider, .preferences = preferencesProvider, .max_enabled = maxEnabledProvider, .queue = queueProvider, .presentation_finished = presentationFinishedProvider, .flush = flushProvider, .play_cue = playCueProvider, .play_max_cue = playMaxCueProvider, .dispatch_attention_required = dispatchAttentionRequiredProvider, };
fn configureProvider(raw: *anyopaque) notification_contract.ConfigureError!void { const self: *@This() = @ptrCast(@alignCast(raw)); if (self.configure_fails) return error.RuntimeFrozen; self.configure_count += 1; }
fn setPreferencesProvider(raw: *anyopaque, preferences_value: Preferences) void { const self: *@This() = @ptrCast(@alignCast(raw)); self.preferences_value = preferences_value; }
fn preferencesProvider(raw: *const anyopaque) Preferences { const self: *const @This() = @ptrCast(@alignCast(raw)); return self.preferences_value; }
fn maxEnabledProvider(raw: *const anyopaque) bool { const self: *const @This() = @ptrCast(@alignCast(raw)); return self.max_enabled_value; }
fn queueProvider(raw: *anyopaque, notification: Notification) void { const self: *@This() = @ptrCast(@alignCast(raw)); self.queued = notification; }
fn presentationFinishedProvider(raw: *anyopaque) void { const self: *@This() = @ptrCast(@alignCast(raw)); self.presentation_finished_count += 1; }
fn flushProvider(raw: *anyopaque) void { const self: *@This() = @ptrCast(@alignCast(raw)); self.flush_count += 1; }
fn playCueProvider(raw: *anyopaque, cue: Cue) void { const self: *@This() = @ptrCast(@alignCast(raw)); self.played_cue = cue; }
fn playMaxCueProvider(raw: *anyopaque, cue: Cue) void { const self: *@This() = @ptrCast(@alignCast(raw)); self.played_max_cue = cue; }
fn dispatchAttentionRequiredProvider( raw: *anyopaque, turn_id: u64, kind: hooks.AttentionKind, ) void { const self: *@This() = @ptrCast(@alignCast(raw)); self.attention_turn_id = turn_id; self.attention_kind = kind; } };
const TestRuntime = Runtime(FakeApp, FakeApp.provider); var app = FakeApp{};
app.configure_fails = true; try std.testing.expectError(error.RuntimeFrozen, TestRuntime.configure(&app)); app.configure_fails = false; try TestRuntime.configure(&app); try std.testing.expectEqual(@as(usize, 1), app.configure_count);
const preferences_value = Preferences{ .turn_end = true, .attention_required = true, .max = true, }; TestRuntime.setPreferences(&app, preferences_value); const captured_preferences = TestRuntime.preferences(&app); try std.testing.expect(captured_preferences.turn_end); try std.testing.expect(captured_preferences.attention_required); try std.testing.expect(captured_preferences.max);
app.max_enabled_value = true; try std.testing.expect(TestRuntime.maxEnabled(&app));
TestRuntime.queue(&app, .{ .kind = .turn_end, .cue = .@"error" }); try std.testing.expectEqual(Kind.turn_end, app.queued.?.kind); try std.testing.expectEqual(Cue.@"error", app.queued.?.cue);
TestRuntime.presentationFinished(&app); TestRuntime.flush(&app); try std.testing.expectEqual(@as(usize, 1), app.presentation_finished_count); try std.testing.expectEqual(@as(usize, 1), app.flush_count);
TestRuntime.playCue(&app, .bloom); TestRuntime.playMaxCue(&app, .toggle); try std.testing.expectEqual(Cue.bloom, app.played_cue.?); try std.testing.expectEqual(Cue.toggle, app.played_max_cue.?);
TestRuntime.dispatchAttentionRequired(&app, 42, .permission); try std.testing.expectEqual(@as(u64, 42), app.attention_turn_id.?); try std.testing.expectEqual(hooks.AttentionKind.permission, app.attention_kind.?);}