1
Fork 0

user.fromLine tests

main
Motiejus Jakštys 2022-07-02 09:14:02 +03:00
parent e7fb0c18d4
commit 186796fffc
2 changed files with 55 additions and 36 deletions

View File

@ -55,6 +55,7 @@ fn fromLine(allocator: Allocator, err: *ErrCtx, line: []const u8) error{ Invalid
const gecos = it.next() orelse return err.returnf("too few fields", .{}, error.InvalidRecord);
const home = it.next() orelse return err.returnf("too few fields", .{}, error.InvalidRecord);
const shell = it.next() orelse return err.returnf("too few fields", .{}, error.InvalidRecord);
if (it.next() != null) return err.returnf("too many fields", .{}, error.InvalidRecord);
const uid = fmt.parseInt(u32, uids, 10) catch
return err.returnf("bad uid: {s}", .{uids}, error.InvalidRecord);
@ -164,33 +165,55 @@ pub const max_user = User{
.shell = "She.LllL" ** 32,
};
const from_line_examples = [_]struct {
line: []const u8,
want: error{InvalidRecord}!User,
wantErrStr: []const u8 = &[_]u8{},
}{
.{
.line = "root:x:0:0:root:/root:/bin/bash",
.want = User{
.uid = 0,
.gid = 0,
.name = "root",
.gecos = "root",
.home = "/root",
.shell = "/bin/bash",
},
},
.{
.line = "žemas:x:0:0:root:/root:/bin/bash",
.want = error.InvalidRecord,
.wantErrStr = "invalid name 'žemas': invalid character at position 0",
},
};
test "User.fromLine" {
//if (true) return error.SkipZigTest;
const examples = [_]struct {
line: []const u8,
want: ?User = null,
wantErr: []const u8 = &[_]u8{},
}{
.{
.line = "root:x:0:0:root:/root:/bin/bash",
.want = User{
.uid = 0,
.gid = 0,
.name = "root",
.gecos = "root",
.home = "/root",
.shell = "/bin/bash",
},
},
.{
.line = "žemas:x:0:0:root:/root:/bin/bash",
.wantErr = "invalid name 'žemas': invalid character at position 0",
},
.{
.line = "root:x:-1:0:root:/root:/bin/bash",
.wantErr = "bad uid: -1",
},
.{
.line = "root:x:0:-1:root:/root:/bin/bash",
.wantErr = "bad gid: -1",
},
.{
.line = "root:x:0:0:root:/root:bin/bash",
.wantErr = "invalid shell 'bin/bash': must start with /",
},
.{
.line = "root:x:0:0:root:/root:/bin/bash:redundant",
.wantErr = "too many fields",
},
.{
.line = "",
.wantErr = "too few fields",
},
.{
.line = "root:x:0:0:root:/root",
.wantErr = "too few fields",
},
};
const allocator = testing.allocator;
for (from_line_examples) |tt| {
for (examples) |tt| {
var err = ErrCtx{};
if (tt.want) |want_user| {
@ -202,16 +225,12 @@ test "User.fromLine" {
try testing.expectEqualStrings(want_user.gecos, got.gecos);
try testing.expectEqualStrings(want_user.home, got.home);
try testing.expectEqualStrings(want_user.shell, got.shell);
} else |want_err| {
try testing.expectError(
want_err,
fromLine(allocator, &err, tt.line),
);
try testing.expectEqualStrings(
tt.wantErrStr,
err.unwrap().constSlice(),
);
continue;
}
const got = fromLine(allocator, &err, tt.line);
try testing.expectError(error.InvalidRecord, got);
try testing.expectEqualStrings(tt.wantErr, err.unwrap().constSlice());
}
}

View File

@ -54,7 +54,7 @@ pub fn path(s: []const u8, err: *ErrCtx) error{InvalidRecord}!void {
return err.returnf("cannot be empty", .{}, error.InvalidRecord);
if (s[0] != '/')
return err.returnf("must start with '/'", .{}, error.InvalidRecord);
return err.returnf("must start with /", .{}, error.InvalidRecord);
for (s[1..]) |c, i| {
if (!(ascii.isAlNum(c) or c == '/' or c == '_' or c == '.' or c == '@' or c == '-'))
@ -128,7 +128,7 @@ test "validate path" {
}{
.{ .path = "/path/ok" },
.{ .path = "/" },
.{ .path = "foo", .wantErr = "must start with '/'" },
.{ .path = "foo", .wantErr = "must start with /" },
.{ .path = "", .wantErr = "cannot be empty" },
.{ .path = "/path:motiejus", .wantErr = "invalid character at position 6" },
.{ .path = "/Herbasž", .wantErr = "invalid character at position 8" },