Skip to content

Commit 2535db8

Browse files
committed
feat(test): add comprehensive tests for msgpack payloads
- add tests for error handling in Payload methods - test integer, string, array, map, ext, and float boundaries - add tests for Unicode strings, nested structures, and mixed arrays - verify correct handling of empty containers and large maps - ensure mapPut frees old keys and arrPayload initializes elements - add getInt and getUint utility methods to Payload - fix MAP16 and MAP32 encoding to write length after type marker
1 parent 4cc6dfc commit 2535db8

File tree

2 files changed

+643
-1
lines changed

2 files changed

+643
-1
lines changed

src/msgpack.zig

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,12 @@ pub const Payload = union(enum) {
125125
if (self.* != .map) {
126126
return Errors.NotMap;
127127
}
128+
// TODO: This maybe memory leak
129+
const old_key = self.map.getKey(key);
130+
if (old_key) |old_key_ptr| {
131+
// if the key is already in map, free the old key
132+
self.map.allocator.free(old_key_ptr);
133+
}
128134
const new_key = try self.map.allocator.alloc(u8, key.len);
129135
@memcpy(new_key, key);
130136
try self.map.put(new_key, val);
@@ -190,6 +196,9 @@ pub const Payload = union(enum) {
190196
/// get an array payload
191197
pub fn arrPayload(len: usize, allocator: Allocator) !Payload {
192198
const arr = try allocator.alloc(Payload, len);
199+
for (0..len) |i| {
200+
arr[i] = Payload.nilToPayload();
201+
}
193202
return Payload{
194203
.arr = arr,
195204
};
@@ -253,6 +262,38 @@ pub const Payload = union(enum) {
253262
else => {},
254263
}
255264
}
265+
266+
/// get a i64 value from payload
267+
/// Note: if the payload is not a int or the value is too large, it will return MsGPackError.INVALID_TYPE
268+
pub fn getInt(self: Payload) !i64 {
269+
return switch (self) {
270+
.int => |val| val,
271+
.uint => |val| {
272+
if (val <= std.math.maxInt(i64)) {
273+
return @intCast(val);
274+
}
275+
// TODO: we can not return this error
276+
return MsGPackError.INVALID_TYPE;
277+
},
278+
else => return MsGPackError.INVALID_TYPE,
279+
};
280+
}
281+
282+
/// get a u64 value from payload
283+
/// Note: if the payload is not a uint or the value is negative, it will return MsGPackError.INVALID_TYPE
284+
pub fn getUint(self: Payload) !u64 {
285+
return switch (self) {
286+
.int => |val| {
287+
if (val >= 0) {
288+
return @intCast(val);
289+
}
290+
// TODO: we can not return this error
291+
return MsGPackError.INVALID_TYPE;
292+
},
293+
.uint => |val| val,
294+
else => return MsGPackError.INVALID_TYPE,
295+
};
296+
}
256297
};
257298

258299
/// markers
@@ -855,8 +896,10 @@ pub fn Pack(
855896
try self.writeU8Value(header);
856897
} else if (len <= 0xffff) {
857898
try self.writeTypeMarker(.MAP16);
899+
try self.writeU16Value(@intCast(len));
858900
} else if (len <= 0xffff_ffff) {
859901
try self.writeTypeMarker(.MAP32);
902+
try self.writeU32Value(@intCast(len));
860903
} else {
861904
return MsGPackError.MAP_LENGTH_TOO_LONG;
862905
}

0 commit comments

Comments
 (0)