╭ changed ──────╮ │src/test/ui.zig│ ╰───────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────────────────────────────────────────────────────────────────────────────╮ │1 const std = @import("std"); │ │2 +const evt = @import("../event.zig"); │ │3 const ui = @import("../ui.zig"); │ │4 const Commits = @import("../ui/Repo/Commits.zig"); │ │5 +const Events = @import("../ui/Repo/Events.zig"); │ │6 +const xit = @import("xit"); │ │7 │ │8 // the "next" row at the bottom of the commits list must be recognized as a │ │9 // cross-page link (so a click navigates), exactly like the diff pane's "next".│ ╰──────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ 69 const parsed_route = parsed.?.repo_commits; │ │ 70 try std.testing.expectEqual(RP.RefOrOid.branch, parsed_route.ref_or_oid.?); │ │ 71 try std.testing.expectEqualStrings("feature%2Ffoo", parsed_route.value.slice()); │ │ 72 +} │ │ 73 + │ │ 74 +test "sync creates missing event branches and preserves head" { │ │ 75 + const io = std.testing.io; │ │ 76 + const allocator = std.testing.allocator; │ │ 77 + const cwd = std.Io.Dir.cwd(); │ │ 78 + const temp_dir_name = "temp-ui-sync"; │ │ 79 + │ │ 80 + cwd.deleteTree(io, temp_dir_name) catch {}; │ │ 81 + var temp_dir = try cwd.createDirPathOpen(io, temp_dir_name, .{}); │ │ 82 + defer cwd.deleteTree(io, temp_dir_name) catch {}; │ │ 83 + defer temp_dir.close(io); │ │ 84 + │ │ 85 + const cwd_path = try std.process.currentPathAlloc(io, allocator); │ │ 86 + defer allocator.free(cwd_path); │ │ 87 + const local_path = try std.fs.path.join(allocator, &.{ cwd_path, temp_dir_name, "local" }); │ │ 88 + defer allocator.free(local_path); │ │ 89 + const remote_path = try std.fs.path.join(allocator, &.{ cwd_path, temp_dir_name, "remote" }); │ │ 90 + defer allocator.free(remote_path); │ │ 91 + │ │ 92 + const Repo = xit.repo.Repo(.git, .{}); │ │ 93 + const RemoteRepo = xit.repo.Repo(.git, .{}); │ │ 94 + { │ │ 95 + var remote = try RemoteRepo.init(io, allocator, .{ .path = remote_path }); │ │ 96 + remote.deinit(io, allocator); │ │ 97 + } │ │ 98 + { │ │ 99 + var local = try Repo.init(io, allocator, .{ .path = local_path }); │ │100 + defer local.deinit(io, allocator); │ │101 + try local.addConfig(io, allocator, .{ .name = "user.name", .value = "user" }); │ │102 + try local.addConfig(io, allocator, .{ .name = "user.email", .value = "user@haxy" }); │ │103 + { │ │104 + const file = try local.core.work_dir.createFile(io, "keep.txt", .{}); │ │105 + defer file.close(io); │ │106 + try file.writeStreamingAll(io, "keep"); │ │107 + } │ │108 + try local.add(io, allocator, &.{"keep.txt"}); │ │109 + _ = try local.commit(io, allocator, .{ .message = "master" }); │ │110 + try local.addRemote(io, allocator, .{ .name = "origin", .value = remote_path }); │ │111 + │ │112 + const id = [_]u8{1} ** evt.event_id_size; │ │113 + try evt.consume(.git, .{}, io, allocator, &local, evt.events_ref, &.{.{ │ │114 + .id = std.fmt.bytesToHex(id, .lower), │ │115 + .author_email = "user@haxy", │ │116 + .event = .{ .issue = .{ .title = "sync", .description = "", .tags = "" } }, │ │117 + }}); │ │118 + } │ │119 + │ │120 + try std.testing.expectEqual(null, try Events.sync(io, allocator, .{ .path = local_path, .repo_kind = .git }));│ │121 + { │ │122 + var local = try Repo.open(io, allocator, .{ .path = local_path }); │ │123 + defer local.deinit(io, allocator); │ │124 + const id = [_]u8{2} ** evt.event_id_size; │ │125 + try evt.consume(.git, .{}, io, allocator, &local, evt.events_ref, &.{.{ │ │126 + .id = std.fmt.bytesToHex(id, .lower), │ │127 + .author_email = "user@haxy", │ │128 + .event = .{ .issue = .{ .title = "local", .description = "", .tags = "" } }, │ │129 + }}); │ │130 + } │ │131 + { │ │132 + var remote = try RemoteRepo.open(io, allocator, .{ .path = remote_path }); │ │133 + defer remote.deinit(io, allocator); │ │134 + const id = [_]u8{3} ** evt.event_id_size; │ │135 + try evt.consume(.git, .{}, io, allocator, &remote, evt.events_ref, &.{.{ │ │136 + .id = std.fmt.bytesToHex(id, .lower), │ │137 + .author_email = "user@haxy", │ │138 + .event = .{ .issue = .{ .title = "remote", .description = "", .tags = "" } }, │ │139 + }}); │ │140 + } │ │141 + try std.testing.expectEqual(null, try Events.sync(io, allocator, .{ .path = local_path, .repo_kind = .git }));│ │142 + { │ │143 + var local = try Repo.open(io, allocator, .{ .path = local_path }); │ │144 + defer local.deinit(io, allocator); │ │145 + try local.removeBranch(io, .{ .name = evt.events_ref.name }); │ │146 + try evt.consume(.git, .{}, io, allocator, &local, evt.events_ref, &.{}); │ │147 + } │ │148 + try std.testing.expectEqual(null, try Events.sync(io, allocator, .{ .path = local_path, .repo_kind = .git }));│ │149 + │ │150 + var local = try Repo.open(io, allocator, .{ .path = local_path }); │ │151 + defer local.deinit(io, allocator); │ │152 + var head_buffer: [xit.ref.MAX_REF_CONTENT_SIZE]u8 = undefined; │ │153 + const head = try local.head(io, &head_buffer); │ │154 + switch (head) { │ │155 + .ref => |ref| try std.testing.expectEqualStrings("master", ref.name), │ │156 + .oid => return error.TestExpectedEqual, │ │157 + } │ │158 + const kept = try local.core.work_dir.openFile(io, "keep.txt", .{}); │ │159 + kept.close(io); │ │160 + const local_tip = (try local.readRef(io, evt.events_ref)) orelse return error.TestExpectedEqual; │ │161 + │ │162 + var remote = try RemoteRepo.open(io, allocator, .{ .path = remote_path }); │ │163 + defer remote.deinit(io, allocator); │ │164 + const remote_tip = (try remote.readRef(io, evt.events_ref)) orelse return error.TestExpectedEqual; │ │165 + try std.testing.expectEqualStrings(&local_tip, &remote_tip); │ │166 + │ │167 + var start_oids = [_][local_tip.len]u8{local_tip}; │ │168 + var commit_iter = try local.log(io, allocator, &start_oids); │ │169 + defer commit_iter.deinit(); │ │170 + var merge_commit = (try commit_iter.next(allocator)) orelse return error.TestExpectedEqual; │ │171 + defer merge_commit.deinit(); │ │172 + const parent_oids = merge_commit.content.commit.metadata.parent_oids orelse return error.TestExpectedEqual; │ │173 + try std.testing.expectEqual(2, parent_oids.len); │ │174 + │ │175 + var arena = std.heap.ArenaAllocator.init(allocator); │ │176 + defer arena.deinit(); │ │177 + const status = try Events.Header.local(.git, .{}, arena.allocator(), &local, io, null); │ │178 + try std.testing.expectEqualStrings("nothing to sync", status.status); │ │179 } │ │180 │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯