use omnilua::{Feature, Lua, LuaVersion};
const FIXTURE: &str =
include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/../../ANALYSES/version_feature_matrix.tsv"));
const ALL_VERSIONS: [LuaVersion; 5] = [
LuaVersion::V51,
LuaVersion::V52,
LuaVersion::V53,
LuaVersion::V54,
LuaVersion::V55,
];
fn version_from(s: &str) -> LuaVersion {
match s {
"5.1" => LuaVersion::V51,
"5.2" => LuaVersion::V52,
"5.3" => LuaVersion::V53,
"5.4" => LuaVersion::V54,
"5.5" => LuaVersion::V55,
other => panic!("unknown version in fixture: {other}"),
}
}
fn feature_from(s: &str) -> Feature {
match s {
"IntegerSubtype" => Feature::IntegerSubtype,
"EnvSandbox" => Feature::EnvSandbox,
"FenvSandbox" => Feature::FenvSandbox,
"GotoLabels" => Feature::GotoLabels,
"NativeBitwise" => Feature::NativeBitwise,
"Bit32Lib" => Feature::Bit32Lib,
"Utf8Lib" => Feature::Utf8Lib,
"StringPack" => Feature::StringPack,
"CloseAttribute" => Feature::CloseAttribute,
"ConstAttribute" => Feature::ConstAttribute,
"CoroutineClose" => Feature::CoroutineClose,
"WarnFunction" => Feature::WarnFunction,
"TableLenMetamethod" => Feature::TableLenMetamethod,
"GcIsRunning" => Feature::GcIsRunning,
"GcParam" => Feature::GcParam,
"GlobalKeyword" => Feature::GlobalKeyword,
"NamedVararg" => Feature::NamedVararg,
"TableCreate" => Feature::TableCreate,
other => panic!("unknown feature in fixture: {other}"),
}
}
#[test]
fn supports_matches_reference_fixture() {
let mut rows = 0;
for line in FIXTURE.lines() {
if line.starts_with('#') || line.trim().is_empty() {
continue;
}
let mut cols = line.split('\t');
let version = version_from(cols.next().unwrap());
let feature = feature_from(cols.next().unwrap());
let expected = match cols.next().unwrap() {
"1" => true,
"0" => false,
other => panic!("bad cell: {other}"),
};
assert_eq!(
version.supports(feature),
expected,
"supports({version:?}, {feature:?}) disagrees with the reference fixture"
);
rows += 1;
}
assert_eq!(
rows,
ALL_VERSIONS.len() * Feature::ALL.len(),
"fixture is missing rows"
);
}
#[test]
fn lua_supports_matches_version_on_a_full_build() {
for v in ALL_VERSIONS {
let lua = Lua::new_versioned(v);
for f in Feature::ALL {
assert_eq!(lua.supports(f), v.supports(f), "{v:?}/{f:?}");
}
}
}
#[test]
fn is_running_is_typed_unsupported_before_5_2() {
let lua = Lua::new_versioned(LuaVersion::V51);
let err = lua.gc().is_running().unwrap_err();
assert!(err.is_unsupported(), "expected a typed Unsupported, got: {err}");
let u = err.as_unsupported().unwrap();
assert_eq!(u.feature, Feature::GcIsRunning);
assert_eq!(u.version, LuaVersion::V51);
assert!(err.to_string().contains("is not available"));
}
#[test]
fn is_running_ok_from_5_2_on() {
for v in [
LuaVersion::V52,
LuaVersion::V53,
LuaVersion::V54,
LuaVersion::V55,
] {
let lua = Lua::new_versioned(v);
assert!(lua.gc().is_running().is_ok(), "{v:?}");
assert!(lua.supports(Feature::GcIsRunning));
}
}
#[test]
fn classification_is_direct_host_only_message_survives_lua_round_trip() {
let lua = Lua::new_versioned(LuaVersion::V51);
let probe = lua
.create_function(|l, ()| {
l.gc().is_running()?;
Ok(())
})
.unwrap();
lua.globals().set("probe", probe).unwrap();
let msg: String = lua
.load("local ok, e = pcall(probe); return tostring(e)")
.eval()
.unwrap();
assert!(
msg.contains("is not available"),
"message should survive the Lua round-trip, got: {msg}"
);
}