Skip to content

Commit 6fe8c49

Browse files
committed
tests: add more auxlib tests
1 parent f633157 commit 6fe8c49

File tree

2 files changed

+103
-28
lines changed

2 files changed

+103
-28
lines changed

src/tests.zig

Lines changed: 77 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,7 @@ test "version" {
429429
defer lua.deinit();
430430

431431
try expectEqual(@as(f64, 504), lua.version());
432+
lua.checkVersion();
432433
}
433434

434435
test "string buffers" {
@@ -484,7 +485,8 @@ test "string buffers" {
484485
b = buffer.prep();
485486
std.mem.copy(u8, b, "defghijklmnopqrstuvwxyz");
486487
buffer.pushResultSize(23);
487-
try expectEqualStrings("abcdefghijklmnopqrstuvwxyz", try lua.toBytes(-1));
488+
try expectEqualStrings("abcdefghijklmnopqrstuvwxyz", lua.toBytesAux(-1));
489+
lua.pop(1);
488490

489491
lua.len(-1);
490492
try expectEqual(@as(Integer, 26), try lua.toInteger(-1));
@@ -1212,7 +1214,8 @@ test "aux check functions" {
12121214
};
12131215

12141216
lua.pushFunction(function);
1215-
lua.pushNil();
1217+
// test pushFail here (currently acts the same as pushNil)
1218+
lua.pushFail();
12161219
lua.pushInteger(3);
12171220
lua.pushBytes("hello world");
12181221
lua.pushNumber(4);
@@ -1250,17 +1253,86 @@ test "metatables" {
12501253
try expectEqual(@as(Number, 10), try lua.toNumber(-1));
12511254
}
12521255

1256+
test "aux opt functions" {
1257+
var lua = try Lua.init(testing.allocator);
1258+
defer lua.deinit();
1259+
1260+
const function = ziglua.wrap(struct {
1261+
fn inner(l: *Lua) i32 {
1262+
expectEqual(@as(Integer, 10), l.optInteger(1, 10)) catch unreachable;
1263+
expectEqualStrings("zig", l.optBytes(2, "zig")) catch unreachable;
1264+
expectEqual(@as(Number, 1.23), l.optNumber(3, 1.23)) catch unreachable;
1265+
expectEqualStringsSentinel("lang", l.optString(4, "lang")) catch unreachable;
1266+
return 0;
1267+
}
1268+
}.inner);
1269+
1270+
lua.pushFunction(function);
1271+
try lua.protectedCall(0, 0, 0);
1272+
1273+
lua.pushFunction(function);
1274+
lua.pushInteger(10);
1275+
lua.pushBytes("zig");
1276+
lua.pushNumber(1.23);
1277+
lua.pushString("lang");
1278+
try lua.protectedCall(4, 0, 0);
1279+
}
1280+
1281+
test "checkOption" {
1282+
var lua = try Lua.init(testing.allocator);
1283+
defer lua.deinit();
1284+
1285+
const Variant = enum {
1286+
one,
1287+
two,
1288+
three,
1289+
};
1290+
1291+
const function = ziglua.wrap(struct {
1292+
fn inner(l: *Lua) i32 {
1293+
const option = l.checkOption(Variant, 1, .one);
1294+
l.pushInteger(switch (option) {
1295+
.one => 1,
1296+
.two => 2,
1297+
.three => 3,
1298+
});
1299+
return 1;
1300+
}
1301+
}.inner);
1302+
1303+
lua.pushFunction(function);
1304+
lua.pushString("one");
1305+
try lua.protectedCall(1, 1, 0);
1306+
try expectEqual(@as(Integer, 1), try lua.toInteger(-1));
1307+
lua.pop(1);
1308+
1309+
lua.pushFunction(function);
1310+
lua.pushString("two");
1311+
try lua.protectedCall(1, 1, 0);
1312+
try expectEqual(@as(Integer, 2), try lua.toInteger(-1));
1313+
lua.pop(1);
1314+
1315+
lua.pushFunction(function);
1316+
lua.pushString("three");
1317+
try lua.protectedCall(1, 1, 0);
1318+
try expectEqual(@as(Integer, 3), try lua.toInteger(-1));
1319+
lua.pop(1);
1320+
1321+
// try the default now
1322+
lua.pushFunction(function);
1323+
try lua.protectedCall(0, 1, 0);
1324+
try expectEqual(@as(Integer, 1), try lua.toInteger(-1));
1325+
lua.pop(1);
1326+
}
1327+
12531328
test "refs" {
12541329
// temporary test that includes a reference to all functions so
12551330
// they will be type-checked
12561331

12571332
// auxlib
12581333
_ = Lua.argCheck;
1259-
_ = Lua.argError;
12601334
_ = Lua.argExpected;
1261-
_ = Lua.checkOption;
12621335
_ = Lua.checkUserdata;
1263-
_ = Lua.checkVersion;
12641336
_ = Lua.doFile;
12651337
_ = Lua.raiseErrorAux;
12661338
_ = Lua.exeResult;
@@ -1271,14 +1343,7 @@ test "refs" {
12711343
_ = Lua.loadBufferX;
12721344
_ = Lua.loadFile;
12731345
_ = Lua.loadFileX;
1274-
_ = Lua.optInteger;
1275-
_ = Lua.optLString;
1276-
_ = Lua.optNumber;
1277-
_ = Lua.optString;
1278-
_ = Lua.pushFail;
1279-
_ = Lua.requireF;
12801346
_ = Lua.testUserdata;
1281-
_ = Lua.toLStringAux;
12821347
_ = Lua.traceback;
12831348
_ = Lua.typeError;
12841349
_ = Lua.typeNameAux;

src/ziglua.zig

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1301,7 +1301,7 @@ pub const Lua = struct {
13011301
}
13021302

13031303
/// Raises an error reporting a problem with argument `arg` of the C function that called it
1304-
pub fn argError(lua: *Lua, arg: i32, extra_msg: [:0]const u8) noreturn {
1304+
pub fn argError(lua: *Lua, arg: i32, extra_msg: [*:0]const u8) noreturn {
13051305
_ = c.luaL_argerror(lua.state, arg, extra_msg);
13061306
unreachable;
13071307
}
@@ -1341,17 +1341,27 @@ pub const Lua = struct {
13411341
return c.luaL_checknumber(lua.state, arg);
13421342
}
13431343

1344-
/// Checks whether the function argument `arg` is a string and searches for the string in the null-terminated array `list`
1344+
/// Checks whether the function argument `arg` is a string and searches for the enum value with the same name in `T`.
13451345
/// `default` is used as a default value when not null
1346-
/// Returns the index in the array where the string was found
1347-
pub fn checkOption(lua: *Lua, arg: i32, default: ?[:0]const u8, list: [:null]?[:0]const u8) i32 {
1348-
return c.luaL_checkoption(
1349-
lua.state,
1350-
arg,
1351-
if (default != null) default.?.ptr else null,
1352-
// TODO: check this cast
1353-
@ptrCast([*c]const [*c]const u8, list.ptr),
1354-
);
1346+
/// Returns the enum value found
1347+
/// Useful for mapping Lua strings to Zig enums
1348+
pub fn checkOption(lua: *Lua, comptime T: type, arg: i32, default: ?T) T {
1349+
const name = blk: {
1350+
if (default) |defaultName| {
1351+
break :blk lua.optBytes(arg, @tagName(defaultName));
1352+
} else {
1353+
break :blk lua.checkBytes(arg);
1354+
}
1355+
};
1356+
1357+
inline for (std.meta.fields(T)) |field| {
1358+
if (std.mem.eql(u8, field.name, name)) {
1359+
return @intToEnum(T, field.value);
1360+
}
1361+
}
1362+
1363+
// NOTE: ptrCast is required because a slice is not supported ziglang/zig/issues/1481
1364+
return lua.argError(arg, lua.pushFStringEx("invalid option '%s'", .{@ptrCast([*c]const u8, name)}));
13551365
}
13561366

13571367
/// Grows the stack size to top + `size` elements, raising an error if the stack cannot grow to that size
@@ -1541,14 +1551,14 @@ pub const Lua = struct {
15411551
return c.luaL_optinteger(lua.state, arg, default);
15421552
}
15431553

1544-
/// If the function argument `arg` is a string, returns the string
1554+
/// If the function argument `arg` is a slice of bytes, returns the slice
15451555
/// If the argument is absent or nil returns `default`
1546-
pub fn optLString(lua: *Lua, arg: i32, default: [:0]const u8) []const u8 {
1556+
pub fn optBytes(lua: *Lua, arg: i32, default: [:0]const u8) [:0]const u8 {
15471557
var length: usize = 0;
15481558
// will never return null because default cannot be null
15491559
const ret: [*]const u8 = c.luaL_optlstring(lua.state, arg, default, &length);
15501560
if (ret == default.ptr) return default;
1551-
return ret[0..length];
1561+
return ret[0..length :0];
15521562
}
15531563

15541564
/// If the function argument `arg` is a number, returns the number
@@ -1610,10 +1620,10 @@ pub const Lua = struct {
16101620
}
16111621

16121622
/// Converts any Lua value at the given index into a string in a reasonable format
1613-
pub fn toLStringAux(lua: *Lua, index: i32) []const u8 {
1623+
pub fn toBytesAux(lua: *Lua, index: i32) [:0]const u8 {
16141624
var length: usize = undefined;
16151625
const ptr = c.luaL_tolstring(lua.state, index, &length);
1616-
return ptr[0..length];
1626+
return ptr[0..length :0];
16171627
}
16181628

16191629
/// Creates and pushes a traceback of the stack of `other`

0 commit comments

Comments
 (0)