Code Monkey home page Code Monkey logo

xtp-test-zig's Introduction

xtp-test

A Zig test framework for xtp / Extism plugins.

Example

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 output = xtp_test.call("count_vowels", "this is a test") catch unreachable;
    const cv = fromJson(output);
    xtp_test.assertEq("count_vowels returns expected count", cv.count, 4);

    // create a group of tests inside a new scope, use defer to close the group at the end of the scope
    {
        const maintain_state_group = xtp_test.newGroup("plugin should maintain state");
        defer maintain_state_group.close();
        var accumTotal: u32 = 0;
        for (0..10) |_| {
            const loop_output = xtp_test.call("count_vowels", "this is a test") catch unreachable;
            const loop_cv = fromJson(loop_output);
            accumTotal += cv.count;
            const msg = std.fmt.allocPrint(std.heap.wasm_allocator, "count_vowels returns expected incremented total: {}", .{accumTotal}) catch unreachable;
            xtp_test.assertEq(msg, loop_cv.total, accumTotal);
        }
    }

    // create a group without a scope, and close it manually at the end of your tests
    const simple_group = xtp_test.newGroup("simple timing tests");
    const sec = xtp_test.timeSec("count_vowels", "this is a test");
    xtp_test.assertLt("it should be fast", sec, 0.5);

    const ns = xtp_test.timeNs("count_vowels", "this is a test");
    xtp_test.assertLt("it should be really fast", ns, 1e5);
    simple_group.close();

    return 0;
}

fn fromJson(json: []const u8) CountVowel {
    const cv = std.json.parseFromSlice(CountVowel, std.heap.wasm_allocator, json, .{}) catch unreachable;
    return cv.value;
}

API Docs

See the main.zig file for the public API of this library.

Usage

1. Create a Zig project using the XTP Test library

mkdir zig-xtp-test
cd zig-xtp-test
zig init
zig fetch --save https://github.com/dylibso/xtp-test-zig/archive/v0.1.0.tar.gz
# see the `build.zig` in this repo for examples on how to configure it

2. Write your test in Zig

const std = @import("std");
const Test = @import("xtp-test").Test;

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

// you _must_ export a single `test` function (in Zig, "test" is a keyword, so use this raw literal syntax)
export fn @"test"() i32 {
    // initialize your test to run functions in a target plugin
    const xtp_test = Test.init(std.heap.wasm_allocator);
    xtp_test.assert("this is a test", true, "Expect true == true");

    // run the "count_vowels" function in the target plugin and assert the output is as expected
    const output = xtp_test.call("count_vowels", "this is a test") catch unreachable;
    const cv = fromJson(output);
    xtp_test.assertEq("count_vowels returns expected count", cv.count, 4);

    ...

3. Compile your test to .wasm:

Ensure your build.zig is set up properly to compile to wasm32 freestanding or wasi. See the Extism zig-pdk examples or the build.zig in this repository for more details.

zig build
# which should output a .wasm into zig-out/bin/

4. Run the test against your plugin: Once you have your test code as a .wasm module, you can run the test against your plugin using the xtp CLI:

Install xtp

curl https://static.dylibso.com/cli/install.sh | sudo sh

Run the test suite

xtp plugin test ./plugin-*.wasm --with test.wasm --mock-host host.wasm
#               ^^^^^^^^^^^^^^^        ^^^^^^^^^             ^^^^^^^^^
#               your plugin(s)         test to run           optional mock host functions

Note: The optional mock host functions must be implemented as Extism plugins, whose exported functions match the host function signature imported by the plugins being tested.

Need Help?

Please reach out via the #xtp channel on Discord.

xtp-test-zig's People

Contributors

nilslice avatar zshipko avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.