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-output / src / tests / echo.rs
6.7 kB 244 lines
1// SPDX-License-Identifier: Apache-2.0 2// SPDX-FileCopyrightText: 2025 The Gleam contributors 3 4use std::{io::Read, process::Stdio}; 5 6use camino::{Utf8Path, Utf8PathBuf}; 7use gleam_core::{ 8 build::{Runtime, Target}, 9 io::Command, 10 paths::ProjectPaths, 11}; 12 13use gleam_cli::{ 14 fs, 15 run::{self, Which}, 16}; 17 18fn run_and_produce_pretty_snapshot( 19 target: Option<Target>, 20 runtime: Option<Runtime>, 21 project_directory: Utf8PathBuf, 22) -> String { 23 let project_root = fs::get_project_root(project_directory).expect("project root"); 24 25 // Node has a bug with paths on Windows at the moment, so we have to 26 // edit the path to work around it. 27 // https://github.com/nodejs/node/issues/60435 28 #[cfg(windows)] 29 let project_root = project_root 30 .to_string() 31 .strip_prefix(r"\\?\") 32 .map(Utf8PathBuf::from) 33 .unwrap_or(project_root); 34 let paths = ProjectPaths::new(project_root); 35 36 let output = run_and_capture_output(&paths, "main", target, runtime) 37 // Since the echo output's contains a path we will replace the `\` with a `/` 38 // so that the snapshot doesn't fail on Windows in CI. 39 .replace("src\\", "src/"); 40 41 let main_module_content = 42 fs::read(paths.src_directory().join("main.gleam")).expect("read main module"); 43 44 format!( 45 "--- main.gleam ---------------------- 46{main_module_content} 47 48--- gleam run output ---------------- 49{output} 50" 51 ) 52} 53 54fn run_and_capture_output( 55 paths: &ProjectPaths, 56 main_module: &str, 57 target: Option<Target>, 58 runtime: Option<Runtime>, 59) -> String { 60 fs::delete_directory(&paths.build_directory()).expect("delete build directory content"); 61 62 let Command { 63 program, 64 args, 65 env, 66 cwd: _, 67 stdio: _, 68 } = run::setup( 69 paths, 70 vec![], 71 target, 72 runtime, 73 Some(main_module.into()), 74 Which::Src, 75 true, 76 ) 77 .expect("run setup"); 78 79 let mut process = std::process::Command::new(&program) 80 .args(args) 81 .stdin(Stdio::null()) 82 .stdout(Stdio::null()) 83 .stderr(Stdio::piped()) 84 .envs(env.iter().map(|pair| (&pair.0, &pair.1))) 85 .current_dir(paths.root()) 86 .spawn() 87 .unwrap_or_else(|e| panic!("Failed to spawn process '{}': {}", &program, &e)); 88 89 let mut stderr = process.stderr.take().expect("take stderr"); 90 let mut output = String::new(); 91 let _ = stderr.read_to_string(&mut output).expect("read stderr"); 92 let _ = process.wait().expect("run with no errors"); 93 output 94} 95 96macro_rules! assert_echo { 97 ($project_name: expr) => { 98 let snapshot_name = snapshot_name(None, None, $project_name); 99 insta::allow_duplicates! { 100 assert_echo!(&snapshot_name, Some(Target::Erlang), None, $project_name); 101 assert_echo!(&snapshot_name, Some(Target::JavaScript), Some(Runtime::Bun), $project_name); 102 assert_echo!(&snapshot_name, Some(Target::JavaScript), Some(Runtime::Deno), $project_name); 103 assert_echo!(&snapshot_name, Some(Target::JavaScript), Some(Runtime::NodeJs), $project_name); 104 } 105 }; 106 107 ($target: expr, $project_name: expr) => { 108 let snapshot_name = snapshot_name(Some($target), None, $project_name); 109 match $target { 110 Target::JavaScript => insta::allow_duplicates! { 111 assert_echo!(&snapshot_name, Some($target), Some(Runtime::Bun), $project_name); 112 assert_echo!(&snapshot_name, Some($target), Some(Runtime::Deno), $project_name); 113 assert_echo!(&snapshot_name, Some($target), Some(Runtime::NodeJs), $project_name); 114 }, 115 Target::Erlang => { 116 assert_echo!(&snapshot_name, Some($target), None, $project_name); 117 } 118 Target::Cranelift => { 119 assert_echo!(&snapshot_name, Some($target), None, $project_name); 120 } 121 } 122 }; 123 124 ($snapshot_name: expr, $target: expr, $runtime: expr, $project_name: expr) => { 125 let path = fs::canonicalise(&Utf8Path::new("../test-output/cases").join($project_name)) 126 .expect("canonicalise path"); 127 let output = run_and_produce_pretty_snapshot($target, $runtime, path); 128 insta::assert_snapshot!($snapshot_name.to_string(), output); 129 }; 130} 131 132fn snapshot_name(target: Option<Target>, runtime: Option<Runtime>, suffix: &str) -> String { 133 let show_target = |target: Target| match target { 134 Target::Erlang => "erlang", 135 Target::JavaScript => "javascript", 136 }; 137 let show_runtime = |runtime: Runtime| match runtime { 138 Runtime::NodeJs => "nodejs", 139 Runtime::Deno => "deno", 140 Runtime::Bun => "bun", 141 }; 142 let prefix = match (target, runtime) { 143 (None, None) => "".into(), 144 (None, Some(runtime)) => format!("{}-", show_runtime(runtime)), 145 (Some(target), None) => format!("{}-", show_target(target)), 146 (Some(target), Some(runtime)) => { 147 format!("{}-{}-", show_target(target), show_runtime(runtime)) 148 } 149 }; 150 format!("{prefix}{suffix}") 151} 152 153#[test] 154fn echo_bitarray() { 155 assert_echo!(Target::JavaScript, "echo_bitarray"); 156 assert_echo!(Target::Erlang, "echo_bitarray"); 157} 158 159#[test] 160fn echo_bool() { 161 assert_echo!("echo_bool"); 162} 163 164#[test] 165fn echo_charlist() { 166 assert_echo!("echo_charlist"); 167} 168 169#[test] 170fn echo_custom_type() { 171 assert_echo!(Target::Erlang, "echo_custom_type"); 172 assert_echo!(Target::JavaScript, "echo_custom_type"); 173} 174 175#[test] 176fn echo_dict() { 177 assert_echo!("echo_dict"); 178} 179 180#[test] 181fn echo_float() { 182 assert_echo!(Target::Erlang, "echo_float"); 183 assert_echo!(Target::JavaScript, "echo_float"); 184} 185 186#[test] 187fn echo_function() { 188 assert_echo!("echo_function"); 189} 190 191#[test] 192fn echo_importing_module_named_inspect() { 193 assert_echo!("echo_importing_module_named_inspect"); 194} 195 196#[test] 197fn echo_int() { 198 assert_echo!("echo_int"); 199} 200 201#[test] 202fn echo_list() { 203 assert_echo!("echo_list"); 204} 205 206#[test] 207fn echo_nil() { 208 assert_echo!("echo_nil"); 209} 210 211#[test] 212fn echo_string() { 213 assert_echo!("echo_string"); 214} 215 216#[test] 217fn echo_tuple() { 218 assert_echo!("echo_tuple"); 219} 220 221#[test] 222fn echo_non_record_atom_tag() { 223 assert_echo!(Target::Erlang, "echo_non_record_atom_tag"); 224} 225 226#[test] 227fn echo_circular_reference() { 228 assert_echo!(Target::JavaScript, "echo_circular_reference"); 229} 230 231#[test] 232fn echo_singleton() { 233 assert_echo!("echo_singleton"); 234} 235 236#[test] 237fn echo_with_message() { 238 assert_echo!("echo_with_message"); 239} 240 241#[test] 242fn linked_process_exit() { 243 assert_echo!(Target::Erlang, "linked_process_exit"); 244}