feat: extend collections

This commit is contained in:
dualfroz committed 2026-09-02 15:39:42 +02:00
1 parent 025f1708c6
commit c281644719
1 file changed
+157
+157
View File
@@ -1105,3 +1105,160 @@ test "counter incrBy rejects a real external conflict" {
try std.testing.expectError(error.Conflict, txn.commit());
}
test "hash set get del getAll" {
const allocator = std.testing.allocator;
var tmp = std.testing.tmpDir(.{});
defer tmp.cleanup();
var db = try openTemp(&tmp, allocator);
defer db.close();
try std.testing.expect(try Hash.set(&db, allocator, "user:1", "name", "ada"));
try std.testing.expect(!try Hash.set(&db, allocator, "user:1", "name", "ada lovelace"));
try std.testing.expect(try Hash.set(&db, allocator, "user:1", "age", "36"));
const name = (try Hash.get(&db, allocator, "user:1", "name")).?;
defer allocator.free(name);
try std.testing.expectEqualStrings("ada lovelace", name);
try std.testing.expectEqual(@as(usize, 2), try Hash.len(&db, allocator, "user:1"));
const all = try Hash.getAll(&db, allocator, "user:1");
defer {
for (all) |f| f.free(allocator);
allocator.free(all);
}
try std.testing.expectEqual(@as(usize, 2), all.len);
try std.testing.expect(try Hash.del(&db, allocator, "user:1", "age"));
try std.testing.expect(!try Hash.del(&db, allocator, "user:1", "age"));
try std.testing.expectEqual(@as(usize, 1), try Hash.len(&db, allocator, "user:1"));
try std.testing.expect(try Hash.get(&db, allocator, "user:1", "age") == null);
}
test "set add remove isMember card members" {
const allocator = std.testing.allocator;
var tmp = std.testing.tmpDir(.{});
defer tmp.cleanup();
var db = try openTemp(&tmp, allocator);
defer db.close();
try std.testing.expect(try Set.add(&db, allocator, "tags", "zig"));
try std.testing.expect(!try Set.add(&db, allocator, "tags", "zig"));
try std.testing.expect(try Set.add(&db, allocator, "tags", "db"));
try std.testing.expect(try Set.isMember(&db, allocator, "tags", "zig"));
try std.testing.expect(!try Set.isMember(&db, allocator, "tags", "rust"));
try std.testing.expectEqual(@as(usize, 2), try Set.card(&db, allocator, "tags"));
const members = try Set.members(&db, allocator, "tags");
defer {
for (members) |m| allocator.free(m);
allocator.free(members);
}
try std.testing.expectEqual(@as(usize, 2), members.len);
try std.testing.expect(try Set.remove(&db, allocator, "tags", "zig"));
try std.testing.expect(!try Set.remove(&db, allocator, "tags", "zig"));
try std.testing.expectEqual(@as(usize, 1), try Set.card(&db, allocator, "tags"));
}
test "set intersect union difference across multiple sets" {
const allocator = std.testing.allocator;
var tmp = std.testing.tmpDir(.{});
defer tmp.cleanup();
var db = try openTemp(&tmp, allocator);
defer db.close();
_ = try Set.add(&db, allocator, "a", "1");
_ = try Set.add(&db, allocator, "a", "2");
_ = try Set.add(&db, allocator, "a", "3");
_ = try Set.add(&db, allocator, "b", "2");
_ = try Set.add(&db, allocator, "b", "3");
_ = try Set.add(&db, allocator, "b", "4");
const inter = try Set.intersect(&db, allocator, &.{ "a", "b" });
defer {
for (inter) |m| allocator.free(m);
allocator.free(inter);
}
try std.testing.expectEqual(@as(usize, 2), inter.len);
const uni = try Set.unionOf(&db, allocator, &.{ "a", "b" });
defer {
for (uni) |m| allocator.free(m);
allocator.free(uni);
}
try std.testing.expectEqual(@as(usize, 4), uni.len);
const diff = try Set.difference(&db, allocator, "a", &.{"b"});
defer {
for (diff) |m| allocator.free(m);
allocator.free(diff);
}
try std.testing.expectEqual(@as(usize, 1), diff.len);
try std.testing.expectEqualStrings("1", diff[0]);
}
test "list push pop both ends preserve order" {
const allocator = std.testing.allocator;
var tmp = std.testing.tmpDir(.{});
defer tmp.cleanup();
var db = try openTemp(&tmp, allocator);
defer db.close();
try List.pushRight(&db, allocator, "queue", "b");
try List.pushRight(&db, allocator, "queue", "c");
try List.pushLeft(&db, allocator, "queue", "a");
try std.testing.expectEqual(@as(usize, 3), try List.len(&db, allocator, "queue"));
const first = (try List.popLeft(&db, allocator, "queue")).?;
defer allocator.free(first);
try std.testing.expectEqualStrings("a", first);
const last = (try List.popRight(&db, allocator, "queue")).?;
defer allocator.free(last);
try std.testing.expectEqualStrings("c", last);
try std.testing.expectEqual(@as(usize, 1), try List.len(&db, allocator, "queue"));
try std.testing.expect(try List.popLeft(&db, allocator, "empty") == null);
}
test "list range supports negative indices redis style" {
const allocator = std.testing.allocator;
var tmp = std.testing.tmpDir(.{});
defer tmp.cleanup();
var db = try openTemp(&tmp, allocator);
defer db.close();
try List.pushRight(&db, allocator, "l", "0");
try List.pushRight(&db, allocator, "l", "1");
try List.pushRight(&db, allocator, "l", "2");
try List.pushRight(&db, allocator, "l", "3");
try List.pushRight(&db, allocator, "l", "4");
const full = try List.range(&db, allocator, "l", 0, -1);
defer {
for (full) |v| allocator.free(v);
allocator.free(full);
}
try std.testing.expectEqual(@as(usize, 5), full.len);
try std.testing.expectEqualStrings("0", full[0]);
try std.testing.expectEqualStrings("4", full[4]);
const lastTwo = try List.range(&db, allocator, "l", -2, -1);
defer {
for (lastTwo) |v| allocator.free(v);
allocator.free(lastTwo);
}
try std.testing.expectEqual(@as(usize, 2), lastTwo.len);
try std.testing.expectEqualStrings("3", lastTwo[0]);
try std.testing.expectEqualStrings("4", lastTwo[1]);
const clamped = try List.range(&db, allocator, "l", -100, 100);
defer {
for (clamped) |v| allocator.free(v);
allocator.free(clamped);
}
try std.testing.expectEqual(@as(usize, 5), clamped.len);
}