2023-01-22 20:23:56 +00:00
|
|
|
use std::collections::HashSet;
|
|
|
|
|
2023-01-21 21:40:57 +00:00
|
|
|
use anyhow::{bail, Result};
|
2023-01-23 02:14:13 +00:00
|
|
|
use mlua::prelude::*;
|
2023-01-21 03:01:02 +00:00
|
|
|
|
|
|
|
pub mod globals;
|
|
|
|
pub mod utils;
|
|
|
|
|
|
|
|
use crate::{
|
2023-01-22 20:23:56 +00:00
|
|
|
globals::{create_console, create_fs, create_net, create_process, create_task},
|
2023-01-21 21:40:57 +00:00
|
|
|
utils::formatting::{format_label, pretty_format_luau_error},
|
2023-01-21 03:01:02 +00:00
|
|
|
};
|
|
|
|
|
2023-01-22 20:23:56 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
|
|
|
pub enum LuneGlobal {
|
|
|
|
Console,
|
|
|
|
Fs,
|
|
|
|
Net,
|
|
|
|
Process,
|
|
|
|
Task,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl LuneGlobal {
|
|
|
|
pub fn get_all() -> Vec<Self> {
|
|
|
|
vec![
|
|
|
|
Self::Console,
|
|
|
|
Self::Fs,
|
|
|
|
Self::Net,
|
|
|
|
Self::Process,
|
|
|
|
Self::Task,
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, Default)]
|
|
|
|
pub struct Lune {
|
|
|
|
globals: HashSet<LuneGlobal>,
|
|
|
|
args: Vec<String>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Lune {
|
|
|
|
pub fn new() -> Self {
|
|
|
|
Self::default()
|
2023-01-21 03:01:02 +00:00
|
|
|
}
|
2023-01-22 20:23:56 +00:00
|
|
|
|
|
|
|
pub fn with_args(mut self, args: Vec<String>) -> Self {
|
|
|
|
self.args = args;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn with_global(mut self, global: LuneGlobal) -> Self {
|
|
|
|
self.globals.insert(global);
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn with_all_globals(mut self) -> Self {
|
|
|
|
for global in LuneGlobal::get_all() {
|
|
|
|
self.globals.insert(global);
|
|
|
|
}
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn run(&self, name: &str, chunk: &str) -> Result<()> {
|
2023-01-23 02:14:13 +00:00
|
|
|
smol::block_on(async {
|
|
|
|
let lua = Lua::new();
|
|
|
|
for global in &self.globals {
|
|
|
|
match &global {
|
|
|
|
LuneGlobal::Console => create_console(&lua).await?,
|
|
|
|
LuneGlobal::Fs => create_fs(&lua).await?,
|
|
|
|
LuneGlobal::Net => create_net(&lua).await?,
|
|
|
|
LuneGlobal::Process => create_process(&lua, self.args.clone()).await?,
|
|
|
|
LuneGlobal::Task => create_task(&lua).await?,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let result = lua.load(chunk).set_name(name)?.exec_async().await;
|
|
|
|
match result {
|
|
|
|
Ok(_) => Ok(()),
|
|
|
|
Err(e) => {
|
|
|
|
if cfg!(test) {
|
|
|
|
bail!(pretty_format_luau_error(&e))
|
|
|
|
} else {
|
|
|
|
bail!(
|
|
|
|
"\n{}\n{}",
|
|
|
|
format_label("ERROR"),
|
|
|
|
pretty_format_luau_error(&e)
|
|
|
|
)
|
2023-01-22 21:26:45 +00:00
|
|
|
}
|
2023-01-23 02:14:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
2023-01-21 03:01:02 +00:00
|
|
|
}
|
|
|
|
}
|
2023-01-21 05:03:16 +00:00
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
2023-01-22 20:23:56 +00:00
|
|
|
use crate::Lune;
|
2023-01-23 00:25:36 +00:00
|
|
|
use anyhow::Result;
|
2023-01-23 02:14:13 +00:00
|
|
|
use smol::fs::read_to_string;
|
2023-01-23 00:25:36 +00:00
|
|
|
use std::env::current_dir;
|
|
|
|
|
|
|
|
const ARGS: &[&str] = &["Foo", "Bar"];
|
2023-01-21 21:40:57 +00:00
|
|
|
|
2023-01-21 05:03:16 +00:00
|
|
|
macro_rules! run_tests {
|
|
|
|
($($name:ident: $value:expr,)*) => {
|
|
|
|
$(
|
2023-01-23 02:14:13 +00:00
|
|
|
#[test]
|
|
|
|
fn $name() -> Result<()> {
|
|
|
|
smol::block_on(async {
|
|
|
|
let path = current_dir()
|
|
|
|
.unwrap()
|
|
|
|
.join(format!("src/tests/{}.luau", $value));
|
|
|
|
let script = read_to_string(&path)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
let lune = Lune::new()
|
|
|
|
.with_args(ARGS.clone().iter().map(ToString::to_string).collect())
|
|
|
|
.with_all_globals();
|
|
|
|
lune.run($value, &script).await
|
|
|
|
})
|
2023-01-21 05:03:16 +00:00
|
|
|
}
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
run_tests! {
|
2023-01-21 06:37:31 +00:00
|
|
|
console_format: "console/format",
|
|
|
|
console_set_color: "console/set_color",
|
|
|
|
console_set_style: "console/set_style",
|
2023-01-21 07:01:46 +00:00
|
|
|
fs_files: "fs/files",
|
|
|
|
fs_dirs: "fs/dirs",
|
2023-01-21 05:03:16 +00:00
|
|
|
process_args: "process/args",
|
|
|
|
process_env: "process/env",
|
2023-01-21 07:07:17 +00:00
|
|
|
// NOTE: This test does not currently work, it will exit the entire
|
|
|
|
// process, meaning it will also exit our test runner and skip testing
|
|
|
|
// process_exit: "process/exit",
|
2023-01-21 05:03:16 +00:00
|
|
|
process_spawn: "process/spawn",
|
2023-01-21 06:10:19 +00:00
|
|
|
net_request_codes: "net/request/codes",
|
|
|
|
net_request_methods: "net/request/methods",
|
|
|
|
net_request_redirect: "net/request/redirect",
|
|
|
|
net_json_decode: "net/json/decode",
|
|
|
|
net_json_encode: "net/json/encode",
|
2023-01-21 22:23:39 +00:00
|
|
|
task_cancel: "task/cancel",
|
2023-01-21 20:07:18 +00:00
|
|
|
task_defer: "task/defer",
|
|
|
|
task_delay: "task/delay",
|
|
|
|
task_spawn: "task/spawn",
|
2023-01-21 18:33:33 +00:00
|
|
|
task_wait: "task/wait",
|
2023-01-21 05:03:16 +00:00
|
|
|
}
|
|
|
|
}
|