Something went wrong. Try again.
zig 0.17 driver for libhegel, with the harness parts for stateful property tests
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273//! a map that caches the sum of its values and forgets to invalidate the//! cache when a put overwrites an existing key. the minimal history is//! put(k0, 0); sum(); put(k0, 1); sum().
const std = @import("std");const hegel = @import("hegel");
const Toy = struct { values: [4]?u8 = @splat(null), cached: ?u32 = null,
fn put(self: *Toy, key: usize, value: u8) void { if (self.values[key] == null) self.cached = null; self.values[key] = value; }
fn sum(self: *Toy) u32 { if (self.cached) |s| return s; self.cached = self.recompute(); return self.cached.?; }
fn count(self: *const Toy) u64 { var keys: u64 = 0; for (self.values) |value| keys += @intFromBool(value != null); return keys; }
fn recompute(self: *const Toy) u32 { var total: u32 = 0; for (self.values) |value| total += value orelse 0; return total; }};
const Rule = enum { put, sum };
var tally: hegel.Tally(Rule) = .{};
fn property(_: void, case: *hegel.TestCase) !void { var toy: Toy = .{}; tally.case(); var machine = try case.machine(Rule, &.{ 2, 1 }, 20); defer machine.deinit(); while (try machine.next()) |rule| { tally.step(rule); switch (rule) { .put => { const key = try case.index(4); const value = try case.int(u8, 0, 255); case.note("put(k{d}, {d})", .{ key, value }); toy.put(key, value); }, .sum => { case.note("sum()", .{}); if (toy.sum() != toy.recompute()) return case.fail("sum() disagrees with a recompute"); }, } } tally.finish(toy.count());}
pub fn main() void { const outcome = hegel.run(.{ .test_cases = 500 }, {}, property); tally.print(); outcome catch { std.debug.print("\nfound the planted bug, as expected\n", .{}); return; }; std.debug.print("the planted bug was not found\n", .{}); std.process.exit(1);}