╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ event.zig ────────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
635 const cwd = std.Io.Dir.cwd(); 636 var temp_dir_or_err = cwd.openDir(io, temp_dir_name, .{}); 637 if (temp_dir_or_err) |*temp_dir| { 638 temp_dir.close(io); 639 try cwd.deleteTree(io, temp_dir_name); 640 } else |_| {} 641 var temp_dir = try cwd.createDirPathOpen(io, temp_dir_name, .{}); 642 defer cwd.deleteTree(io, temp_dir_name) catch {}; 643 defer temp_dir.close(io); 644 645 const cwd_path = try std.process.currentPathAlloc(io, allocator); 646 defer allocator.free(cwd_path); 647 648 const work_path = try std.fs.path.join(allocator, &.{ cwd_path, temp_dir_name }); 649 defer allocator.free(work_path); 650 651 const repo_opts: rp.RepoOpts(.xit) = .{ .is_test = true }; 652 const Repo = rp.Repo(.xit, repo_opts); 653 var repo = try Repo.init(io, allocator, .{ .path = work_path }); 654 defer repo.deinit(io, allocator); 655 656 var arena = std.heap.ArenaAllocator.init(allocator); 657 defer arena.deinit(); 658 659 // 660 // define test events 661 // 662 663 var prng = std.Random.DefaultPrng.init(std.testing.random_seed); 664 const user_event_id = evt.EventWithId.randomId(prng.random()); 665 const repo_event_id = evt.EventWithId.randomId(prng.random()); 666 667 var first_password_hash_buf: [evt.User.password_hash_max_len]u8 = undefined; 668 const first_password_hash = try evt.User.hashPassword("correct horse battery staple", &first_password_hash_buf, io); 669 670 var second_password_hash_buf: [evt.User.password_hash_max_len]u8 = undefined; 671 const second_password_hash = try evt.User.hashPassword("Tr0ub4dor&3", &second_password_hash_buf, io); 672 673 const events_to_consume = [_]evt.EventWithId{ 674 .{ 675 .id = std.fmt.bytesToHex(user_event_id, .lower), 676 .event = .{ 677 .user = .{ 678 .name = "alice", 679 .display_name = "Alice Example", 680 .email = "alice@example.test", 681 .password_hash = first_password_hash, 682 }, 683 }, 684 }, 685 // this event edits the previous one because it has the same id 686 .{ 687 .id = std.fmt.bytesToHex(user_event_id, .lower), 688 .event = .{ 689 .user = .{ 690 .name = "alice", 691 .display_name = "Alice Example", 692 .email = "alice@example.test", 693 .password_hash = second_password_hash, 694 }, 695 }, 696 }, 697 .{ 698 .id = std.fmt.bytesToHex(repo_event_id, .lower), 699 .event = .{ 700 .repo = .{ 701 .user_id = &user_event_id, 702 .name = "ziglings", 703 .description = "Learn the Zig programming language by fixing tiny broken programs", 704 .enable_issue = true, 705 }, 706 }, 707 }, 708 }; 709 710 // commit and consume the seed events 711 try evt.commitAndConsume(repo_opts, io, allocator, &repo, .{ .kind = .head, .name = "haxy/meta" }, &events_to_consume); 712 713 { 714 const haxy_moment = try evt.currentMoment(repo_opts, &repo); 715 716 // get the map of users 717 const event_id_to_user_cursor = try haxy_moment.getCursor(hash.hashInt(repo_opts.hash, "event-id->user")) orelse return error.NotFound; 718 const event_id_to_user = try Repo.DB.HashMap(.read_only).init(event_id_to_user_cursor); 719 720 // get the user out of the map that was edited 721 const user_cursor = try event_id_to_user.getCursor(hash.hashInt(repo_opts.hash, &user_event_id)) orelse return error.NotFound; 722 const user_map = try Repo.DB.HashMap(.read_only).init(user_cursor); 723 const user_event = try evt.read(evt.User, Repo.DB, repo_opts.hash, &arena, user_map); 724 725 // the password was correctly edited 726 try std.testing.expectEqualStrings(events_to_consume[1].event.user.?.password_hash, user_event.password_hash); 727 728 // get the map of repos 729 const event_id_to_repo_cursor = try haxy_moment.getCursor(hash.hashInt(repo_opts.hash, "event-id->repo")) orelse return error.NotFound; 730 const event_id_to_repo = try Repo.DB.HashMap(.read_only).init(event_id_to_repo_cursor); 731 732 // get the repo out of the map 733 const repo_cursor = try event_id_to_repo.getCursor(hash.hashInt(repo_opts.hash, &repo_event_id)) orelse return error.NotFound; 734 const repo_map = try Repo.DB.HashMap(.read_only).init(repo_cursor); 735 const repo_event = try evt.read(evt.Repo, Repo.DB, repo_opts.hash, &arena, repo_map); 736 737 try std.testing.expectEqualSlices(u8, &user_event_id, repo_event.user_id); 738 try std.testing.expectEqualStrings("ziglings", repo_event.name); 739 740 // get the repos created by the user 741 const user_id_to_repos_cursor = try haxy_moment.getCursor(hash.hashInt(repo_opts.hash, "user-id->repos")) orelse return error.NotFound; 742 const user_id_to_repos = try Repo.DB.HashMap(.read_only).init(user_id_to_repos_cursor); 743 744 const user_repos_cursor = try user_id_to_repos.getCursor(hash.hashInt(repo_opts.hash, &user_event_id)) orelse return error.NotFound; 745 const user_repos = try Repo.DB.CountedHashSet(.read_only).init(user_repos_cursor); 746 747 try std.testing.expectEqual(1, try user_repos.count()); 748 749 try std.testing.expect(null != try user_repos.getCursor(hash.hashInt(repo_opts.hash, &repo_event_id))); 750 } 751 752 // 753 // remove the repo 754 // 755 756 const events_to_consume2 = [_]evt.EventWithId{ 757 .{ 758 .id = std.fmt.bytesToHex(repo_event_id, .lower), 759 .event = .{ .repo = null }, 760 }, 761 }; 762 763 // commit and consume the removal 764 try evt.commitAndConsume(repo_opts, io, allocator, &repo, .{ .kind = .head, .name = "haxy/meta" }, &events_to_consume2); 765 766 { 767 const haxy_moment = try evt.currentMoment(repo_opts, &repo); 768 769 // get the map of repos 770 const event_id_to_repo_cursor = try haxy_moment.getCursor(hash.hashInt(repo_opts.hash, "event-id->repo")) orelse return error.NotFound; 771 const event_id_to_repo = try Repo.DB.HashMap(.read_only).init(event_id_to_repo_cursor); 772 773 try std.testing.expect(null == try event_id_to_repo.getCursor(hash.hashInt(repo_opts.hash, &repo_event_id))); 774 775 // get the repos created by the user 776 const user_id_to_repos_cursor = try haxy_moment.getCursor(hash.hashInt(repo_opts.hash, "user-id->repos")) orelse return error.NotFound; 777 const user_id_to_repos = try Repo.DB.HashMap(.read_only).init(user_id_to_repos_cursor); 778 779 const user_repos_cursor = try user_id_to_repos.getCursor(hash.hashInt(repo_opts.hash, &user_event_id)) orelse return error.NotFound; 780 const user_repos = try Repo.DB.CountedHashSet(.read_only).init(user_repos_cursor); 781 782 try std.testing.expectEqual(0, try user_repos.count()); 783 try std.testing.expect(null == try user_repos.getCursor(hash.hashInt(repo_opts.hash, &repo_event_id))); 784 } 785 786 // 787 // remove the user 788 // 789 790 const events_to_consume3 = [_]evt.EventWithId{ 791 .{ 792 .id = std.fmt.bytesToHex(user_event_id, .lower), 793 .event = .{ .user = null }, 794 }, 795 }; 796 797 // commit and consume the removal 798 try evt.commitAndConsume(repo_opts, io, allocator, &repo, .{ .kind = .head, .name = "haxy/meta" }, &events_to_consume3); 799 800 { 801 const haxy_moment = try evt.currentMoment(repo_opts, &repo); 802 803 // get the map of users 804 const event_id_to_user_cursor = try haxy_moment.getCursor(hash.hashInt(repo_opts.hash, "event-id->user")) orelse return error.NotFound; 805 const event_id_to_user = try Repo.DB.HashMap(.read_only).init(event_id_to_user_cursor); 806 807 try std.testing.expect(null == try event_id_to_user.getCursor(hash.hashInt(repo_opts.hash, &user_event_id))); 808 } 809 } 810