diff options
| author | Grace Yoder <grace_yoder@outlook.com> | 2026-06-24 17:48:16 -0600 |
|---|---|---|
| committer | Grace Yoder <grace_yoder@outlook.com> | 2026-06-25 16:42:38 -0600 |
| commit | ecdcf0c0b89e478e8bf65cbd76655411c341c156 (patch) | |
| tree | feec34c70902ba0a6da8862fd0b649174cc18b2c | |
| parent | 47f2491ae0688637d82900dfe8d92b8b4e774e8e (diff) | |
tests(Clip): added explicit interface checking
| -rw-r--r-- | build.zig | 13 | ||||
| -rw-r--r-- | src/Clip.zig | 29 |
2 files changed, 42 insertions, 0 deletions
@@ -14,6 +14,19 @@ pub fn build(b: *std.Build) void { b.installArtifact(exe); + const tests = b.addTest(.{ + .name = "tpb", + .root_module = b.createModule(.{ + .root_source_file = b.path("src/main.zig"), + .target = target, + .optimize = optimize, + }), + }); + + const test_step = b.step("test", "Run tests"); + const run_tests = b.addRunArtifact(tests); + test_step.dependOn(&run_tests.step); + const run_step = b.step("run", "Run the app"); const run_cmd = b.addRunArtifact(exe); diff --git a/src/Clip.zig b/src/Clip.zig index 7d2f6db..8d264c8 100644 --- a/src/Clip.zig +++ b/src/Clip.zig @@ -1 +1,30 @@ pub const OSC52 = @import("Clip/OSC52.zig"); + +// I am not sure if this is super idiomatic Zig or if this is bad practice, but +// by ensuring that all Clip backends implement the same methods, we are able +// to use the `anytype` type and we are able to have an interface that is able +// to dispatch statically + +/// Check if a function with the given name and type exists. +/// `@compileError` if not +fn assertFn(comptime T: type, comptime name: []const u8, comptime Sig: type) void { + if (!@import("std").meta.hasFn(T, name)) + @compileError(@typeName(T) ++ " missing fn " ++ name); + if (@TypeOf(@field(T, name)) != Sig) + @compileError(@typeName(T) ++ "." ++ name ++ " must be " ++ @typeName(Sig)); +} + +test { + inline for (@typeInfo(@This()).@"struct".decls) |decl| { + // Only grab types of structs + const T = @field(@This(), decl.name); + if (@TypeOf(T) != type) continue; + if (@typeInfo(T) != .@"struct") continue; + + // ============================== + // === Interface Requirements === + // ============================== + assertFn(T, "writeCopyBuffer", fn (*T, []const u8) anyerror!void); + assertFn(T, "writePasteboard", fn (*T) anyerror!void); + } +} |
