authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2024-01-28 22:02:48 -08:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2024-01-28 22:02:48 -08:00
loga1d0efbb3e97764e36caf81ac8f9ac93bb1e8a84
tree8da74ca858903cb9a90b4a084bb4d8164ab59fd5
parent081f21d7b99764305f3025bb007c7caf2c2422ef

add more tests


18 files changed, 239 insertions(+), 3 deletions(-)

src/AnyReader.zig+4
...@@ -121,3 +121,7 @@ pub const AnyReader = struct {...@@ -121,3 +121,7 @@ pub const AnyReader = struct {
121 }121 }
122 }122 }
123};123};
124
125test {
126 std.testing.refAllDecls(AnyReader);
127}
src/OneBiggerInt.zig+31
...@@ -7,3 +7,34 @@ pub fn OneBiggerInt(comptime T: type) type {...@@ -7,3 +7,34 @@ pub fn OneBiggerInt(comptime T: type) type {
7 info.Int.bits += 1;7 info.Int.bits += 1;
8 return @Type(info);8 return @Type(info);
9}9}
10
11test {
12 try std.testing.expect(OneBiggerInt(u0) == u1);
13}
14test {
15 try std.testing.expect(OneBiggerInt(u1) == u2);
16}
17test {
18 try std.testing.expect(OneBiggerInt(u2) == u3);
19}
20test {
21 try std.testing.expect(OneBiggerInt(u3) == u4);
22}
23test {
24 try std.testing.expect(OneBiggerInt(u4) == u5);
25}
26test {
27 try std.testing.expect(OneBiggerInt(i0) == i1);
28}
29test {
30 try std.testing.expect(OneBiggerInt(i1) == i2);
31}
32test {
33 try std.testing.expect(OneBiggerInt(i2) == i3);
34}
35test {
36 try std.testing.expect(OneBiggerInt(i3) == i4);
37}
38test {
39 try std.testing.expect(OneBiggerInt(i4) == i5);
40}
src/Partial.zig+18
...@@ -1,7 +1,10 @@...@@ -1,7 +1,10 @@
1const std = @import("std");1const std = @import("std");
2const string = []const u8;2const string = []const u8;
3const extras = @import("./lib.zig");3const extras = @import("./lib.zig");
4const expectSimilarType = extras.expectSimilarType;
45
6/// Creates a new version of struct T where all fields are optional.
7/// Name inspried by https://www.typescriptlang.org/docs/handbook/utility-types.html#partialtype.
5pub fn Partial(comptime T: type) type {8pub fn Partial(comptime T: type) type {
6 const fields_before = std.meta.fields(T);9 const fields_before = std.meta.fields(T);
7 var fields_after: [fields_before.len]std.builtin.Type.StructField = undefined;10 var fields_after: [fields_before.len]std.builtin.Type.StructField = undefined;
...@@ -22,3 +25,18 @@ pub fn Partial(comptime T: type) type {...@@ -22,3 +25,18 @@ pub fn Partial(comptime T: type) type {
22 .is_tuple = false,25 .is_tuple = false,
23 }));26 }));
24}27}
28
29test {
30 try expectSimilarType(
31 Partial(struct {
32 a: u32,
33 b: u8,
34 c: u16,
35 }),
36 struct {
37 a: ?u32,
38 b: ?u8,
39 c: ?u16,
40 },
41 );
42}
src/ReverseFields.zig+12
...@@ -12,3 +12,15 @@ pub fn ReverseFields(comptime T: type) type {...@@ -12,3 +12,15 @@ pub fn ReverseFields(comptime T: type) type {
12 info.fields = &fields;12 info.fields = &fields;
13 return @Type(.{ .Struct = info });13 return @Type(.{ .Struct = info });
14}14}
15
16test {
17 const A = struct { x: u8, y: u16 };
18 const B = ReverseFields(A);
19 const fields = std.meta.fields(B);
20
21 try std.testing.expect(fields.len == 2);
22 try std.testing.expect(fields[0].type == u16);
23 try std.testing.expect(std.mem.eql(u8, fields[0].name, "y"));
24 try std.testing.expect(fields[1].type == u8);
25 try std.testing.expect(std.mem.eql(u8, fields[1].name, "x"));
26}
src/RingBuffer.zig+4
...@@ -20,3 +20,7 @@ pub fn RingBuffer(comptime T: type, comptime capacity: usize) type {...@@ -20,3 +20,7 @@ pub fn RingBuffer(comptime T: type, comptime capacity: usize) type {
20 }20 }
21 };21 };
22}22}
23
24test {
25 std.testing.refAllDecls(RingBuffer(u8, 16));
26}
src/base64DecodeAlloc.zig+4
...@@ -8,3 +8,7 @@ pub fn base64DecodeAlloc(alloc: std.mem.Allocator, input: string) !string {...@@ -8,3 +8,7 @@ pub fn base64DecodeAlloc(alloc: std.mem.Allocator, input: string) !string {
8 try base64.decode(buf, input);8 try base64.decode(buf, input);
9 return buf;9 return buf;
10}10}
11
12test {
13 std.testing.refAllDecls(@This());
14}
src/base64EncodeAlloc.zig+4
...@@ -7,3 +7,7 @@ pub fn base64EncodeAlloc(alloc: std.mem.Allocator, input: string) !string {...@@ -7,3 +7,7 @@ pub fn base64EncodeAlloc(alloc: std.mem.Allocator, input: string) !string {
7 var buf = try alloc.alloc(u8, base64.calcSize(input.len));7 var buf = try alloc.alloc(u8, base64.calcSize(input.len));
8 return base64.encode(buf, input);8 return base64.encode(buf, input);
9}9}
10
11test {
12 std.testing.refAllDecls(@This());
13}
src/coalescePartial.zig+15-1
...@@ -1,11 +1,25 @@...@@ -1,11 +1,25 @@
1const std = @import("std");1const std = @import("std");
2const string = []const u8;2const string = []const u8;
3const extras = @import("./lib.zig");3const extras = @import("./lib.zig");
4const Partial = extras.Partial;
45
5pub fn coalescePartial(comptime T: type, into: T, from: extras.Partial(T)) T {6pub fn coalescePartial(comptime T: type, into: T, from: Partial(T)) T {
6 var temp = into;7 var temp = into;
7 inline for (comptime std.meta.fieldNames(T)) |name| {8 inline for (comptime std.meta.fieldNames(T)) |name| {
8 if (@field(from, name)) |val| @field(temp, name) = val;9 if (@field(from, name)) |val| @field(temp, name) = val;
9 }10 }
10 return temp;11 return temp;
11}12}
13
14test {
15 const S = struct {
16 a: u8 = 4,
17 b: u8 = 7,
18 c: u8 = 1,
19 };
20 try std.testing.expect(std.meta.eql(coalescePartial(S, .{}, .{ .b = 9 }), .{
21 .a = 4,
22 .b = 9,
23 .c = 1,
24 }));
25}
src/containsAggregate.zig+23
...@@ -10,3 +10,26 @@ pub fn containsAggregate(comptime T: type, haystack: []const T, needle: T) bool...@@ -10,3 +10,26 @@ pub fn containsAggregate(comptime T: type, haystack: []const T, needle: T) bool
10 }10 }
11 return false;11 return false;
12}12}
13
14test {
15 const S = struct {
16 a: u8,
17
18 fn eql(this: @This(), other: @This()) bool {
19 return this.a == other.a;
20 }
21 };
22 const data = [_]S{
23 .{ .a = 8 },
24 .{ .a = 6 },
25 .{ .a = 7 },
26 .{ .a = 2 },
27 .{ .a = 4 },
28 .{ .a = 1 },
29 .{ .a = 9 },
30 .{ .a = 3 },
31 .{ .a = 5 },
32 };
33 try std.testing.expect(containsAggregate(S, &data, .{ .a = 4 }));
34 try std.testing.expect(!containsAggregate(S, &data, .{ .a = 0 }));
35}
src/fmtByteCountIEC.zig+27-1
...@@ -1,7 +1,33 @@...@@ -1,7 +1,33 @@
1const std = @import("std");1const std = @import("std");
2const string = []const u8;2const string = []const u8;
3const extras = @import("./lib.zig");3const extras = @import("./lib.zig");
4const reduceNumber = extras.reduceNumber;
45
5pub fn fmtByteCountIEC(alloc: std.mem.Allocator, b: u64) !string {6pub fn fmtByteCountIEC(alloc: std.mem.Allocator, b: u64) !string {
6 return try extras.reduceNumber(alloc, b, 1024, "B", "KMGTPEZYRQ");7 return try reduceNumber(alloc, b, 1024, "B", "KMGTPEZYRQ");
8}
9
10test {
11 const allocator = std.testing.allocator;
12 const actual = try fmtByteCountIEC(allocator, std.math.pow(u64, 1024, 0));
13 defer allocator.free(actual);
14 try std.testing.expect(std.mem.eql(u8, actual, "1 B"));
15}
16test {
17 const allocator = std.testing.allocator;
18 const actual = try fmtByteCountIEC(allocator, std.math.pow(u64, 1024, 1));
19 defer allocator.free(actual);
20 try std.testing.expect(std.mem.eql(u8, actual, "1.000 KB"));
21}
22test {
23 const allocator = std.testing.allocator;
24 const actual = try fmtByteCountIEC(allocator, std.math.pow(u64, 1024, 2));
25 defer allocator.free(actual);
26 try std.testing.expect(std.mem.eql(u8, actual, "1.000 MB"));
27}
28test {
29 const allocator = std.testing.allocator;
30 const actual = try fmtByteCountIEC(allocator, std.math.pow(u64, 1024, 3));
31 defer allocator.free(actual);
32 try std.testing.expect(std.mem.eql(u8, actual, "1.000 GB"));
7}33}
src/randomSlice.zig+8
...@@ -12,3 +12,11 @@ pub fn randomSlice(alloc: std.mem.Allocator, rand: std.rand.Random, comptime T:...@@ -12,3 +12,11 @@ pub fn randomSlice(alloc: std.mem.Allocator, rand: std.rand.Random, comptime T:
12 }12 }
13 return buf;13 return buf;
14}14}
15
16test {
17 const allocator = std.testing.allocator;
18 const rand = std.crypto.random;
19 const slice = try randomSlice(allocator, rand, u8, 10);
20 defer allocator.free(slice);
21 try std.testing.expect(slice.len == 10);
22}
src/reduceNumber.zig+29-1
...@@ -12,6 +12,34 @@ pub fn reduceNumber(alloc: std.mem.Allocator, input: u64, comptime unit: u64, co...@@ -12,6 +12,34 @@ pub fn reduceNumber(alloc: std.mem.Allocator, input: u64, comptime unit: u64, co
12 while (n >= unit) : (n /= unit) {12 while (n >= unit) : (n /= unit) {
13 div *= unit;13 div *= unit;
14 exp += 1;14 exp += 1;
15 if (exp == prefixes.len - 1) break;
15 }16 }
16 return try std.fmt.allocPrint(alloc, "{d:.3} {s}{s}", .{ @as(f64, @floatFromInt(input)) / @as(f64, @floatFromInt(div)), prefixes[exp .. exp + 1], base });17 const input_f: f64 = @floatFromInt(input);
18 const div_f: f64 = @floatFromInt(div);
19 return try std.fmt.allocPrint(alloc, "{d:.3} {s}{s}", .{ input_f / div_f, prefixes[exp..][0..1], base });
20}
21
22test {
23 const allocator = std.testing.allocator;
24 const actual = try reduceNumber(allocator, 1, 60, "s", "mh");
25 defer allocator.free(actual);
26 try std.testing.expect(std.mem.eql(u8, actual, "1 s"));
27}
28test {
29 const allocator = std.testing.allocator;
30 const actual = try reduceNumber(allocator, 60, 60, "s", "mh");
31 defer allocator.free(actual);
32 try std.testing.expect(std.mem.eql(u8, actual, "1.000 ms"));
33}
34test {
35 const allocator = std.testing.allocator;
36 const actual = try reduceNumber(allocator, 3600, 60, "s", "mh");
37 defer allocator.free(actual);
38 try std.testing.expect(std.mem.eql(u8, actual, "1.000 hs"));
39}
40test {
41 const allocator = std.testing.allocator;
42 const actual = try reduceNumber(allocator, 216000, 60, "s", "mh");
43 defer allocator.free(actual);
44 try std.testing.expect(std.mem.eql(u8, actual, "60.000 hs"));
17}45}
src/stringToEnum.zig+13
...@@ -5,3 +5,16 @@ const extras = @import("./lib.zig");...@@ -5,3 +5,16 @@ const extras = @import("./lib.zig");
5pub fn stringToEnum(comptime E: type, str: ?string) ?E {5pub fn stringToEnum(comptime E: type, str: ?string) ?E {
6 return std.meta.stringToEnum(E, str orelse return null);6 return std.meta.stringToEnum(E, str orelse return null);
7}7}
8
9test {
10 try std.testing.expect(stringToEnum(enum { A, B }, "A") == .A);
11}
12test {
13 try std.testing.expect(stringToEnum(enum { A, B }, "B") == .B);
14}
15test {
16 try std.testing.expect(stringToEnum(enum { A, B }, "C") == null);
17}
18test {
19 try std.testing.expect(stringToEnum(enum { A, B }, null) == null);
20}
src/sum.zig+19
...@@ -7,3 +7,22 @@ pub fn sum(comptime T: type, slice: []const T) T {...@@ -7,3 +7,22 @@ pub fn sum(comptime T: type, slice: []const T) T {
7 for (slice) |item| res += item;7 for (slice) |item| res += item;
8 return res;8 return res;
9}9}
10
11test {
12 try std.testing.expect(sum(u8, &.{ 4, 3, 0, 9, 6, 7, 1, 2, 5, 8 }) == 45);
13}
14test {
15 try std.testing.expect(sum(u16, &.{ 8, 6, 7, 3, 2, 1, 5, 0, 9, 4 }) == 45);
16}
17test {
18 try std.testing.expect(sum(u21, &.{ 5, 4, 6, 1, 8, 3, 2, 9, 0, 7 }) == 45);
19}
20test {
21 try std.testing.expect(sum(u32, &.{ 3, 4, 5, 1, 9, 0, 6, 2, 7, 8 }) == 45);
22}
23test {
24 try std.testing.expect(sum(u40, &.{ 0, 5, 6, 7, 1, 2, 4, 9, 3, 8 }) == 45);
25}
26test {
27 try std.testing.expect(sum(u64, &.{ 5, 4, 3, 9, 1, 7, 6, 2, 0, 8 }) == 45);
28}
src/trimPrefix.zig+7
...@@ -8,3 +8,10 @@ pub fn trimPrefix(in: string, prefix: string) string {...@@ -8,3 +8,10 @@ pub fn trimPrefix(in: string, prefix: string) string {
8 }8 }
9 return in;9 return in;
10}10}
11
12test {
13 try std.testing.expect(std.mem.eql(u8, trimPrefix("abaabbaaba", "c"), "abaabbaaba"));
14}
15test {
16 try std.testing.expect(std.mem.eql(u8, trimPrefix("abaabbaaba", "aba"), "abbaaba"));
17}
src/trimPrefixEnsure.zig+7
...@@ -6,3 +6,10 @@ pub fn trimPrefixEnsure(in: string, prefix: string) ?string {...@@ -6,3 +6,10 @@ pub fn trimPrefixEnsure(in: string, prefix: string) ?string {
6 if (!std.mem.startsWith(u8, in, prefix)) return null;6 if (!std.mem.startsWith(u8, in, prefix)) return null;
7 return in[prefix.len..];7 return in[prefix.len..];
8}8}
9
10test {
11 try std.testing.expect(trimPrefixEnsure("abaabbaaba", "c") == null);
12}
13test {
14 try std.testing.expect(std.mem.eql(u8, trimPrefixEnsure("abaabbaaba", "aba").?, "abbaaba"));
15}
src/trimSuffix.zig+7
...@@ -8,3 +8,10 @@ pub fn trimSuffix(in: string, suffix: string) string {...@@ -8,3 +8,10 @@ pub fn trimSuffix(in: string, suffix: string) string {
8 }8 }
9 return in;9 return in;
10}10}
11
12test {
13 try std.testing.expect(std.mem.eql(u8, trimSuffix("abaabbaaba", "c"), "abaabbaaba"));
14}
15test {
16 try std.testing.expect(std.mem.eql(u8, trimSuffix("abaabbaaba", "aba"), "abaabba"));
17}
src/trimSuffixEnsure.zig+7
...@@ -6,3 +6,10 @@ pub fn trimSuffixEnsure(in: string, suffix: string) ?string {...@@ -6,3 +6,10 @@ pub fn trimSuffixEnsure(in: string, suffix: string) ?string {
6 if (!std.mem.endsWith(u8, in, suffix)) return null;6 if (!std.mem.endsWith(u8, in, suffix)) return null;
7 return in[0 .. in.len - suffix.len];7 return in[0 .. in.len - suffix.len];
8}8}
9
10test {
11 try std.testing.expect(trimSuffixEnsure("abaabbaaba", "c") == null);
12}
13test {
14 try std.testing.expect(std.mem.eql(u8, trimSuffixEnsure("abaabbaaba", "aba").?, "abaabba"));
15}