╭ changed ────╮ │src/event.zig│ ╰─────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────╮ │172 } │ │173 } │ │174 } │ │175 + if (repo_events.items.len == 0) return; │ │176 │ │177 // if this branch was rebased and force pushed, we need to detect that and│ │178 // properly revert the haxy state to the last valid state. we detect this │ ╰───────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ─────────╮ │src/test/event.zig│ ╰──────────────────╯ ╭────────────────────────────────────────────────────────────────────────╮ │31 const Repo = rp.Repo(.xit, repo_opts); │ │32 var repo = try Repo.init(io, allocator, .{ .path = work_path });│ │33 defer repo.deinit(io, allocator); │ │34 + │ │35 + var arena = std.heap.ArenaAllocator.init(allocator); │ │36 + defer arena.deinit(); │ │37 │ │38 // │ │39 // define test events │ ╰────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────╮ │91 // insert issues as commits in the repo │ │92 // │ │93 │ │91 - var arena = std.heap.ArenaAllocator.init(allocator); │ │92 - defer arena.deinit(); │ │93 - │ │94 var first_oid: [hash.byteLen(repo_opts.hash)]u8 = undefined;│ │95 │ │96 { │ ╰────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │153 │ │154 // the tags were correctly edited │ │155 try std.testing.expectEqualStrings(events_to_consume[1].data.issue.tags, first_issue.issue.tags); │ │156 + } │ │157 + │ │158 + // │ │159 + // add another event │ │160 + // │ │161 + │ │162 + const events_to_consume2 = [_]evt.Event{ │ │163 + .{ │ │164 + .id = std.fmt.bytesToHex(evt.randomId(prng.random()), .lower), │ │165 + .data = .{ │ │166 + .issue = .{ │ │167 + .title = "Double clicking causes the form to submit twice", │ │168 + .description = "When I double click the post button I see duplicate posts.", │ │169 + .tags = "bug\x00priority-high\x00ui", │ │170 + }, │ │171 + }, │ │172 + }, │ │173 + }; │ │174 + │ │175 + { │ │176 + var json: std.Io.Writer.Allocating = .init(std.testing.allocator); │ │177 + defer json.deinit(); │ │178 + │ │179 + for (events_to_consume2) |event| { │ │180 + json.clearRetainingCapacity(); │ │181 + │ │182 + try std.json.Stringify.value(event, .{}, &json.writer); │ │183 + │ │184 + // commit the event into a special branch │ │185 + _ = try repo.commitAtRef(io, allocator, .{ .message = json.written() }, null, .{ .kind = .head, .name = "haxy/meta" }); │ │186 + } │ │187 + } │ │188 + │ │189 + // │ │190 + // consume events into the database │ │191 + // │ │192 + │ │193 + { │ │194 + try evt.consume(repo_opts, io, allocator, &repo, .{ .kind = .head, .name = "haxy/meta" }); │ │195 + │ │196 + const history = try Repo.DB.ArrayList(.read_only).init(repo.core.db.rootCursor().readOnly()); │ │197 + │ │198 + // read the moment we just created │ │199 + const moment_cursor = try history.getCursor(-1) orelse return error.NotFound; │ │200 + const moment = try Repo.DB.HashMap(.read_only).init(moment_cursor); │ │201 + │ │202 + // get the last object id │ │203 + const last_object_id_cursor = try moment.getCursor(hash.hashInt(repo_opts.hash, "haxy-last-object-id")) orelse return error.NotFound;│ │204 + var last_object_id: [hash.byteLen(repo_opts.hash)]u8 = undefined; │ │205 + _ = try last_object_id_cursor.readBytes(&last_object_id); │ │206 + │ │207 + const haxy_cursor = try moment.getCursor(hash.hashInt(repo_opts.hash, "haxy")) orelse return error.NotFound; │ │208 + const haxy = try Repo.DB.ArrayList(.read_only).init(haxy_cursor); │ │209 + │ │210 + try std.testing.expectEqual(2, try haxy.count()); │ │211 } │ │212 │ │213 // │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────╮ │214 // rebase the branch so it no longer includes the edit event│ │215 // │ │216 │ │162 - const rebased_events_to_consume = [_]evt.Event{ │ │217 + const events_to_consume3 = [_]evt.Event{ │ │218 events_to_consume[2], │ │219 events_to_consume[3], │ │220 }; │ ╰─────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────╮ │223 var json: std.Io.Writer.Allocating = .init(std.testing.allocator);│ │224 defer json.deinit(); │ │225 │ │171 - for (rebased_events_to_consume, 0..) |event, i| { │ │226 + for (events_to_consume3, 0..) |event, i| { │ │227 json.clearRetainingCapacity(); │ │228 │ │229 try std.json.Stringify.value(event, .{}, &json.writer); │ ╰───────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │289 │ │290 // the tags are no longer edited │ │291 try std.testing.expectEqualStrings(events_to_consume[0].data.issue.tags, first_issue.issue.tags); │ │292 + │ │293 + // an event added by the second push is no longer there because it was wiped out by the rebase │ │294 + try std.testing.expect(null == try event_id_to_issue.getCursor(hash.hashInt(repo_opts.hash, &events_to_consume2[0].id)));│ │295 } │ │296 │ │297 // │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────╮ │302 var json: std.Io.Writer.Allocating = .init(std.testing.allocator);│ │303 defer json.deinit(); │ │304 │ │247 - for (rebased_events_to_consume, 0..) |event, i| { │ │305 + for (events_to_consume3, 0..) |event, i| { │ │306 json.clearRetainingCapacity(); │ │307 │ │308 try std.json.Stringify.value(event, .{}, &json.writer); │ ╰───────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────╮ │390 var repo = try Repo.init(io, allocator, .{ .path = work_path });│ │391 defer repo.deinit(io, allocator); │ │392 │ │393 + var arena = std.heap.ArenaAllocator.init(allocator); │ │394 + defer arena.deinit(); │ │395 + │ │396 // │ │397 // define test events │ │398 // │ ╰─────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────╮ │436 // insert issues as commits in the repo │ │437 // │ │438 │ │378 - var arena = std.heap.ArenaAllocator.init(allocator); │ │379 - defer arena.deinit(); │ │380 - │ │439 var first_oid: [hash.byteLen(repo_opts.hash)]u8 = undefined;│ │440 │ │441 { │ ╰─────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯