Skip to content

Commit 849036d

Browse files
committed
Update to Zig 0.15.1
1 parent d7dd807 commit 849036d

5 files changed

Lines changed: 32 additions & 39 deletions

File tree

.github/workflows/zig.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@ jobs:
1818
- macos-latest
1919
- windows-latest
2020
- ubuntu-24.04-arm
21-
zig_version: [ "0.14.0-dev.3187+d4c85079c", "master" ]
21+
zig_version: [ "master" ]
2222

2323
steps:
2424
- name: Check out repository
2525
uses: actions/checkout@v4
2626

2727
- name: Install Zig
28-
uses: mlugg/setup-zig@v1
28+
uses: mlugg/setup-zig@v2
2929
with:
3030
version: ${{ matrix.zig_version }}
3131

README.md

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Marble is a [metamorphic testing](https://en.wikipedia.org/wiki/Metamorphic_testing) library for Zig.
44

5-
This library tracks Zig master and was last tested on `0.14.0-dev.3187+d4c85079c`
5+
The main branch tracks Zig master. Use a tagged release to target a specific Zig version.
66

77
Metamorphic testing is a powerful technique that provides additional test coverage by applying a number of transformations to test input, and then checking if certain relations still hold between the outputs. Marble will automatically run through all possible combinations of these transformations.
88

@@ -30,13 +30,6 @@ zig build
3030
zig build test
3131
```
3232

33-
## Importing the library
34-
Add Marble as a Zig package in your build file, or simply import it directly after vendoring/adding a submodule:
35-
36-
```zig
37-
const marble = @import("marble/main.zig");
38-
```
39-
4033
## Writing tests
4134

4235
A metamorphic Zig test looks something like this:
@@ -73,12 +66,12 @@ const SinusTest = struct {
7366
}
7467
};
7568
76-
test "sinus" {
77-
var i: f64 = 1;
78-
while (i < 100) : (i += 1) {
79-
var t = SinusTest{ .value = i };
80-
try std.testing.expect(try marble.run(SinusTest, &t, .{}));
81-
}
69+
...
70+
71+
var i: f64 = 1;
72+
while (i < 100) : (i += 1) {
73+
var t = SinusTest{ .value = i };
74+
try std.testing.expect(try marble.run(SinusTest, &t, allocator, .{}));
8275
}
8376
```
8477

build.zig

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,23 @@ pub fn build(b: *std.Build) void {
88
.root_source_file = b.path("src/main.zig"),
99
});
1010

11-
const lib = b.addStaticLibrary(.{
11+
const lib = b.addLibrary(.{
1212
.name = "marble",
13-
.root_source_file = b.path("src/main.zig"),
14-
.target = target,
15-
.optimize = optimize,
13+
.root_module = b.createModule(.{
14+
.root_source_file = b.path("src/main.zig"),
15+
.target = target,
16+
.optimize = optimize,
17+
}),
1618
});
1719
b.installArtifact(lib);
1820

1921
const tests = b.addTest(.{
2022
.name = "example_tests",
21-
.root_source_file = b.path("src/example_tests.zig"),
22-
.target = target,
23-
.optimize = optimize,
23+
.root_module = b.createModule(.{
24+
.root_source_file = b.path("src/example_tests.zig"),
25+
.target = target,
26+
.optimize = optimize,
27+
}),
2428
});
2529
tests.root_module.addImport("marble", marble_mod);
2630

src/example_tests.zig

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ test "sinus" {
3737
var i: f64 = 1;
3838
while (i < 100) : (i += 1) {
3939
var t = SinusTest{ .value = i };
40-
try std.testing.expect(try marble.run(SinusTest, &t, .{}));
40+
try std.testing.expect(try marble.run(SinusTest, &t, std.testing.allocator, .{}));
4141
}
4242
}
4343

@@ -98,7 +98,7 @@ const QueryTest = struct {
9898

9999
test "query" {
100100
var query_test = QueryTest{ .value = .{} };
101-
try std.testing.expect(try marble.run(QueryTest, &query_test, .{ .skip_combinations = false, .verbose = false }));
101+
try std.testing.expect(try marble.run(QueryTest, &query_test, std.testing.allocator, .{ .skip_combinations = false, .verbose = false }));
102102
}
103103

104104
/// Test some metamorphic relations of binary search
@@ -161,6 +161,6 @@ test "std.sort.binarySearch" {
161161
var i: usize = 0;
162162
while (i < array.len) : (i += 1) {
163163
var bs_test = BinarySearchTest{ .value = i, .arr = array };
164-
try std.testing.expect(try marble.run(BinarySearchTest, &bs_test, .{ .skip_combinations = true }));
164+
try std.testing.expect(try marble.run(BinarySearchTest, &bs_test, std.testing.allocator, .{ .skip_combinations = true }));
165165
}
166166
}

src/main.zig

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,19 @@ const std = @import("std");
66
/// Generate an (n take r) list of transformer indices
77
/// Number of combinations returned is n! / (r! (n-r)!)
88
fn generateCombinations(n: usize, r: usize, allocator: std.mem.Allocator) !std.ArrayList(std.ArrayList(usize)) {
9-
var combinations = std.ArrayList(std.ArrayList(usize)).init(allocator);
10-
var combination = std.ArrayList(usize).init(allocator);
9+
var combinations = std.ArrayList(std.ArrayList(usize)).empty;
10+
var combination = std.ArrayList(usize).empty;
1111

1212
// Start with the smallest lexicographic combination
1313
{
1414
var i: usize = 0;
1515
while (i < r) : (i += 1) {
16-
try combination.append(i);
16+
try combination.append(allocator, i);
1717
}
1818
}
1919

2020
while (combination.items[r - 1] < n) {
21-
try combinations.append(try combination.clone());
21+
try combinations.append(allocator, try combination.clone(allocator));
2222

2323
// Next combination in lexicographic order
2424
var k = r - 1;
@@ -38,10 +38,10 @@ fn generateCombinations(n: usize, r: usize, allocator: std.mem.Allocator) !std.A
3838

3939
/// Generate the combinations for every n = 0..count-1 and r = 1..count
4040
fn generateAllCombinations(transformation_count: usize, allocator: std.mem.Allocator) !std.ArrayList(std.ArrayList(usize)) {
41-
var res = std.ArrayList(std.ArrayList(usize)).init(allocator);
41+
var res = std.ArrayList(std.ArrayList(usize)).empty;
4242
var i: usize = 1;
4343
while (i <= transformation_count) : (i += 1) {
44-
try res.appendSlice((try generateCombinations(transformation_count, i, allocator)).items[0..]);
44+
try res.appendSlice(allocator, (try generateCombinations(transformation_count, i, allocator)).items[0..]);
4545
}
4646
return res;
4747
}
@@ -88,7 +88,7 @@ pub const RunConfiguration = struct {
8888
};
8989

9090
/// Run a testcase, returns true if all succeed
91-
pub fn run(comptime T: type, testcase: *T, config: RunConfiguration) !bool {
91+
pub fn run(comptime T: type, testcase: *T, allocator: std.mem.Allocator, config: RunConfiguration) !bool {
9292
if (config.verbose) std.debug.print("\n", .{});
9393
const metamorphicTest = comptime findTransformers(T);
9494
if (@hasDecl(T, "before")) testcase.before(Phase.Test);
@@ -99,9 +99,9 @@ pub fn run(comptime T: type, testcase: *T, config: RunConfiguration) !bool {
9999
// holds after transformations.
100100
const org_output = testcase.execute();
101101

102-
var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
102+
var arena = std.heap.ArenaAllocator.init(allocator);
103103
defer arena.deinit();
104-
var combinations = try generateAllCombinations(metamorphicTest.len, arena.allocator());
104+
const combinations = try generateAllCombinations(metamorphicTest.len, arena.allocator());
105105
for (combinations.items) |combination| {
106106
if (combination.items.len > 1 and config.skip_combinations) {
107107
if (config.verbose) std.debug.print("Skipping transformation combinations\n", .{});
@@ -143,9 +143,5 @@ pub fn run(comptime T: type, testcase: *T, config: RunConfiguration) !bool {
143143

144144
if (@hasDecl(T, "after")) testcase.after(Phase.Test);
145145

146-
for (combinations.items) |*combination| {
147-
combination.deinit();
148-
}
149-
combinations.deinit();
150146
return true;
151147
}

0 commit comments

Comments
 (0)