feat: extend protocol
This commit is contained in:
1 parent
06e9e3fe13
commit
b94896cb62
1 file changed
+157
@@ -3295,3 +3295,160 @@ test "coll_op payload round trips a zero-arg action" {
|
|||||||
try std.testing.expectEqual(@as(usize, 0), decoded.args.len);
|
try std.testing.expectEqual(@as(usize, 0), decoded.args.len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "decodeCollOp rejects an unknown action byte" {
|
||||||
|
const allocator = std.testing.allocator;
|
||||||
|
var buf = std.ArrayList(u8).init(allocator);
|
||||||
|
defer buf.deinit();
|
||||||
|
const w = encode.ByteWriter.init(&buf);
|
||||||
|
try w.byte(250);
|
||||||
|
try putLenPrefixed(w, "x");
|
||||||
|
try w.putU32(0);
|
||||||
|
try std.testing.expectError(error.Malformed, decodeCollOp(allocator, buf.items));
|
||||||
|
}
|
||||||
|
|
||||||
|
test "coll reply round trips nil and ok" {
|
||||||
|
const allocator = std.testing.allocator;
|
||||||
|
|
||||||
|
const nilPayload = try encodeCollReply(allocator, .nil);
|
||||||
|
defer allocator.free(nilPayload);
|
||||||
|
var nilReply = try decodeCollReply(allocator, nilPayload);
|
||||||
|
defer nilReply.deinit(allocator);
|
||||||
|
try std.testing.expect(nilReply == .nil);
|
||||||
|
|
||||||
|
const okPayload = try encodeCollReply(allocator, .ok);
|
||||||
|
defer allocator.free(okPayload);
|
||||||
|
var okReply = try decodeCollReply(allocator, okPayload);
|
||||||
|
defer okReply.deinit(allocator);
|
||||||
|
try std.testing.expect(okReply == .ok);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "coll reply round trips int and real" {
|
||||||
|
const allocator = std.testing.allocator;
|
||||||
|
|
||||||
|
const intPayload = try encodeCollReply(allocator, .{ .int = -42 });
|
||||||
|
defer allocator.free(intPayload);
|
||||||
|
var intReply = try decodeCollReply(allocator, intPayload);
|
||||||
|
defer intReply.deinit(allocator);
|
||||||
|
try std.testing.expectEqual(@as(i64, -42), intReply.int);
|
||||||
|
|
||||||
|
const realPayload = try encodeCollReply(allocator, .{ .real = 3.5 });
|
||||||
|
defer allocator.free(realPayload);
|
||||||
|
var realReply = try decodeCollReply(allocator, realPayload);
|
||||||
|
defer realReply.deinit(allocator);
|
||||||
|
try std.testing.expectEqual(@as(f64, 3.5), realReply.real);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "coll reply round trips raw bytes independently of the source payload" {
|
||||||
|
const allocator = std.testing.allocator;
|
||||||
|
const payload = try encodeCollReply(allocator, .{ .bytes = "hello" });
|
||||||
|
defer allocator.free(payload);
|
||||||
|
var reply = try decodeCollReply(allocator, payload);
|
||||||
|
defer reply.deinit(allocator);
|
||||||
|
try std.testing.expectEqualStrings("hello", reply.bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "coll reply round trips a string list, including empty" {
|
||||||
|
const allocator = std.testing.allocator;
|
||||||
|
const items = [_][]const u8{ "a", "bb", "ccc" };
|
||||||
|
const payload = try encodeCollReply(allocator, .{ .stringList = &items });
|
||||||
|
defer allocator.free(payload);
|
||||||
|
var reply = try decodeCollReply(allocator, payload);
|
||||||
|
defer reply.deinit(allocator);
|
||||||
|
try std.testing.expectEqual(@as(usize, 3), reply.stringList.len);
|
||||||
|
try std.testing.expectEqualStrings("bb", reply.stringList[1]);
|
||||||
|
|
||||||
|
const emptyPayload = try encodeCollReply(allocator, .{ .stringList = &.{} });
|
||||||
|
defer allocator.free(emptyPayload);
|
||||||
|
var emptyReply = try decodeCollReply(allocator, emptyPayload);
|
||||||
|
defer emptyReply.deinit(allocator);
|
||||||
|
try std.testing.expectEqual(@as(usize, 0), emptyReply.stringList.len);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "coll reply round trips a pair list (hash getall shape)" {
|
||||||
|
const allocator = std.testing.allocator;
|
||||||
|
const pairs = [_]CollPair{
|
||||||
|
.{ .field = "name", .value = "ada" },
|
||||||
|
.{ .field = "age", .value = "36" },
|
||||||
|
};
|
||||||
|
const payload = try encodeCollReply(allocator, .{ .pairList = &pairs });
|
||||||
|
defer allocator.free(payload);
|
||||||
|
var reply = try decodeCollReply(allocator, payload);
|
||||||
|
defer reply.deinit(allocator);
|
||||||
|
try std.testing.expectEqual(@as(usize, 2), reply.pairList.len);
|
||||||
|
try std.testing.expectEqualStrings("name", reply.pairList[0].field);
|
||||||
|
try std.testing.expectEqualStrings("ada", reply.pairList[0].value);
|
||||||
|
try std.testing.expectEqualStrings("age", reply.pairList[1].field);
|
||||||
|
try std.testing.expectEqualStrings("36", reply.pairList[1].value);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "coll reply round trips a score pair list (zset range shape), including negative scores" {
|
||||||
|
const allocator = std.testing.allocator;
|
||||||
|
const pairs = [_]CollScorePair{
|
||||||
|
.{ .member = "bob", .score = -1.5 },
|
||||||
|
.{ .member = "ada", .score = 10.25 },
|
||||||
|
};
|
||||||
|
const payload = try encodeCollReply(allocator, .{ .scorePairList = &pairs });
|
||||||
|
defer allocator.free(payload);
|
||||||
|
var reply = try decodeCollReply(allocator, payload);
|
||||||
|
defer reply.deinit(allocator);
|
||||||
|
try std.testing.expectEqual(@as(usize, 2), reply.scorePairList.len);
|
||||||
|
try std.testing.expectEqualStrings("bob", reply.scorePairList[0].member);
|
||||||
|
try std.testing.expectEqual(@as(f64, -1.5), reply.scorePairList[0].score);
|
||||||
|
try std.testing.expectEqualStrings("ada", reply.scorePairList[1].member);
|
||||||
|
try std.testing.expectEqual(@as(f64, 10.25), reply.scorePairList[1].score);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "decodeCollReply rejects an unknown tag byte" {
|
||||||
|
const allocator = std.testing.allocator;
|
||||||
|
var buf = std.ArrayList(u8).init(allocator);
|
||||||
|
defer buf.deinit();
|
||||||
|
const w = encode.ByteWriter.init(&buf);
|
||||||
|
try w.byte(250);
|
||||||
|
try std.testing.expectError(error.Malformed, decodeCollReply(allocator, buf.items));
|
||||||
|
}
|
||||||
|
|
||||||
|
test "txn_op entries round trip put and del across two tables" {
|
||||||
|
const allocator = std.testing.allocator;
|
||||||
|
const putFields = [_]rowmod.Field{
|
||||||
|
.{ .name = "balance", .value = .{ .int = 100 } },
|
||||||
|
.{ .name = "city", .value = .{ .text = "warsaw" } },
|
||||||
|
};
|
||||||
|
const entries = [_]TxnOpEntry{
|
||||||
|
.{ .verb = .put, .table = "accounts", .pk = .{ .int = 1 }, .fields = &putFields },
|
||||||
|
.{ .verb = .del, .table = "sessions", .pk = .{ .text = "abc" } },
|
||||||
|
};
|
||||||
|
const payload = try encodeTxnOp(allocator, &entries);
|
||||||
|
defer allocator.free(payload);
|
||||||
|
|
||||||
|
const decoded = try decodeTxnOp(allocator, payload);
|
||||||
|
defer allocator.free(decoded);
|
||||||
|
try std.testing.expectEqual(@as(usize, 2), decoded.len);
|
||||||
|
|
||||||
|
try std.testing.expectEqual(TxnVerb.put, decoded[0].verb);
|
||||||
|
try std.testing.expectEqualStrings("accounts", decoded[0].table);
|
||||||
|
const pk0 = try rowmod.decodeValue(allocator, decoded[0].pkBytes);
|
||||||
|
try std.testing.expectEqual(@as(i64, 1), pk0.int);
|
||||||
|
var fields0 = try rowmod.Row.decode(allocator, decoded[0].fieldsBytes);
|
||||||
|
defer fields0.deinit();
|
||||||
|
try std.testing.expectEqual(@as(i64, 100), fields0.get("balance").?.int);
|
||||||
|
try std.testing.expectEqualStrings("warsaw", fields0.get("city").?.text);
|
||||||
|
|
||||||
|
try std.testing.expectEqual(TxnVerb.del, decoded[1].verb);
|
||||||
|
try std.testing.expectEqualStrings("sessions", decoded[1].table);
|
||||||
|
var pk1 = try rowmod.decodeValue(allocator, decoded[1].pkBytes);
|
||||||
|
defer pk1.free(allocator);
|
||||||
|
try std.testing.expectEqualStrings("abc", pk1.text);
|
||||||
|
var fields1 = try rowmod.Row.decode(allocator, decoded[1].fieldsBytes);
|
||||||
|
defer fields1.deinit();
|
||||||
|
try std.testing.expectEqual(@as(usize, 0), fields1.count());
|
||||||
|
}
|
||||||
|
|
||||||
|
test "empty txn_op entry list round trips" {
|
||||||
|
const allocator = std.testing.allocator;
|
||||||
|
const payload = try encodeTxnOp(allocator, &[_]TxnOpEntry{});
|
||||||
|
defer allocator.free(payload);
|
||||||
|
const decoded = try decodeTxnOp(allocator, payload);
|
||||||
|
defer allocator.free(decoded);
|
||||||
|
try std.testing.expectEqual(@as(usize, 0), decoded.len);
|
||||||
|
}
|
||||||
|
|
||||||
Reference in new issue
Block a user