use std::path::{Path, PathBuf}; use lex_lua::{Lexer, Token}; #[test] fn try_all() { let lua_repo_dir = std::env::var("LUA_REPO_DIR").unwrap_or_else(|_| "./lua".to_string()); let lua_repo_path = PathBuf::from(lua_repo_dir); assert!( lua_repo_path.exists(), "Unable to find lua repo directory, try setting LUA_REPO_DIR" ); let lua_tests_path = lua_repo_path.join("testes"); assert!( lua_tests_path.exists(), "Unable to find the lua testes directory at {}", lua_tests_path.display() ); for ent in std::fs::read_dir(&lua_tests_path).unwrap() { let entry = ent.unwrap(); if entry .path() .extension() .as_ref() .map(|e| *e == "lua") .unwrap_or(false) { println!("trying {}", entry.path().display()); let text = std::fs::read(entry.path()).unwrap(); let mut t = Lexer::new(text.as_slice()); let mut tok_ct = 0; while let Some(tok) = t.next_token() { tok_ct += 1; println!("{} {:?}", tok_ct, tok); if matches!(tok, Token::Unknown(_)) { let (_, full_line) = text.split(|c| *c == b'\n').fold((0, None), |mut acc, l| { acc.0 += l.len(); if acc.0 >= t.current_pos() && acc.1.is_none() { acc.1 = Some(String::from_utf8_lossy(l)) } acc }); let (line_idx, line) = text[0..t.current_pos()] .split(|c| *c == b'\n') .enumerate() .last() .unwrap(); let (behind_current, _) = text[..t.current_pos()] .iter() .enumerate() .rfind(|(_, &b)| b == b'\n') .unwrap(); panic!( "{} unknown token in {}:{}:0 {:?}\n{}\n{}", tok_ct, entry.path().display(), line_idx + 1, tok, String::from_utf8_lossy(line), "^".repeat(full_line.map(|l| l.len()).unwrap_or(0)) ) } } } } } fn try_read(p: impl AsRef) -> String { let bytes = std::fs::read(p.as_ref()).unwrap_or_else(|e| { panic!( "failed to read file as bytes {}: {}", p.as_ref().display(), e ) }); let mut s = String::with_capacity(bytes.len()); for (idx, line) in bytes.split(|b| *b == b'\n').enumerate() { match String::from_utf8(line.to_vec()) { Ok(l) => { s.push_str(&l); s.push('\n'); } Err(_) => { println!("Invalid utf8 {}:{}:0", p.as_ref().display(), idx + 1) } } } s }