2021-12-11 14:00:45 +01:00
use predicates ::boolean ::PredicateBooleanExt ;
2020-09-20 20:47:21 +02:00
use predicates ::{ prelude ::predicate , str ::PredicateStrExt };
2021-01-04 15:45:56 +01:00
use serial_test ::serial ;
2021-01-10 14:05:39 +01:00
use std ::path ::Path ;
2020-05-13 02:51:49 -07:00
use std ::str ::from_utf8 ;
2021-02-28 16:56:16 +01:00
use tempfile ::tempdir ;
2021-01-06 22:09:22 +01:00
#[cfg(unix)]
2021-02-27 15:33:13 +01:00
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 ;
pub use std ::time ::Duration ;
pub use assert_cmd ::assert ::OutputAssertExt ;
pub use nix ::pty ::{ openpty , OpenptyResult };
pub use wait_timeout ::ChildExt ;
pub const SAFE_CHILD_PROCESS_CREATION_TIME : Duration = Duration ::from_millis ( 100 );
pub const CHILD_WAIT_TIMEOUT : Duration = Duration ::from_secs ( 15 );
}
#[cfg(unix)]
use unix ::* ;
2020-05-13 02:51:49 -07:00
2021-01-10 14:05:39 +01:00
mod utils ;
2021-10-28 13:52:59 +02:00
use utils ::command ::{ bat , bat_with_config };
#[cfg(unix)]
use utils ::command ::bat_raw_command ;
2021-01-10 14:05:39 +01:00
use utils ::mocked_pagers ;
2020-05-13 02:51:49 -07:00
const EXAMPLES_DIR : & str = "tests/examples" ;
2021-01-06 20:09:01 +01:00
2018-10-10 22:56:56 +02:00
#[test]
fn basic () {
2020-06-01 16:50:24 -05:00
bat ()
2018-10-10 22:56:56 +02:00
. arg ( "test.txt" )
2020-06-01 16:50:24 -05:00
. assert ()
2018-10-10 22:56:56 +02:00
. success ()
. stdout ( "hello world \n " )
. stderr ( "" );
}
#[test]
fn stdin () {
2020-06-01 16:50:24 -05:00
bat ()
2020-03-07 00:01:35 +01:00
. write_stdin ( "foo \n bar \n " )
2020-06-01 16:50:24 -05:00
. assert ()
2018-10-10 22:56:56 +02:00
. success ()
. stdout ( "foo \n bar \n " );
}
#[test]
fn concatenate () {
2020-06-01 16:50:24 -05:00
bat ()
2018-10-10 22:56:56 +02:00
. arg ( "test.txt" )
. arg ( "test.txt" )
2020-06-01 16:50:24 -05:00
. assert ()
2018-10-10 22:56:56 +02:00
. success ()
. stdout ( "hello world \n hello world \n " );
}
#[test]
fn concatenate_stdin () {
2020-06-01 16:50:24 -05:00
bat ()
2018-10-10 22:56:56 +02:00
. arg ( "test.txt" )
. arg ( "-" )
. arg ( "test.txt" )
2020-03-07 00:01:35 +01:00
. write_stdin ( "stdin \n " )
2020-06-01 16:50:24 -05:00
. assert ()
2018-10-10 22:56:56 +02:00
. success ()
. stdout ( "hello world \n stdin \n hello world \n " );
}
2019-02-07 19:27:48 -08:00
#[test]
fn concatenate_empty_first () {
2020-06-01 16:50:24 -05:00
bat ()
2019-02-07 19:27:48 -08:00
. arg ( "empty.txt" )
. arg ( "test.txt" )
2020-06-01 16:50:24 -05:00
. assert ()
2019-02-07 19:27:48 -08:00
. success ()
. stdout ( "hello world \n " );
}
#[test]
fn concatenate_empty_last () {
2020-06-01 16:50:24 -05:00
bat ()
2019-02-07 19:27:48 -08:00
. arg ( "test.txt" )
. arg ( "empty.txt" )
2020-06-01 16:50:24 -05:00
. assert ()
2019-02-07 19:27:48 -08:00
. success ()
. stdout ( "hello world \n " );
}
#[test]
fn concatenate_empty_both () {
2020-06-01 16:50:24 -05:00
bat ()
2019-02-07 19:27:48 -08:00
. arg ( "empty.txt" )
. arg ( "empty.txt" )
2020-06-01 16:50:24 -05:00
. assert ()
2019-02-07 19:27:48 -08:00
. success ()
. stdout ( "" );
}
#[test]
fn concatenate_empty_between () {
2020-06-01 16:50:24 -05:00
bat ()
2019-02-07 19:27:48 -08:00
. arg ( "test.txt" )
. arg ( "empty.txt" )
. arg ( "test.txt" )
2020-06-01 16:50:24 -05:00
. assert ()
2019-02-07 19:27:48 -08:00
. success ()
. stdout ( "hello world \n hello world \n " );
}
#[test]
fn concatenate_empty_first_and_last () {
2020-06-01 16:50:24 -05:00
bat ()
2019-02-07 19:27:48 -08:00
. arg ( "empty.txt" )
. arg ( "test.txt" )
. arg ( "empty.txt" )
2020-06-01 16:50:24 -05:00
. assert ()
2019-02-07 19:27:48 -08:00
. success ()
. stdout ( "hello world \n " );
}
2019-02-10 08:52:38 +01:00
#[test]
fn concatenate_single_line () {
2020-06-01 16:50:24 -05:00
bat ()
2019-02-10 08:52:38 +01:00
. arg ( "single-line.txt" )
. arg ( "single-line.txt" )
2020-06-01 16:50:24 -05:00
. assert ()
2019-02-10 08:52:38 +01:00
. success ()
. stdout ( "Single LineSingle Line" );
}
#[test]
fn concatenate_single_line_empty () {
2020-06-01 16:50:24 -05:00
bat ()
2019-02-10 08:52:38 +01:00
. arg ( "single-line.txt" )
. arg ( "empty.txt" )
. arg ( "single-line.txt" )
2020-06-01 16:50:24 -05:00
. assert ()
2019-02-10 08:52:38 +01:00
. success ()
. stdout ( "Single LineSingle Line" );
}
2018-10-10 22:56:56 +02:00
#[test]
fn line_numbers () {
2020-06-01 16:50:24 -05:00
bat ()
2018-10-10 22:56:56 +02:00
. arg ( "multiline.txt" )
. arg ( "--style=numbers" )
. arg ( "--decorations=always" )
2020-06-01 16:50:24 -05:00
. assert ()
2018-10-10 22:56:56 +02:00
. success ()
. stdout ( " 1 line 1 \n 2 line 2 \n 3 line 3 \n 4 line 4 \n " );
}
#[test]
fn line_range_2_3 () {
2020-06-01 16:50:24 -05:00
bat ()
2018-10-10 22:56:56 +02:00
. arg ( "multiline.txt" )
. arg ( "--line-range=2:3" )
2020-06-01 16:50:24 -05:00
. assert ()
2018-10-10 22:56:56 +02:00
. success ()
. stdout ( "line 2 \n line 3 \n " );
}
#[test]
fn line_range_first_two () {
2020-06-01 16:50:24 -05:00
bat ()
2018-10-10 22:56:56 +02:00
. arg ( "multiline.txt" )
. arg ( "--line-range=:2" )
2020-06-01 16:50:24 -05:00
. assert ()
2018-10-10 22:56:56 +02:00
. success ()
. stdout ( "line 1 \n line 2 \n " );
}
#[test]
fn line_range_last_3 () {
2020-06-01 16:50:24 -05:00
bat ()
2018-10-10 22:56:56 +02:00
. arg ( "multiline.txt" )
. arg ( "--line-range=2:" )
2020-06-01 16:50:24 -05:00
. assert ()
2018-10-10 22:56:56 +02:00
. success ()
. stdout ( "line 2 \n line 3 \n line 4 \n " );
}
2018-10-20 00:10:10 +02:00
#[test]
fn line_range_multiple () {
2020-06-01 16:50:24 -05:00
bat ()
2018-10-20 00:10:10 +02:00
. arg ( "multiline.txt" )
. arg ( "--line-range=1:2" )
. arg ( "--line-range=4:4" )
2020-06-01 16:50:24 -05:00
. assert ()
2018-10-20 00:10:10 +02:00
. success ()
. stdout ( "line 1 \n line 2 \n line 4 \n " );
}
2021-02-27 15:33:13 +01:00
#[cfg(unix)]
fn setup_temp_file ( content : & [ u8 ]) -> io ::Result < ( PathBuf , tempfile ::TempDir ) > {
let dir = tempfile ::tempdir (). expect ( "Couldn't create tempdir" );
let path = dir . path (). join ( "temp_file" );
File ::create ( & path ) ? . write_all ( content ) ? ;
Ok (( path , dir ))
2021-01-05 10:54:14 +01:00
}
2021-02-27 15:33:13 +01:00
#[cfg(unix)]
2021-01-05 10:54:14 +01:00
#[test]
2021-02-27 15:33:13 +01:00
fn basic_io_cycle () -> io ::Result < () > {
let ( filename , dir ) = setup_temp_file ( b "I am not empty" ) ? ;
let file_out = Stdio ::from ( File ::create ( & filename ) ? );
let res = bat_raw_command ()
. arg ( "test.txt" )
. arg ( & filename )
. stdout ( file_out )
. assert ();
drop ( dir );
res . failure ();
Ok (())
}
#[cfg(unix)]
#[test]
fn first_file_cyclic_is_ok () -> io ::Result < () > {
let ( filename , dir ) = setup_temp_file ( b "I am not empty" ) ? ;
let file_out = Stdio ::from ( File ::create ( & filename ) ? );
let res = bat_raw_command ()
. arg ( & filename )
. arg ( "test.txt" )
. stdout ( file_out )
. assert ();
drop ( dir );
res . success ();
Ok (())
}
#[cfg(unix)]
#[test]
fn empty_file_cycle_is_ok () -> io ::Result < () > {
let ( filename , dir ) = setup_temp_file ( b "I am not empty" ) ? ;
let file_out = Stdio ::from ( File ::create ( & filename ) ? );
let res = bat_raw_command ()
. arg ( "empty.txt" )
. arg ( & filename )
. stdout ( file_out )
. assert ();
drop ( dir );
res . success ();
Ok (())
}
#[cfg(unix)]
#[test]
fn stdin_to_stdout_cycle () -> io ::Result < () > {
let ( filename , dir ) = setup_temp_file ( b "I am not empty" ) ? ;
let file_in = Stdio ::from ( File ::open ( & filename ) ? );
let file_out = Stdio ::from ( File ::create ( & filename ) ? );
let res = bat_raw_command ()
2021-01-05 10:54:14 +01:00
. arg ( "test.txt" )
. arg ( "-" )
2021-02-27 15:33:13 +01:00
. stdin ( file_in )
2021-01-05 10:54:14 +01:00
. stdout ( file_out )
2021-02-27 15:33:13 +01:00
. assert ();
drop ( dir );
res . failure ();
Ok (())
2021-01-05 10:54:14 +01:00
}
2021-01-05 10:55:22 +01:00
#[cfg(unix)]
#[test]
fn no_args_doesnt_break () {
// To simulate bat getting started from the shell, a process is created with stdin and stdout
// 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 = unsafe { Stdio ::from_raw_fd ( slave ) };
let stdout = unsafe { Stdio ::from_raw_fd ( slave ) };
let mut child = bat_raw_command ()
. stdin ( stdin )
. stdout ( stdout )
. spawn ()
. expect ( "Failed to start." );
// Some time for the child process to start and to make sure, that we can poll the exit status.
// Although this waiting period is not necessary, it is best to keep it in and be absolutely
// sure, that the try_wait does not error later.
thread ::sleep ( SAFE_CHILD_PROCESS_CREATION_TIME );
// The child process should be running and waiting for input,
// therefore no exit status should be available.
let exit_status = child
. try_wait ()
. expect ( "Error polling exit status, this should never happen." );
assert! ( exit_status . is_none ());
// Write Ctrl-D (end of transmission) to the pty.
master
. write_all ( & [ 0x04 ])
. expect ( "Couldn't write EOT character to master end." );
let exit_status = child
. wait_timeout ( CHILD_WAIT_TIMEOUT )
. expect ( "Error polling exit status, this should never happen." )
. expect ( "Exit status not set, but the child should have exited already." );
assert! ( exit_status . success ());
}
2018-10-18 20:27:04 +08:00
#[test]
fn tabs_numbers () {
2020-06-01 16:50:24 -05:00
bat ()
2018-10-18 20:27:04 +08:00
. arg ( "tabs.txt" )
. arg ( "--tabs=4" )
. arg ( "--style=numbers" )
. arg ( "--decorations=always" )
2020-06-01 16:50:24 -05:00
. assert ()
2018-10-18 20:27:04 +08:00
. success ()
2018-10-19 08:55:50 +08:00
. stdout (
" 1 1 2 3 4
2018-10-18 20:35:10 +08:00
2 1 ?
3 22 ?
4 333 ?
5 4444 ?
6 55555 ?
7 666666 ?
8 7777777 ?
9 88888888 ?
2018-10-19 08:55:50 +08:00
" ,
);
2018-10-18 20:27:04 +08:00
}
2018-10-14 22:22:59 +08:00
#[test]
fn tabs_passthrough_wrapped () {
2020-06-01 16:50:24 -05:00
bat ()
2018-10-15 23:22:23 +08:00
. arg ( "tabs.txt" )
. arg ( "--tabs=0" )
. arg ( "--style=plain" )
. arg ( "--decorations=always" )
2020-06-01 16:50:24 -05:00
. assert ()
2018-10-15 23:22:23 +08:00
. success ()
2018-10-19 08:55:50 +08:00
. stdout (
" 1 2 3 4
2018-10-15 23:22:23 +08:00
1 ?
22 ?
333 ?
4444 ?
55555 ?
666666 ?
7777777 ?
88888888 ?
2018-10-19 08:55:50 +08:00
" ,
);
2018-10-14 22:22:59 +08:00
}
#[test]
fn tabs_4_wrapped () {
2020-06-01 16:50:24 -05:00
bat ()
2018-10-15 23:22:23 +08:00
. arg ( "tabs.txt" )
. arg ( "--tabs=4" )
. arg ( "--style=plain" )
. arg ( "--decorations=always" )
2020-06-01 16:50:24 -05:00
. assert ()
2018-10-15 23:22:23 +08:00
. success ()
2018-10-19 08:55:50 +08:00
. stdout (
" 1 2 3 4
2018-10-15 23:22:23 +08:00
1 ?
22 ?
333 ?
4444 ?
55555 ?
666666 ?
7777777 ?
88888888 ?
2018-10-19 08:55:50 +08:00
" ,
);
2018-10-14 22:22:59 +08:00
}
#[test]
fn tabs_8_wrapped () {
2020-06-01 16:50:24 -05:00
bat ()
2018-10-15 23:22:23 +08:00
. arg ( "tabs.txt" )
. arg ( "--tabs=8" )
. arg ( "--style=plain" )
. arg ( "--decorations=always" )
2020-06-01 16:50:24 -05:00
. assert ()
2018-10-15 23:22:23 +08:00
. success ()
2018-10-19 08:55:50 +08:00
. stdout (
" 1 2 3 4
2018-10-15 23:22:23 +08:00
1 ?
22 ?
333 ?
4444 ?
55555 ?
666666 ?
7777777 ?
88888888 ?
2018-10-19 08:55:50 +08:00
" ,
);
2018-10-14 22:22:59 +08:00
}
#[test]
fn tabs_passthrough () {
2020-06-01 16:50:24 -05:00
bat ()
2018-10-15 23:22:23 +08:00
. arg ( "tabs.txt" )
. arg ( "--tabs=0" )
. arg ( "--style=plain" )
. arg ( "--decorations=always" )
2020-06-01 16:50:24 -05:00
. assert ()
2018-10-15 23:22:23 +08:00
. success ()
2018-10-19 08:55:50 +08:00
. stdout (
" 1 2 3 4
2018-10-15 23:22:23 +08:00
1 ?
22 ?
333 ?
4444 ?
55555 ?
666666 ?
7777777 ?
88888888 ?
2018-10-19 08:55:50 +08:00
" ,
);
2018-10-14 22:22:59 +08:00
}
#[test]
fn tabs_4 () {
2020-06-01 16:50:24 -05:00
bat ()
2018-10-15 23:22:23 +08:00
. arg ( "tabs.txt" )
. arg ( "--tabs=4" )
. arg ( "--style=plain" )
. arg ( "--decorations=always" )
2020-06-01 16:50:24 -05:00
. assert ()
2018-10-15 23:22:23 +08:00
. success ()
2018-10-19 08:55:50 +08:00
. stdout (
" 1 2 3 4
2018-10-15 23:22:23 +08:00
1 ?
22 ?
333 ?
4444 ?
55555 ?
666666 ?
7777777 ?
88888888 ?
2018-10-19 08:55:50 +08:00
" ,
);
2018-10-14 22:22:59 +08:00
}
#[test]
fn tabs_8 () {
2020-06-01 16:50:24 -05:00
bat ()
2018-10-15 23:22:23 +08:00
. arg ( "tabs.txt" )
. arg ( "--tabs=8" )
. arg ( "--style=plain" )
. arg ( "--decorations=always" )
2020-06-01 16:50:24 -05:00
. assert ()
2018-10-15 23:22:23 +08:00
. success ()
2018-10-19 08:55:50 +08:00
. stdout (
" 1 2 3 4
2018-10-15 23:22:23 +08:00
1 ?
22 ?
333 ?
4444 ?
55555 ?
666666 ?
7777777 ?
88888888 ?
2018-10-19 08:55:50 +08:00
" ,
);
2018-10-14 22:22:59 +08:00
}
2018-10-10 22:56:56 +02:00
#[test]
fn fail_non_existing () {
bat (). arg ( "non-existing-file" ). assert (). failure ();
}
#[test]
fn fail_directory () {
bat (). arg ( "sub_directory" ). assert (). failure ();
}
2018-10-11 21:54:19 +02:00
#[test]
fn do_not_exit_directory () {
2020-06-01 16:50:24 -05:00
bat ()
2018-10-11 21:54:19 +02:00
. arg ( "sub_directory" )
. arg ( "test.txt" )
2020-06-01 16:50:24 -05:00
. assert ()
2018-10-11 21:54:19 +02:00
. stdout ( "hello world \n " )
. failure ();
}
2018-10-17 20:44:15 +02:00
#[test]
fn pager_basic () {
2020-06-01 16:50:24 -05:00
bat ()
2020-05-27 22:30:51 -05:00
. env ( "PAGER" , "echo pager-output" )
2018-10-17 20:44:15 +02:00
. arg ( "--paging=always" )
. arg ( "test.txt" )
2020-06-01 16:50:24 -05:00
. assert ()
2018-10-17 20:44:15 +02:00
. success ()
2020-05-28 09:43:51 -05:00
. stdout ( predicate ::eq ( "pager-output \n " ). normalize ());
2018-10-17 20:44:15 +02:00
}
#[test]
fn pager_overwrite () {
2020-06-01 16:50:24 -05:00
bat ()
2020-05-27 22:30:51 -05:00
. env ( "PAGER" , "echo other-pager" )
. env ( "BAT_PAGER" , "echo pager-output" )
2018-10-17 20:44:15 +02:00
. arg ( "--paging=always" )
. arg ( "test.txt" )
2020-06-01 16:50:24 -05:00
. assert ()
2018-10-17 20:44:15 +02:00
. success ()
2020-05-28 09:43:51 -05:00
. stdout ( predicate ::eq ( "pager-output \n " ). normalize ());
2018-10-17 20:44:15 +02:00
}
#[test]
fn pager_disable () {
2020-06-01 16:50:24 -05:00
bat ()
2020-05-27 22:30:51 -05:00
. env ( "PAGER" , "echo other-pager" )
2018-10-17 20:44:15 +02:00
. env ( "BAT_PAGER" , "" )
. arg ( "--paging=always" )
. arg ( "test.txt" )
2020-06-01 16:50:24 -05:00
. assert ()
2018-10-17 20:44:15 +02:00
. success ()
2020-05-28 09:43:51 -05:00
. stdout ( predicate ::eq ( "hello world \n " ). normalize ());
2018-10-17 20:44:15 +02:00
}
2018-11-01 15:48:56 +00:00
2021-01-10 16:48:13 +01:00
#[test]
fn env_var_pager_value_bat () {
bat ()
. env ( "PAGER" , "bat" )
. arg ( "--paging=always" )
. arg ( "test.txt" )
. assert ()
. success ()
. stdout ( predicate ::eq ( "hello world \n " ). normalize ());
}
#[test]
fn env_var_bat_pager_value_bat () {
bat ()
. env ( "BAT_PAGER" , "bat" )
. arg ( "--paging=always" )
. arg ( "test.txt" )
. assert ()
. failure ()
. stderr ( predicate ::str ::contains ( "bat as a pager is disallowed" ));
}
2020-10-25 02:13:57 -07:00
#[test]
fn pager_value_bat () {
bat ()
. arg ( "--pager=bat" )
. arg ( "--paging=always" )
. arg ( "test.txt" )
. assert ()
2021-01-10 16:48:13 +01:00
. failure ()
. stderr ( predicate ::str ::contains ( "bat as a pager is disallowed" ));
2020-10-25 02:13:57 -07:00
}
2021-01-04 10:23:13 +01:00
/// We shall use less instead of most if PAGER is used since PAGER
/// is a generic env var
2020-11-27 06:47:46 +01:00
#[test]
2021-01-04 15:45:56 +01:00
#[serial] // Because of PATH
2021-01-04 10:23:13 +01:00
fn pager_most_from_pager_env_var () {
2021-01-10 14:05:39 +01:00
mocked_pagers ::with_mocked_versions_of_more_and_most_in_path ( || {
2021-01-04 17:20:02 +01:00
// If the output is not "I am most" then we know 'most' is not used
2021-01-04 10:23:13 +01:00
bat ()
2021-01-10 14:05:39 +01:00
. env ( "PAGER" , mocked_pagers ::from ( "most" ))
2021-01-04 10:23:13 +01:00
. arg ( "--paging=always" )
. arg ( "test.txt" )
. assert ()
. success ()
. stdout ( predicate ::eq ( "hello world \n " ). normalize ());
});
2020-11-27 06:47:46 +01:00
}
2021-01-04 10:23:13 +01:00
/// If the bat-specific BAT_PAGER is used, obey the wish of the user
/// and allow 'most'
#[test]
2021-01-04 15:45:56 +01:00
#[serial] // Because of PATH
2021-01-04 10:23:13 +01:00
fn pager_most_from_bat_pager_env_var () {
2021-01-10 14:05:39 +01:00
mocked_pagers ::with_mocked_versions_of_more_and_most_in_path ( || {
2021-01-04 10:23:13 +01:00
bat ()
2021-01-10 14:05:39 +01:00
. env ( "BAT_PAGER" , mocked_pagers ::from ( "most" ))
2021-01-04 10:23:13 +01:00
. arg ( "--paging=always" )
. arg ( "test.txt" )
. assert ()
. success ()
2021-01-04 17:20:02 +01:00
. stdout ( predicate ::str ::contains ( "I am most" ));
2021-01-04 10:23:13 +01:00
});
}
/// Same reasoning with --pager as with BAT_PAGER
#[test]
2021-01-04 15:45:56 +01:00
#[serial] // Because of PATH
2021-01-04 10:23:13 +01:00
fn pager_most_from_pager_arg () {
2021-01-10 14:05:39 +01:00
mocked_pagers ::with_mocked_versions_of_more_and_most_in_path ( || {
2021-01-04 10:23:13 +01:00
bat ()
. arg ( "--paging=always" )
2021-01-10 14:05:39 +01:00
. arg ( format! ( "--pager= {} " , mocked_pagers ::from ( "most" )))
2021-01-04 10:23:13 +01:00
. arg ( "test.txt" )
. assert ()
. success ()
2021-01-04 17:20:02 +01:00
. stdout ( predicate ::str ::contains ( "I am most" ));
2021-01-04 10:23:13 +01:00
});
}
/// Make sure the logic for 'most' applies even if an argument is passed
2020-11-27 06:47:46 +01:00
#[test]
2021-01-04 15:45:56 +01:00
#[serial] // Because of PATH
2020-11-27 06:47:46 +01:00
fn pager_most_with_arg () {
2021-01-10 14:05:39 +01:00
mocked_pagers ::with_mocked_versions_of_more_and_most_in_path ( || {
2021-01-04 10:23:13 +01:00
bat ()
2021-01-10 14:05:39 +01:00
. env ( "PAGER" , format! ( " {} -w" , mocked_pagers ::from ( "most" )))
2021-01-04 10:23:13 +01:00
. arg ( "--paging=always" )
. arg ( "test.txt" )
. assert ()
. success ()
. stdout ( predicate ::eq ( "hello world \n " ). normalize ());
});
}
/// Sanity check that 'more' is treated like 'most'
#[test]
2021-01-04 15:45:56 +01:00
#[serial] // Because of PATH
2021-01-04 10:23:13 +01:00
fn pager_more () {
2021-01-10 14:05:39 +01:00
mocked_pagers ::with_mocked_versions_of_more_and_most_in_path ( || {
2021-01-04 10:23:13 +01:00
bat ()
2021-01-10 14:05:39 +01:00
. env ( "PAGER" , mocked_pagers ::from ( "more" ))
2021-01-04 10:23:13 +01:00
. arg ( "--paging=always" )
. arg ( "test.txt" )
. assert ()
. success ()
. stdout ( predicate ::eq ( "hello world \n " ). normalize ());
});
2020-11-27 06:47:46 +01:00
}
2020-06-30 12:41:50 -07:00
#[test]
fn alias_pager_disable () {
bat ()
. env ( "PAGER" , "echo other-pager" )
. arg ( "-P" )
. arg ( "test.txt" )
. assert ()
. success ()
. stdout ( predicate ::eq ( "hello world \n " ). normalize ());
}
#[test]
fn alias_pager_disable_long_overrides_short () {
bat ()
. env ( "PAGER" , "echo pager-output" )
. arg ( "-P" )
. arg ( "--paging=always" )
. arg ( "test.txt" )
. assert ()
. success ()
. stdout ( predicate ::eq ( "pager-output \n " ). normalize ());
}
2022-08-14 21:09:13 +02:00
#[test]
fn disable_pager_if_disable_paging_flag_comes_after_paging () {
bat ()
. env ( "PAGER" , "echo pager-output" )
. arg ( "--paging=always" )
. arg ( "-P" )
. arg ( "test.txt" )
. assert ()
. success ()
. stdout ( predicate ::eq ( "hello world \n " ). normalize ());
}
2021-01-05 10:14:30 +01:00
#[test]
fn pager_failed_to_parse () {
bat ()
. env ( "BAT_PAGER" , "mismatched-quotes 'a" )
. arg ( "--paging=always" )
. arg ( "test.txt" )
. assert ()
. failure ()
. stderr ( predicate ::str ::contains ( "Could not parse pager command" ));
}
2021-08-07 12:13:12 +02:00
#[test]
fn diagnostic_sanity_check () {
bat ()
. arg ( "--diagnostic" )
. assert ()
. success ()
. stdout ( predicate ::str ::contains ( "BAT_PAGER=" ))
. stderr ( "" );
}
2018-11-01 15:48:56 +00:00
#[test]
fn config_location_test () {
2020-06-01 16:50:24 -05:00
bat_with_config ()
2018-11-01 15:48:56 +00:00
. env ( "BAT_CONFIG_PATH" , "bat.conf" )
. arg ( "--config-file" )
2020-06-01 16:50:24 -05:00
. assert ()
2018-11-01 15:48:56 +00:00
. success ()
. stdout ( "bat.conf \n " );
2021-02-27 12:21:06 +01:00
bat_with_config ()
. env ( "BAT_CONFIG_PATH" , "not-existing.conf" )
. arg ( "--config-file" )
. assert ()
. success ()
. stdout ( "not-existing.conf \n " );
2018-11-01 15:48:56 +00:00
}
2021-02-28 15:05:41 +01:00
#[test]
fn config_location_when_generating () {
2021-02-28 16:56:16 +01:00
let tmp_dir = tempdir (). expect ( "can create temporary directory" );
let tmp_config_path = tmp_dir . path (). join ( "should-be-created.conf" );
2021-02-28 15:05:41 +01:00
// Create the file with bat
bat_with_config ()
. env ( "BAT_CONFIG_PATH" , tmp_config_path . to_str (). unwrap ())
. arg ( "--generate-config-file" )
. assert ()
. success ()
2021-02-28 16:56:16 +01:00
. stdout (
predicate ::str ::is_match ( "Success! Config file written to .*should-be-created.conf \n " )
. unwrap (),
);
2021-02-28 15:05:41 +01:00
// Now we expect the file to exist. If it exists, we assume contents are correct
assert! ( tmp_config_path . exists ());
}
2021-08-12 17:08:13 -05:00
#[test]
fn config_location_from_bat_config_dir_variable () {
bat_with_config ()
2021-08-14 14:42:34 -05:00
. env ( "BAT_CONFIG_DIR" , "conf/" )
. arg ( "--config-file" )
2021-08-12 17:08:13 -05:00
. assert ()
. success ()
2021-08-18 13:45:22 +02:00
. stdout ( predicate ::str ::is_match ( "conf/config \n " ). unwrap ());
2021-08-12 17:08:13 -05:00
}
2018-11-01 15:48:56 +00:00
#[test]
2018-11-04 10:56:31 +01:00
fn config_read_arguments_from_file () {
2020-06-01 16:50:24 -05:00
bat_with_config ()
2018-11-01 15:48:56 +00:00
. env ( "BAT_CONFIG_PATH" , "bat.conf" )
. arg ( "test.txt" )
2020-06-01 16:50:24 -05:00
. assert ()
2018-11-01 15:48:56 +00:00
. success ()
2020-05-28 09:43:51 -05:00
. stdout ( predicate ::eq ( "dummy-pager-from-config \n " ). normalize ());
2018-11-01 15:48:56 +00:00
}
2019-02-10 09:19:38 +01:00
#[test]
fn utf16 () {
2022-09-06 19:08:38 +02:00
// The output will be converted to UTF-8 with the leading UTF-16
// BOM removed. This behavior is wanted in interactive mode as
// some terminals seem to display the BOM character as a space,
// and it also breaks syntax highlighting.
2020-06-01 16:50:24 -05:00
bat ()
2019-02-10 09:19:38 +01:00
. arg ( "--plain" )
. arg ( "--decorations=always" )
. arg ( "test_UTF-16LE.txt" )
2020-06-01 16:50:24 -05:00
. assert ()
2019-02-10 09:19:38 +01:00
. success ()
2022-09-06 19:08:38 +02:00
. stdout ( "hello world \n " );
}
// Regression test for https://github.com/sharkdp/bat/issues/1922
#[test]
fn bom_not_stripped_in_loop_through_mode () {
bat ()
. arg ( "--plain" )
. arg ( "--decorations=never" )
. arg ( "--color=never" )
. arg ( "test_BOM.txt" )
. assert ()
. success ()
. stdout ( " \u{feff} hello world \n " );
}
// Regression test for https://github.com/sharkdp/bat/issues/1922
#[test]
fn bom_stripped_when_colored_output () {
bat ()
. arg ( "--color=always" )
. arg ( "--decorations=never" )
. arg ( "test_BOM.txt" )
. assert ()
. success ()
. stdout (
predicate ::str ::is_match ( " \u{1b}\\ [38;5;[0-9]{3}mhello world \u{1b}\\ [0m \n " ). unwrap (),
);
}
// Regression test for https://github.com/sharkdp/bat/issues/1922
#[test]
fn bom_stripped_when_no_color_and_not_loop_through () {
bat ()
. arg ( "--color=never" )
. arg ( "--decorations=always" )
. arg ( "--style=numbers,grid,header" )
. arg ( "--terminal-width=80" )
. arg ( "test_BOM.txt" )
. assert ()
. success ()
. stdout (
" \
─────┬──────────────────────────────────────────────────────────────────────────
│ File: test_BOM.txt
─────┼──────────────────────────────────────────────────────────────────────────
1 │ hello world
─────┴──────────────────────────────────────────────────────────────────────────
" ,
);
2019-02-10 09:19:38 +01:00
}
2019-05-10 14:02:08 -05:00
#[test]
fn can_print_file_named_cache () {
2020-06-01 16:50:24 -05:00
bat_with_config ()
2019-05-10 14:02:08 -05:00
. arg ( "cache" )
2020-06-01 16:50:24 -05:00
. assert ()
2019-05-10 14:02:08 -05:00
. success ()
. stdout ( "test \n " )
. stderr ( "" );
}
2019-09-21 09:10:12 +02:00
#[test]
fn can_print_file_named_cache_with_additional_argument () {
2020-06-01 16:50:24 -05:00
bat_with_config ()
2019-09-21 09:10:12 +02:00
. arg ( "cache" )
. arg ( "test.txt" )
2020-06-01 16:50:24 -05:00
. assert ()
2019-09-21 09:10:12 +02:00
. success ()
. stdout ( "test \n hello world \n " )
. stderr ( "" );
}
2019-08-31 14:13:19 +02:00
#[test]
fn can_print_file_starting_with_cache () {
2020-06-01 16:50:24 -05:00
bat_with_config ()
2019-08-31 14:13:19 +02:00
. arg ( "cache.c" )
2020-06-01 16:50:24 -05:00
. assert ()
2019-08-31 14:13:19 +02:00
. success ()
. stdout ( "test \n " )
. stderr ( "" );
}
2019-05-10 14:02:08 -05:00
#[test]
fn does_not_print_unwanted_file_named_cache () {
bat_with_config (). arg ( "cach" ). assert (). failure ();
}
2019-08-31 12:46:03 +02:00
2021-07-27 20:11:58 +02:00
#[test]
fn accepts_no_custom_assets_arg () {
// Just make sure --no-custom-assets is considered a valid arg
// Don't bother to actually verify that it works
bat ()
. arg ( "--no-custom-assets" )
. arg ( "test.txt" )
. assert ()
. success ();
}
2020-02-01 18:49:29 +09:00
#[test]
fn unicode_wrap () {
2020-06-01 16:50:24 -05:00
bat_with_config ()
2020-02-01 18:49:29 +09:00
. arg ( "unicode-wrap.txt" )
. arg ( "--style=numbers,snip" )
. arg ( "--decorations=always" )
. arg ( "--terminal-width=40" )
2020-06-01 16:50:24 -05:00
. assert ()
2020-02-01 18:49:29 +09:00
. success ()
2020-02-28 10:27:06 +01:00
. stdout (
" 1 ビタミンA ビタミンD ビタミンE ビ
2020-02-28 11:42:44 +09:00
タミンK ビタミンB1 ビタミンB2 ナ
イアシン パントテン酸 ビタミンB6
ビタミンB12 葉酸 ビオチン ビタ
ミンC
2020-02-01 18:49:29 +09:00
2
2020-02-28 11:42:44 +09:00
3 고양이 고양이 고양이 고양이 고양이
고양이 고양이 고양이 고양이 고양이
고양이 고양이 고양이 고양이 고양이
고양이 고양이 고양이 고양이 고양이
고양이 고양이 고양이 고양이 고양이
고양이 고양이 고양이 고양이 고양이
고양이 고양이 고양이 고양이 고양이
고양이 고양이 고양이 고양이 고양이
고양이
2020-02-01 18:49:29 +09:00
4
2020-02-28 11:42:44 +09:00
5 1 บวก 2 บวก 3 บวก 4 บวก 5 บวก 6 บวก
7 บวก 8 บวก 9 บวก 10 บวก 11 บวก 12
บวก 13 บวก 14 บวก 15 บวก 16 บวก 17
บวก 18 บวก 19 บวก 20
2020-02-01 18:49:29 +09:00
6
2020-02-28 11:42:44 +09:00
7 Бельгия Болгария Чехия Дания Герман
ия Эстония Ирландия Греция Испания
Франция Хорватия Италия Кипр Латвия
Литва Люксембург Венгрия Мальта Ни
дерланды Австрия Польша Португалия
Румыния Словения Словакия Финляндия
Швеция Великобритания
2020-02-28 10:27:06 +01:00
" ,
);
2020-02-01 18:49:29 +09:00
}
2019-08-31 12:46:03 +02:00
#[test]
fn snip () {
2020-06-01 16:50:24 -05:00
bat ()
2019-08-31 12:46:03 +02:00
. arg ( "multiline.txt" )
. arg ( "--style=numbers,snip" )
. arg ( "--decorations=always" )
. arg ( "--line-range=1:2" )
. arg ( "--line-range=4:" )
2019-08-31 13:01:36 +02:00
. arg ( "--terminal-width=80" )
2020-06-01 16:50:24 -05:00
. assert ()
2019-08-31 12:46:03 +02:00
. success ()
. stdout (
" 1 line 1
2 line 2
...─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ 8< ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
4 line 4
" ,
);
}
2020-02-27 15:09:01 -08:00
#[test]
fn empty_file_leads_to_empty_output_with_grid_enabled () {
2020-06-01 16:50:24 -05:00
bat ()
2020-02-27 15:09:01 -08:00
. arg ( "empty.txt" )
. arg ( "--style=grid" )
. arg ( "--decorations=always" )
. arg ( "--terminal-width=80" )
2020-06-01 16:50:24 -05:00
. assert ()
2020-02-27 15:09:01 -08:00
. success ()
. stdout ( "" );
}
2020-03-19 20:46:19 -06:00
2020-10-06 16:57:47 +01:00
#[test]
fn empty_file_leads_to_empty_output_with_rule_enabled () {
bat ()
. arg ( "empty.txt" )
. arg ( "--style=rule" )
. arg ( "--decorations=always" )
. arg ( "--terminal-width=80" )
. assert ()
. success ()
. stdout ( "" );
}
2020-03-19 20:46:19 -06:00
#[test]
2022-02-07 19:48:57 +00:00
fn header_basic () {
2020-06-01 16:50:24 -05:00
bat ()
2020-03-19 20:46:19 -06:00
. arg ( "test.txt" )
. arg ( "--decorations=always" )
. arg ( "--style=header" )
. arg ( "-r=0:0" )
. arg ( "--file-name=foo" )
2020-06-01 16:50:24 -05:00
. assert ()
2020-03-19 20:46:19 -06:00
. success ()
. stdout ( "File: foo \n " )
. stderr ( "" );
}
#[test]
2022-02-07 19:48:57 +00:00
fn header_full_basic () {
bat ()
. arg ( "test.txt" )
. arg ( "--decorations=always" )
. arg ( "--style=header-filename,header-filesize" )
. arg ( "-r=0:0" )
. arg ( "--file-name=foo" )
. assert ()
. success ()
. stdout ( "File: foo \n Size: 12 B \n " )
. stderr ( "" );
}
#[test]
fn header_binary () {
2020-06-01 16:50:24 -05:00
bat ()
2020-03-19 20:46:19 -06:00
. arg ( "test.binary" )
. arg ( "--decorations=always" )
. arg ( "--style=header" )
. arg ( "-r=0:0" )
. arg ( "--file-name=foo" )
2020-06-01 16:50:24 -05:00
. assert ()
2020-03-19 20:46:19 -06:00
. success ()
. stdout ( "File: foo <BINARY> \n " )
. stderr ( "" );
}
2022-02-07 19:48:57 +00:00
#[test]
fn header_full_binary () {
bat ()
. arg ( "test.binary" )
. arg ( "--decorations=always" )
. arg ( "--style=header-filename,header-filesize" )
. arg ( "-r=0:0" )
. arg ( "--file-name=foo" )
. assert ()
. success ()
. stdout ( "File: foo <BINARY> \n Size: 4 B \n " )
. stderr ( "" );
}
2022-05-04 15:31:32 -04:00
#[test]
2022-08-18 10:20:31 +02:00
#[cfg(feature = "git" )] // Expected output assumes git is enabled
2022-05-04 15:31:32 -04:00
fn header_default () {
bat ()
. arg ( "--paging=never" )
. arg ( "--color=never" )
. arg ( "--terminal-width=80" )
. arg ( "--wrap=never" )
. arg ( "--decorations=always" )
. arg ( "--style=default" )
. arg ( "single-line.txt" )
. assert ()
. success ()
. stdout (
" \
───────┬────────────────────────────────────────────────────────────────────────
│ File: single-line.txt
───────┼────────────────────────────────────────────────────────────────────────
1 │ Single Line
───────┴────────────────────────────────────────────────────────────────────────
" ,
)
. stderr ( "" );
}
#[test]
2022-08-18 10:20:31 +02:00
#[cfg(feature = "git" )] // Expected output assumes git is enabled
2022-05-04 15:31:32 -04:00
fn header_default_is_default () {
bat ()
. arg ( "--paging=never" )
. arg ( "--color=never" )
. arg ( "--terminal-width=80" )
. arg ( "--wrap=never" )
. arg ( "--decorations=always" )
. arg ( "single-line.txt" )
. assert ()
. success ()
. stdout (
" \
───────┬────────────────────────────────────────────────────────────────────────
│ File: single-line.txt
───────┼────────────────────────────────────────────────────────────────────────
1 │ Single Line
───────┴────────────────────────────────────────────────────────────────────────
" ,
)
. stderr ( "" );
}
2020-03-19 20:46:19 -06:00
#[test]
fn filename_stdin () {
2020-06-01 16:50:24 -05:00
bat ()
2020-03-19 20:46:19 -06:00
. arg ( "--decorations=always" )
. arg ( "--style=header" )
. arg ( "-r=0:0" )
. arg ( "-" )
. write_stdin ( "stdin \n " )
. arg ( "--file-name=foo" )
2020-06-01 16:50:24 -05:00
. assert ()
2020-03-19 20:46:19 -06:00
. success ()
. stdout ( "File: foo \n " )
. stderr ( "" );
}
#[test]
fn filename_stdin_binary () {
let vec = vec! [ 0 ; 1 ];
2020-06-01 16:50:24 -05:00
bat_with_config ()
2020-03-19 20:46:19 -06:00
. arg ( "--decorations=always" )
. arg ( "--style=header" )
. write_stdin ( vec )
. arg ( "--file-name=foo" )
2020-06-01 16:50:24 -05:00
. assert ()
2020-03-19 20:46:19 -06:00
. success ()
. stdout ( "File: foo <BINARY> \n " )
. stderr ( "" );
}
2020-03-24 18:26:00 -06:00
#[test]
fn filename_multiple_ok () {
2020-06-01 16:50:24 -05:00
bat ()
2020-03-24 18:26:00 -06:00
. arg ( "--decorations=always" )
. arg ( "--style=header" )
. arg ( "-r=0:0" )
. arg ( "test.txt" )
. arg ( "--file-name=foo" )
. arg ( "single-line.txt" )
. arg ( "--file-name=bar" )
2020-06-01 16:50:24 -05:00
. assert ()
2020-03-24 18:26:00 -06:00
. success ()
2020-05-11 17:57:51 -07:00
. stdout ( "File: foo \n\n File: bar \n " )
2020-03-24 18:26:00 -06:00
. stderr ( "" );
}
#[test]
fn filename_multiple_err () {
bat ()
. arg ( "--decorations=always" )
. arg ( "--style=header" )
. arg ( "-r=0:0" )
. arg ( "test.txt" )
. arg ( "--file-name=foo" )
. arg ( "single-line.txt" )
. assert ()
. failure ();
}
2020-04-21 09:59:17 +02:00
2020-05-11 17:57:51 -07:00
#[test]
fn header_padding () {
2020-06-01 16:50:24 -05:00
bat ()
2020-05-11 17:57:51 -07:00
. arg ( "--decorations=always" )
2020-05-12 07:06:58 -07:00
. arg ( "--style=header" )
2020-05-11 17:57:51 -07:00
. arg ( "test.txt" )
. arg ( "single-line.txt" )
2020-06-01 16:50:24 -05:00
. assert ()
2020-05-12 07:06:58 -07:00
. stdout ( "File: test.txt \n hello world \n\n File: single-line.txt \n Single Line \n " )
2020-05-11 17:57:51 -07:00
. stderr ( "" );
}
2022-02-07 19:48:57 +00:00
#[test]
fn header_full_padding () {
bat ()
. arg ( "--decorations=always" )
. arg ( "--style=header-filename,header-filesize" )
. arg ( "test.txt" )
. arg ( "single-line.txt" )
. assert ()
. stdout ( "File: test.txt \n Size: 12 B \n hello world \n\n File: single-line.txt \n Size: 11 B \n Single Line \n " )
. stderr ( "" );
}
2020-10-08 09:59:14 +01:00
#[test]
fn header_padding_rule () {
bat ()
. arg ( "--decorations=always" )
. arg ( "--style=header,rule" )
. arg ( "--terminal-width=80" )
. arg ( "test.txt" )
. arg ( "single-line.txt" )
. assert ()
. stdout (
"File: test.txt
hello world
────────────────────────────────────────────────────────────────────────────────
File: single-line.txt
Single Line
" ,
)
. stderr ( "" );
}
2022-02-07 19:48:57 +00:00
#[test]
fn header_full_padding_rule () {
bat ()
. arg ( "--decorations=always" )
. arg ( "--style=header-filename,header-filesize,rule" )
. arg ( "--terminal-width=80" )
. arg ( "test.txt" )
. arg ( "single-line.txt" )
. assert ()
. stdout (
"File: test.txt
Size: 12 B
hello world
────────────────────────────────────────────────────────────────────────────────
File: single-line.txt
Size: 11 B
Single Line
" ,
)
. stderr ( "" );
}
2020-10-12 09:02:08 +01:00
#[test]
fn grid_overrides_rule () {
bat ()
. arg ( "--decorations=always" )
. arg ( "--style=grid,rule" )
. arg ( "--terminal-width=80" )
. arg ( "test.txt" )
. arg ( "single-line.txt" )
. assert ()
. stdout (
" \
────────────────────────────────────────────────────────────────────────────────
hello world
────────────────────────────────────────────────────────────────────────────────
────────────────────────────────────────────────────────────────────────────────
Single Line
────────────────────────────────────────────────────────────────────────────────
" ,
)
2022-02-27 00:01:00 +08:00
. stderr (
" \x1b [33m[bat warning] \x1b [0m: Style 'rule' is a subset of style 'grid', 'rule' will not be visible. \n " ,
);
2020-10-12 09:02:08 +01:00
}
2020-04-21 14:09:05 +02:00
#[cfg(target_os = "linux" )]
#[test]
fn file_with_invalid_utf8_filename () {
use std ::ffi ::OsStr ;
2020-04-21 16:02:28 +02:00
use std ::fs ::File ;
use std ::io ::Write ;
2020-04-21 14:09:05 +02:00
use std ::os ::unix ::ffi ::OsStrExt ;
2021-02-28 16:56:16 +01:00
let tmp_dir = tempdir (). expect ( "can create temporary directory" );
2020-04-21 16:02:28 +02:00
let file_path = tmp_dir
. path ()
. join ( OsStr ::from_bytes ( b "test-invalid-utf8- \xC3 (.rs" ));
{
let mut file = File ::create ( & file_path ). expect ( "can create temporary file" );
writeln! ( file , "dummy content" ). expect ( "can write to file" );
}
2020-06-01 16:50:24 -05:00
bat ()
2020-04-21 16:02:28 +02:00
. arg ( file_path . as_os_str ())
2020-06-01 16:50:24 -05:00
. assert ()
2020-04-21 16:02:28 +02:00
. success ()
. stdout ( "dummy content \n " );
2020-04-21 14:09:05 +02:00
}
2020-04-21 09:59:17 +02:00
#[test]
fn do_not_panic_regression_tests () {
for filename in & [
"issue_28.md" ,
"issue_190.md" ,
"issue_314.hs" ,
"issue_914.rb" ,
"issue_915.vue" ,
] {
bat ()
. arg ( "--color=always" )
. arg ( & format! ( "regression_tests/ {} " , filename ))
. assert ()
. success ();
}
}
2020-05-13 02:51:49 -07:00
#[test]
fn do_not_detect_different_syntax_for_stdin_and_files () {
let file = "regression_tests/issue_985.js" ;
2020-05-15 12:29:01 -07:00
let cmd_for_file = bat ()
2020-05-13 02:51:49 -07:00
. arg ( "--color=always" )
. arg ( "--map-syntax=*.js:Markdown" )
. arg ( & format! ( "--file-name= {} " , file ))
. arg ( "--style=plain" )
. arg ( file )
. assert ()
2020-05-15 12:29:01 -07:00
. success ();
2020-05-13 02:51:49 -07:00
2020-05-15 12:29:01 -07:00
let cmd_for_stdin = bat ()
2020-05-13 02:51:49 -07:00
. arg ( "--color=always" )
. arg ( "--map-syntax=*.js:Markdown" )
. arg ( "--style=plain" )
. arg ( & format! ( "--file-name= {} " , file ))
. pipe_stdin ( Path ::new ( EXAMPLES_DIR ). join ( file ))
. unwrap ()
. assert ()
2020-05-15 12:29:01 -07:00
. success ();
2020-05-13 02:51:49 -07:00
assert_eq! (
2020-05-15 12:29:01 -07:00
from_utf8 ( & cmd_for_file . get_output (). stdout ). expect ( "output is valid utf-8" ),
from_utf8 ( & cmd_for_stdin . get_output (). stdout ). expect ( "output is valid utf-8" )
2020-05-13 02:51:49 -07:00
);
}
2020-06-20 19:00:32 +04:00
2021-09-16 17:01:12 +02:00
#[test]
fn no_first_line_fallback_when_mapping_to_invalid_syntax () {
let file = "regression_tests/first_line_fallback.invalid-syntax" ;
bat ()
. arg ( "--color=always" )
. arg ( "--map-syntax=*.invalid-syntax:InvalidSyntax" )
. arg ( & format! ( "--file-name= {} " , file ))
. arg ( "--style=plain" )
. arg ( file )
. assert ()
. failure ()
. stderr ( predicate ::str ::contains ( "unknown syntax: 'InvalidSyntax'" ));
}
2020-06-20 19:00:32 +04:00
#[test]
fn show_all_mode () {
bat ()
. arg ( "--show-all" )
. arg ( "nonprintable.txt" )
. assert ()
2020-07-06 13:44:19 -07:00
. stdout ( "hello·world␊ \n ├──┤␍␀␇␈␛" )
2020-06-20 19:00:32 +04:00
. stderr ( "" );
}
2020-12-21 08:34:22 +01:00
2022-01-23 12:27:10 +01:00
#[test]
2022-03-06 19:44:31 +01:00
fn show_all_extends_tab_markers_to_next_tabstop () {
2022-01-23 12:27:10 +01:00
bat ()
. arg ( "tabs.txt" )
. arg ( "--show-all" )
. arg ( "--tabs=4" )
. arg ( "--style=plain" )
. assert ()
. success ()
. stdout (
2022-01-24 12:40:17 +01:00
"├──┤1├─┤2├─┤3├─┤4␊
2022-01-23 12:27:10 +01:00
1├─┤?␊
22├┤?␊
333↹?␊
4444├──┤?␊
55555├─┤?␊
666666├┤?␊
7777777↹?␊
88888888├──┤?␊
" ,
);
}
2022-01-23 12:35:05 +01:00
#[test]
2022-03-06 19:44:31 +01:00
fn show_all_extends_tab_markers_to_next_tabstop_width_8 () {
2022-01-23 12:35:05 +01:00
bat ()
. arg ( "tabs.txt" )
. arg ( "--show-all" )
. arg ( "--tabs=8" )
. arg ( "--style=plain" )
. assert ()
. success ()
. stdout (
2022-01-24 12:40:17 +01:00
"├──────┤1├─────┤2├─────┤3├─────┤4␊
2022-01-23 12:35:05 +01:00
1├─────┤?␊
22├────┤?␊
333├───┤?␊
4444├──┤?␊
55555├─┤?␊
666666├┤?␊
7777777↹?␊
88888888├──────┤?␊
" ,
);
}
2021-08-09 10:54:32 +02:00
#[test]
fn no_paging_arg () {
bat ()
. arg ( "--no-paging" )
. arg ( "--color=never" )
. arg ( "--decorations=never" )
. arg ( "single-line.txt" )
. assert ()
. success ()
. stdout ( "Single Line" );
}
#[test]
fn no_paging_short_arg () {
bat ()
. arg ( "-P" )
. arg ( "--color=never" )
. arg ( "--decorations=never" )
. arg ( "single-line.txt" )
. assert ()
. success ()
. stdout ( "Single Line" );
}
#[test]
fn no_pager_arg () {
bat ()
. arg ( "--no-pager" )
. arg ( "--color=never" )
. arg ( "--decorations=never" )
. arg ( "single-line.txt" )
. assert ()
. success ()
. stdout ( "Single Line" );
}
2020-12-21 08:34:22 +01:00
#[test]
fn plain_mode_does_not_add_nonexisting_newline () {
bat ()
. arg ( "--paging=never" )
. arg ( "--color=never" )
. arg ( "--decorations=always" )
. arg ( "--style=plain" )
. arg ( "single-line.txt" )
. assert ()
. success ()
. stdout ( "Single Line" );
}
2020-12-21 17:00:14 +01:00
// Regression test for https://github.com/sharkdp/bat/issues/299
#[test]
2022-08-18 10:20:31 +02:00
#[cfg(feature = "git" )] // Expected output assumes git is enabled
2020-12-21 17:00:14 +01:00
fn grid_for_file_without_newline () {
bat ()
. arg ( "--paging=never" )
. arg ( "--color=never" )
. arg ( "--terminal-width=80" )
. arg ( "--wrap=never" )
. arg ( "--decorations=always" )
. arg ( "--style=full" )
. arg ( "single-line.txt" )
. assert ()
. success ()
. stdout (
" \
───────┬────────────────────────────────────────────────────────────────────────
│ File: single-line.txt
2022-02-07 19:48:57 +00:00
│ Size: 11 B
2020-12-21 17:00:14 +01:00
───────┼────────────────────────────────────────────────────────────────────────
1 │ Single Line
───────┴────────────────────────────────────────────────────────────────────────
" ,
)
. stderr ( "" );
}
2021-11-19 11:05:23 -05:00
2022-02-14 18:02:14 +00:00
// For ANSI theme, use underscore as a highlighter
#[test]
fn ansi_highlight_underline () {
bat ()
. arg ( "--paging=never" )
. arg ( "--color=never" )
. arg ( "--terminal-width=80" )
. arg ( "--wrap=never" )
. arg ( "--decorations=always" )
. arg ( "--theme=ansi" )
. arg ( "--style=plain" )
. arg ( "--highlight-line=1" )
. write_stdin ( "Ansi Underscore Test \n Another Line" )
. assert ()
. success ()
. stdout ( " \x1B [4mAnsi Underscore Test \n\x1B [24mAnother Line" )
. stderr ( "" );
}
2021-11-19 11:05:23 -05:00
#[test]
fn ignored_suffix_arg () {
bat ()
. arg ( "-f" )
2022-05-24 19:29:03 +02:00
. arg ( "--theme" )
. arg ( "Monokai Extended" )
2021-11-19 11:05:23 -05:00
. arg ( "-p" )
. arg ( "test.json~" )
. assert ()
. success ()
. stdout ( " \u{1b} [38;5;231m{ \u{1b} [0m \u{1b} [38;5;208m \"\u{1b} [0m \u{1b} [38;5;208mtest \u{1b} [0m \u{1b} [38;5;208m \"\u{1b} [0m \u{1b} [38;5;231m: \u{1b} [0m \u{1b} [38;5;231m \u{1b} [0m \u{1b} [38;5;186m \"\u{1b} [0m \u{1b} [38;5;186mvalue \u{1b} [0m \u{1b} [38;5;186m \"\u{1b} [0m \u{1b} [38;5;231m} \u{1b} [0m" )
. stderr ( "" );
bat ()
. arg ( "-f" )
2022-05-24 19:29:03 +02:00
. arg ( "--theme" )
. arg ( "Monokai Extended" )
2021-11-19 11:05:23 -05:00
. arg ( "-p" )
. arg ( "--ignored-suffix=.suffix" )
. arg ( "test.json.suffix" )
. assert ()
. success ()
. stdout ( " \u{1b} [38;5;231m{ \u{1b} [0m \u{1b} [38;5;208m \"\u{1b} [0m \u{1b} [38;5;208mtest \u{1b} [0m \u{1b} [38;5;208m \"\u{1b} [0m \u{1b} [38;5;231m: \u{1b} [0m \u{1b} [38;5;231m \u{1b} [0m \u{1b} [38;5;186m \"\u{1b} [0m \u{1b} [38;5;186mvalue \u{1b} [0m \u{1b} [38;5;186m \"\u{1b} [0m \u{1b} [38;5;231m} \u{1b} [0m" )
. stderr ( "" );
bat ()
. arg ( "-f" )
2022-05-24 19:29:03 +02:00
. arg ( "--theme" )
. arg ( "Monokai Extended" )
2021-11-19 11:05:23 -05:00
. arg ( "-p" )
. arg ( "test.json.suffix" )
. assert ()
. success ()
. stdout ( " \u{1b} [38;5;231m{ \" test \" : \" value \" } \u{1b} [0m" )
. stderr ( "" );
}
2021-12-11 14:00:45 +01:00
2022-05-04 08:59:24 +03:00
#[test]
fn highlighting_is_skipped_on_long_lines () {
let expected = " \u{1b} [38;5;231m{ \u{1b} [0m \u{1b} [38;5;208m \"\u{1b} [0m \u{1b} [38;5;208mapi \u{1b} [0m \u{1b} [38;5;208m \"\u{1b} [0m \u{1b} [38;5;231m: \u{1b} [0m \n " . to_owned () +
" \u{1b} " +
r #"[38;5;231m {"ANGLE_instanced_arrays":{"__compat":{"mdn_url":"https://developer.mozilla.org/docs/Web/API/ANGLE_instanced_arrays","spec_url":"https://www.khronos.org/registry/webgl/extensions/ANGLE_instanced_arrays/","support":{"chrome":{"version_added":"32"},"chrome_android":{"version_added":"32"},"edge":{"version_added":"12"},"firefox":{"version_added":"47"},"firefox_android":{"version_added":true},"ie":{"version_added":"11"},"opera":{"version_added":"19"},"opera_android":{"version_added":"19"},"safari":{"version_added":"8"},"safari_ios":{"version_added":"8"},"samsunginternet_android":{"version_added":"2.0"},"webview_android":{"version_added":"4.4"}},"status":{"experimental":false,"standard_track":true,"deprecated":false}},"drawArraysInstancedANGLE":{"__compat":{"mdn_url":"https://developer.mozilla.org/docs/Web/API/ANGLE_instanced_arrays/drawArraysInstancedANGLE","spec_url":"https://www.khronos.org/registry/webgl/extensions/ANGLE_instanced_arrays/","support":{"chrome":{"version_added":"32"},"chrome_android":{"version_added":"32"},"edge":{"version_added":"12"},"firefox":{"version_added":"47"},"firefox_android":{"version_added":true},"ie":{"version_added":"11"},"opera":{"version_added":"19"},"opera_android":{"version_added":"19"},"safari":{"version_added":"8"},"safari_ios":{"version_added":"8"},"samsunginternet_android":{"version_added":"2.0"},"webview_android":{"version_added":"4.4"}},"status":{"experimental":false,"standard_track":true,"deprecated":false}}},"drawElementsInstancedANGLE":{"__compat":{"mdn_url":"https://developer.mozilla.org/docs/Web/API/ANGLE_instanced_arrays/drawElementsInstancedANGLE","spec_url":"https://www.khronos.org/registry/webgl/extensions/ANGLE_instanced_arrays/","support":{"chrome":{"version_added":"32"},"chrome_android":{"version_added":"32"},"edge":{"version_added":"12"},"firefox":{"version_added":"47"},"firefox_android":{"version_added":true},"ie":{"version_added":"11"},"opera":{"version_added":"19"},"opera_android":{"version_added":"19"},"safari":{"version_added":"8"},"safari_ios":{"version_added":"8"},"samsunginternet_android":{"version_added":"2.0"},"webview_android":{"version_added":"4.4"}},"status":{"experimental":false,"standard_track":true,"deprecated":false}}},"vertexAttribDivisorANGLE":{"__compat":{"mdn_url":"https://developer.mozilla.org/docs/Web/API/ANGLE_instanced_arrays/vertexAttribDivisorANGLE","spec_url":"https://www.khronos.org/registry/webgl/extensions/ANGLE_instanced_arrays/","support":{"chrome":{"version_added":"32"},"chrome_android":{"version_added":"32"},"edge":{"version_added":"12"},"firefox":{"version_added":"47"},"firefox_android":{"version_added":true},"ie":{"version_added":"11"},"opera":{"version_added":"19"},"opera_android":{"version_added":"19"},"safari":{"version_added":"8"},"safari_ios":{"version_added":"8"},"samsunginternet_android":{"version_added":"2.0"},"webview_android":{"version_added":"4.4"}},"status":{"experimental":false,"standard_track":true,"deprecated":false}}}},"AbortController":{"__compat":{"mdn_url":"https://developer.mozilla.org/docs/Web/API/AbortController","spec_url":"https://dom.spec.whatwg.org/#interface-abortcontroller","support":{"chrome":{"version_added":"66"},"chrome_android":{"version_added":"66"},"edge":{"version_added":"16"},"firefox":{"version_added":"57"},"firefox_android":{"version_added":"57"},"ie":{"version_added":false},"nodejs":{"version_added":"15.0.0"},"opera":{"version_added":"53"},"opera_android":{"version_added":"47"},"safari":[{"version_added":"12.1"},{"version_added":"11.1","partial_implementation":true,"notes":"Even though <code>window.AbortController</code> is defined, it doesn't really abort <code>fetch</code> requests. See <a href='https://webkit.org/b/174980'>bug 174980</a>."}],"safari_ios":[{"version_added":"12.2"},{"version_added":"11.3","partial_implementation":true,"notes":"Even though <code>window.AbortController</code> is defined, it doesn't really abort <code>fetch</code> requests. See <a href='https://webkit.org/b/174980'>bug 174980</a>."}],"samsunginternet_android":{"version_added":"9.0"},"webvi
"\u{1b}[0m\n\u{1b}[38;5;231m \u{1b}[0m\u{1b}[38;5;231m{\u{1b}[0m\u{1b}[38;5;208m\"\u{1b}[0m\u{1b}[38;5;208mversion_added\u{1b}[0m\u{1b}[38;5;208m\"\u{1b}[0m\u{1b}[38;5;231m:\u{1b}[0m\u{1b}[38;5;141mfalse\u{1b}[0m\u{1b}[38;5;231m}\u{1b}[0m\n";
bat()
.arg("-f")
2022-05-24 19:29:03 +02:00
.arg("--theme")
.arg("Monokai Extended")
2022-05-04 08:59:24 +03:00
.arg("-p")
.arg("longline.json")
.assert()
.success()
.stdout(expected)
.stderr("");
}
2022-02-27 00:01:00 +08:00
#[test]
fn all_global_git_config_locations_syntax_mapping_work() {
let fake_home = Path::new(EXAMPLES_DIR).join("git").canonicalize().unwrap();
let expected = "\u{1b}[38;5;231m[\u{1b}[0m\u{1b}[38;5;149muser\u{1b}[0m\u{1b}[38;5;231m]\u{1b}[0m
\u{1b}[38;5;231m \u{1b}[0m\u{1b}[38;5;231memail\u{1b}[0m\u{1b}[38;5;231m \u{1b}[0m\u{1b}[38;5;203m=\u{1b}[0m\u{1b}[38;5;231m \u{1b}[0m\u{1b}[38;5;186mfoo@bar.net\u{1b}[0m
\u{1b}[38;5;231m \u{1b}[0m\u{1b}[38;5;231mname\u{1b}[0m\u{1b}[38;5;231m \u{1b}[0m\u{1b}[38;5;203m=\u{1b}[0m\u{1b}[38;5;231m \u{1b}[0m\u{1b}[38;5;186mfoobar\u{1b}[0m
";
bat()
.env("XDG_CONFIG_HOME", fake_home.join(".config").as_os_str())
.arg("-f")
2022-05-24 19:29:03 +02:00
.arg("--theme")
.arg("Monokai Extended")
2022-02-27 00:01:00 +08:00
.arg("-p")
.arg("git/.config/git/config")
.assert()
.success()
.stdout(expected)
.stderr("");
bat()
.env("HOME", fake_home.as_os_str())
.arg("-f")
2022-05-24 19:29:03 +02:00
.arg("--theme")
.arg("Monokai Extended")
2022-02-27 00:01:00 +08:00
.arg("-p")
.arg("git/.config/git/config")
.assert()
.success()
.stdout(expected)
.stderr("");
bat()
.env("HOME", fake_home.as_os_str())
.arg("-f")
2022-05-24 19:29:03 +02:00
.arg("--theme")
.arg("Monokai Extended")
2022-02-27 00:01:00 +08:00
.arg("-p")
.arg("git/.gitconfig")
.assert()
.success()
.stdout(expected)
.stderr("");
}
2022-08-16 22:42:15 +02:00
#[test]
fn map_syntax_and_ignored_suffix_work_together() {
bat()
.arg("-f")
.arg("--theme")
.arg("Monokai Extended")
.arg("-p")
.arg("--ignored-suffix=.suffix")
.arg("--map-syntax=*.demo:JSON")
.arg("test.demo.suffix")
.assert()
.success()
.stdout("\u{1b}[38;5;231m{\u{1b}[0m\u{1b}[38;5;208m\"\u{1b}[0m\u{1b}[38;5;208mtest\u{1b}[0m\u{1b}[38;5;208m\"\u{1b}[0m\u{1b}[38;5;231m:\u{1b}[0m\u{1b}[38;5;231m \u{1b}[0m\u{1b}[38;5;186m\"\u{1b}[0m\u{1b}[38;5;186mvalue\u{1b}[0m\u{1b}[38;5;186m\"\u{1b}[0m\u{1b}[38;5;231m}\u{1b}[0m")
.stderr("");
bat()
.arg("-f")
.arg("--theme")
.arg("Monokai Extended")
.arg("-p")
.arg("--ignored-suffix=.suffix")
.arg("--ignored-suffix=.foo")
.arg("--map-syntax=*.demo:JSON")
.arg("test.demo.foo.suffix")
.assert()
.success()
.stdout("\u{1b}[38;5;231m{\u{1b}[0m\u{1b}[38;5;208m\"\u{1b}[0m\u{1b}[38;5;208mtest\u{1b}[0m\u{1b}[38;5;208m\"\u{1b}[0m\u{1b}[38;5;231m:\u{1b}[0m\u{1b}[38;5;231m \u{1b}[0m\u{1b}[38;5;186m\"\u{1b}[0m\u{1b}[38;5;186mvalue\u{1b}[0m\u{1b}[38;5;186m\"\u{1b}[0m\u{1b}[38;5;231m}\u{1b}[0m")
.stderr("");
}
2021-12-11 14:00:45 +01:00
#[test]
fn acknowledgements() {
bat()
.arg("--acknowledgements")
.assert()
.success()
.stdout(
// Just some sanity checking that avoids names of persons, except our own Keith Hall :)
predicate::str::contains(
"Copyright (c) 2018-2021 bat-developers (https://github.com/sharkdp/bat).",
)
.and(predicate::str::contains(
"Copyright (c) 2012-2020 The Sublime CMake authors",
))
.and(predicate::str::contains(
"Copyright 2014-2015 SaltStack Team",
))
.and(predicate::str::contains(
"Copyright (c) 2013-present Dracula Theme",
))
.and(predicate::str::contains(
"# # syntaxes / 01_ Packages / Rust / LICENSE . txt ",
))
.and(predicate::str::contains(
" ## syntaxes / 02_ Extra / http - request - response / LICENSE ",
))
.and(predicate::str::contains(
" ## themes / dracula - sublime / LICENSE ",
))
.and(predicate::str::contains(" Copyright ( c ) 2017 b123400 "))
.and(predicate::str::contains(" Copyright ( c ) 2021 Keith Hall "))
.and(predicate::str::contains(" Copyright 2014 Clams ")),
)
.stderr("");
}