mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
editor launch fix + new test
This commit is contained in:
parent
e32cd140a8
commit
652dbde26e
13 changed files with 126 additions and 43 deletions
|
@ -31,6 +31,9 @@ jobs:
|
||||||
- name: execute tests with --release
|
- name: execute tests with --release
|
||||||
run: nix develop -c cargo test --locked --release
|
run: nix develop -c cargo test --locked --release
|
||||||
|
|
||||||
|
- name: test launching the editor
|
||||||
|
run: cargo test --release --locked editor_launch_test::launch -- --ignored # --ignored to run this test that is ignored for "normal" runs
|
||||||
|
|
||||||
# we run the llvm wasm tests only on this machine because it is fast and wasm should be cross-target
|
# we run the llvm wasm tests only on this machine because it is fast and wasm should be cross-target
|
||||||
- name: execute llvm wasm tests with --release
|
- name: execute llvm wasm tests with --release
|
||||||
run: nix develop -c cargo test-gen-llvm-wasm --locked --release
|
run: nix develop -c cargo test-gen-llvm-wasm --locked --release
|
||||||
|
|
3
.github/workflows/ubuntu_x86_64.yml
vendored
3
.github/workflows/ubuntu_x86_64.yml
vendored
|
@ -33,6 +33,9 @@ jobs:
|
||||||
- name: regular rust tests
|
- name: regular rust tests
|
||||||
run: cargo test --locked --release --features with_sound serde --workspace && sccache --show-stats
|
run: cargo test --locked --release --features with_sound serde --workspace && sccache --show-stats
|
||||||
|
|
||||||
|
- name: test launching the editor
|
||||||
|
run: cargo test --release --locked editor_launch_test::launch -- --ignored # --ignored to run this test that is ignored for "normal" runs
|
||||||
|
|
||||||
- name: test the dev backend # these tests require an explicit feature flag
|
- name: test the dev backend # these tests require an explicit feature flag
|
||||||
run: cargo test --locked --release --package test_gen --no-default-features --features gen-dev && sccache --show-stats
|
run: cargo test --locked --release --package test_gen --no-default-features --features gen-dev && sccache --show-stats
|
||||||
|
|
||||||
|
|
3
Cargo.lock
generated
3
Cargo.lock
generated
|
@ -493,6 +493,7 @@ dependencies = [
|
||||||
"roc_load",
|
"roc_load",
|
||||||
"roc_module",
|
"roc_module",
|
||||||
"roc_reporting",
|
"roc_reporting",
|
||||||
|
"roc_utils",
|
||||||
"serde",
|
"serde",
|
||||||
"serde-xml-rs",
|
"serde-xml-rs",
|
||||||
"strip-ansi-escapes",
|
"strip-ansi-escapes",
|
||||||
|
@ -3425,6 +3426,7 @@ dependencies = [
|
||||||
"roc_target",
|
"roc_target",
|
||||||
"roc_test_utils",
|
"roc_test_utils",
|
||||||
"roc_tracing",
|
"roc_tracing",
|
||||||
|
"roc_utils",
|
||||||
"serial_test",
|
"serial_test",
|
||||||
"signal-hook",
|
"signal-hook",
|
||||||
"target-lexicon",
|
"target-lexicon",
|
||||||
|
@ -3574,6 +3576,7 @@ dependencies = [
|
||||||
"roc_solve",
|
"roc_solve",
|
||||||
"roc_types",
|
"roc_types",
|
||||||
"roc_unify",
|
"roc_unify",
|
||||||
|
"roc_utils",
|
||||||
"rodio",
|
"rodio",
|
||||||
"serde",
|
"serde",
|
||||||
"snafu",
|
"snafu",
|
||||||
|
|
|
@ -95,6 +95,7 @@ wasmer = { version = "2.2.1", optional = true, default-features = false, feature
|
||||||
wasmer-wasi = "2.2.1"
|
wasmer-wasi = "2.2.1"
|
||||||
pretty_assertions = "1.3.0"
|
pretty_assertions = "1.3.0"
|
||||||
roc_test_utils = { path = "../test_utils" }
|
roc_test_utils = { path = "../test_utils" }
|
||||||
|
roc_utils = { path = "../utils" }
|
||||||
indoc = "1.0.7"
|
indoc = "1.0.7"
|
||||||
serial_test = "0.9.0"
|
serial_test = "0.9.0"
|
||||||
criterion = { git = "https://github.com/Anton-4/criterion.rs"}
|
criterion = { git = "https://github.com/Anton-4/criterion.rs"}
|
||||||
|
|
|
@ -175,7 +175,7 @@ mod cli_run {
|
||||||
run_with_valgrind(stdin.iter().copied(), &valgrind_args);
|
run_with_valgrind(stdin.iter().copied(), &valgrind_args);
|
||||||
if valgrind_out.status.success() {
|
if valgrind_out.status.success() {
|
||||||
let memory_errors = extract_valgrind_errors(&raw_xml).unwrap_or_else(|err| {
|
let memory_errors = extract_valgrind_errors(&raw_xml).unwrap_or_else(|err| {
|
||||||
panic!("failed to parse the `valgrind` xml output. Error was:\n\n{:?}\n\nvalgrind xml was: \"{}\"\n\nvalgrind stdout was: \"{}\"\n\nvalgrind stderr was: \"{}\"", err, raw_xml, valgrind_out.stdout, valgrind_out.stderr);
|
panic!("failed to parse the `valgrind` xml output:\n\n Error was:\n\n {:?}\n\n valgrind xml was:\n\n \"{}\"\n\n valgrind stdout was:\n\n \"{}\"\n\n valgrind stderr was:\n\n \"{}\"", err, raw_xml, valgrind_out.stdout, valgrind_out.stderr);
|
||||||
});
|
});
|
||||||
|
|
||||||
if !memory_errors.is_empty() {
|
if !memory_errors.is_empty() {
|
||||||
|
|
52
crates/cli/tests/editor.rs
Normal file
52
crates/cli/tests/editor.rs
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
#[cfg(test)]
|
||||||
|
mod editor_launch_test {
|
||||||
|
|
||||||
|
use core::time;
|
||||||
|
use std::{
|
||||||
|
env,
|
||||||
|
process::{Command, Stdio},
|
||||||
|
thread,
|
||||||
|
};
|
||||||
|
|
||||||
|
use cli_utils::helpers::build_roc_bin_cached;
|
||||||
|
use roc_cli::CMD_EDIT;
|
||||||
|
use roc_utils::root_dir;
|
||||||
|
use std::io::Read;
|
||||||
|
|
||||||
|
// ignored because we don't want to bring up the editor window during regular tests, only on specific CI machines
|
||||||
|
#[ignore]
|
||||||
|
#[test]
|
||||||
|
fn launch() {
|
||||||
|
let root_dir = root_dir();
|
||||||
|
env::set_current_dir(&root_dir)
|
||||||
|
.unwrap_or_else(|_| panic!("Failed to set current dir to {:?}", root_dir));
|
||||||
|
|
||||||
|
let roc_binary_path = build_roc_bin_cached();
|
||||||
|
|
||||||
|
let mut roc_process = Command::new(roc_binary_path)
|
||||||
|
.arg(CMD_EDIT)
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.spawn()
|
||||||
|
.expect("Failed to start editor from cli.");
|
||||||
|
|
||||||
|
// wait for editor to show
|
||||||
|
thread::sleep(time::Duration::from_millis(2000));
|
||||||
|
|
||||||
|
// We extract 12 bytes from the logs for verification
|
||||||
|
let mut stdout_buffer = [0; 12];
|
||||||
|
let mut stdout = roc_process.stdout.take().unwrap();
|
||||||
|
stdout.read_exact(&mut stdout_buffer).unwrap();
|
||||||
|
|
||||||
|
match roc_process.try_wait() {
|
||||||
|
Ok(Some(status)) => panic!(
|
||||||
|
"The editor exited with status \"{status}\" but I expected it to still be running."
|
||||||
|
),
|
||||||
|
Ok(None) => {
|
||||||
|
// The editor is still running as desired, we check if logs are as expected:
|
||||||
|
assert_eq!("Loading file", std::str::from_utf8(&stdout_buffer).unwrap());
|
||||||
|
roc_process.kill().unwrap();
|
||||||
|
}
|
||||||
|
Err(e) => panic!("Failed to wait launch editor cli command: {e}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,6 +14,7 @@ roc_collections = { path = "../compiler/collections" }
|
||||||
roc_reporting = { path = "../reporting" }
|
roc_reporting = { path = "../reporting" }
|
||||||
roc_load = { path = "../compiler/load" }
|
roc_load = { path = "../compiler/load" }
|
||||||
roc_module = { path = "../compiler/module" }
|
roc_module = { path = "../compiler/module" }
|
||||||
|
roc_utils = { path = "../utils" }
|
||||||
bumpalo = { version = "3.8.0", features = ["collections"] }
|
bumpalo = { version = "3.8.0", features = ["collections"] }
|
||||||
criterion = { git = "https://github.com/Anton-4/criterion.rs"}
|
criterion = { git = "https://github.com/Anton-4/criterion.rs"}
|
||||||
serde = { version = "1.0.130", features = ["derive"] }
|
serde = { version = "1.0.130", features = ["derive"] }
|
||||||
|
|
|
@ -4,6 +4,7 @@ extern crate roc_load;
|
||||||
extern crate roc_module;
|
extern crate roc_module;
|
||||||
extern crate tempfile;
|
extern crate tempfile;
|
||||||
|
|
||||||
|
use roc_utils::root_dir;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde_xml_rs::from_str;
|
use serde_xml_rs::from_str;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
@ -27,9 +28,15 @@ where
|
||||||
I: IntoIterator<Item = S>,
|
I: IntoIterator<Item = S>,
|
||||||
S: AsRef<OsStr>,
|
S: AsRef<OsStr>,
|
||||||
{
|
{
|
||||||
|
let roc_binary_path = build_roc_bin_cached();
|
||||||
|
|
||||||
|
run_with_stdin_and_env(&roc_binary_path, args, stdin_vals, extra_env)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we don't already have a /target/release/roc, build it!
|
||||||
|
pub fn build_roc_bin_cached() -> PathBuf {
|
||||||
let roc_binary_path = path_to_roc_binary();
|
let roc_binary_path = path_to_roc_binary();
|
||||||
|
|
||||||
// If we don't have a /target/release/roc, rebuild it!
|
|
||||||
if !roc_binary_path.exists() {
|
if !roc_binary_path.exists() {
|
||||||
// Remove the /target/release/roc part
|
// Remove the /target/release/roc part
|
||||||
let root_project_dir = roc_binary_path
|
let root_project_dir = roc_binary_path
|
||||||
|
@ -48,21 +55,26 @@ where
|
||||||
vec!["build", "--release", "--bin", "roc"]
|
vec!["build", "--release", "--bin", "roc"]
|
||||||
};
|
};
|
||||||
|
|
||||||
let output = Command::new("cargo")
|
let run_command = "cargo";
|
||||||
|
|
||||||
|
let output = Command::new(run_command)
|
||||||
.current_dir(root_project_dir)
|
.current_dir(root_project_dir)
|
||||||
.args(args)
|
.args(&args)
|
||||||
.output()
|
.output()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
if !output.status.success() {
|
if !output.status.success() {
|
||||||
panic!("cargo build --release --bin roc failed. stdout was:\n\n{:?}\n\nstderr was:\n\n{:?}\n",
|
panic!(
|
||||||
output.stdout,
|
"{} {} failed:\n\n stdout was:\n\n {}\n\n stderr was:\n\n {}\n",
|
||||||
output.stderr
|
run_command,
|
||||||
|
args.join(" "),
|
||||||
|
String::from_utf8(output.stdout).unwrap(),
|
||||||
|
String::from_utf8(output.stderr).unwrap()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
run_with_stdin_and_env(&roc_binary_path, args, stdin_vals, extra_env)
|
roc_binary_path
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_glue<I, S>(args: I) -> Out
|
pub fn run_glue<I, S>(args: I) -> Out
|
||||||
|
@ -357,30 +369,6 @@ pub fn extract_valgrind_errors(xml: &str) -> Result<Vec<ValgrindError>, serde_xm
|
||||||
Ok(answer)
|
Ok(answer)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn root_dir() -> PathBuf {
|
|
||||||
let mut path = env::current_exe().ok().unwrap();
|
|
||||||
|
|
||||||
// Get rid of the filename in target/debug/deps/cli_run-99c65e4e9a1fbd06
|
|
||||||
path.pop();
|
|
||||||
|
|
||||||
// If we're in deps/ get rid of deps/ in target/debug/deps/
|
|
||||||
if path.ends_with("deps") {
|
|
||||||
path.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get rid of target/debug/ so we're back at the project root
|
|
||||||
path.pop();
|
|
||||||
path.pop();
|
|
||||||
|
|
||||||
// running cargo with --target will put us in the target dir
|
|
||||||
if path.ends_with("target") {
|
|
||||||
path.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
path
|
|
||||||
}
|
|
||||||
|
|
||||||
// start the dir with crates/cli_testing_examples
|
// start the dir with crates/cli_testing_examples
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn cli_testing_dir(dir_name: &str) -> PathBuf {
|
pub fn cli_testing_dir(dir_name: &str) -> PathBuf {
|
||||||
|
|
|
@ -29,6 +29,7 @@ roc_module = { path = "../compiler/module" }
|
||||||
roc_problem = { path = "../compiler/problem" }
|
roc_problem = { path = "../compiler/problem" }
|
||||||
roc_types = { path = "../compiler/types" }
|
roc_types = { path = "../compiler/types" }
|
||||||
roc_unify = { path = "../compiler/unify" }
|
roc_unify = { path = "../compiler/unify" }
|
||||||
|
roc_utils = { path = "../utils"}
|
||||||
roc_reporting = { path = "../reporting" }
|
roc_reporting = { path = "../reporting" }
|
||||||
roc_solve = { path = "../compiler/solve" }
|
roc_solve = { path = "../compiler/solve" }
|
||||||
ven_graph = { path = "../vendor/pathfinding" }
|
ven_graph = { path = "../vendor/pathfinding" }
|
||||||
|
|
|
@ -30,6 +30,7 @@ use roc_load::Threading;
|
||||||
use roc_module::symbol::IdentIds;
|
use roc_module::symbol::IdentIds;
|
||||||
use roc_types::subs::VarStore;
|
use roc_types::subs::VarStore;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
use std::env;
|
||||||
use std::fs::{self, File};
|
use std::fs::{self, File};
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
@ -521,7 +522,7 @@ fn read_main_roc_file(project_dir_path_opt: Option<&Path>) -> (PathBuf, String)
|
||||||
|
|
||||||
// returns path and content of app file
|
// returns path and content of app file
|
||||||
fn init_new_roc_project(project_dir_path: &Path) -> (PathBuf, String) {
|
fn init_new_roc_project(project_dir_path: &Path) -> (PathBuf, String) {
|
||||||
let orig_platform_path = Path::new("./examples/cli").join(PLATFORM_DIR_NAME);
|
let orig_platform_path = Path::new("./examples/cli/").join(PLATFORM_DIR_NAME);
|
||||||
|
|
||||||
let roc_file_path = Path::new("./new-roc-project/main.roc");
|
let roc_file_path = Path::new("./new-roc-project/main.roc");
|
||||||
|
|
||||||
|
@ -576,9 +577,11 @@ fn copy_roc_platform_if_not_exists(
|
||||||
) {
|
) {
|
||||||
if !orig_platform_path.exists() && !project_platform_path.exists() {
|
if !orig_platform_path.exists() && !project_platform_path.exists() {
|
||||||
panic!(
|
panic!(
|
||||||
r#"No roc file path was passed to the editor, I wanted to create a new roc project but I could not find the platform at {:?}.
|
r#"No roc file path was passed to the editor, so I wanted to create a new roc project but I could not find the platform at {:?}.
|
||||||
Are you at the root of the roc repository?"#,
|
Are you at the root of the roc repository?
|
||||||
orig_platform_path
|
My current directory is: {:?}"#,
|
||||||
|
orig_platform_path,
|
||||||
|
env::current_dir()
|
||||||
);
|
);
|
||||||
} else if !project_platform_path.exists() {
|
} else if !project_platform_path.exists() {
|
||||||
copy(orig_platform_path, project_dir_path, &CopyOptions::new()).unwrap_or_else(|err|{
|
copy(orig_platform_path, project_dir_path, &CopyOptions::new()).unwrap_or_else(|err|{
|
||||||
|
|
|
@ -16,12 +16,16 @@ For convenience and consistency, there is only one way to format roc.
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
pub const HELLO_WORLD: &str = r#"
|
pub const HELLO_WORLD: &str = r#"
|
||||||
app "test-app"
|
app "helloWorld"
|
||||||
packages { pf: "platform/main.roc" }
|
packages { pf: "cli-platform/main.roc" }
|
||||||
imports []
|
imports [pf.Stdout, pf.Program.{ Program }]
|
||||||
provides [main] to pf
|
provides [main] to pf
|
||||||
|
|
||||||
main = "Hello, world!"
|
main = Program.noArgs mainTask
|
||||||
|
|
||||||
|
mainTask =
|
||||||
|
Stdout.line "Hello, World!"
|
||||||
|
|> Program.exit 0
|
||||||
|
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
|
@ -29,7 +33,7 @@ pub fn nr_hello_world_lines() -> usize {
|
||||||
HELLO_WORLD.matches('\n').count() - 1
|
HELLO_WORLD.matches('\n').count() - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const PLATFORM_DIR_NAME: &str = "platform";
|
pub const PLATFORM_DIR_NAME: &str = "cli-platform";
|
||||||
pub const PLATFORM_FILE_NAME: &str = "main.roc";
|
pub const PLATFORM_FILE_NAME: &str = "main.roc";
|
||||||
|
|
||||||
pub const PLATFORM_STR: &str = r#"
|
pub const PLATFORM_STR: &str = r#"
|
||||||
|
|
|
@ -47,7 +47,7 @@ mod glue_cli_run {
|
||||||
assert_eq!(stderr, "");
|
assert_eq!(stderr, "");
|
||||||
assert!(
|
assert!(
|
||||||
out.stdout.ends_with($ends_with),
|
out.stdout.ends_with($ends_with),
|
||||||
"Unexpected stdout ending\n\nexpected:\n\n{}\n\nbut stdout was:\n\n{}",
|
"Unexpected stdout ending\n\n expected:\n\n {}\n\n but stdout was:\n\n {}",
|
||||||
$ends_with,
|
$ends_with,
|
||||||
out.stdout
|
out.stdout
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use snafu::OptionExt;
|
use snafu::OptionExt;
|
||||||
use std::{collections::HashMap, path::PathBuf, slice::SliceIndex};
|
use std::{collections::HashMap, env, path::PathBuf, slice::SliceIndex};
|
||||||
use util_error::{IndexOfFailedSnafu, KeyNotFoundSnafu, OutOfBoundsSnafu, UtilResult};
|
use util_error::{IndexOfFailedSnafu, KeyNotFoundSnafu, OutOfBoundsSnafu, UtilResult};
|
||||||
|
|
||||||
pub mod util_error;
|
pub mod util_error;
|
||||||
|
@ -120,3 +120,27 @@ pub fn get_lib_path() -> Option<PathBuf> {
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get the Path of the root of the repository
|
||||||
|
pub fn root_dir() -> PathBuf {
|
||||||
|
let mut path = env::current_exe().ok().unwrap();
|
||||||
|
|
||||||
|
// Get rid of the filename in target/debug/deps/cli_run-99c65e4e9a1fbd06
|
||||||
|
path.pop();
|
||||||
|
|
||||||
|
// If we're in deps/ get rid of deps/ in target/debug/deps/
|
||||||
|
if path.ends_with("deps") {
|
||||||
|
path.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get rid of target/debug/ so we're back at the project root
|
||||||
|
path.pop();
|
||||||
|
path.pop();
|
||||||
|
|
||||||
|
// running cargo with --target will put us in the target dir
|
||||||
|
if path.ends_with("target") {
|
||||||
|
path.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
path
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue