PranitInitial commit439f83c2 months agoHistory
144 lines · 5.2 KB · Zig
RawDownload
const std = @import("std");const host = @import("../hosts/host.zig");const composer_selection = @import("../input/composer_selection.zig");const composer_replacement = @import("../input/composer_replacement.zig");const composer_undo = @import("../input/composer_undo.zig");const edit_history = @import("../input/edit_history.zig");const editor_state = @import("../input/editor_state.zig");const input_limit_rejection = @import("../input/input_limit_rejection.zig");const picker_state = @import("../input/picker_state.zig");const registered_entities = @import("../input/registered_entities.zig");const vertical_navigation = @import("../input/vertical_navigation.zig"); pub const ClipboardResult = enum {    inactive,    copied,    cut,    copy_failed,    delete_failed,}; pub fn copySelection(    edit: *const editor_state.State,    clipboard: host.Clipboard,) ClipboardResult {    const selected = edit.selectedText() orelse return .inactive;    if (!(clipboard.copy(selected) catch false)) return .copy_failed;    return .copied;} pub fn cutSelection(    alloc: std.mem.Allocator,    selection: composer_selection.State,    pending_images: ?*composer_replacement.ImageBlocks,    clipboard: host.Clipboard,) ClipboardResult {    const selected = selection.selectedText() orelse return .inactive;    if (!(clipboard.copy(selected) catch false)) return .copy_failed;    if (!selection.delete(alloc, pending_images)) return .delete_failed;    return .cut;} const TestInput = struct {    edit: editor_state.State = .{},    history: edit_history.State = .{},    picker: picker_state.State = .{},    entities: registered_entities.State = .{},    vertical_navigation: vertical_navigation.State = .{},    input_limit_rejection: input_limit_rejection.State = .{},     fn deinit(self: *TestInput, alloc: std.mem.Allocator) void {        self.edit.deinit(alloc);        self.history.deinit(alloc);        self.picker.deinit(alloc);        self.entities.deinit(alloc);    }     fn selection(self: *TestInput) composer_selection.State {        return .{ .insertion = .{            .edit = &self.edit,            .history = &self.history,            .picker = &self.picker,            .entities = &self.entities,            .vertical_navigation = &self.vertical_navigation,            .input_limit_rejection = &self.input_limit_rejection,        } };    }     fn undo(self: *TestInput) composer_undo.State {        return .{            .edit = &self.edit,            .history = &self.history,            .picker = &self.picker,            .entities = &self.entities,            .vertical_navigation = &self.vertical_navigation,            .input_limit_rejection = &self.input_limit_rejection,        };    }}; const TestClipboard = struct {    copied: std.ArrayList(u8) = .empty,    succeed: bool = true,     fn deinit(self: *TestClipboard, alloc: std.mem.Allocator) void {        self.copied.deinit(alloc);    }     fn clipboard(self: *TestClipboard) host.Clipboard {        return .{ .context = self, .copy_fn = copy };    }     fn copy(raw_context: ?*anyopaque, bytes: []const u8) host.ClipboardError!bool {        const self: *TestClipboard = @ptrCast(@alignCast(raw_context.?));        if (!self.succeed) return false;        self.copied.appendSlice(std.testing.allocator, bytes) catch return error.CopyFailed;        return true;    }}; test "selection clipboard operations copy before cut" {    const alloc = std.testing.allocator;    var input: TestInput = .{};    defer input.deinit(alloc);    try input.edit.setText(alloc, "alpha beta");    _ = input.selection().begin(0);    _ = input.selection().extend("alpha".len);     var test_clipboard: TestClipboard = .{};    defer test_clipboard.deinit(alloc);    try std.testing.expectEqual(        ClipboardResult.copied,        copySelection(&input.edit, test_clipboard.clipboard()),    );    try std.testing.expectEqualStrings("alpha", test_clipboard.copied.items);    try std.testing.expectEqualStrings("alpha beta", input.edit.input.items);     test_clipboard.copied.clearRetainingCapacity();    try std.testing.expectEqual(        ClipboardResult.cut,        cutSelection(alloc, input.selection(), null, test_clipboard.clipboard()),    );    try std.testing.expectEqualStrings("alpha", test_clipboard.copied.items);    try std.testing.expectEqualStrings(" beta", input.edit.input.items);    try std.testing.expect(try input.undo().undo(alloc));    try std.testing.expectEqualStrings("alpha beta", input.edit.input.items);} test "failed clipboard copy preserves selection and text" {    const alloc = std.testing.allocator;    var input: TestInput = .{};    defer input.deinit(alloc);    try input.edit.setText(alloc, "alpha beta");    _ = input.selection().begin(0);    _ = input.selection().extend("alpha".len);     var test_clipboard: TestClipboard = .{ .succeed = false };    defer test_clipboard.deinit(alloc);    try std.testing.expectEqual(        ClipboardResult.copy_failed,        cutSelection(alloc, input.selection(), null, test_clipboard.clipboard()),    );    try std.testing.expectEqualStrings("alpha beta", input.edit.input.items);    try std.testing.expectEqualStrings("alpha", input.selection().selectedText().?);}