Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f72fb82

Browse files
committed
chore: add README
1 parent 160216c commit f72fb82

File tree

1 file changed

+142
-0
lines changed

1 file changed

+142
-0
lines changed

README.md

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
# xtp-test
2+
3+
A Zig test framework for [xtp](https://getxtp.com) /
4+
[Extism](https://extism.org) plugins.
5+
6+
## Example
7+
8+
```zig
9+
const std = @import("std");
10+
const Test = @import("xtp-test").Test;
11+
12+
const CountVowel = struct {
13+
total: u32,
14+
count: u32,
15+
vowels: []const u8,
16+
};
17+
18+
// you _must_ export a single `test` function (in Zig, "test" is a keyword, so use this raw literal syntax)
19+
export fn @"test"() i32 {
20+
// initialize your test to run functions in a target plugin
21+
const xtp_test = Test.init(std.heap.wasm_allocator);
22+
xtp_test.assert("this is a test", true);
23+
24+
// run the "count_vowels" function in the target plugin and assert the output is as expected
25+
const output = xtp_test.call("count_vowels", "this is a test") catch unreachable;
26+
const cv = fromJson(output);
27+
xtp_test.assertEq("count_vowels returns expected count", cv.count, 4);
28+
29+
// create a group of tests inside a new scope, use defer to close the group at the end of the scope
30+
// NOTE: creating a group will reset the target plugin, before the group starts and after it's closed
31+
{
32+
const maintain_state_group = xtp_test.newGroup("plugin should maintain state");
33+
errdefer maintain_state_group.close();
34+
var accumTotal: u32 = 0;
35+
for (0..10) |_| {
36+
const loop_output = xtp_test.call("count_vowels", "this is a test") catch unreachable;
37+
const loop_cv = fromJson(loop_output);
38+
accumTotal += cv.count;
39+
const msg = std.fmt.allocPrint(std.heap.wasm_allocator, "count_vowels returns expected incremented total: {}", .{accumTotal}) catch unreachable;
40+
xtp_test.assertEq(msg, loop_cv.total, accumTotal);
41+
}
42+
}
43+
44+
// create a group without a scope, and close it manually at the end of your tests
45+
const simple_group = xtp_test.newGroup("simple timing tests");
46+
// get the number of seconds elapsed in the "count_vowels" function using some input
47+
const sec = xtp_test.timeSec("count_vowels", "this is a test");
48+
xtp_test.assert("it should be fast", sec < 0.5);
49+
50+
// get the number of nanoseconds elapsed in the "count_vowels" function using some input
51+
const ns = xtp_test.timeNs("count_vowels", "this is a test");
52+
xtp_test.assert("it should be really fast", ns < 1e5);
53+
simple_group.close();
54+
55+
return 0;
56+
}
57+
58+
fn fromJson(json: []const u8) CountVowel {
59+
const cv = std.json.parseFromSlice(CountVowel, std.heap.wasm_allocator, json, .{}) catch unreachable;
60+
return cv.value;
61+
}
62+
```
63+
64+
## API Docs
65+
66+
See the [`main.zig`](/src/main.zig) file for the public API of this library.
67+
68+
## Usage
69+
70+
**1. Create a Zig project using the XTP Test library**
71+
72+
```sh
73+
mkdir zig-xtp-test
74+
cd zig-xtp-test
75+
zig init
76+
zig fetch --save https://github.com/dylibso/xtp-test-zig/archive/v0.0.1.tar.gz
77+
# see the `build.zig` in this repo for examples on how to configure it
78+
```
79+
80+
**2. Write your test in Zig**
81+
82+
```zig
83+
const std = @import("std");
84+
const Test = @import("xtp-test").Test;
85+
86+
const CountVowel = struct {
87+
total: u32,
88+
count: u32,
89+
vowels: []const u8,
90+
};
91+
92+
// you _must_ export a single `test` function (in Zig, "test" is a keyword, so use this raw literal syntax)
93+
export fn @"test"() i32 {
94+
// initialize your test to run functions in a target plugin
95+
const xtp_test = Test.init(std.heap.wasm_allocator);
96+
xtp_test.assert("this is a test", true);
97+
98+
// run the "count_vowels" function in the target plugin and assert the output is as expected
99+
const output = xtp_test.call("count_vowels", "this is a test") catch unreachable;
100+
const cv = fromJson(output);
101+
xtp_test.assertEq("count_vowels returns expected count", cv.count, 4);
102+
103+
...
104+
```
105+
106+
**3. Compile your test to .wasm:**
107+
108+
Ensure your `build.zig` is set up properly to compile to wasm32 `freestanding`
109+
or `wasi`. See the
110+
[Extism `zig-pdk` examples](https://github.com/extism/zig-pdk) or the
111+
`build.zig` in this repository for more details.
112+
113+
```sh
114+
zig build
115+
# which should output a .wasm into zig-out/bin/
116+
```
117+
118+
**4. Run the test against your plugin:** Once you have your test code as a
119+
`.wasm` module, you can run the test against your plugin using the `xtp` CLI:
120+
121+
### Install `xtp`
122+
123+
```sh
124+
curl https://static.dylibso.com/cli/install.sh | sudo sh
125+
```
126+
127+
### Run the test suite
128+
129+
```sh
130+
xtp plugin test ./plugin-*.wasm --with test.wasm --host host.wasm
131+
# ^^^^^^^^^^^^^^^ ^^^^^^^^^ ^^^^^^^^^
132+
# your plugin(s) test to run optional mock host functions
133+
```
134+
135+
**Note:** The optional mock host functions must be implemented as Extism
136+
plugins, whose exported functions match the host function signature imported by
137+
the plugins being tested.
138+
139+
## Need Help?
140+
141+
Please reach out via the
142+
[`#xtp` channel on Discord](https://discord.com/channels/1011124058408112148/1220464672784908358).

0 commit comments

Comments
 (0)