Skip to content

Commit

Permalink
FIX osc combinatorial testcases
Browse files Browse the repository at this point in the history
  • Loading branch information
Matt Helsley committed Jun 27, 2023
1 parent b8a2f80 commit da9aadc
Showing 1 changed file with 178 additions and 149 deletions.
327 changes: 178 additions & 149 deletions tests/osc.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
use nu_ansi_term::{AnsiGenericString, Color};
use std::io::Write;
use std::process::{Command, Stdio};

fn is_executable(s: &str) -> bool {
let path = std::path::Path::new(s).canonicalize();
if let Ok(path) = path {
path.exists() && path.is_file()
} else {
false
mod osc {

use nu_ansi_term::{AnsiGenericString, Color};
use std::io::Write;
use std::process::{Command, Stdio};

fn is_executable(s: &str) -> bool {
let path = std::path::Path::new(s).canonicalize();
if let Ok(path) = path {
path.exists() && path.is_file()
} else {
false
}
}
}

trait Terminal {
fn exists() -> Option<bool>;
fn cmd() -> Command;
}
trait Terminal {
fn exists() -> Option<bool>;
fn cmd() -> Command;
}

macro_rules! term {
($name:ident, $plat:meta , $cmd:literal, $( $arg:literal),*) => {
macro_rules! term {
($name:ident, $plat:meta , $cmd:literal, $( $arg:literal),* $(,)?) => {
struct $name;

impl Terminal for $name {
Expand All @@ -40,156 +42,183 @@ macro_rules! term {
};
}

term!(TerminalExe, target_family = "windows", "wt.exe", ""); // TODO REVIEW

term!(
TerminalApp,
target_os = "macos",
"/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal",
""
); // TODO REVIEW

term!(
GnomeTerminal,
target_os = "linux",
"/usr/bin/gnome-terminal",
"--wait",
"--",
"/usr/bin/bash",
"-c",
"/usr/bin/echo ; /usr/bin/sleep 3"
);

term!(
XTerm,
target_family = "unix",
"/usr/bin/xterm",
"-hold",
"-e",
"/usr/bin/echo"
);

term!(
Rxvt,
target_family = "unix",
"/usr/bin/rxvt",
"-hold",
"-e",
"/usr/bin/echo"
);

term!(
ETerm,
target_os = "linux",
"/usr/bin/Eterm",
"--pause",
"--finished-title",
"",
"-e",
"/usr/bin/bash",
"-c",
"/usr/bin/echo ; /usr/bin/sleep 3"
);

//term!(Alacritty, any, "~/.cargo/bin/alacritty", "-e", "/usr/bin/echo");

#[cfg(windows)]
pub fn setup() {
nu_ansi_term::enable_ansi_support().unwrap();
}
term!(TerminalExe, target_family = "windows", "wt.exe", ""); // TODO REVIEW

// From: https://ss64.com/osx/open.html
term!(
TerminalApp,
target_os = "macos",
"open",
"-n",
"-F",
"-W",
"-a",
// Alternative: "/System/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal",
"/Applications/Utilities/Terminal.app",
"--args",
"/usr/bin/bash",
"-c",
); // TODO REVIEW

term!(
GnomeTerminal,
target_os = "linux",
"/usr/bin/gnome-terminal",
"--wait",
"--",
"/usr/bin/bash",
"-c",
);

term!(
XTerm,
target_family = "unix",
"/usr/bin/xterm",
"-hold",
"-e",
"/usr/bin/bash",
"-c",
);

term!(
Rxvt,
target_family = "unix",
"/usr/bin/rxvt",
"-hold",
"-e",
"/usr/bin/bash",
"-c",
);

term!(
ETerm,
target_os = "linux",
"/usr/bin/Eterm",
"--pause",
"--finished-title",
"",
"-e",
"/usr/bin/bash",
"-c",
"/usr/bin/cat - ; /usr/bin/sleep 3"
);

//term!(Alacritty, any, "~/.cargo/bin/alacritty", "-e", "/usr/bin/echo");

pub fn setup() {
#[cfg(windows)]
{
nu_ansi_term::enable_ansi_support().unwrap();
}

let mut cmd = Command::new("cargo");
cmd.stdin(Stdio::piped());
cmd.stdout(Stdio::null());
cmd.stderr(Stdio::null());
cmd.args(["build", "--examples"]);

macro_rules! test_one_term {
($term:ident) => {
#[test]
#[ignore]
#[allow(non_snake_case)]
fn $term() {
// Must fit within a single write to a pipe or else we could deadlock.
// Most pipe buffers are at least 4096 bytes
let input = input();
assert!(input.len() < 2048, "input too big");

//
// TODO escape the input strings for echo -e
//
if let Some(true) = $term::exists() {
let mut cmd = $term::cmd();
cmd.stdin(Stdio::piped());
cmd.stdout(Stdio::null());
cmd.stderr(Stdio::null());
cmd.arg(input.as_str());
//eprintln!("Running {:?} in {}", cmd, stringify!($term));
let mut child = cmd.spawn().expect("Failed to spawn terminal");
let mut stdin = child.stdin.take().expect("Failed to open terminal stdin");
stdin
.write_all(input.as_bytes())
.expect("Failed to write terminal input");
let output = child
.wait_with_output()
.expect("Failed to wait for terminal");
assert!(output.status.success(), "{:?}", output);
} else if let Some(false) = $term::exists() {
eprintln!("Missing {}", stringify!($term));
} else if let None = $term::exists() {
eprintln!("Platform cannot run {}", stringify!($term));
let status = cmd.status().expect("Failed to build examples");
assert!(status.success());
}

macro_rules! test_one_term {
($term:ident) => {
#[test]
#[ignore]
#[allow(non_snake_case)]
fn $term() {
// Must fit within a single write to a pipe or else we could deadlock.
// Most pipe buffers are at least 4096 bytes
let input = input();
assert!(input.len() < 2048, "input too big");

//
// TODO escape the input strings for echo -e
//
if let Some(true) = $term::exists() {
let mut cmd = $term::cmd();
cmd.stdin(Stdio::piped());
cmd.stdout(Stdio::null());
cmd.stderr(Stdio::null());
cmd.arg(format!("cargo run --example {} -- --sleep 10000", EXAMPLE));

eprintln!("Running {:?} in {}", cmd, stringify!($term));
let mut child = cmd.spawn().expect("Failed to spawn terminal");
let mut stdin = child.stdin.take().expect("Failed to open terminal stdin");
stdin
.write_all(input.as_bytes())
.expect("Failed to write terminal input");
let output = child
.wait_with_output()
.expect("Failed to wait for terminal");
assert!(output.status.success(), "{:?}", output);
} else if let Some(false) = $term::exists() {
eprintln!("Missing {}", stringify!($term));
} else if let None = $term::exists() {
eprintln!("Platform cannot run {}", stringify!($term));
}
}
}
};
}
};
}

macro_rules! test_terms {
macro_rules! test_terms {
($( $term:ident ),+) => { $( test_one_term!($term); )+ }
}

macro_rules! test_all_terms {
() => {
test_terms!(TerminalExe, GnomeTerminal, XTerm, Rxvt, ETerm, TerminalApp);
};
}
macro_rules! test_all_terms {
() => {
test_terms!(TerminalExe, GnomeTerminal, XTerm, Rxvt, ETerm, TerminalApp);
};
}

mod hyperlink {
use super::*;
mod hyperlink {
use super::*;

fn input() -> String {
let mut link = Color::Blue.underline().paint("Link to example.com");
link.hyperlink("https://example.com");
link.to_string()
fn input() -> String {
let mut link = Color::Blue.underline().paint("Link to example.com");
link.hyperlink("https://example.com");
link.to_string()
}

const EXAMPLE: &str = "hyperlink";
test_all_terms!();
}

test_all_terms!();
}
mod title {
use super::*;

mod title {
use super::*;
fn input() -> String {
let title = AnsiGenericString::title("Success: Set Title");
title.to_string()
}

fn input() -> String {
let title = AnsiGenericString::title("My Title");
title.to_string()
const EXAMPLE: &str = "title";
test_all_terms!();
}

test_all_terms!();
}
mod cwd {
use super::*;

mod cwd {
use super::*;
fn input() -> String {
let path = std::path::Path::new("Success: Set CWD").to_str().unwrap();
let cwd = AnsiGenericString::cwd(path);
cwd.to_string()
}

fn input() -> String {
let path = std::path::Path::new("./for_cwd/").to_str().unwrap();
let cwd = AnsiGenericString::cwd(path);
cwd.to_string()
const EXAMPLE: &str = "cwd";
test_all_terms!();
}

test_all_terms!();
}
mod icon {
use super::*;

mod icon {
use super::*;
fn input() -> String {
let path = std::path::Path::new("Success: Set Icon").to_str().unwrap();
let icon = AnsiGenericString::icon(path);
icon.to_string()
}

fn input() -> String {
let path = std::path::Path::new("./foo.icn").to_str().unwrap();
let icon = AnsiGenericString::icon(path);
icon.to_string()
const EXAMPLE: &str = "icon";
test_all_terms!();
}

test_all_terms!();
}
} // mod osc

0 comments on commit da9aadc

Please sign in to comment.