authorgravatar for mason@gamesbymason.comMason Remaley <mason@gamesbymason.com> 2026-08-12 15:04:31-07:00
committergravatar for mason@gamesbymason.comMason Remaley <mason@gamesbymason.com> 2026-09-26 12:35:38-07:00
log3b779c2e276d4b22a8d398b36379c173a607fa21
treeb72dcf3d7f26e4b5f19832932dfad06fba6e96a4
parenta6552e7d009883ae33a1b6aa24d216df6c964f17

Add decltests for common functions


1 files changed, 99 insertions(+), 0 deletions(-)

lib/std/zon/parse.zig+99
...@@ -224,6 +224,44 @@ pub fn fromSlice(T: type, options: FromSliceOptions) error{ OutOfMemory, ParseZo...@@ -224,6 +224,44 @@ pub fn fromSlice(T: type, options: FromSliceOptions) error{ OutOfMemory, ParseZo
224 return value;224 return value;
225}225}
226226
227test fromSlice {
228 const gpa = std.testing.allocator;
229 var arena_allocator: ArenaAllocator = .init(gpa);
230 defer arena_allocator.deinit();
231 const arena = arena_allocator.allocator();
232
233 const TextureOptions = struct {
234 const AddressMode = enum { clamp, reflect, wrap, zero };
235 address_mode: struct { u: AddressMode = .wrap, v: AddressMode = .wrap },
236 mipmaps: bool = true,
237 premultiply: bool = true,
238 };
239
240 const source =
241 \\.{
242 \\ .address_mode = .{ .u = .clamp },
243 \\ .mipmaps = false,
244 \\}
245 ;
246
247 var errors: Errors = .empty;
248 const options = fromSlice(TextureOptions, .{
249 .gpa = gpa,
250 .arena = arena,
251 .source = source,
252 .errors = &errors,
253 }) catch |err| {
254 errors.log("texture_options.zon", err);
255 return err;
256 };
257
258 try std.testing.expectEqualDeep(TextureOptions{
259 .address_mode = .{ .u = .clamp, .v = .wrap },
260 .mipmaps = false,
261 .premultiply = true,
262 }, options);
263}
264
227/// Like `fromSlice` but the result type may not contain pointers, allowing it to outlive265/// Like `fromSlice` but the result type may not contain pointers, allowing it to outlive
228/// `options.arena`.266/// `options.arena`.
229pub fn fromSliceNoAlloc(T: type, options: FromSliceOptions) error{ OutOfMemory, ParseZon }!T {267pub fn fromSliceNoAlloc(T: type, options: FromSliceOptions) error{ OutOfMemory, ParseZon }!T {
...@@ -244,6 +282,67 @@ pub fn updateFromSlice(...@@ -244,6 +282,67 @@ pub fn updateFromSlice(
244 try fromSliceInner(T, value, true, options);282 try fromSliceInner(T, value, true, options);
245}283}
246284
285test updateFromSlice {
286 const gpa = std.testing.allocator;
287 var arena_allocator: ArenaAllocator = .init(gpa);
288 defer arena_allocator.deinit();
289 const arena = arena_allocator.allocator();
290
291 const MyTextEditorConfig = struct {
292 indentation: enum { spaces, tabs },
293 columns: []const u16,
294 dark_mode: enum { auto, dark, light },
295 theme: []const u8,
296 };
297
298 const global_config =
299 \\.{
300 \\ .indentation = .spaces,
301 \\ .columns = .{ 100 },
302 \\ .dark_mode = .dark,
303 \\}
304 ;
305 const project_config =
306 \\.{
307 \\ .indentation = .tabs,
308 \\}
309 ;
310
311 var config: MyTextEditorConfig = .{
312 .indentation = .spaces,
313 .columns = &.{},
314 .dark_mode = .auto,
315 .theme = "default",
316 };
317
318 var errors: Errors = .empty;
319 updateFromSlice(MyTextEditorConfig, &config, .{
320 .gpa = gpa,
321 .arena = arena,
322 .source = global_config,
323 .errors = &errors,
324 }) catch |err| {
325 errors.log("global_config.zon", err);
326 return err;
327 };
328 updateFromSlice(MyTextEditorConfig, &config, .{
329 .gpa = gpa,
330 .arena = arena,
331 .source = project_config,
332 .errors = &errors,
333 }) catch |err| {
334 errors.log("project_config.zon", err);
335 return err;
336 };
337
338 try std.testing.expectEqualDeep(MyTextEditorConfig{
339 .indentation = .tabs,
340 .columns = &.{100},
341 .dark_mode = .dark,
342 .theme = "default",
343 }, config);
344}
345
247/// Like `updateFromSlice` but the `T` may not contain pointers, allowing `value` to outlive346/// Like `updateFromSlice` but the `T` may not contain pointers, allowing `value` to outlive
248/// `options.arena`.347/// `options.arena`.
249pub fn updateFromSliceNoAlloc(348pub fn updateFromSliceNoAlloc(