PranitInitial commit439f83c3 months agoHistory
159 lines · 5.2 KB · Zig
RawDownload
const std = @import("std");const activity_runtime = @import("../../core/output/activity_runtime.zig");const activity_overlay = @import("activity_overlay.zig");const frame_layout = @import("frame_layout.zig"); pub fn resolve(    projection: activity_runtime.ActivityProjection,    activity: frame_layout.ActivityState,    layout: frame_layout.FrameLayout,) activity_overlay.ActivityPlacement {    return switch (projection) {        .none => .none,        .tool_slot => |slot| if (slot.active)            resolveToolSlot(slot, activity, layout)        else            .none,        .turn_thinking => resolveTransient(activity, layout),    };} fn resolveToolSlot(    slot: activity_runtime.ActivityProjection.ToolSlot,    activity: frame_layout.ActivityState,    layout: frame_layout.FrameLayout,) activity_overlay.ActivityPlacement {    const placement = resolveTransient(activity, layout);    if (slot.thinking_label == null) return placement;    return switch (placement) {        .transient_row => |transient| if (layout.tool_activity_row) |tool_row|            .{ .transient_row = .{                .row = transient.row,                .row_count = transient.row_count,                .gap_above_rows = transient.gap_above_rows,                .footer_clearance_rows = transient.footer_clearance_rows,                .tool_row = tool_row,            } }        else            placement,        .none, .overlay_entry => placement,    };} fn resolveTransient(    activity: frame_layout.ActivityState,    layout: frame_layout.FrameLayout,) activity_overlay.ActivityPlacement {    return switch (activity) {        .thinking => |thinking| if (layout.activity_row) |row|            .{ .transient_row = .{                .row = row,                .row_count = @max(layout.activity_rows, 1),                .gap_above_rows = thinking.gap_above_activity,                .footer_clearance_rows = thinking.footer_gap_after_activity,            } }        else            .none,        .overlay_entry => |row| if (layout.transcript_area.containsRow(row))            .{ .overlay_entry = row }        else            .none,        .none => .none,    };} fn testLayout() frame_layout.FrameLayout {    return frame_layout.solve(.{        .terminal = .{            .rows = 12,            .cols = 80,            .content_bottom = 8,            .divider_top_row = 9,            .input_row = 10,            .divider_bottom_row = 11,            .hint_row = 12,        },        .owned_top = 1,        .footer = .{ .natural_rows = 4, .min_rows = 1, .max_rows = 4 },        .transcript = .{ .natural_visual_rows = 5 },        .activity = .{ .thinking = .{ .gap_above_activity = 1 } },    });} test "activity placement maps projection only through solved layout" {    const layout = testLayout();     try std.testing.expectEqual(        activity_overlay.ActivityPlacement.none,        resolve(.none, .none, layout),    );    switch (resolve(        .{ .turn_thinking = .{ .label = "thinking" } },        .{ .thinking = .{ .gap_above_activity = 1, .footer_gap_after_activity = 1 } },        layout,    )) {        .transient_row => |activity| {            try std.testing.expectEqual(layout.activity_row.?, activity.row);            try std.testing.expectEqual(@as(u16, 1), activity.gap_above_rows);            try std.testing.expectEqual(@as(u16, 1), activity.footer_clearance_rows);        },        .none, .overlay_entry => return error.TestUnexpectedResult,    }     try std.testing.expectEqual(        activity_overlay.ActivityPlacement.none,        resolve(            .{ .turn_thinking = .{ .label = "thinking" } },            .{ .overlay_entry = 99 },            layout,        ),    );} test "active tool slot stays transient when its entry is visible" {    const layout = frame_layout.solve(.{        .terminal = .{            .rows = 12,            .cols = 80,            .content_bottom = 8,            .divider_top_row = 9,            .input_row = 10,            .divider_bottom_row = 11,            .hint_row = 12,        },        .owned_top = 1,        .footer = .{ .natural_rows = 4, .min_rows = 1, .max_rows = 4 },        .transcript = .{ .natural_visual_rows = 8 },        .activity = .{ .thinking = .{ .gap_above_activity = 1 } },    });    const active = activity_runtime.ActivityProjection{ .tool_slot = .{        .entry_id = 9,        .fallback_label = "Running",        .active = true,        .kind = .command,    } };     switch (resolve(        active,        .{ .thinking = .{ .gap_above_activity = 1, .footer_gap_after_activity = 1 } },        layout,    )) {        .transient_row => |placement| {            try std.testing.expectEqual(layout.activity_row.?, placement.row);            try std.testing.expectEqual(@as(u16, 1), placement.gap_above_rows);            try std.testing.expectEqual(@as(u16, 1), placement.footer_clearance_rows);        },        .none, .overlay_entry => return error.TestUnexpectedResult,    }     var terminal = active;    terminal.tool_slot.active = false;    try std.testing.expectEqual(        activity_overlay.ActivityPlacement.none,        resolve(            terminal,            .{ .thinking = .{ .gap_above_activity = 1 } },            layout,        ),    );}