Skip to content

Commit 087eb21

Browse files
committed
test(stream): added incomplete read tests
1 parent 2fec2cf commit 087eb21

1 file changed

Lines changed: 57 additions & 0 deletions

File tree

src/stream.zig

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,30 @@ test "stream: ignored limited reader is drained automatically" {
461461
try testing.expectEqual(@as(u32, 2), (try sd.next()).?.after);
462462
}
463463

464+
test "stream: partially read limited reader drains the leftover for the following field" {
465+
const src: WithString = .{ .before = 11, .name = "hello world", .after = 22 };
466+
const bytes = try encodeToOwned(src, testing.allocator);
467+
defer testing.allocator.free(bytes);
468+
469+
var reader: std.Io.Reader = .fixed(bytes);
470+
var sd = StreamDecoder(WithString).init(&reader);
471+
472+
try testing.expectEqual(@as(u32, 11), (try sd.next()).?.before);
473+
474+
// Read only the first few bytes of the 11-byte string, leaving the rest
475+
// buffered/unread in the limited sub-reader.
476+
{
477+
const limited = (try sd.next()).?.name;
478+
var buf: [4]u8 = undefined;
479+
try limited.readSliceAll(&buf);
480+
try testing.expectEqualStrings("hell", &buf);
481+
}
482+
483+
// The unread "o world" tail must be drained so the next field decodes.
484+
try testing.expectEqual(@as(u32, 22), (try sd.next()).?.after);
485+
try testing.expectEqual(@as(?StreamDecoder(WithString).Event, null), try sd.next());
486+
}
487+
464488
const Packed = struct {
465489
values: std.ArrayList(u32) = .empty,
466490

@@ -492,6 +516,39 @@ test "stream: packed repeated emits one event per element" {
492516
try testing.expectEqualSlices(u32, &.{ 1, 2, 300, 40000, 5 }, collected.items);
493517
}
494518

519+
const Unpacked = struct {
520+
values: std.ArrayList(u32) = .empty,
521+
522+
// `.repeated` (not `.packed_repeated`) encodes one individually-tagged
523+
// element per value, which the decoder emits via the non-packed path.
524+
pub const _desc_table = .{
525+
.values = fd(1, .{ .repeated = .{ .scalar = .uint32 } }),
526+
};
527+
528+
pub fn deinit(self: *@This(), allocator: std.mem.Allocator) void {
529+
return protobuf.deinit(allocator, self);
530+
}
531+
};
532+
533+
test "stream: unpacked repeated emits one event per individually-tagged element" {
534+
var src: Unpacked = .{};
535+
defer src.deinit(testing.allocator);
536+
try src.values.appendSlice(testing.allocator, &.{ 1, 2, 300, 40000, 5 });
537+
538+
const bytes = try encodeToOwned(src, testing.allocator);
539+
defer testing.allocator.free(bytes);
540+
541+
var reader: std.Io.Reader = .fixed(bytes);
542+
var sd = StreamDecoder(Unpacked).init(&reader);
543+
544+
var collected: std.ArrayList(u32) = .empty;
545+
defer collected.deinit(testing.allocator);
546+
while (try sd.next()) |item| switch (item) {
547+
.values => |v| try collected.append(testing.allocator, v),
548+
};
549+
try testing.expectEqualSlices(u32, &.{ 1, 2, 300, 40000, 5 }, collected.items);
550+
}
551+
495552
const Inner = struct {
496553
x: i32 = 0,
497554
y: i32 = 0,

0 commit comments

Comments
 (0)