1
0
mirror of https://github.com/sharkdp/bat.git synced 2025-09-02 03:12:25 +01:00

Merge branch 'master' into read-from-tail

This commit is contained in:
Keith Hall
2025-04-15 20:27:26 +03:00
130 changed files with 3567 additions and 1099 deletions

View File

@@ -9,7 +9,6 @@ use tempfile::tempdir;
mod unix {
pub use std::fs::File;
pub use std::io::{self, Write};
pub use std::os::unix::io::FromRawFd;
pub use std::path::PathBuf;
pub use std::process::Stdio;
pub use std::thread;
@@ -314,11 +313,8 @@ fn squeeze_limit_line_numbers() {
#[test]
fn list_themes_with_colors() {
#[cfg(target_os = "macos")]
let default_theme_chunk = "Monokai Extended Light\x1B[0m (default)";
#[cfg(not(target_os = "macos"))]
let default_theme_chunk = "Monokai Extended\x1B[0m (default)";
let default_light_theme_chunk = "Monokai Extended Light\x1B[0m (default light)";
bat()
.arg("--color=always")
@@ -327,34 +323,50 @@ fn list_themes_with_colors() {
.success()
.stdout(predicate::str::contains("DarkNeon").normalize())
.stdout(predicate::str::contains(default_theme_chunk).normalize())
.stdout(predicate::str::contains(default_light_theme_chunk).normalize())
.stdout(predicate::str::contains("Output the square of a number.").normalize());
}
#[test]
fn list_themes_without_colors() {
#[cfg(target_os = "macos")]
let default_theme_chunk = "Monokai Extended Light (default)";
#[cfg(not(target_os = "macos"))]
let default_theme_chunk = "Monokai Extended (default)";
let default_light_theme_chunk = "Monokai Extended Light (default light)";
bat()
.arg("--color=never")
.arg("--decorations=always") // trick bat into setting `Config::loop_through` to false
.arg("--list-themes")
.assert()
.success()
.stdout(predicate::str::contains("DarkNeon").normalize())
.stdout(predicate::str::contains(default_theme_chunk).normalize());
.stdout(predicate::str::contains(default_theme_chunk).normalize())
.stdout(predicate::str::contains(default_light_theme_chunk).normalize());
}
#[test]
#[cfg_attr(any(not(feature = "git"), target_os = "windows"), ignore)]
fn list_themes_to_piped_output() {
bat().arg("--list-themes").assert().success().stdout(
predicate::str::contains("(default)")
.not()
.and(predicate::str::contains("(default light)").not())
.and(predicate::str::contains("(default dark)").not()),
);
}
#[test]
#[cfg_attr(
any(not(feature = "git"), feature = "lessopen", target_os = "windows"),
ignore
)]
fn short_help() {
test_help("-h", "../doc/short-help.txt");
}
#[test]
#[cfg_attr(any(not(feature = "git"), target_os = "windows"), ignore)]
#[cfg_attr(
any(not(feature = "git"), feature = "lessopen", target_os = "windows"),
ignore
)]
fn long_help() {
test_help("--help", "../doc/long-help.txt");
}
@@ -445,9 +457,10 @@ fn no_args_doesnt_break() {
// as the slave end of a pseudo terminal. Although both point to the same "file", bat should
// not exit, because in this case it is safe to read and write to the same fd, which is why
// this test exists.
let OpenptyResult { master, slave } = openpty(None, None).expect("Couldn't open pty.");
let mut master = unsafe { File::from_raw_fd(master) };
let stdin_file = unsafe { File::from_raw_fd(slave) };
let mut master = File::from(master);
let stdin_file = File::from(slave);
let stdout_file = stdin_file.try_clone().unwrap();
let stdin = Stdio::from(stdin_file);
let stdout = Stdio::from(stdout_file);
@@ -455,6 +468,7 @@ fn no_args_doesnt_break() {
let mut child = bat_raw_command()
.stdin(stdin)
.stdout(stdout)
.env("TERM", "dumb") // Suppresses color detection
.spawn()
.expect("Failed to start.");
@@ -1050,6 +1064,31 @@ fn enable_pager_if_pp_flag_comes_before_paging() {
.stdout(predicate::eq("pager-output\n").normalize());
}
#[test]
fn paging_does_not_override_simple_plain() {
bat()
.env("PAGER", "echo pager-output")
.arg("--decorations=always")
.arg("--plain")
.arg("--paging=never")
.arg("test.txt")
.assert()
.success()
.stdout(predicate::eq("hello world\n"));
}
#[test]
fn simple_plain_does_not_override_paging() {
bat()
.env("PAGER", "echo pager-output")
.arg("--paging=always")
.arg("--plain")
.arg("test.txt")
.assert()
.success()
.stdout(predicate::eq("pager-output\n"));
}
#[test]
fn pager_failed_to_parse() {
bat()
@@ -1601,6 +1640,17 @@ oken
.stderr("");
}
#[test]
fn header_narrow_terminal_with_multibyte_chars() {
bat()
.arg("--terminal-width=30")
.arg("--decorations=always")
.arg("test.A—B가")
.assert()
.success()
.stderr("");
}
#[test]
#[cfg(feature = "git")] // Expected output assumes git is enabled
fn header_default() {
@@ -1833,7 +1883,7 @@ fn do_not_panic_regression_tests() {
] {
bat()
.arg("--color=always")
.arg(&format!("regression_tests/{filename}"))
.arg(format!("regression_tests/{filename}"))
.assert()
.success();
}
@@ -1846,7 +1896,7 @@ fn do_not_detect_different_syntax_for_stdin_and_files() {
let cmd_for_file = bat()
.arg("--color=always")
.arg("--map-syntax=*.js:Markdown")
.arg(&format!("--file-name={file}"))
.arg(format!("--file-name={file}"))
.arg("--style=plain")
.arg(file)
.assert()
@@ -1856,7 +1906,7 @@ fn do_not_detect_different_syntax_for_stdin_and_files() {
.arg("--color=always")
.arg("--map-syntax=*.js:Markdown")
.arg("--style=plain")
.arg(&format!("--file-name={file}"))
.arg(format!("--file-name={file}"))
.pipe_stdin(Path::new(EXAMPLES_DIR).join(file))
.unwrap()
.assert()
@@ -1875,7 +1925,7 @@ fn no_first_line_fallback_when_mapping_to_invalid_syntax() {
bat()
.arg("--color=always")
.arg("--map-syntax=*.invalid-syntax:InvalidSyntax")
.arg(&format!("--file-name={file}"))
.arg(format!("--file-name={file}"))
.arg("--style=plain")
.arg(file)
.assert()
@@ -1969,6 +2019,16 @@ fn show_all_with_unicode() {
.stderr("");
}
#[test]
fn binary_as_text() {
bat()
.arg("--binary=as-text")
.arg("control_characters.txt")
.assert()
.stdout("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x7F")
.stderr("");
}
#[test]
fn no_paging_arg() {
bat()
@@ -2257,6 +2317,46 @@ fn theme_arg_overrides_env_withconfig() {
.stderr("");
}
#[test]
fn theme_light_env_var_is_respected() {
bat()
.env("BAT_THEME_LIGHT", "Coldark-Cold")
.env("COLORTERM", "truecolor")
.arg("--theme=light")
.arg("--paging=never")
.arg("--color=never")
.arg("--terminal-width=80")
.arg("--wrap=never")
.arg("--decorations=always")
.arg("--style=plain")
.arg("--highlight-line=1")
.write_stdin("Lorem Ipsum")
.assert()
.success()
.stdout("\x1B[48;2;208;218;231mLorem Ipsum\x1B[0m")
.stderr("");
}
#[test]
fn theme_dark_env_var_is_respected() {
bat()
.env("BAT_THEME_DARK", "Coldark-Dark")
.env("COLORTERM", "truecolor")
.arg("--theme=dark")
.arg("--paging=never")
.arg("--color=never")
.arg("--terminal-width=80")
.arg("--wrap=never")
.arg("--decorations=always")
.arg("--style=plain")
.arg("--highlight-line=1")
.write_stdin("Lorem Ipsum")
.assert()
.success()
.stdout("\x1B[48;2;33;48;67mLorem Ipsum\x1B[0m")
.stderr("");
}
#[test]
fn theme_env_overrides_config() {
bat_with_config()
@@ -2435,7 +2535,6 @@ fn lessopen_stdin_piped() {
#[cfg(unix)] // Expected output assumed that tests are run on a Unix-like system
#[cfg(feature = "lessopen")]
#[test]
#[serial] // Randomly fails otherwise
fn lessopen_and_lessclose_file_temp() {
// This is mainly to test that $LESSCLOSE gets passed the correct file paths
// In this case, the original file and the temporary file returned by $LESSOPEN
@@ -2453,7 +2552,6 @@ fn lessopen_and_lessclose_file_temp() {
#[cfg(unix)] // Expected output assumed that tests are run on a Unix-like system
#[cfg(feature = "lessopen")]
#[test]
#[serial] // Randomly fails otherwise
fn lessopen_and_lessclose_file_piped() {
// This is mainly to test that $LESSCLOSE gets passed the correct file paths
// In these cases, the original file and a dash
@@ -2480,8 +2578,6 @@ fn lessopen_and_lessclose_file_piped() {
#[cfg(unix)] // Expected output assumed that tests are run on a Unix-like system
#[cfg(feature = "lessopen")]
#[test]
#[serial] // Randomly fails otherwise
#[ignore = "randomly failing on some systems"]
fn lessopen_and_lessclose_stdin_temp() {
// This is mainly to test that $LESSCLOSE gets passed the correct file paths
// In this case, a dash and the temporary file returned by $LESSOPEN
@@ -2499,7 +2595,6 @@ fn lessopen_and_lessclose_stdin_temp() {
#[cfg(unix)] // Expected output assumed that tests are run on a Unix-like system
#[cfg(feature = "lessopen")]
#[test]
#[serial] // Randomly fails otherwise
fn lessopen_and_lessclose_stdin_piped() {
// This is mainly to test that $LESSCLOSE gets passed the correct file paths
// In these cases, two dashes