Fork of daniellemaywood.uk/gleam — Wasm codegen work
2

Configure Feed

Select the types of activity you want to include in your feed.

gleam / test-helpers-rs / src / lib.rs
3.8 kB 108 lines
1use camino::{Utf8Path, Utf8PathBuf}; 2use gleam_core::{ 3 io::{Content, FileSystemWriter, memory::InMemoryFileSystem}, 4 version::COMPILER_VERSION, 5}; 6use itertools::Itertools; 7use regex::Regex; 8use std::{collections::HashMap, fmt::Write, sync::LazyLock}; 9 10#[derive(Debug)] 11pub struct TestCompileOutput { 12 pub files: HashMap<Utf8PathBuf, Content>, 13 pub warnings: Vec<gleam_core::Warning>, 14} 15 16impl TestCompileOutput { 17 pub fn as_overview_text(&self) -> String { 18 let mut buffer = String::new(); 19 for (path, content) in self.files.iter().sorted_by(|a, b| a.0.cmp(b.0)) { 20 let normalised_path = if path.as_str().contains("cases") { 21 path.as_str() 22 .split("cases") 23 .skip(1) 24 .collect::<String>() 25 .as_str() 26 .replace('\\', "/") 27 .split('/') 28 .skip(1) 29 .join("/") 30 } else { 31 path.as_str().replace('\\', "/") 32 }; 33 buffer.push_str("//// "); 34 buffer.push_str(&normalised_path); 35 buffer.push('\n'); 36 37 let extension = path.extension(); 38 match content { 39 _ if extension == Some("cache") => buffer.push_str("<.cache binary>"), 40 Content::Binary(data) => write!(buffer, "<{} byte binary>", data.len()).unwrap(), 41 42 Content::Text(_) if normalised_path.ends_with("@@main.erl") => { 43 write!(buffer, "<erlang entrypoint>").unwrap() 44 } 45 46 Content::Text(text) => { 47 let text = FILE_LINE_REGEX 48 .replace_all(text, |caps: &regex::Captures| { 49 let path = caps 50 .get(1) 51 .expect("file path") 52 .as_str() 53 .replace("\\\\", "/"); 54 let line_number = caps.get(2).expect("line number").as_str(); 55 format!("-file(\"{path}\", {line_number}).") 56 }) 57 .replace(COMPILER_VERSION, "<gleam compiler version string>"); 58 buffer.push_str(&text) 59 } 60 }; 61 buffer.push('\n'); 62 buffer.push('\n'); 63 } 64 65 for warning in self.warnings.iter().map(|w| w.to_pretty_string()).sorted() { 66 write!(buffer, "//// Warning\n{}", normalise_diagnostic(&warning)).unwrap(); 67 buffer.push('\n'); 68 buffer.push('\n'); 69 } 70 71 buffer 72 } 73} 74 75pub fn to_in_memory_filesystem(path: &Utf8Path) -> InMemoryFileSystem { 76 let fs = InMemoryFileSystem::new(); 77 78 let files = walkdir::WalkDir::new(path) 79 .follow_links(true) 80 .into_iter() 81 .filter_map(Result::ok) 82 .filter(|entry| entry.file_type().is_file()) 83 .map(|entry| entry.into_path()); 84 85 for fullpath in files { 86 let content = std::fs::read(&fullpath).unwrap(); 87 let path = fullpath.strip_prefix(path).unwrap(); 88 fs.write_bytes(Utf8Path::from_path(path).unwrap(), &content) 89 .unwrap(); 90 } 91 92 fs 93} 94 95static FILE_LINE_REGEX: LazyLock<Regex> = 96 LazyLock::new(|| Regex::new(r#"-file\("([^"]+)", (\d+)\)\."#).expect("Invalid regex")); 97 98pub fn normalise_diagnostic(text: &str) -> String { 99 // There is an extra ^ on Windows in some error messages' code 100 // snippets. 101 // I've not managed to determine why this is yet (it is especially 102 // tricky without a Windows computer) so for now we just squash them 103 // in these cross-platform tests. 104 Regex::new(r"\^+") 105 .expect("^ sequence regex") 106 .replace_all(text, "^") 107 .replace('\\', "/") 108}