| author | |
| committer | |
| log | a1d0efbb3e97764e36caf81ac8f9ac93bb1e8a84 |
| tree | 8da74ca858903cb9a90b4a084bb4d8164ab59fd5 |
| parent | 081f21d7b99764305f3025bb007c7caf2c2422ef |
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 | |||
| 125 | test { | ||
| 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 | |||
| 11 | test { | ||
| 12 | try std.testing.expect(OneBiggerInt(u0) == u1); | ||
| 13 | } | ||
| 14 | test { | ||
| 15 | try std.testing.expect(OneBiggerInt(u1) == u2); | ||
| 16 | } | ||
| 17 | test { | ||
| 18 | try std.testing.expect(OneBiggerInt(u2) == u3); | ||
| 19 | } | ||
| 20 | test { | ||
| 21 | try std.testing.expect(OneBiggerInt(u3) == u4); | ||
| 22 | } | ||
| 23 | test { | ||
| 24 | try std.testing.expect(OneBiggerInt(u4) == u5); | ||
| 25 | } | ||
| 26 | test { | ||
| 27 | try std.testing.expect(OneBiggerInt(i0) == i1); | ||
| 28 | } | ||
| 29 | test { | ||
| 30 | try std.testing.expect(OneBiggerInt(i1) == i2); | ||
| 31 | } | ||
| 32 | test { | ||
| 33 | try std.testing.expect(OneBiggerInt(i2) == i3); | ||
| 34 | } | ||
| 35 | test { | ||
| 36 | try std.testing.expect(OneBiggerInt(i3) == i4); | ||
| 37 | } | ||
| 38 | test { | ||
| 39 | try std.testing.expect(OneBiggerInt(i4) == i5); | ||
| 40 | } |
src/Partial.zig+18| ... | @@ -1,7 +1,10 @@ | ... | @@ -1,7 +1,10 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const string = []const u8; | 2 | const string = []const u8; |
| 3 | const extras = @import("./lib.zig"); | 3 | const extras = @import("./lib.zig"); |
| 4 | const expectSimilarType = extras.expectSimilarType; | ||
| 4 | 5 | ||
| 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. | ||
| 5 | pub fn Partial(comptime T: type) type { | 8 | pub 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 | |||
| 29 | test { | ||
| 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 | |||
| 16 | test { | ||
| 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 | |||
| 24 | test { | ||
| 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 | |||
| 12 | test { | ||
| 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 | |||
| 11 | test { | ||
| 12 | std.testing.refAllDecls(@This()); | ||
| 13 | } |
src/coalescePartial.zig+15-1| ... | @@ -1,11 +1,25 @@ | ... | @@ -1,11 +1,25 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const string = []const u8; | 2 | const string = []const u8; |
| 3 | const extras = @import("./lib.zig"); | 3 | const extras = @import("./lib.zig"); |
| 4 | const Partial = extras.Partial; | ||
| 4 | 5 | ||
| 5 | pub fn coalescePartial(comptime T: type, into: T, from: extras.Partial(T)) T { | 6 | pub 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 | |||
| 14 | test { | ||
| 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 | |||
| 14 | test { | ||
| 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 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const string = []const u8; | 2 | const string = []const u8; |
| 3 | const extras = @import("./lib.zig"); | 3 | const extras = @import("./lib.zig"); |
| 4 | const reduceNumber = extras.reduceNumber; | ||
| 4 | 5 | ||
| 5 | pub fn fmtByteCountIEC(alloc: std.mem.Allocator, b: u64) !string { | 6 | pub 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 | |||
| 10 | test { | ||
| 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 | } | ||
| 16 | test { | ||
| 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 | } | ||
| 22 | test { | ||
| 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 | } | ||
| 28 | test { | ||
| 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 | |||
| 16 | test { | ||
| 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 | |||
| 22 | test { | ||
| 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 | } | ||
| 28 | test { | ||
| 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 | } | ||
| 34 | test { | ||
| 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 | } | ||
| 40 | test { | ||
| 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"); |
| 5 | pub fn stringToEnum(comptime E: type, str: ?string) ?E { | 5 | pub 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 | |||
| 9 | test { | ||
| 10 | try std.testing.expect(stringToEnum(enum { A, B }, "A") == .A); | ||
| 11 | } | ||
| 12 | test { | ||
| 13 | try std.testing.expect(stringToEnum(enum { A, B }, "B") == .B); | ||
| 14 | } | ||
| 15 | test { | ||
| 16 | try std.testing.expect(stringToEnum(enum { A, B }, "C") == null); | ||
| 17 | } | ||
| 18 | test { | ||
| 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 | |||
| 11 | test { | ||
| 12 | try std.testing.expect(sum(u8, &.{ 4, 3, 0, 9, 6, 7, 1, 2, 5, 8 }) == 45); | ||
| 13 | } | ||
| 14 | test { | ||
| 15 | try std.testing.expect(sum(u16, &.{ 8, 6, 7, 3, 2, 1, 5, 0, 9, 4 }) == 45); | ||
| 16 | } | ||
| 17 | test { | ||
| 18 | try std.testing.expect(sum(u21, &.{ 5, 4, 6, 1, 8, 3, 2, 9, 0, 7 }) == 45); | ||
| 19 | } | ||
| 20 | test { | ||
| 21 | try std.testing.expect(sum(u32, &.{ 3, 4, 5, 1, 9, 0, 6, 2, 7, 8 }) == 45); | ||
| 22 | } | ||
| 23 | test { | ||
| 24 | try std.testing.expect(sum(u40, &.{ 0, 5, 6, 7, 1, 2, 4, 9, 3, 8 }) == 45); | ||
| 25 | } | ||
| 26 | test { | ||
| 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 | |||
| 12 | test { | ||
| 13 | try std.testing.expect(std.mem.eql(u8, trimPrefix("abaabbaaba", "c"), "abaabbaaba")); | ||
| 14 | } | ||
| 15 | test { | ||
| 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 | |||
| 10 | test { | ||
| 11 | try std.testing.expect(trimPrefixEnsure("abaabbaaba", "c") == null); | ||
| 12 | } | ||
| 13 | test { | ||
| 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 | |||
| 12 | test { | ||
| 13 | try std.testing.expect(std.mem.eql(u8, trimSuffix("abaabbaaba", "c"), "abaabbaaba")); | ||
| 14 | } | ||
| 15 | test { | ||
| 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 | |||
| 10 | test { | ||
| 11 | try std.testing.expect(trimSuffixEnsure("abaabbaaba", "c") == null); | ||
| 12 | } | ||
| 13 | test { | ||
| 14 | try std.testing.expect(std.mem.eql(u8, trimSuffixEnsure("abaabbaaba", "aba").?, "abaabba")); | ||
| 15 | } |