Skip to content

Commit ffccc1b

Browse files
author
Bharat Sharma
committed
adding test case for schema
1 parent 6be1d57 commit ffccc1b

File tree

5 files changed

+348
-3
lines changed

5 files changed

+348
-3
lines changed

build.zig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ pub fn build(b: *std.Build) void {
254254
"settings.h",
255255
"transport.h",
256256
"websocket_transport.h",
257-
"schema/schema.h",
257+
"schema.h",
258258
"schema/types.h",
259259
"schema/decode.h",
260260
"schema/ref_tracker.h",
@@ -370,6 +370,7 @@ pub fn build(b: *std.Build) void {
370370
.{ .name = "test_auth", .file = "tests/test_auth.zig", .description = "Run authentication tests" },
371371
.{ .name = "test_room", .file = "tests/test_room.zig", .description = "Run room tests" },
372372
.{ .name = "test_storage", .file = "tests/test_storage.zig", .description = "Run storage tests" },
373+
.{ .name = "test_schema", .file = "tests/test_schema.zig", .description = "Run schema tests" },
373374
.{ .name = "test_suite", .file = "tests/test_suite.zig", .description = "Run unit test suite" },
374375
.{ .name = "test_integration", .file = "tests/test_integration.zig", .description = "Run integration tests (requires server)" },
375376
};

src/schema/decode.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ float colyseus_decode_number(const uint8_t* bytes, colyseus_iterator_t* it) {
8888
}
8989

9090
int8_t colyseus_decode_int8(const uint8_t* bytes, colyseus_iterator_t* it) {
91-
return (int8_t)((colyseus_decode_uint8(bytes, it) << 24) >> 24);
91+
uint8_t val = colyseus_decode_uint8(bytes, it);
92+
return (int8_t)val;
9293
}
9394

9495
uint8_t colyseus_decode_uint8(const uint8_t* bytes, colyseus_iterator_t* it) {

src/schema/serializer.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#include "colyseus/schema/schema.h"
1+
#include "colyseus/schema.h"
22
#include <stdlib.h>
33
#include <string.h>
44
#include <stdio.h>

tests/test_schema.zig

Lines changed: 343 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,343 @@
1+
const std = @import("std");
2+
const testing = std.testing;
3+
4+
// ============================================================================
5+
// C bindings for schema types
6+
// ============================================================================
7+
8+
const c = @cImport({
9+
@cInclude("colyseus/schema/types.h");
10+
@cInclude("colyseus/schema/decode.h");
11+
});
12+
13+
// ============================================================================
14+
// Test helpers
15+
// ============================================================================
16+
17+
fn expectEqualStrings(expected: []const u8, actual: [*c]const u8) !void {
18+
if (actual == null) {
19+
return error.NullPointer;
20+
}
21+
const actual_slice = std.mem.span(actual);
22+
try testing.expectEqualStrings(expected, actual_slice);
23+
}
24+
25+
// ============================================================================
26+
// Decode primitive tests
27+
// ============================================================================
28+
29+
test "decode_uint8" {
30+
const bytes = [_]u8{0x42};
31+
var it = c.colyseus_iterator_t{ .offset = 0 };
32+
33+
const result = c.colyseus_decode_uint8(&bytes, &it);
34+
35+
try testing.expectEqual(@as(u8, 0x42), result);
36+
try testing.expectEqual(@as(c_int, 1), it.offset);
37+
}
38+
39+
test "decode_int8_positive" {
40+
const bytes = [_]u8{0x7F};
41+
var it = c.colyseus_iterator_t{ .offset = 0 };
42+
43+
const result = c.colyseus_decode_int8(&bytes, &it);
44+
45+
try testing.expectEqual(@as(i8, 127), result);
46+
}
47+
48+
test "decode_int8_negative" {
49+
const bytes = [_]u8{0xFF};
50+
var it = c.colyseus_iterator_t{ .offset = 0 };
51+
52+
const result = c.colyseus_decode_int8(&bytes, &it);
53+
54+
try testing.expectEqual(@as(i8, -1), result);
55+
}
56+
57+
test "decode_uint16" {
58+
// Little-endian: 0x0102 = 258
59+
const bytes = [_]u8{ 0x02, 0x01 };
60+
var it = c.colyseus_iterator_t{ .offset = 0 };
61+
62+
const result = c.colyseus_decode_uint16(&bytes, &it);
63+
64+
try testing.expectEqual(@as(u16, 258), result);
65+
try testing.expectEqual(@as(c_int, 2), it.offset);
66+
}
67+
68+
test "decode_int16" {
69+
// Little-endian: -1 = 0xFFFF
70+
const bytes = [_]u8{ 0xFF, 0xFF };
71+
var it = c.colyseus_iterator_t{ .offset = 0 };
72+
73+
const result = c.colyseus_decode_int16(&bytes, &it);
74+
75+
try testing.expectEqual(@as(i16, -1), result);
76+
}
77+
78+
test "decode_uint32" {
79+
// Little-endian: 0x01020304 = 16909060
80+
const bytes = [_]u8{ 0x04, 0x03, 0x02, 0x01 };
81+
var it = c.colyseus_iterator_t{ .offset = 0 };
82+
83+
const result = c.colyseus_decode_uint32(&bytes, &it);
84+
85+
try testing.expectEqual(@as(u32, 16909060), result);
86+
try testing.expectEqual(@as(c_int, 4), it.offset);
87+
}
88+
89+
test "decode_int32" {
90+
// Little-endian: -1
91+
const bytes = [_]u8{ 0xFF, 0xFF, 0xFF, 0xFF };
92+
var it = c.colyseus_iterator_t{ .offset = 0 };
93+
94+
const result = c.colyseus_decode_int32(&bytes, &it);
95+
96+
try testing.expectEqual(@as(i32, -1), result);
97+
}
98+
99+
test "decode_float32" {
100+
// IEEE 754: 1.0f = 0x3F800000
101+
const bytes = [_]u8{ 0x00, 0x00, 0x80, 0x3F };
102+
var it = c.colyseus_iterator_t{ .offset = 0 };
103+
104+
const result = c.colyseus_decode_float32(&bytes, &it);
105+
106+
try testing.expectApproxEqAbs(@as(f32, 1.0), result, 0.0001);
107+
}
108+
109+
test "decode_float64" {
110+
// IEEE 754: 1.0 = 0x3FF0000000000000
111+
const bytes = [_]u8{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F };
112+
var it = c.colyseus_iterator_t{ .offset = 0 };
113+
114+
const result = c.colyseus_decode_float64(&bytes, &it);
115+
116+
try testing.expectApproxEqAbs(@as(f64, 1.0), result, 0.0001);
117+
}
118+
119+
test "decode_boolean_true" {
120+
const bytes = [_]u8{0x01};
121+
var it = c.colyseus_iterator_t{ .offset = 0 };
122+
123+
const result = c.colyseus_decode_boolean(&bytes, &it);
124+
125+
try testing.expect(result);
126+
}
127+
128+
test "decode_boolean_false" {
129+
const bytes = [_]u8{0x00};
130+
var it = c.colyseus_iterator_t{ .offset = 0 };
131+
132+
const result = c.colyseus_decode_boolean(&bytes, &it);
133+
134+
try testing.expect(!result);
135+
}
136+
137+
// ============================================================================
138+
// Decode number (msgpack format) tests
139+
// ============================================================================
140+
141+
test "decode_number_positive_fixint" {
142+
// Positive fixint: 0x00-0x7F
143+
const bytes = [_]u8{0x2A}; // 42
144+
var it = c.colyseus_iterator_t{ .offset = 0 };
145+
146+
const result = c.colyseus_decode_number(&bytes, &it);
147+
148+
try testing.expectApproxEqAbs(@as(f32, 42.0), result, 0.0001);
149+
}
150+
151+
test "decode_number_negative_fixint" {
152+
// Negative fixint: 0xE0-0xFF (-1 to -32)
153+
const bytes = [_]u8{0xFF}; // -1
154+
var it = c.colyseus_iterator_t{ .offset = 0 };
155+
156+
const result = c.colyseus_decode_number(&bytes, &it);
157+
158+
try testing.expectApproxEqAbs(@as(f32, -1.0), result, 0.0001);
159+
}
160+
161+
test "decode_number_uint8" {
162+
// 0xCC prefix + uint8
163+
const bytes = [_]u8{ 0xCC, 0xFF }; // 255
164+
var it = c.colyseus_iterator_t{ .offset = 0 };
165+
166+
const result = c.colyseus_decode_number(&bytes, &it);
167+
168+
try testing.expectApproxEqAbs(@as(f32, 255.0), result, 0.0001);
169+
}
170+
171+
test "decode_number_uint16" {
172+
// 0xCD prefix + uint16 LE
173+
const bytes = [_]u8{ 0xCD, 0x00, 0x01 }; // 256
174+
var it = c.colyseus_iterator_t{ .offset = 0 };
175+
176+
const result = c.colyseus_decode_number(&bytes, &it);
177+
178+
try testing.expectApproxEqAbs(@as(f32, 256.0), result, 0.0001);
179+
}
180+
181+
test "decode_number_float32" {
182+
// 0xCA prefix + float32 LE (1.5)
183+
const bytes = [_]u8{ 0xCA, 0x00, 0x00, 0xC0, 0x3F };
184+
var it = c.colyseus_iterator_t{ .offset = 0 };
185+
186+
const result = c.colyseus_decode_number(&bytes, &it);
187+
188+
try testing.expectApproxEqAbs(@as(f32, 1.5), result, 0.0001);
189+
}
190+
191+
// ============================================================================
192+
// Decode string tests
193+
// ============================================================================
194+
195+
test "decode_string_fixstr" {
196+
// fixstr: 0xA0-0xBF, length in low 5 bits
197+
// 0xA5 = 0xA0 | 5, followed by "hello"
198+
const bytes = [_]u8{ 0xA5, 'h', 'e', 'l', 'l', 'o' };
199+
var it = c.colyseus_iterator_t{ .offset = 0 };
200+
201+
const result = c.colyseus_decode_string(&bytes, &it);
202+
defer std.c.free(result);
203+
204+
try testing.expect(result != null);
205+
try expectEqualStrings("hello", result);
206+
try testing.expectEqual(@as(c_int, 6), it.offset);
207+
}
208+
209+
test "decode_string_str8" {
210+
// str8: 0xD9 prefix + 1-byte length
211+
const bytes = [_]u8{ 0xD9, 0x05, 'w', 'o', 'r', 'l', 'd' };
212+
var it = c.colyseus_iterator_t{ .offset = 0 };
213+
214+
const result = c.colyseus_decode_string(&bytes, &it);
215+
defer std.c.free(result);
216+
217+
try testing.expect(result != null);
218+
try expectEqualStrings("world", result);
219+
}
220+
221+
test "decode_string_empty" {
222+
// fixstr with length 0
223+
const bytes = [_]u8{0xA0};
224+
var it = c.colyseus_iterator_t{ .offset = 0 };
225+
226+
const result = c.colyseus_decode_string(&bytes, &it);
227+
defer std.c.free(result);
228+
229+
try testing.expect(result != null);
230+
try expectEqualStrings("", result);
231+
}
232+
233+
// ============================================================================
234+
// Iterator offset tests
235+
// ============================================================================
236+
237+
test "iterator_multiple_decodes" {
238+
// Decode multiple values sequentially
239+
const bytes = [_]u8{
240+
0x01, // uint8: 1
241+
0x02, // uint8: 2
242+
0x03, // uint8: 3
243+
};
244+
var it = c.colyseus_iterator_t{ .offset = 0 };
245+
246+
const v1 = c.colyseus_decode_uint8(&bytes, &it);
247+
try testing.expectEqual(@as(u8, 1), v1);
248+
try testing.expectEqual(@as(c_int, 1), it.offset);
249+
250+
const v2 = c.colyseus_decode_uint8(&bytes, &it);
251+
try testing.expectEqual(@as(u8, 2), v2);
252+
try testing.expectEqual(@as(c_int, 2), it.offset);
253+
254+
const v3 = c.colyseus_decode_uint8(&bytes, &it);
255+
try testing.expectEqual(@as(u8, 3), v3);
256+
try testing.expectEqual(@as(c_int, 3), it.offset);
257+
}
258+
259+
test "iterator_mixed_types" {
260+
// uint8 + uint16 LE + uint8
261+
const bytes = [_]u8{
262+
0xFF, // uint8: 255
263+
0x34, 0x12, // uint16 LE: 0x1234 = 4660
264+
0xAB, // uint8: 171
265+
};
266+
var it = c.colyseus_iterator_t{ .offset = 0 };
267+
268+
const v1 = c.colyseus_decode_uint8(&bytes, &it);
269+
try testing.expectEqual(@as(u8, 255), v1);
270+
271+
const v2 = c.colyseus_decode_uint16(&bytes, &it);
272+
try testing.expectEqual(@as(u16, 0x1234), v2);
273+
274+
const v3 = c.colyseus_decode_uint8(&bytes, &it);
275+
try testing.expectEqual(@as(u8, 0xAB), v3);
276+
277+
try testing.expectEqual(@as(c_int, 4), it.offset);
278+
}
279+
280+
// ============================================================================
281+
// Switch check test
282+
// ============================================================================
283+
284+
test "decode_switch_check" {
285+
const bytes_with_switch = [_]u8{ 0xFF, 0x00 };
286+
var it1 = c.colyseus_iterator_t{ .offset = 0 };
287+
try testing.expect(c.colyseus_decode_switch_check(&bytes_with_switch, &it1));
288+
289+
const bytes_without_switch = [_]u8{ 0xFE, 0x00 };
290+
var it2 = c.colyseus_iterator_t{ .offset = 0 };
291+
try testing.expect(!c.colyseus_decode_switch_check(&bytes_without_switch, &it2));
292+
}
293+
294+
// ============================================================================
295+
// Operation code tests
296+
// ============================================================================
297+
298+
test "operation_codes_defined" {
299+
try testing.expectEqual(@as(c_int, 128), c.COLYSEUS_OP_ADD);
300+
try testing.expectEqual(@as(c_int, 0), c.COLYSEUS_OP_REPLACE);
301+
try testing.expectEqual(@as(c_int, 64), c.COLYSEUS_OP_DELETE);
302+
try testing.expectEqual(@as(c_int, 192), c.COLYSEUS_OP_DELETE_AND_ADD);
303+
try testing.expectEqual(@as(c_int, 10), c.COLYSEUS_OP_CLEAR);
304+
}
305+
306+
test "special_bytes_defined" {
307+
try testing.expectEqual(@as(c_int, 255), c.COLYSEUS_SPEC_SWITCH_TO_STRUCTURE);
308+
try testing.expectEqual(@as(c_int, 213), c.COLYSEUS_SPEC_TYPE_ID);
309+
}
310+
311+
// ============================================================================
312+
// Field type enum tests
313+
// ============================================================================
314+
315+
test "field_types_defined" {
316+
try testing.expectEqual(@as(c_uint, 0), c.COLYSEUS_FIELD_STRING);
317+
try testing.expectEqual(@as(c_uint, 1), c.COLYSEUS_FIELD_NUMBER);
318+
try testing.expectEqual(@as(c_uint, 2), c.COLYSEUS_FIELD_BOOLEAN);
319+
try testing.expectEqual(@as(c_uint, 13), c.COLYSEUS_FIELD_REF);
320+
try testing.expectEqual(@as(c_uint, 14), c.COLYSEUS_FIELD_ARRAY);
321+
try testing.expectEqual(@as(c_uint, 15), c.COLYSEUS_FIELD_MAP);
322+
}
323+
324+
// ============================================================================
325+
// Number check test
326+
// ============================================================================
327+
328+
test "decode_number_check" {
329+
// Positive fixint should be a number
330+
const bytes_fixint = [_]u8{0x42};
331+
var it1 = c.colyseus_iterator_t{ .offset = 0 };
332+
try testing.expect(c.colyseus_decode_number_check(&bytes_fixint, &it1));
333+
334+
// Float32 prefix should be a number
335+
const bytes_float = [_]u8{0xCA};
336+
var it2 = c.colyseus_iterator_t{ .offset = 0 };
337+
try testing.expect(c.colyseus_decode_number_check(&bytes_float, &it2));
338+
339+
// String prefix should not be a number
340+
const bytes_string = [_]u8{0xA5};
341+
var it3 = c.colyseus_iterator_t{ .offset = 0 };
342+
try testing.expect(!c.colyseus_decode_number_check(&bytes_string, &it3));
343+
}

0 commit comments

Comments
 (0)