Skip to content

Commit

Permalink
feat: add mockInputJson helper, rearrange for multiple tests
Browse files Browse the repository at this point in the history
  • Loading branch information
nilslice committed May 22, 2024
1 parent 5831f7b commit a72d746
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 5 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@ jobs:
- name: Test example
run: |
# this is configured by the `xtp.toml` in the root
xtp plugin test
xtp plugin test --path examples/basic
xtp plugin test --path examples/json
16 changes: 14 additions & 2 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,27 @@ pub fn build(b: *std.Build) void {

var basic_test = b.addExecutable(.{
.name = "basic-test",
.root_source_file = b.path("examples/basic.zig"),
.root_source_file = b.path("examples/basic/basic.zig"),
.target = target,
.optimize = optimize,
});
basic_test.rdynamic = true;
basic_test.entry = .disabled; // or, add an empty `pub fn main() void {}` in your code
basic_test.root_module.addImport("xtp-test", xtp_test_module);

b.installArtifact(basic_test);
const basic_test_step = b.step("basic_test", "Build basic_test");
basic_test_step.dependOn(b.getInstallStep());

var json_test = b.addExecutable(.{
.name = "json-test",
.root_source_file = b.path("examples/json/json.zig"),
.target = target,
.optimize = optimize,
});
json_test.rdynamic = true;
json_test.entry = .disabled; // or, add an empty `pub fn main() void {}` in your code
json_test.root_module.addImport("xtp-test", xtp_test_module);
b.installArtifact(json_test);
const json_test_step = b.step("json_test", "Build json_test");
json_test_step.dependOn(b.getInstallStep());
}
2 changes: 1 addition & 1 deletion build.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
.name = "xtp-test",
// This is a [Semantic Version](https://semver.org/).
// In a future version of Zig it will be used for package deduplication.
.version = "0.0.0",
.version = "0.1.0",

// This field is optional.
// This is currently advisory only; Zig does not yet do anything
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion xtp.toml → examples/basic/xtp.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ mock_input = { data = "this is my mock input data" }
name = "basic - file input"
build = "zig build basic_test"
with = "zig-out/bin/basic-test.wasm"
mock_input = { file = "examples/basic.zig" }
mock_input = { file = "examples/basic/basic.zig" }
18 changes: 18 additions & 0 deletions examples/json/json.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const std = @import("std");
const Test = @import("xtp-test").Test;

const CountVowel = struct {
total: u32,
count: u32,
vowels: []const u8,
};

export fn @"test"() i32 {
const xtp_test = Test.init(std.heap.wasm_allocator);
const input = xtp_test.mockInputJson(CountVowel, null) catch unreachable;
const example = CountVowel{ .total = 2, .count = 1, .vowels = "aeiouAEIOU" };
xtp_test.assertEq("json works (consistent .count)", input.count, example.count);
xtp_test.assertEq("json works (consistent .total)", input.total, example.total);
xtp_test.assert("json works (consistent .vowels)", std.mem.eql(u8, input.vowels, example.vowels), "expected count and vowels fields to match after conversion");
return 0;
}
7 changes: 7 additions & 0 deletions examples/json/xtp.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
bin = "https://raw.githubusercontent.com/extism/extism/main/wasm/code.wasm"

[[test]]
name = "json"
build = "zig build json_test"
with = "zig-out/bin/json-test.wasm"
mock_input = { data = '{ "count": 1, "total": 2, "vowels": "aeiouAEIOU" }' }
24 changes: 24 additions & 0 deletions src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,21 @@ const harness = @import("harness.zig");

const FORMAT_FAILED = "-- test runner failed to format reason --";

pub fn Json(comptime T: type) type {
return struct {
parsed: std.json.Parsed(T),
slice: []const u8,

pub fn value(self: @This()) T {
return self.parsed.value;
}

pub fn deinit(self: @This()) void {
self.parsed.deinit();
}
};
}

pub const Test = struct {
plugin: Plugin,

Expand All @@ -29,6 +44,15 @@ pub const Test = struct {
}
}

pub fn mockInputJson(self: Test, comptime T: type, options: ?std.json.ParseOptions) !T {
const default_opts = .{ .allocate = .alloc_always, .ignore_unknown_fields = true };
const bytes = self.mockInput() orelse return error.NoMockInput;
const out = try std.json.parseFromSlice(T, self.plugin.allocator, bytes, options orelse default_opts);
const FromJson = Json(T);
const input = FromJson{ .parsed = out, .slice = bytes };
return input.parsed.value;
}

// Call a function from the Extism plugin being tested, passing input and returning its output.
pub fn call(self: Test, func_name: []const u8, input: []const u8) ![]const u8 {
const func_mem = self.plugin.allocateBytes(func_name);
Expand Down

0 comments on commit a72d746

Please sign in to comment.