Implement test suite for roblox datatypes

This commit is contained in:
Filip Tibell 2023-03-11 11:21:34 +01:00
parent e330986da5
commit 4afb51830c
No known key found for this signature in database
12 changed files with 214 additions and 4 deletions

1
Cargo.lock generated
View file

@ -861,6 +861,7 @@ dependencies = [
name = "lune-roblox" name = "lune-roblox"
version = "0.5.6" version = "0.5.6"
dependencies = [ dependencies = [
"anyhow",
"base64 0.21.0", "base64 0.21.0",
"glam", "glam",
"mlua", "mlua",

View file

@ -26,3 +26,6 @@ rbx_dom_weak = { git = "https://github.com/rojo-rbx/rbx-dom", rev = "ce4c5bf7b18
rbx_reflection = { git = "https://github.com/rojo-rbx/rbx-dom", rev = "ce4c5bf7b18c813417ad14cc37e5abe281dfb51a" } rbx_reflection = { git = "https://github.com/rojo-rbx/rbx-dom", rev = "ce4c5bf7b18c813417ad14cc37e5abe281dfb51a" }
rbx_reflection_database = { git = "https://github.com/rojo-rbx/rbx-dom", rev = "ce4c5bf7b18c813417ad14cc37e5abe281dfb51a" } rbx_reflection_database = { git = "https://github.com/rojo-rbx/rbx-dom", rev = "ce4c5bf7b18c813417ad14cc37e5abe281dfb51a" }
rbx_xml = { git = "https://github.com/rojo-rbx/rbx-dom", rev = "ce4c5bf7b18c813417ad14cc37e5abe281dfb51a" } rbx_xml = { git = "https://github.com/rojo-rbx/rbx-dom", rev = "ce4c5bf7b18c813417ad14cc37e5abe281dfb51a" }
[dev-dependencies]
anyhow = "1.0"

View file

@ -60,6 +60,7 @@ impl LuaUserData for Vector2 {
methods.add_meta_method(LuaMetaMethod::Mul, |_, this, rhs: LuaValue| { methods.add_meta_method(LuaMetaMethod::Mul, |_, this, rhs: LuaValue| {
match &rhs { match &rhs {
LuaValue::Number(n) => return Ok(Vector2(this.0 * Vec2::splat(*n as f32))), LuaValue::Number(n) => return Ok(Vector2(this.0 * Vec2::splat(*n as f32))),
LuaValue::Integer(i) => return Ok(Vector2(this.0 * Vec2::splat(*i as f32))),
LuaValue::UserData(ud) => { LuaValue::UserData(ud) => {
if let Ok(vec) = ud.borrow::<Vector2>() { if let Ok(vec) = ud.borrow::<Vector2>() {
return Ok(Vector2(this.0 * vec.0)); return Ok(Vector2(this.0 * vec.0));
@ -79,6 +80,7 @@ impl LuaUserData for Vector2 {
methods.add_meta_method(LuaMetaMethod::Div, |_, this, rhs: LuaValue| { methods.add_meta_method(LuaMetaMethod::Div, |_, this, rhs: LuaValue| {
match &rhs { match &rhs {
LuaValue::Number(n) => return Ok(Vector2(this.0 / Vec2::splat(*n as f32))), LuaValue::Number(n) => return Ok(Vector2(this.0 / Vec2::splat(*n as f32))),
LuaValue::Integer(i) => return Ok(Vector2(this.0 / Vec2::splat(*i as f32))),
LuaValue::UserData(ud) => { LuaValue::UserData(ud) => {
if let Ok(vec) = ud.borrow::<Vector2>() { if let Ok(vec) = ud.borrow::<Vector2>() {
return Ok(Vector2(this.0 / vec.0)); return Ok(Vector2(this.0 / vec.0));

View file

@ -41,6 +41,7 @@ impl LuaUserData for Vector2int16 {
methods.add_meta_method(LuaMetaMethod::Mul, |_, this, rhs: LuaValue| { methods.add_meta_method(LuaMetaMethod::Mul, |_, this, rhs: LuaValue| {
match &rhs { match &rhs {
LuaValue::Number(n) => return Ok(Vector2int16(this.0 * IVec2::splat(*n as i32))), LuaValue::Number(n) => return Ok(Vector2int16(this.0 * IVec2::splat(*n as i32))),
LuaValue::Integer(i) => return Ok(Vector2int16(this.0 * IVec2::splat(*i))),
LuaValue::UserData(ud) => { LuaValue::UserData(ud) => {
if let Ok(vec) = ud.borrow::<Vector2int16>() { if let Ok(vec) = ud.borrow::<Vector2int16>() {
return Ok(Vector2int16(this.0 * vec.0)); return Ok(Vector2int16(this.0 * vec.0));
@ -60,6 +61,7 @@ impl LuaUserData for Vector2int16 {
methods.add_meta_method(LuaMetaMethod::Div, |_, this, rhs: LuaValue| { methods.add_meta_method(LuaMetaMethod::Div, |_, this, rhs: LuaValue| {
match &rhs { match &rhs {
LuaValue::Number(n) => return Ok(Vector2int16(this.0 / IVec2::splat(*n as i32))), LuaValue::Number(n) => return Ok(Vector2int16(this.0 / IVec2::splat(*n as i32))),
LuaValue::Integer(i) => return Ok(Vector2int16(this.0 / IVec2::splat(*i))),
LuaValue::UserData(ud) => { LuaValue::UserData(ud) => {
if let Ok(vec) = ud.borrow::<Vector2int16>() { if let Ok(vec) = ud.borrow::<Vector2int16>() {
return Ok(Vector2int16(this.0 / vec.0)); return Ok(Vector2int16(this.0 / vec.0));

View file

@ -71,6 +71,7 @@ impl LuaUserData for Vector3 {
methods.add_meta_method(LuaMetaMethod::Mul, |_, this, rhs: LuaValue| { methods.add_meta_method(LuaMetaMethod::Mul, |_, this, rhs: LuaValue| {
match &rhs { match &rhs {
LuaValue::Number(n) => return Ok(Vector3(this.0 * Vec3::splat(*n as f32))), LuaValue::Number(n) => return Ok(Vector3(this.0 * Vec3::splat(*n as f32))),
LuaValue::Integer(i) => return Ok(Vector3(this.0 * Vec3::splat(*i as f32))),
LuaValue::UserData(ud) => { LuaValue::UserData(ud) => {
if let Ok(vec) = ud.borrow::<Vector3>() { if let Ok(vec) = ud.borrow::<Vector3>() {
return Ok(Vector3(this.0 * vec.0)); return Ok(Vector3(this.0 * vec.0));
@ -90,6 +91,7 @@ impl LuaUserData for Vector3 {
methods.add_meta_method(LuaMetaMethod::Div, |_, this, rhs: LuaValue| { methods.add_meta_method(LuaMetaMethod::Div, |_, this, rhs: LuaValue| {
match &rhs { match &rhs {
LuaValue::Number(n) => return Ok(Vector3(this.0 / Vec3::splat(*n as f32))), LuaValue::Number(n) => return Ok(Vector3(this.0 / Vec3::splat(*n as f32))),
LuaValue::Integer(i) => return Ok(Vector3(this.0 / Vec3::splat(*i as f32))),
LuaValue::UserData(ud) => { LuaValue::UserData(ud) => {
if let Ok(vec) = ud.borrow::<Vector3>() { if let Ok(vec) = ud.borrow::<Vector3>() {
return Ok(Vector3(this.0 / vec.0)); return Ok(Vector3(this.0 / vec.0));

View file

@ -41,6 +41,7 @@ impl LuaUserData for Vector3int16 {
methods.add_meta_method(LuaMetaMethod::Mul, |_, this, rhs: LuaValue| { methods.add_meta_method(LuaMetaMethod::Mul, |_, this, rhs: LuaValue| {
match &rhs { match &rhs {
LuaValue::Number(n) => return Ok(Vector3int16(this.0 * IVec3::splat(*n as i32))), LuaValue::Number(n) => return Ok(Vector3int16(this.0 * IVec3::splat(*n as i32))),
LuaValue::Integer(i) => return Ok(Vector3int16(this.0 * IVec3::splat(*i))),
LuaValue::UserData(ud) => { LuaValue::UserData(ud) => {
if let Ok(vec) = ud.borrow::<Vector3int16>() { if let Ok(vec) = ud.borrow::<Vector3int16>() {
return Ok(Vector3int16(this.0 * vec.0)); return Ok(Vector3int16(this.0 * vec.0));
@ -60,6 +61,7 @@ impl LuaUserData for Vector3int16 {
methods.add_meta_method(LuaMetaMethod::Div, |_, this, rhs: LuaValue| { methods.add_meta_method(LuaMetaMethod::Div, |_, this, rhs: LuaValue| {
match &rhs { match &rhs {
LuaValue::Number(n) => return Ok(Vector3int16(this.0 / IVec3::splat(*n as i32))), LuaValue::Number(n) => return Ok(Vector3int16(this.0 / IVec3::splat(*n as i32))),
LuaValue::Integer(i) => return Ok(Vector3int16(this.0 / IVec3::splat(*i))),
LuaValue::UserData(ud) => { LuaValue::UserData(ud) => {
if let Ok(vec) = ud.borrow::<Vector3int16>() { if let Ok(vec) = ud.borrow::<Vector3int16>() {
return Ok(Vector3int16(this.0 / vec.0)); return Ok(Vector3int16(this.0 / vec.0));

View file

@ -4,6 +4,9 @@ pub mod datatypes;
pub mod document; pub mod document;
pub mod instance; pub mod instance;
#[cfg(test)]
mod tests;
use datatypes::types::*; use datatypes::types::*;
use datatypes::DatatypeTable; use datatypes::DatatypeTable;
@ -18,15 +21,18 @@ where
} }
#[rustfmt::skip] #[rustfmt::skip]
pub fn module(lua: &Lua) -> LuaResult<LuaTable> { fn make_all_datatypes(lua: &Lua) -> LuaResult<Vec<(&'static str, LuaTable)>> {
let datatypes = vec![ Ok(vec![
("Vector2", make_dt(lua, Vector2::make_dt_table)?), ("Vector2", make_dt(lua, Vector2::make_dt_table)?),
("Vector2int16", make_dt(lua, Vector2int16::make_dt_table)?), ("Vector2int16", make_dt(lua, Vector2int16::make_dt_table)?),
("Vector3", make_dt(lua, Vector3::make_dt_table)?), ("Vector3", make_dt(lua, Vector3::make_dt_table)?),
("Vector3int16", make_dt(lua, Vector3int16::make_dt_table)?), ("Vector3int16", make_dt(lua, Vector3int16::make_dt_table)?),
]; ])
}
pub fn module(lua: &Lua) -> LuaResult<LuaTable> {
let exports = lua.create_table()?; let exports = lua.create_table()?;
for (name, tab) in datatypes { for (name, tab) in make_all_datatypes(lua)? {
exports.set(name, tab)?; exports.set(name, tab)?;
} }
Ok(exports) Ok(exports)

View file

@ -0,0 +1,45 @@
use std::{env::set_current_dir, fs::read_to_string, path::PathBuf};
use anyhow::{Context, Result};
use mlua::prelude::*;
use super::make_all_datatypes;
macro_rules! create_tests {
($($test_name:ident: $file_path:expr,)*) => { $(
#[test]
fn $test_name() -> Result<()> {
// NOTE: This path is relative to the lib
// package, not the cwd or workspace root,
// so we need to cd to the repo root first
let crate_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let root_dir = crate_dir.join("../../").canonicalize()?;
set_current_dir(root_dir)?;
// Create all datatypes as globals
let lua = Lua::new();
let env = lua.globals();
for (name, tab) in make_all_datatypes(&lua)? {
env.set(name, tab)?;
}
// The rest of the test logic can continue as normal
let full_name = format!("tests/roblox/{}.luau", $file_path);
let script = read_to_string(full_name)
.with_context(|| format!(
"Failed to read test file '{}'",
$file_path
))?;
lua.load(&script)
.set_name($file_path)?
.set_environment(env)?
.exec()?;
Ok(())
}
)* }
}
create_tests! {
datatypes_vector2: "datatypes/Vector2",
datatypes_vector2int16: "datatypes/Vector2int16",
datatypes_vector3: "datatypes/Vector3",
datatypes_vector3int16: "datatypes/Vector3int16",
}

View file

@ -0,0 +1,40 @@
-- HACK: Make luau happy, with the mlua rust
-- crate all globals are also present in _G
local Vector2 = _G.Vector2
-- Constructors
Vector2.new()
Vector2.new(0)
Vector2.new(0, 0)
Vector2.new(0 / 0, 0 / 0)
assert(not pcall(function()
return Vector2.new(false)
end))
assert(not pcall(function()
return Vector2.new("", "")
end))
assert(not pcall(function()
return Vector2.new(newproxy(true))
end))
-- Constants
assert(Vector2.one == Vector2.new(1, 1))
assert(Vector2.zero == Vector2.new(0, 0))
assert(Vector2.xAxis == Vector2.new(1, 0))
assert(Vector2.yAxis == Vector2.new(0, 1))
assert(Vector2.zAxis == nil)
-- Ops
assert(Vector2.new(2, 4) + Vector2.new(1, 1) == Vector2.new(3, 5))
assert(Vector2.new(2, 4) - Vector2.new(1, 1) == Vector2.new(1, 3))
assert(Vector2.new(2, 4) * Vector2.new(1, 2) == Vector2.new(2, 8))
assert(Vector2.new(2, 4) / Vector2.new(1, 2) == Vector2.new(2, 2))
assert(Vector2.new(2, 4) * 2 == Vector2.new(4, 8))
assert(Vector2.new(2, 4) / 2 == Vector2.new(1, 2))
-- TODO: Vector math

View file

@ -0,0 +1,32 @@
-- HACK: Make luau happy, with the mlua rust
-- crate all globals are also present in _G
local Vector2int16 = _G.Vector2int16
-- Constructors
Vector2int16.new()
Vector2int16.new(0)
Vector2int16.new(0, 0)
assert(not pcall(function()
return Vector2int16.new(999_999, 999_999)
end))
assert(not pcall(function()
return Vector2int16.new(false)
end))
assert(not pcall(function()
return Vector2int16.new("", "")
end))
assert(not pcall(function()
return Vector2int16.new(newproxy(true))
end))
-- Ops
assert(Vector2int16.new(2, 4) + Vector2int16.new(1, 1) == Vector2int16.new(3, 5))
assert(Vector2int16.new(2, 4) - Vector2int16.new(1, 1) == Vector2int16.new(1, 3))
assert(Vector2int16.new(2, 4) * Vector2int16.new(1, 2) == Vector2int16.new(2, 8))
assert(Vector2int16.new(2, 4) / Vector2int16.new(1, 2) == Vector2int16.new(2, 2))
assert(Vector2int16.new(2, 4) * 2 == Vector2int16.new(4, 8))
assert(Vector2int16.new(2, 4) / 2 == Vector2int16.new(1, 2))

View file

@ -0,0 +1,42 @@
-- HACK: Make luau happy, with the mlua rust
-- crate all globals are also present in _G
local Vector3 = _G.Vector3
-- Constructors
Vector3.new()
Vector3.new(0)
Vector3.new(0, 0)
Vector3.new(0, 0, 0)
Vector3.new(0 / 0, 0 / 0)
Vector3.new(0 / 0, 0 / 0, 0 / 0)
assert(not pcall(function()
return Vector3.new(false)
end))
assert(not pcall(function()
return Vector3.new("", "")
end))
assert(not pcall(function()
return Vector3.new(newproxy(true))
end))
-- Constants
assert(Vector3.one == Vector3.new(1, 1, 1))
assert(Vector3.zero == Vector3.new(0, 0, 0))
assert(Vector3.xAxis == Vector3.new(1, 0, 0))
assert(Vector3.yAxis == Vector3.new(0, 1, 0))
assert(Vector3.zAxis == Vector3.new(0, 0, 1))
-- Ops
assert(Vector3.new(2, 4, 8) + Vector3.new(1, 1, 1) == Vector3.new(3, 5, 9))
assert(Vector3.new(2, 4, 8) - Vector3.new(1, 1, 1) == Vector3.new(1, 3, 7))
assert(Vector3.new(2, 4, 8) * Vector3.new(1, 1, 2) == Vector3.new(2, 4, 16))
assert(Vector3.new(2, 4, 8) / Vector3.new(1, 1, 2) == Vector3.new(2, 4, 4))
assert(Vector3.new(2, 4, 8) * 2 == Vector3.new(4, 8, 16))
assert(Vector3.new(2, 4, 8) / 2 == Vector3.new(1, 2, 4))
-- TODO: Vector math

View file

@ -0,0 +1,33 @@
-- HACK: Make luau happy, with the mlua rust
-- crate all globals are also present in _G
local Vector3int16 = _G.Vector3int16
-- Constructors
Vector3int16.new()
Vector3int16.new(0)
Vector3int16.new(0, 0)
Vector3int16.new(0, 0, 0)
assert(not pcall(function()
return Vector3int16.new(999_999, 999_999, 999_999)
end))
assert(not pcall(function()
return Vector3int16.new(false)
end))
assert(not pcall(function()
return Vector3int16.new("", "")
end))
assert(not pcall(function()
return Vector3int16.new(newproxy(true))
end))
-- Ops
assert(Vector3int16.new(2, 4, 8) + Vector3int16.new(1, 1, 1) == Vector3int16.new(3, 5, 9))
assert(Vector3int16.new(2, 4, 8) - Vector3int16.new(1, 1, 1) == Vector3int16.new(1, 3, 7))
assert(Vector3int16.new(2, 4, 8) * Vector3int16.new(1, 1, 2) == Vector3int16.new(2, 4, 16))
assert(Vector3int16.new(2, 4, 8) / Vector3int16.new(1, 1, 2) == Vector3int16.new(2, 4, 4))
assert(Vector3int16.new(2, 4, 8) * 2 == Vector3int16.new(4, 8, 16))
assert(Vector3int16.new(2, 4, 8) / 2 == Vector3int16.new(1, 2, 4))