#[cfg(test)] mod tests { use crate::ansi::{self, strip_ansi_codes}; use crate::cli::InspectRawLines; use crate::delta::{DiffType, State}; use crate::handlers::hunk_header::ParsedHunkHeader; use crate::style; use crate::tests::ansi_test_utils::ansi_test_utils; use crate::tests::integration_test_utils; use crate::tests::integration_test_utils::DeltaTest; use insta::assert_snapshot; #[test] fn test_added_file() { DeltaTest::with_args(&[]) .with_input(ADDED_FILE_INPUT) .expect_contains("\nadded: a.py\n"); } #[test] fn test_added_empty_file() { DeltaTest::with_args(&[]) .with_input(ADDED_EMPTY_FILE) .expect_contains("\nadded: file\n"); } #[test] fn test_added_file_directory_path_containing_space() { DeltaTest::with_args(&[]) .with_input(ADDED_FILES_DIRECTORY_PATH_CONTAINING_SPACE) .expect_contains("\nadded: with space/file1\n") .expect_contains("\nadded: nospace/file2\n"); } #[test] fn test_renamed_file() { DeltaTest::with_args(&[]) .with_input(RENAMED_FILE_INPUT) .expect_contains_once("\nrenamed: a.py ⟶ b.py\n"); } #[test] fn test_copied_file() { DeltaTest::with_args(&[]) .with_input(GIT_DIFF_WITH_COPIED_FILE) .expect_contains_once("\ncopied: first_file ⟶ copied_file\n"); } #[test] fn test_renamed_file_with_changes() { let t = DeltaTest::with_args(&[]) .with_input(RENAMED_FILE_WITH_CHANGES_INPUT) .expect_contains_once( "\nrenamed: Casks/font-dejavusansmono-nerd-font.rb ⟶ Casks/font-dejavu-sans-mono-nerd-font.rb\n" ); println!("{}", t.output); } #[test] fn test_recognized_file_type() { // In addition to the background color, the code has language syntax highlighting. let config = integration_test_utils::make_config_from_args(&[]); let output = integration_test_utils::get_line_of_code_from_delta( ADDED_FILE_INPUT, 14, "class X:", &config, ); ansi_test_utils::assert_has_color_other_than_plus_color(&output, &config); } #[test] fn test_unrecognized_file_type_with_syntax_theme() { // In addition to the background color, the code has the foreground color using the default // .txt syntax under the theme. let config = integration_test_utils::make_config_from_args(&[]); let input = ADDED_FILE_INPUT.replace("a.py", "a"); let output = integration_test_utils::get_line_of_code_from_delta(&input, 14, "class X:", &config); ansi_test_utils::assert_has_color_other_than_plus_color(&output, &config); } #[test] fn test_unrecognized_file_type_no_syntax_theme() { // The code has the background color only. (Since there is no theme, the code has no // foreground ansi color codes.) let config = integration_test_utils::make_config_from_args(&[ "--syntax-theme", "none", "--width", "variable", ]); let input = ADDED_FILE_INPUT.replace("a.py", "a"); let output = integration_test_utils::get_line_of_code_from_delta(&input, 14, "class X:", &config); ansi_test_utils::assert_has_plus_color_only(&output, &config); } #[test] fn test_default_language_is_used_for_syntax_highlighting() { // Note: default-language will be used for files with no extension, but also // for files with an extension, but for which the language was not detected. // Use color-only so that we can refer to the line numbers from the input diff. let config = integration_test_utils::make_config_from_args(&[ "--color-only", "--default-language", "bash", ]); let output = integration_test_utils::run_delta(MODIFIED_BASH_AND_CSHARP_FILES, &config); ansi_test_utils::assert_line_has_syntax_highlighted_substring( &output, 12, 1, " rsync -avu --delete $src/ $dst", "abc.bash", State::HunkZero(DiffType::Unified, None), &config, ); } #[test] fn test_default_language_is_not_used_when_other_language_is_detected() { // Use color-only so that we can refer to the line numbers from the input diff. let config = integration_test_utils::make_config_from_args(&[ "--color-only", "--default-language", "bash", ]); let output = integration_test_utils::run_delta(MODIFIED_BASH_AND_CSHARP_FILES, &config); ansi_test_utils::assert_line_has_syntax_highlighted_substring( &output, 19, 1, " static void Main(string[] args)", "abc.cs", State::HunkZero(DiffType::Unified, None), &config, ); } #[test] fn test_full_filename_used_to_detect_language() { let config = integration_test_utils::make_config_from_args(&[ "--color-only", "--default-language", "txt", ]); let output = integration_test_utils::run_delta(MODIFIED_DOCKER_AND_RS_FILES, &config); let ansi = ansi::explain_ansi(&output, false); // Ensure presence and absence of highlighting. Do not use `assert_line_has_syntax_highlighted_substring` // because it uses the same code path as the one to be tested here. let expected = r"(normal)diff --git a/Dockerfile b/Dockerfile index 0123456..1234567 100644 --- a/Dockerfile +++ b/Dockerfile @@ -0,0 +2 @@ (normal 22)+(203)FROM(231) foo(normal) (normal 22)+(203)COPY(231) bar baz(normal) diff --git a/rs b/rs index 0123456..1234567 100644 --- a/rs +++ b/rs @@ -0,0 +2 @@ (normal 22)+(231)fn foobar() -> i8 {(normal) (normal 22)+(231) 8(normal) (normal 22)+(231)}(normal) "; assert_eq!(expected, ansi); } #[test] fn test_diff_unified_two_files() { let config = integration_test_utils::make_config_from_args(&["--file-modified-label", "comparing:"]); let output = integration_test_utils::run_delta(DIFF_UNIFIED_TWO_FILES, &config); let output = strip_ansi_codes(&output); let mut lines = output.lines(); // Header assert_eq!(lines.nth(1).unwrap(), "comparing: one.rs ⟶ src/two.rs"); // Change assert_eq!(lines.nth(7).unwrap(), "println!(\"Hello ruster\");"); // Unchanged in second chunk assert_eq!(lines.nth(7).unwrap(), "Unchanged"); } #[test] fn test_diff_unified_two_directories() { let config = integration_test_utils::make_config_from_args(&["--width", "80", "--navigate"]); let output = integration_test_utils::run_delta(DIFF_UNIFIED_TWO_DIRECTORIES, &config); let output = strip_ansi_codes(&output); let mut lines = output.lines(); // Header assert_eq!(lines.nth(1).unwrap(), "Δ a/different ⟶ b/different"); // Change assert_eq!(lines.nth(7).unwrap(), "This is different from b"); // File uniqueness assert_eq!(lines.nth(2).unwrap(), "Only in a/: just_a"); // DiffHeader divider assert!(lines.next().unwrap().starts_with("───────")); // Next hunk assert_eq!( lines.nth(4).unwrap(), "Δ a/more_difference ⟶ b/more_difference" ); } #[test] fn test_diff_unified_concatenated() { // See #1002. Line buffers were not being flushed correctly, leading to material from first // file last hunk appearing at beginning of second file first hunk. DeltaTest::with_args(&[]) .with_input(DIFF_UNIFIED_CONCATENATED) .expect_contains("\nLINES.\n\n1/y 2022-03-06"); } #[test] #[ignore] // Ideally, delta would make this test pass. See #121. fn test_delta_ignores_non_diff_input() { let config = integration_test_utils::make_config_from_args(&[]); let output = integration_test_utils::run_delta(NOT_A_DIFF_OUTPUT, &config); let output = strip_ansi_codes(&output); assert_eq!(output, NOT_A_DIFF_OUTPUT.to_owned() + "\n"); } #[test] fn test_certain_bugs_are_not_present() { for input in [ DIFF_EXHIBITING_PARSE_FILE_NAME_BUG, DIFF_EXHIBITING_STATE_MACHINE_PARSER_BUG, DIFF_EXHIBITING_TRUNCATION_BUG, ] { let config = integration_test_utils::make_config_from_args(&["--raw"]); let output = integration_test_utils::run_delta(input, &config); assert_eq!(strip_ansi_codes(&output), input); assert_ne!(output, input); } } #[test] fn test_delta_paints_diff_when_there_is_unrecognized_initial_content() { for input in [ DIFF_WITH_UNRECOGNIZED_PRECEDING_MATERIAL_1, DIFF_WITH_UNRECOGNIZED_PRECEDING_MATERIAL_2, ] { let config = integration_test_utils::make_config_from_args(&["--raw"]); let output = integration_test_utils::run_delta(input, &config); assert_eq!(strip_ansi_codes(&output), input); assert_ne!(output, input); } } #[test] fn test_diff_with_merge_conflict_is_not_truncated() { let config = integration_test_utils::make_config_from_args(&[]); let output = integration_test_utils::run_delta(DIFF_WITH_MERGE_CONFLICT, &config); println!("{}", strip_ansi_codes(&output)); } #[test] fn test_diff_with_merge_conflict_is_passed_on_unchanged_under_raw() { let config = integration_test_utils::make_config_from_args(&["--raw"]); let output = integration_test_utils::run_delta(DIFF_WITH_MERGE_CONFLICT, &config); assert_eq!(strip_ansi_codes(&output), DIFF_WITH_MERGE_CONFLICT); } #[test] fn test_simple_dirty_submodule_diff() { DeltaTest::with_args(&["--width", "30"]) .with_input(SUBMODULE_DIRTY) .inspect() .expect_after_skip( 1, r#" some_submodule ────────────────────────────── ca030fd1a022..803be42ca46a"#, ); } #[test] fn test_submodule_diff_log() { // See etc/examples/662-submodules // diff.submodule = log let config = integration_test_utils::make_config_from_args(&["--width", "49"]); let output = integration_test_utils::run_delta(SUBMODULE_DIFF_LOG, &config); let output = strip_ansi_codes(&output); assert_eq!(output, SUBMODULE_DIFF_LOG_EXPECTED_OUTPUT); } #[test] fn test_submodule_contains_untracked_content() { let config = integration_test_utils::make_config_from_args(&[]); let output = integration_test_utils::run_delta(SUBMODULE_CONTAINS_UNTRACKED_CONTENT_INPUT, &config); let output = strip_ansi_codes(&output); assert!(output.contains("\nSubmodule x/y/z contains untracked content\n")); } #[test] fn test_triple_dash_at_beginning_of_line_in_code() { let config = integration_test_utils::make_config_from_args(&[]); let output = integration_test_utils::run_delta(TRIPLE_DASH_AT_BEGINNING_OF_LINE_IN_CODE, &config); let output = strip_ansi_codes(&output); assert!(output.contains("-- instance (Category p, Category q) => Category (p ∧ q) where\n")); } #[test] fn test_binary_files_differ() { let output = DeltaTest::with_args(&["--file-modified-label", "modified:"]) .with_input(BINARY_FILES_DIFFER) .skip_header(); assert_snapshot!(output, @r###" modified: foo (binary file) ─────────────────────────────────────────── "###); } #[test] fn test_binary_file_added() { let output = DeltaTest::with_args(&[]) .with_input(BINARY_FILE_ADDED) .skip_header(); assert_snapshot!(output, @r###" added: foo (binary file) ─────────────────────────────────────────── "###); } #[test] fn test_binary_file_removed() { let output = DeltaTest::with_args(&[]) .with_input(BINARY_FILE_REMOVED) .skip_header(); assert_snapshot!(output, @r###" removed: foo (binary file) ─────────────────────────────────────────── "###); } #[test] fn test_binary_files_differ_after_other() { let output = DeltaTest::with_args(&["--file-modified-label", "modified:"]) .with_input(BINARY_FILES_DIFFER_AFTER_OTHER) .output; assert_snapshot!(output, @r###" renamed: foo ⟶ bar ─────────────────────────────────────────── modified: qux (binary file) ─────────────────────────────────────────── "###); } #[test] fn test_diff_in_diff() { let config = integration_test_utils::make_config_from_args(&[]); let output = integration_test_utils::run_delta(DIFF_IN_DIFF, &config); let output = strip_ansi_codes(&output); assert!(output.contains("\n---\n")); assert!(output.contains("\nSubject: [PATCH] Init\n")); } #[test] fn test_standalone_diff_files_are_identical() { let diff = "Files foo and bar are identical\n"; let config = integration_test_utils::make_config_from_args(&[]); let output = integration_test_utils::run_delta(diff, &config); assert_eq!(strip_ansi_codes(&output), diff); } #[test] fn test_standalone_diff_binary_files_differ() { let diff = "Binary files foo and bar differ\n"; let config = integration_test_utils::make_config_from_args(&[]); let output = integration_test_utils::run_delta(diff, &config); assert_eq!(strip_ansi_codes(&output), diff); } #[test] fn test_diff_no_index_binary_files_differ() { let config = integration_test_utils::make_config_from_args(&[]); let output = integration_test_utils::run_delta(DIFF_NO_INDEX_BINARY_FILES_DIFFER, &config); assert_eq!( strip_ansi_codes(&output), "Binary files foo bar and sub dir/foo bar baz differ\n" ); } #[test] fn test_commit_style_raw_no_decoration() { let config = integration_test_utils::make_config_from_args(&[ "--commit-style", "raw", "--commit-decoration-style", "omit", ]); let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config); ansi_test_utils::assert_line_has_no_color( &output, 0, "commit 94907c0f136f46dc46ffae2dc92dca9af7eb7c2e", ); assert!(output.contains( "\ commit 94907c0f136f46dc46ffae2dc92dca9af7eb7c2e " )); } #[test] fn test_commit_style_colored_input_color_is_stripped_under_normal() { let config = integration_test_utils::make_config_from_args(&[ "--commit-style", "normal", "--commit-decoration-style", "omit", ]); let output = integration_test_utils::run_delta( GIT_DIFF_SINGLE_HUNK_WITH_ANSI_ESCAPE_SEQUENCES, &config, ); ansi_test_utils::assert_line_has_no_color( &output, 0, "commit 94907c0f136f46dc46ffae2dc92dca9af7eb7c2e", ); } #[test] fn test_commit_style_colored_input_color_is_preserved_under_raw() { let config = integration_test_utils::make_config_from_args(&[ "--commit-style", "raw", "--commit-decoration-style", "omit", ]); let output = integration_test_utils::run_delta( GIT_DIFF_SINGLE_HUNK_WITH_ANSI_ESCAPE_SEQUENCES, &config, ); ansi_test_utils::assert_line_has_4_bit_color_style( &output, 0, "commit 94907c0f136f46dc46ffae2dc92dca9af7eb7c2e", "bold 31", &config, ); } #[test] fn test_orphan_carriage_return_is_stripped() { let config = integration_test_utils::make_config_from_args(&[]); let output = integration_test_utils::run_delta( GIT_DIFF_SINGLE_HUNK_WITH_SEQUENCE_OF_CR_ESCAPE_SEQUENCES_LF, &config, ); assert!(output.bytes().all(|b: u8| b != b'\r')); } #[test] fn test_commit_decoration_style_omit() { _do_test_commit_style_no_decoration(&[ "--commit-style", "blue", "--commit-decoration-style", "omit", ]); } #[test] fn test_commit_decoration_style_empty_string() { _do_test_commit_style_no_decoration(&[ "--commit-style", "blue", "--commit-decoration-style", "", ]); } fn _do_test_commit_style_no_decoration(args: &[&str]) { let config = integration_test_utils::make_config_from_args(args); let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config); if false { // `--commit-style xxx` is not honored yet: always behaves like xxx=raw ansi_test_utils::assert_line_has_style( &output, 0, "commit 94907c0f136f46dc46ffae2dc92dca9af7eb7c2e", "blue", &config, ); } let output = strip_ansi_codes(&output); assert!(output.contains("commit 94907c0f136f46dc46ffae2dc92dca9af7eb7c2e")); assert!(!output.contains("commit 94907c0f136f46dc46ffae2dc92dca9af7eb7c2e │")); assert!(!output.contains( "\ commit 94907c0f136f46dc46ffae2dc92dca9af7eb7c2e ───────────────────────────────────────────────" )); } #[test] fn test_commit_style_omit() { let config = integration_test_utils::make_config_from_args(&["--commit-style", "omit"]); let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config); let output = strip_ansi_codes(&output); assert!(!output.contains( "\ commit 94907c0f136f46dc46ffae2dc92dca9af7eb7c2e " )); } #[test] fn test_commit_style_box() { _do_test_commit_style_box(&[ "--commit-style", "blue", "--commit-decoration-style", "blue box", ]); } #[test] fn test_commit_style_box_ul() { _do_test_commit_style_box_ul(&[ "--commit-style", "blue", "--commit-decoration-style", "blue box ul", "--width=64", ]); } #[ignore] #[test] fn test_commit_style_box_ol() { _do_test_commit_style_box_ol(&[ "--commit-style", "blue", "--commit-decoration-style", "blue box ol", ]); } fn _do_test_commit_style_box(args: &[&str]) { let config = integration_test_utils::make_config_from_args(args); let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config); ansi_test_utils::assert_line_has_style( &output, 0, "────────────────────────────────────────────────┐", "blue", &config, ); ansi_test_utils::assert_line_has_style( &output, 1, "commit 94907c0f136f46dc46ffae2dc92dca9af7eb7c2e │", "blue", &config, ); ansi_test_utils::assert_line_has_style( &output, 2, "────────────────────────────────────────────────┘", "blue", &config, ); let output = strip_ansi_codes(&output); assert!(output.contains( "\ ────────────────────────────────────────────────┐ commit 94907c0f136f46dc46ffae2dc92dca9af7eb7c2e │ ────────────────────────────────────────────────┘ " )); } fn _do_test_commit_style_box_ul(args: &[&str]) { let config = integration_test_utils::make_config_from_args(args); let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config); ansi_test_utils::assert_line_has_style( &output, 0, "────────────────────────────────────────────────┐", "blue", &config, ); ansi_test_utils::assert_line_has_style( &output, 1, "commit 94907c0f136f46dc46ffae2dc92dca9af7eb7c2e │", "blue", &config, ); ansi_test_utils::assert_line_has_style( &output, 2, "────────────────────────────────────────────────┴─", "blue", &config, ); let output = strip_ansi_codes(&output); assert!(output.contains( "\ ────────────────────────────────────────────────┐ commit 94907c0f136f46dc46ffae2dc92dca9af7eb7c2e │ ────────────────────────────────────────────────┴─" )); } fn _do_test_commit_style_box_ol(args: &[&str]) { let config = integration_test_utils::make_config_from_args(args); let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config); ansi_test_utils::assert_line_has_style( &output, 0, "────────────────────────────────────────────────┬─", "blue", &config, ); ansi_test_utils::assert_line_has_style( &output, 1, "commit 94907c0f136f46dc46ffae2dc92dca9af7eb7c2e │", "blue", &config, ); ansi_test_utils::assert_line_has_style( &output, 2, "────────────────────────────────────────────────┘", "blue", &config, ); let output = strip_ansi_codes(&output); assert!(output.contains( "\ ────────────────────────────────────────────────┬─ commit 94907c0f136f46dc46ffae2dc92dca9af7eb7c2e │ ────────────────────────────────────────────────┘ " )); } #[test] fn test_commit_style_box_raw() { let config = integration_test_utils::make_config_from_args(&[ "--commit-style", "raw", "--commit-decoration-style", "box ul", "--width=64", ]); let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config); ansi_test_utils::assert_line_has_no_color( &output, 1, "commit 94907c0f136f46dc46ffae2dc92dca9af7eb7c2e │", ); assert!(output.contains( "\ ────────────────────────────────────────────────┐ commit 94907c0f136f46dc46ffae2dc92dca9af7eb7c2e │ ────────────────────────────────────────────────┴─" )); } // TODO: test overline #[test] fn test_commit_style_underline() { _do_test_commit_style_underline(&[ "--commit-style", "yellow", "--commit-decoration-style", "yellow underline", ]); } fn _do_test_commit_style_underline(args: &[&str]) { let config = integration_test_utils::make_config_from_args(args); let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config); ansi_test_utils::assert_line_has_style( &output, 0, "commit 94907c0f136f46dc46ffae2dc92dca9af7eb7c2e", "yellow", &config, ); ansi_test_utils::assert_line_has_style( &output, 1, "───────────────────────────────────────────────", "yellow", &config, ); let output = strip_ansi_codes(&output); assert!(output.contains( "\ commit 94907c0f136f46dc46ffae2dc92dca9af7eb7c2e ───────────────────────────────────────────────" )); } #[test] fn test_file_style_raw_no_decoration() { let config = integration_test_utils::make_config_from_args(&[ "--file-style", "raw", "--file-decoration-style", "omit", ]); let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config); for (i, line) in [ "diff --git a/src/align.rs b/src/align.rs", "index 8e37a9e..6ce4863 100644", "--- a/src/align.rs", "+++ b/src/align.rs", ] .iter() .enumerate() { ansi_test_utils::assert_line_has_no_color(&output, 6 + i, line); } assert!(output.contains( " diff --git a/src/align.rs b/src/align.rs index 8e37a9e..6ce4863 100644 --- a/src/align.rs +++ b/src/align.rs " )); } #[test] fn test_file_style_colored_input_color_is_stripped_under_normal() { let config = integration_test_utils::make_config_from_args(&[ "--file-style", "normal", "--file-decoration-style", "omit", ]); let output = integration_test_utils::run_delta( GIT_DIFF_SINGLE_HUNK_WITH_ANSI_ESCAPE_SEQUENCES, &config, ); ansi_test_utils::assert_line_has_no_color(&output, 7, "src/align.rs"); } #[test] fn test_file_style_colored_input_color_is_preserved_under_raw() { let config = integration_test_utils::make_config_from_args(&[ "--file-style", "raw", "--file-decoration-style", "omit", ]); let output = integration_test_utils::run_delta( GIT_DIFF_SINGLE_HUNK_WITH_ANSI_ESCAPE_SEQUENCES, &config, ); for (i, line) in [ "diff --git a/src/align.rs b/src/align.rs", "index 8e37a9e..6ce4863 100644", "--- a/src/align.rs", "+++ b/src/align.rs", ] .iter() .enumerate() { ansi_test_utils::assert_line_has_4_bit_color_style(&output, 6 + i, line, "31", &config) } } #[test] fn test_file_decoration_style_omit() { _do_test_file_style_no_decoration(&[ "--file-style", "green", "--file-decoration-style", "omit", ]); } #[test] fn test_file_decoration_style_empty_string() { _do_test_file_style_no_decoration(&[ "--file-style", "green", "--file-decoration-style", "", ]); } fn _do_test_file_style_no_decoration(args: &[&str]) { let config = integration_test_utils::make_config_from_args(args); let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config); ansi_test_utils::assert_line_has_style(&output, 7, "src/align.rs", "green", &config); let output = strip_ansi_codes(&output); assert!(output.contains("src/align.rs")); assert!(!output.contains("src/align.rs │")); assert!(!output.contains( " src/align.rs ────────────" )); } #[test] fn test_file_style_omit() { let config = integration_test_utils::make_config_from_args(&["--file-style", "omit"]); let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config); assert!(!output.contains("src/align.rs")); } #[test] fn test_file_style_box() { _do_test_file_style_box(&[ "--file-style", "green", "--file-decoration-style", "green box", ]); } #[test] fn test_file_style_box_ul() { _do_test_file_style_box_ul(&[ "--file-style", "green", "--file-decoration-style", "green box ul", ]); } #[ignore] #[test] fn test_file_style_box_ol() { _do_test_file_style_box_ol(&[ "--file-style", "green", "--file-decoration-style", "green box ol", ]); } fn _do_test_file_style_box(args: &[&str]) { let config = integration_test_utils::make_config_from_args(args); let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config); ansi_test_utils::assert_line_has_style(&output, 7, "─────────────┐", "green", &config); ansi_test_utils::assert_line_has_style(&output, 8, "src/align.rs │", "green", &config); ansi_test_utils::assert_line_has_style(&output, 9, "─────────────┘", "green", &config); let output = strip_ansi_codes(&output); assert!(output.contains( " ─────────────┐ src/align.rs │ ─────────────┘ " )); } fn _do_test_file_style_box_ul(args: &[&str]) { let config = integration_test_utils::make_config_from_args(args); let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config); ansi_test_utils::assert_line_has_style(&output, 7, "─────────────┐", "green", &config); ansi_test_utils::assert_line_has_style(&output, 8, "src/align.rs │", "green", &config); ansi_test_utils::assert_line_has_style(&output, 9, "─────────────┴─", "green", &config); let output = strip_ansi_codes(&output); assert!(output.contains( " ─────────────┐ src/align.rs │ ─────────────┴─" )); } fn _do_test_file_style_box_ol(args: &[&str]) { let config = integration_test_utils::make_config_from_args(args); let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config); ansi_test_utils::assert_line_has_style(&output, 7, "─────────────┬─", "green", &config); ansi_test_utils::assert_line_has_style(&output, 8, "src/align.rs │", "green", &config); ansi_test_utils::assert_line_has_style(&output, 9, "─────────────┘", "green", &config); let output = strip_ansi_codes(&output); assert!(output.contains( " ─────────────┬─ src/align.rs │ ─────────────┘ " )); } #[test] fn test_file_style_box_raw() { let config = integration_test_utils::make_config_from_args(&[ "--file-style", "raw", "--file-decoration-style", "box ul", ]); let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config); ansi_test_utils::assert_line_has_no_color(&output, 8, "src/align.rs │"); assert!(output.contains( " ─────────────┐ src/align.rs │ ─────────────┴─" )); } #[test] fn test_file_style_underline() { _do_test_file_style_underline(&[ "--file-style", "magenta", "--file-decoration-style", "magenta underline", ]); } fn _do_test_file_style_underline(args: &[&str]) { let config = integration_test_utils::make_config_from_args(args); let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config); ansi_test_utils::assert_line_has_style(&output, 7, "src/align.rs", "magenta", &config); ansi_test_utils::assert_line_has_style(&output, 8, "────────────", "magenta", &config); let output = strip_ansi_codes(&output); assert!(output.contains( " src/align.rs ────────────" )); } #[test] fn test_hunk_header_style_raw_no_decoration() { let config = integration_test_utils::make_config_from_args(&[ "--hunk-header-style", "raw", "--hunk-header-decoration-style", "omit", ]); let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config); ansi_test_utils::assert_line_has_no_color( &output, 9, "@@ -71,11 +71,8 @@ impl<'a> Alignment<'a> {", ); assert!(output.contains("@@ -71,11 +71,8 @@ impl<'a> Alignment<'a> {")); } #[test] fn test_hunk_header_style_raw_no_decoration_with_line_numbers() { let config = integration_test_utils::make_config_from_args(&[ "--hunk-header-style", "raw", "--hunk-header-decoration-style", "omit", "--line-numbers", ]); let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config); assert!(output.contains( " @@ -71,11 +71,8 @@ impl<'a> Alignment<'a> {" )); assert!(!output.contains( " @@ -71,11 +71,8 @@ impl<'a> Alignment<'a> {" )); ansi_test_utils::assert_line_has_no_color( &output, 9, "@@ -71,11 +71,8 @@ impl<'a> Alignment<'a> {", ); } #[test] fn test_color_only_output_is_in_one_to_one_correspondence_with_input() { let user_suppliable_configs: &[&[&str]] = &[ &["--color-only", "--light"], &["--color-only", "--dark"], &["--color-only", "--line-numbers"], &["--color-only", "--side-by-side"], &["--color-only", "--diff-highlight"], &["--color-only", "--diff-so-fancy"], &["--color-only", "--navigate"], &["--color-only", "--hyperlinks"], &["--color-only", "--keep-plus-minus-markers"], &["--color-only", "--raw"], &["--color-only", "--syntax-theme", "Monokai Extended"], &["--color-only", "--minus-style", "syntax bold auto"], &["--color-only", "--zero-style", "red strike"], &["--color-only", "--plus-style", "red blink"], &["--color-only", "--minus-emph-style", "red dim"], &["--color-only", "--minus-non-emph-style", "red hidden"], &["--color-only", "--plus-emph-style", "red reverse"], &["--color-only", "--plus-non-emph-style", "red bold ul"], &["--color-only", "--commit-style", "red bold ul"], &[ "--color-only", "--commit-decoration-style", "bold yellow box ul", ], &["--color-only", "--file-style", "red bold ul"], &[ "--color-only", "--file-decoration-style", "bold yellow box ul", ], &["--color-only", "--hunk-header-style", "red bold ul"], &[ "--color-only", "--hunk-header-decoration-style", "bold yellow box ul", ], &[ "--color-only", "--line-numbers", "--line-numbers-minus-style", "#444444", ], &[ "--color-only", "--line-numbers", "--line-numbers-zero-style", "#444444", ], &[ "--color-only", "--line-numbers", "--line-numbers-plus-style", "#444444", ], &[ "--color-only", "--line-numbers", "--line-numbers-left-format", "{nm:>4}┊", ], &[ "--color-only", "--line-numbers", "--line-numbers-right-format", "{np:>4}│", ], &[ "--color-only", "--line-numbers", "--line-numbers-left-style", "blue", ], &[ "--color-only", "--line-numbers", "--line-numbers-right-style", "blue", ], &["--color-only", "--file-modified-label", "hogehoge"], &["--color-only", "--file-removed-label", "hogehoge"], &["--color-only", "--file-added-label", "hogehoge"], &["--color-only", "--file-renamed-label", "hogehoge"], &["--color-only", "--max-line-length", "1"], &["--color-only", "--width", "1"], &["--color-only", "--tabs", "10"], &["--color-only", "--true-color", "always"], &["--color-only", "--inspect-raw-lines", "false"], &["--color-only", "--whitespace-error-style", "22 reverse"], ]; for config in user_suppliable_configs { _do_test_output_is_in_one_to_one_correspondence_with_input(config); } } fn _do_test_output_is_in_one_to_one_correspondence_with_input(args: &[&str]) { let config = integration_test_utils::make_config_from_args(args); let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config); let output = strip_ansi_codes(&output); let input_lines: Vec<&str> = GIT_DIFF_SINGLE_HUNK.lines().collect(); let output_lines: Vec<&str> = output.lines().collect(); assert_eq!(input_lines.len(), output_lines.len()); // Although git patch options only checks the line counts of input and output, // we should check if they are identical as well to avoid unexpected decoration. if args.contains(&"--max-line-length") { return; } for (n, input_line) in input_lines.into_iter().enumerate() { // If config.line_numbers is enabled, // we should remove line_numbers decoration while checking. let output_line = if config.line_numbers && n > 11 { &output_lines[n][14..] } else { output_lines[n] }; assert_eq!(input_line, output_line); } } #[test] fn test_file_style_with_color_only_has_style() { let config = integration_test_utils::make_config_from_args(&["--color-only", "--file-style", "red"]); let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config); ansi_test_utils::assert_line_has_style(&output, 8, "--- a/src/align.rs", "red", &config); ansi_test_utils::assert_line_has_style(&output, 9, "+++ b/src/align.rs", "red", &config); let output = strip_ansi_codes(&output); assert!(output.contains( "\ --- a/src/align.rs +++ b/src/align.rs " )); } #[test] fn test_hunk_header_style_with_color_only_has_style() { let config = integration_test_utils::make_config_from_args(&[ "--color-only", "--hunk-header-style", "red", ]); let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config); ansi_test_utils::assert_line_has_style( &output, 10, "@@ -71,11 +71,8 @@ impl<'a> Alignment<'a> {", "red", &config, ); let output = strip_ansi_codes(&output); assert!(output.contains("@@ -71,11 +71,8 @@ impl<'a> Alignment<'a> {")); } #[test] fn test_hunk_header_style_with_file() { let config = integration_test_utils::make_config_from_args(&[ "--hunk-header-file-style", "yellow", "--hunk-header-style", "file line-number red", "--hunk-header-decoration-style", "box", ]); let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config); ansi_test_utils::assert_line_has_style( &output, 11, "src/align.rs:71: impl<'a> Alignment<'a> {", "yellow", &config, ); let output = strip_ansi_codes(&output); assert!(output.contains( " ──────────────────────────────────────────┐ src/align.rs:71: impl<'a> Alignment<'a> { │ ──────────────────────────────────────────┘ " )); } #[test] fn test_hunk_header_style_with_file_no_frag() { let config = integration_test_utils::make_config_from_args(&[ "--hunk-header-file-style", "yellow", "--hunk-header-style", "file line-number red", "--hunk-header-decoration-style", "box", ]); let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK_NO_FRAG, &config); ansi_test_utils::assert_line_has_style(&output, 5, "src/delta.rs:1: ", "yellow", &config); let output = strip_ansi_codes(&output); assert!(output.contains( " ────────────────┐ src/delta.rs:1: │ ────────────────┘ " )); } #[test] fn test_commit_style_with_color_only_has_style() { let config = integration_test_utils::make_config_from_args(&[ "--color-only", "--commit-style", "red", ]); let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config); ansi_test_utils::assert_line_has_style( &output, 0, "commit 94907c0f136f46dc46ffae2dc92dca9af7eb7c2e", "red", &config, ); let output = strip_ansi_codes(&output); assert!(output.contains("commit 94907c0f136f46dc46ffae2dc92dca9af7eb7c2e")); } #[test] fn test_hunk_header_omit_code_fragment() { let config = integration_test_utils::make_config_from_args(&[ "--hunk-header-style", "line-number omit-code-fragment", "--hunk-header-decoration-style", "none", ]); let output = strip_ansi_codes(&integration_test_utils::run_delta( GIT_DIFF_SINGLE_HUNK, &config, )); assert!(output.contains("\n71: \n")); } #[test] fn test_hunk_header_style_colored_input_color_is_stripped_under_normal() { let config = integration_test_utils::make_config_from_args(&[ "--hunk-header-style", "line-number normal", "--hunk-header-line-number-style", "normal", "--hunk-header-decoration-style", "omit", ]); let output = integration_test_utils::run_delta( GIT_DIFF_SINGLE_HUNK_WITH_ANSI_ESCAPE_SEQUENCES, &config, ); // An additional newline is inserted under anything other than `style=raw, // decoration-style=omit`, to better separate the hunks. Hence 9 + 1. ansi_test_utils::assert_line_has_no_color(&output, 9 + 1, "71: impl<'a> Alignment<'a> {"); } #[test] fn test_hunk_header_style_colored_input_color_is_preserved_under_raw() { let config = integration_test_utils::make_config_from_args(&[ "--hunk-header-style", "raw", "--hunk-header-decoration-style", "omit", ]); let output = integration_test_utils::run_delta( GIT_DIFF_SINGLE_HUNK_WITH_ANSI_ESCAPE_SEQUENCES, &config, ); ansi_test_utils::assert_line_has_4_bit_color_style( &output, 9, "@@ -71,11 +71,8 @@ impl<'a> Alignment<'a> {", "bold 31", &config, ); } #[test] fn test_hunk_header_decoration_style_omit() { _do_test_hunk_header_style_no_decoration(&["--hunk-header-decoration-style", "omit"]); } #[test] fn test_hunk_header_decoration_style_none() { _do_test_hunk_header_style_no_decoration(&["--hunk-header-decoration-style", "none"]); } #[test] fn test_hunk_header_decoration_style_empty_string() { _do_test_hunk_header_style_no_decoration(&["--hunk-header-decoration-style", ""]); } fn _do_test_hunk_header_style_no_decoration(args: &[&str]) { let config = integration_test_utils::make_config_from_args(args); let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config); let output = strip_ansi_codes(&output); assert!(output.contains("impl<'a> Alignment<'a> {")); assert!(!output.contains("impl<'a> Alignment<'a> { │")); assert!(!output.contains( " impl<'a> Alignment<'a> { ────────────────────────" )); } #[test] fn test_hunk_header_style_omit() { let config = integration_test_utils::make_config_from_args(&["--hunk-header-style", "omit"]); let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config); let output = strip_ansi_codes(&output); assert!(!output.contains("impl<'a> Alignment<'a> {")); } #[test] fn test_hunk_header_style_empty_string() { _do_test_hunk_header_empty_style(&["--hunk-header-style", ""]); } #[test] fn test_hunk_header_style_none() { _do_test_hunk_header_empty_style(&["--hunk-header-style", "None"]); } fn _do_test_hunk_header_empty_style(args: &[&str]) { let config = integration_test_utils::make_config_from_args(args); let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config); assert!(output.contains("impl<'a> Alignment<'a> {")); assert!(!output.contains("@@")); } #[test] fn test_hunk_header_style_box() { _do_test_hunk_header_style_box(&["--hunk-header-decoration-style", "white box"]); } #[test] fn test_hunk_header_style_box_line_number() { _do_test_hunk_header_style_box(&[ "--hunk-header-style", "line-number", "--hunk-header-decoration-style", "white box", ]); } #[test] fn test_hunk_header_style_box_file_line_number() { _do_test_hunk_header_style_box_file_line_number(&[ "--hunk-header-style", "file line-number", "--hunk-header-decoration-style", "white box", ]); } #[test] fn test_hunk_header_style_box_file() { _do_test_hunk_header_style_box_file(&[ "--hunk-header-style", "file", "--hunk-header-decoration-style", "white box", ]); } fn _do_test_hunk_header_style_box(args: &[&str]) { let config = integration_test_utils::make_config_from_args(args); let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config); ansi_test_utils::assert_line_has_style( &output, 10, "─────────────────────────────┐", "white", &config, ); ansi_test_utils::assert_line_has_style( &output, 12, "─────────────────────────────┘", "white", &config, ); let output = strip_ansi_codes(&output); assert!(output.contains( " ─────────────────────────────┐ 71: impl<'a> Alignment<'a> { │ ─────────────────────────────┘ " )); } fn _do_test_hunk_header_style_box_file(args: &[&str]) { let config = integration_test_utils::make_config_from_args(args); let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config); ansi_test_utils::assert_line_has_style( &output, 10, "───────────────────────────────────────┐", "white", &config, ); ansi_test_utils::assert_line_has_style( &output, 12, "───────────────────────────────────────┘", "white", &config, ); let output = strip_ansi_codes(&output); assert!(output.contains( " ───────────────────────────────────────┐ src/align.rs: impl<'a> Alignment<'a> { │ ───────────────────────────────────────┘ " )); } fn _do_test_hunk_header_style_box_file_line_number(args: &[&str]) { let config = integration_test_utils::make_config_from_args(args); let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config); ansi_test_utils::assert_line_has_style( &output, 10, "──────────────────────────────────────────┐", "white", &config, ); ansi_test_utils::assert_line_has_style( &output, 12, "──────────────────────────────────────────┘", "white", &config, ); let output = strip_ansi_codes(&output); assert!(output.contains( " ──────────────────────────────────────────┐ src/align.rs:71: impl<'a> Alignment<'a> { │ ──────────────────────────────────────────┘ " )); } #[test] fn test_hunk_header_style_box_raw() { let config = integration_test_utils::make_config_from_args(&[ "--hunk-header-style", "raw", "--hunk-header-decoration-style", "box", ]); let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config); ansi_test_utils::assert_line_has_no_color( &output, 11, "@@ -71,11 +71,8 @@ impl<'a> Alignment<'a> { │", ); assert!(output.contains( " ────────────────────────────────────────────┐ @@ -71,11 +71,8 @@ impl<'a> Alignment<'a> { │ ────────────────────────────────────────────┘ " )); } #[test] fn test_hunk_header_style_underline() { _do_test_hunk_header_style_underline(&[ "--hunk-header-decoration-style", "black underline", ]); } fn _do_test_hunk_header_style_underline(args: &[&str]) { let config = integration_test_utils::make_config_from_args(args); let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config); ansi_test_utils::assert_line_has_style( &output, 11, "─────────────────────────", "black", &config, ); let output = strip_ansi_codes(&output); assert!(output.contains( " 71: impl<'a> Alignment<'a> { ────────────────────────────" )); } #[test] fn test_hunk_header_style_box_with_syntax_highlighting() { // For this test we are currently forced to disable styling of the decoration, since // otherwise it will confuse assert_line_is_syntax_highlighted. let config = integration_test_utils::make_config_from_args(&[ "--hunk-header-style", "line-number syntax", "--hunk-header-decoration-style", "box", ]); let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config); ansi_test_utils::assert_line_has_no_color(&output, 10, "─────────────────────────────┐"); ansi_test_utils::assert_line_has_syntax_highlighted_substring( &output, 11, 4, "impl<'a> Alignment<'a> { ", "a.rs", State::HunkHeader( DiffType::Unified, ParsedHunkHeader::default(), "".to_owned(), "".to_owned(), ), &config, ); ansi_test_utils::assert_line_has_no_color(&output, 12, "─────────────────────────────┘"); let output = strip_ansi_codes(&output); assert!(output.contains( " ─────────────────────────────┐ 71: impl<'a> Alignment<'a> { │ ─────────────────────────────┘ " )); } #[test] fn test_removed_empty_line_highlight() { let minus_empty_line_marker_style = "bold yellow magenta ul"; _do_test_removed_empty_line_highlight(minus_empty_line_marker_style, "red reverse", true); _do_test_removed_empty_line_highlight(minus_empty_line_marker_style, "normal red", true); _do_test_removed_empty_line_highlight(minus_empty_line_marker_style, "red", false); _do_test_removed_empty_line_highlight( minus_empty_line_marker_style, "normal red reverse", false, ); } fn _do_test_removed_empty_line_highlight( empty_line_marker_style: &str, base_style: &str, base_style_has_background_color: bool, ) { _do_test_empty_line_highlight( "--minus-empty-line-marker-style", empty_line_marker_style, "--minus-style", base_style, base_style_has_background_color, DIFF_WITH_REMOVED_EMPTY_LINE, ); } #[test] fn test_added_empty_line_highlight() { let plus_empty_line_marker_style = "bold yellow red ul"; _do_test_added_empty_line_highlight(plus_empty_line_marker_style, "green reverse", true); _do_test_added_empty_line_highlight(plus_empty_line_marker_style, "normal green", true); _do_test_added_empty_line_highlight(plus_empty_line_marker_style, "green", false); _do_test_added_empty_line_highlight( plus_empty_line_marker_style, "normal green reverse", false, ); } fn _do_test_added_empty_line_highlight( empty_line_marker_style: &str, base_style: &str, base_style_has_background_color: bool, ) { _do_test_empty_line_highlight( "--plus-empty-line-marker-style", empty_line_marker_style, "--plus-style", base_style, base_style_has_background_color, DIFF_WITH_ADDED_EMPTY_LINE, ); } fn _do_test_empty_line_highlight( empty_line_marker_style_name: &str, empty_line_marker_style: &str, base_style_name: &str, base_style: &str, base_style_has_background_color: bool, example_diff: &str, ) { let config = integration_test_utils::make_config_from_args(&[ base_style_name, base_style, empty_line_marker_style_name, empty_line_marker_style, ]); let output = integration_test_utils::run_delta(example_diff, &config); let line = output.lines().nth(8).unwrap(); if base_style_has_background_color { let style = style::Style::from_str(base_style, None, None, true, None); assert_eq!( line, &style .ansi_term_style .paint(ansi::ANSI_CSI_CLEAR_TO_EOL) .to_string() ); } else { assert_eq!(line, ""); } } #[test] fn test_whitespace_error() { let whitespace_error_style = "bold yellow red ul"; let config = integration_test_utils::make_config_from_args(&[ "--whitespace-error-style", whitespace_error_style, ]); let output = integration_test_utils::run_delta(DIFF_WITH_WHITESPACE_ERROR, &config); ansi_test_utils::assert_line_has_style(&output, 8, " ", whitespace_error_style, &config); let output = integration_test_utils::run_delta(DIFF_WITH_REMOVED_WHITESPACE_ERROR, &config); ansi_test_utils::assert_line_does_not_have_style( &output, 8, " ", whitespace_error_style, &config, ); } #[test] fn test_whitespace_unrelated_edit_text_error() { let whitespace_error_style = "bold yellow red ul"; let config = integration_test_utils::make_config_from_args(&[ "--whitespace-error-style", whitespace_error_style, ]); let output = integration_test_utils::run_delta(DIFF_WITH_WHITESPACE_UNRELATED_EDIT_ERROR, &config); ansi_test_utils::assert_line_contain_substring_style( &output, 9, "some new", " ", whitespace_error_style, &config, ); } #[test] fn test_whitespace_edit_text_error() { let whitespace_error_style = "bold yellow red ul"; let config = integration_test_utils::make_config_from_args(&[ "--whitespace-error-style", whitespace_error_style, ]); let output = integration_test_utils::run_delta(DIFF_WITH_WHITESPACE_EDIT_ERROR, &config); ansi_test_utils::assert_line_contain_substring_style( &output, 9, "same ", " ", whitespace_error_style, &config, ); } #[test] fn test_whitespace_added_empty_line_error() { let whitespace_error_style = "bold yellow red ul"; let config = integration_test_utils::make_config_from_args(&[ "--whitespace-error-style", whitespace_error_style, ]); let output = integration_test_utils::run_delta(DIFF_WITH_ADDED_WHITESPACE_EMPTY_LINE_ERROR, &config); // TODO is this the first style ? ansi_test_utils::assert_line_has_style(&output, 9, " ", whitespace_error_style, &config); ansi_test_utils::assert_line_contain_substring_style( &output, 9, "", " ", whitespace_error_style, &config, ); } #[test] fn test_whitespace_after_text_error() { let whitespace_error_style = "bold yellow red ul"; let config = integration_test_utils::make_config_from_args(&[ "--whitespace-error-style", whitespace_error_style, ]); let output = integration_test_utils::run_delta(DIFF_WITH_WHITESPACE_AFTER_TEXT_ERROR, &config); ansi_test_utils::assert_line_contain_substring_style( &output, 8, "foo bar", " ", whitespace_error_style, &config, ); let output = integration_test_utils::run_delta( DIFF_WITH_REMOVED_WHITESPACE_AFTER_TEXT_ERROR, &config, ); ansi_test_utils::assert_line_does_not_contain_substring_style( &output, 8, "foo bar", whitespace_error_style, &config, ); } #[test] fn test_whitespace_complex_error() { let whitespace_error_style = "bold yellow red ul"; let config = integration_test_utils::make_config_from_args(&[ "--whitespace-error-style", whitespace_error_style, ]); let output = integration_test_utils::run_delta(DIFF_WITH_WHITESPACE_COMPLEX_ERROR, &config); // `minus` line should not display whitespace error ansi_test_utils::assert_line_does_not_have_style( &output, 8, " ", whitespace_error_style, &config, ); ansi_test_utils::assert_line_does_not_have_style( &output, 9, " ", whitespace_error_style, &config, ); ansi_test_utils::assert_line_does_not_contain_substring_style( &output, 10, " foo0 ", whitespace_error_style, &config, ); ansi_test_utils::assert_line_does_not_contain_substring_style( &output, 11, " foo1 ", whitespace_error_style, &config, ); ansi_test_utils::assert_line_does_not_contain_substring_style( &output, 12, " bar ", whitespace_error_style, &config, ); // `plus` line should display whitespace error ansi_test_utils::assert_line_contain_substring_style( &output, 13, " ", " ", whitespace_error_style, &config, ); ansi_test_utils::assert_line_contain_substring_style( &output, 14, " ", " ", whitespace_error_style, &config, ); ansi_test_utils::assert_line_contain_substring_style( &output, 15, " foo0", " ", whitespace_error_style, &config, ); ansi_test_utils::assert_line_contain_substring_style( &output, 16, " foo1", " ", whitespace_error_style, &config, ); ansi_test_utils::assert_line_contain_substring_style( &output, 17, " bAr", " ", whitespace_error_style, &config, ); } #[test] fn test_added_empty_line_is_not_whitespace_error() { let plus_style = "bold yellow red ul"; let config = integration_test_utils::make_config_from_args(&[ "--light", "--keep-plus-minus-markers", "--plus-style", plus_style, ]); let output = integration_test_utils::run_delta(DIFF_WITH_ADDED_EMPTY_LINE, &config); ansi_test_utils::assert_line_has_style(&output, 8, "", plus_style, &config) } #[test] fn test_single_character_line_is_not_whitespace_error() { let plus_style = "bold yellow red ul"; let config = integration_test_utils::make_config_from_args(&[ "--light", "--keep-plus-minus-markers", "--plus-style", plus_style, ]); let output = integration_test_utils::run_delta(DIFF_WITH_SINGLE_CHARACTER_LINE, &config); ansi_test_utils::assert_line_has_style(&output, 14, "+}", plus_style, &config) } #[test] fn test_color_only_mode() { let config = integration_test_utils::make_config_from_args(&["--color-only"]); let output = integration_test_utils::run_delta(GIT_DIFF_SINGLE_HUNK, &config); ansi_test_utils::assert_line_has_syntax_highlighted_substring( &output, 12, 1, " for (i, x_i) in self.x.iter().enumerate() {", "align.rs", State::HunkZero(DiffType::Unified, None), &config, ); } #[test] fn test_git_diff_is_unchanged_under_color_only() { let config = integration_test_utils::make_config_from_args(&["--color-only"]); let input = DIFF_WITH_TWO_ADDED_LINES; let output = integration_test_utils::run_delta(input, &config); let output = strip_ansi_codes(&output); assert_eq!(output, input); } #[test] #[allow(non_snake_case)] fn test_git_diff_U0_is_unchanged_under_color_only() { let config = integration_test_utils::make_config_from_args(&["--color-only"]); let input = DIFF_WITH_TWO_ADDED_LINES_CREATED_BY_GIT_DIFF_U0; let output = integration_test_utils::run_delta(input, &config); let output = strip_ansi_codes(&output); assert_eq!(output, input); } #[test] fn test_git_diff_binary_is_unchanged_under_color_only() { let config = integration_test_utils::make_config_from_args(&["--color-only"]); let input = BINARY_FILES_DIFFER_BETWEEN_OTHER; let output = integration_test_utils::run_delta(input, &config); let output = strip_ansi_codes(&output); assert_eq!(output, input); } // See https://github.com/dandavison/delta/issues/371#issuecomment-720173435 #[test] fn test_keep_plus_minus_markers_under_inspect_raw_lines() { let config = integration_test_utils::make_config_from_args(&["--keep-plus-minus-markers"]); assert_eq!(config.inspect_raw_lines, InspectRawLines::True); let output = integration_test_utils::run_delta( GIT_DIFF_UNDER_COLOR_MOVED_DIMMED_ZEBRA_WITH_ANSI_ESCAPE_SEQUENCES, &config, ); let output = strip_ansi_codes(&output); assert!(output.contains( r#" - "stddev": 0.004157057519168492, "# )); } #[test] fn test_file_mode_change_with_rename() { let config = integration_test_utils::make_config_from_args(&["--right-arrow=->"]); let output = integration_test_utils::run_delta(GIT_DIFF_FILE_MODE_CHANGE_WITH_RENAME, &config); let output = strip_ansi_codes(&output); assert!(output.contains("renamed: old-longer-name -> shorter-name (mode +x)")); } #[test] fn test_file_mode_change_gain_executable_bit() { DeltaTest::with_args(&[]) .with_input(GIT_DIFF_FILE_MODE_CHANGE_GAIN_EXECUTABLE_BIT) .expect_contains("src/delta.rs (mode +x)"); } #[test] fn test_file_mode_change_lose_executable_bit() { DeltaTest::with_args(&[]) .with_input(GIT_DIFF_FILE_MODE_CHANGE_LOSE_EXECUTABLE_BIT) .expect_contains("src/delta.rs (mode -x)"); } #[test] fn test_file_mode_change_unexpected_bits() { DeltaTest::with_args(&["--navigate", "--right-arrow=->"]) .with_input(GIT_DIFF_FILE_MODE_CHANGE_UNEXPECTED_BITS) .expect_contains("Δ src/delta.rs (mode 100700 -> 100644)"); } #[test] fn test_file_deleted_without_preimage() { DeltaTest::with_args(&[]) .with_input(GIT_DIFF_FILE_DELETED_WITHOUT_PREIMAGE) .expect_contains("removed: foo.bar"); } #[test] fn test_files_deleted_without_preimage() { DeltaTest::with_args(&[]) .with_input(GIT_DIFF_FILES_DELETED_WITHOUT_PREIMAGE) .expect_contains("removed: foo") .expect_contains("removed: bar"); } #[test] fn test_file_mode_change_with_diff() { DeltaTest::with_args(&["--navigate", "--keep-plus-minus-markers"]) .with_input(GIT_DIFF_FILE_MODE_CHANGE_WITH_DIFF) .expect_contains("Δ src/script (mode +x)") .expect_after_skip( 5, " ─────┐ • 1: │ ─────┘ -#!/bin/sh +#!/bin/bash", ); } #[test] fn test_hyperlinks_commit_link_format() { // If commit-style is not set then the commit line is handled in raw // mode, in which case we only format hyperlinks if output is a tty; // this causes the test to fail on GitHub Actions, but pass locally // if output is left going to the screen. DeltaTest::with_args(&[ "--commit-style", "blue", "--hyperlinks", "--hyperlinks-commit-link-format", "https://invent.kde.org/utilities/konsole/-/commit/{commit}", ]) .with_input(GIT_DIFF_SINGLE_HUNK) .expect_raw_contains( r"https://invent.kde.org/utilities/konsole/-/commit/94907c0f136f46dc46ffae2dc92dca9af7eb7c2e" ); } #[test] fn test_filenames_with_spaces() { DeltaTest::with_args(&[]) .with_input(GIT_DIFF_NO_INDEX_FILENAMES_WITH_SPACES) .expect_contains("a b ⟶ c d\n"); } #[test] fn test_file_removal_in_log_output() { DeltaTest::with_args(&[]) .with_input(GIT_LOG_FILE_REMOVAL_IN_FIRST_COMMIT) .expect_after_header("#partial\n\nremoved: a"); } #[test] fn test_lines_with_syntax_width_limit() { let result = DeltaTest::with_args(&[ "--max-line-length=42", "--max-syntax-highlighting-length=18", ]) .explain_ansi() .with_input(GIT_DIFF_SINGLE_HUNK); assert_snapshot!(result.output, @r###" (normal)commit 94907c0f136f46dc46ffae2dc92dca9af7(reverse normal)→(normal) Author: Dan Davison (149)Alignmen(normal)t<'a> { (blue)│(normal) (blue)─────────────────────────────(blue)┘(normal) (231) (203)for(231) (i, x_(normal)i) in self.x.iter().en→ (231) (203)for(231) (j(normal), y_j) in self.y.iter(→ (normal 52) let (left, diag, up) =(normal 124) ((normal) (normal 52) self.index(i, j + 1(normal 124)),(normal) (normal 52) self.index(i, j),(normal) (normal 52) self.index(i + 1, j),(normal) (normal 52) );(normal) (231 22) le(normal 22)t (left, diag, up) =(normal) (231 22) (normal 22) (normal 28)((normal 22)self.index(i, j + 1(normal 28)→(normal) (231) le(normal)t candidates = [ (231) (normal) Cell { (231) (normal) parent: left, "###); } #[test] fn test_lines_with_syntax_width_limit_wrapping() { let result = DeltaTest::with_args(&[ "--side-by-side", "--width=55", "--wrap-max-lines=1", "--max-line-length=10", // this gets ignored! "--max-syntax-highlighting-length=22", ]) .explain_ansi() .with_input(GIT_DIFF_SINGLE_HUNK); // eprintln!("{}", result.raw_output); assert_snapshot!(result.output, @r###" (normal)commit 94907c0f136f46dc46ffae2dc92dca9af7eb7c2e Author: Dan Davison Date: Thu May 14 11:13:17 2020 -0400 rustfmt (blue)src/align.rs(normal) (blue)───────────────────────────────────────────────────────(normal) (blue)─────────────────────────────(blue)┐(normal) (blue)71(normal):(231) (81)impl(231)<(203)'a(231)> (149)Alignment(231)<(203)'a(normal)> { (blue)│(normal) (blue)─────────────────────────────(blue)┘(normal) (blue)│(238) 71 (blue)│(231) (203)for(231) (i, x_i)(blue)↵(blue) │(238) 71 (blue)│(231) (203)for(231) (i, x_i)(blue)↵(normal) (blue)│(238) (blue)│(231) i(normal)n self.x.iter().en(reverse normal)→(blue) │(238) (blue)│(231) i(normal)n self.x.iter().en(reverse normal)→(normal) (blue)│(238) 72 (blue)│(231) (203)for(231) (j, (blue)↵(blue) │(238) 72 (blue)│(231) (203)for(231) (j, (blue)↵(normal) (blue)│(238) (blue)│(231)y_(normal)j) in self.y.iter((reverse normal)→(blue) │(238) (blue)│(231)y_(normal)j) in self.y.iter((reverse normal)→(normal) (blue)│(88) 73 (blue)│(231 52) (81)let(231) (blue)↵(blue) │(28) 73 (blue)│(231 22) (81)let(231) (blue)↵(normal) (blue)│(88) (blue)│(231 52)(l(normal 52)eft, diag, up) =(normal 124) ((normal 52) (blue) │(28) (blue)│(231 22)(l(normal 22)eft, diag, up) =(normal) (blue)│(88) 74 (blue)│(231 52) (blue)↵(blue) │(28) 74 (blue)│(231 22) (blue)↵(normal) (blue)│(88) (blue)│(231 52)se(normal 52)lf.index(i, j + 1),(blue) │(28) (blue)│(231 28)((normal 22)s(normal 22)elf.index(i, j + 1(reverse normal)→(normal) (blue)│(88) 75 (blue)│(231 52) (blue)↵(blue) │(28) (blue)│(normal) (blue)│(88) (blue)│(231 52)se(normal 52)lf.index(i, j),(normal 52) (blue) │(28) (blue)│(normal) (blue)│(88) 76 (blue)│(231 52) (blue)↵(blue) │(28) (blue)│(normal) (blue)│(88) (blue)│(231 52)se(normal 52)lf.index(i + 1, j),(blue) │(28) (blue)│(normal) (blue)│(88) 77 (blue)│(231 52) );(normal 52) (blue) │(28) (blue)│(normal) (blue)│(238) 78 (blue)│(231) (81)let(231) (blue)↵(blue) │(238) 75 (blue)│(231) (81)let(231) (blue)↵(normal) (blue)│(238) (blue)│(231)ca(normal)ndidates = [ (blue) │(238) (blue)│(231)ca(normal)ndidates = [ (blue)│(238) 79 (blue)│(231) (blue)↵(blue) │(238) 76 (blue)│(231) (blue)↵(normal) (blue)│(238) (blue)│(231)Ce(normal)ll { (blue) │(238) (blue)│(231)Ce(normal)ll { (blue)│(238) 80 (blue)│(231) (blue)↵(blue) │(238) 77 (blue)│(231) (blue)↵(normal) (blue)│(238) (blue)│(231) (normal) parent: left, (blue) │(238) (blue)│(231) (normal) parent: left, "###); } #[test] fn test_lines_with_syntax_width_unicode() { let result = DeltaTest::with_args(&["--max-syntax-highlighting-length=11"]) .explain_ansi() .with_input(GIT_DIFF_ALL_UNICODE_W_FULLWIDTH); assert_snapshot!(result.output, @r###" (normal) (blue)src/a(normal) (blue)───────────────────────────────────────────(normal) (blue)───(blue)┐(normal) (blue)1(normal): (blue)│(normal) (blue)───(blue)┘(normal) (231)一æäöø€ÆÄÖ(normal)〇Øß一 (231)一æäöø€ÆÄÖ(normal)〇Øß一 (normal 52)二æäöø(normal 124)¢(normal 52)ÆÄÖ〇Øß二(normal) (normal 52)二æäöø(normal 124)¢(normal 52)ÆÄÖ〇Øß二(normal) (231 22)二æäöø(normal 28)€(normal 22)ÆÄÖ(normal 22)〇Øß二(normal) (231 22)二æäöø(normal 28)€(normal 22)ÆÄÖ(normal 22)〇Øß二(normal) (231)三æäöø€ÆÄÖ(normal)〇Øß三 (231)三æäöø€ÆÄÖ(normal)〇Øß三 (231)¶(normal) "###); let result = DeltaTest::with_args(&[ "--max-syntax-highlighting-length=10", "--max-line-length=16", ]) .explain_ansi() .with_input(GIT_DIFF_ALL_UNICODE_W_FULLWIDTH); // eprintln!("{}", result.raw_output); assert_snapshot!(result.output, @r###" (normal) (blue)src/a(normal) (blue)───────────────────────────────────────────(normal) (blue)───(blue)┐(normal) (blue)1(normal): (blue)│(normal) (blue)───(blue)┘(normal) (231)一æäöø€ÆÄÖ(normal)〇Øß→ (231)一æäöø€ÆÄÖ(normal)〇Øß→ (normal 52)二æäöø(normal 124)¢(normal 52)ÆÄÖ〇Øß→(normal) (normal 52)二æäöø(normal 124)¢(normal 52)ÆÄÖ〇Øß→(normal) (231 22)二æäöø(normal 28)€(normal 22)ÆÄÖ(normal 22)〇Øß→(normal) (231 22)二æäöø(normal 28)€(normal 22)ÆÄÖ(normal 22)〇Øß→(normal) (231)三æäöø€ÆÄÖ(normal)〇Øß→ (231)三æäöø€ÆÄÖ(normal)〇Øß→ (231)¶(normal) "###); } #[test] fn test_color_only_diff_filter_zero_style_bg() { let result = DeltaTest::with_args(&["--color-only", r##"--zero-style='syntax "#1d1f21" dim'"##]) .set_config(|c| c.available_terminal_width = 80) .explain_ansi() .with_input(GIT_DIFF_OF_WIDTH_81); assert_snapshot!(result.output, @r###" (normal) --- a.rs +++ b.rs @@ -1,3 +1,3 @@ (normal 22)+(231) (203)if(231) (81)let(231) (149)Ok(231)(foo) { (242)// Works fine with plus hunk lines which are longer 81(normal) (normal 52)-// and it works fine with minus lines, however 81(normal) (dim normal 234) (242)// styled(!) zero lines can only be as long as the width fallback of 80(normal) (dim normal 234) (231)panic!(); (242)/* if no tty can be queried, and delta crashes on longer lines: 81(normal) "###); } const GIT_DIFF_OF_WIDTH_81: &str = r#" --- a.rs +++ b.rs @@ -1,3 +1,3 @@ + if let Ok(foo) { // Works fine with plus hunk lines which are longer 81 -// and it works fine with minus lines, however 81 // styled(!) zero lines can only be as long as the width fallback of 80 panic!(); /* if no tty can be queried, and delta crashes on longer lines: 81 "#; const GIT_DIFF_SINGLE_HUNK: &str = "\ commit 94907c0f136f46dc46ffae2dc92dca9af7eb7c2e Author: Dan Davison Date: Thu May 14 11:13:17 2020 -0400 rustfmt diff --git a/src/align.rs b/src/align.rs index 8e37a9e..6ce4863 100644 --- a/src/align.rs +++ b/src/align.rs @@ -71,11 +71,8 @@ impl<'a> Alignment<'a> { for (i, x_i) in self.x.iter().enumerate() { for (j, y_j) in self.y.iter().enumerate() { - let (left, diag, up) = ( - self.index(i, j + 1), - self.index(i, j), - self.index(i + 1, j), - ); + let (left, diag, up) = + (self.index(i, j + 1), self.index(i, j), self.index(i + 1, j)); let candidates = [ Cell { parent: left, "; const GIT_DIFF_SINGLE_HUNK_NO_FRAG: &str = "\ diff --git a/src/delta.rs b/src/delta.rs index e401e269..e5304e01 100644 --- a/src/delta.rs +++ b/src/delta.rs @@ -1,4 +1,3 @@ -use std::borrow::Cow; use std::fmt::Write as FmtWrite; use std::io::BufRead; use std::io::Write; "; const GIT_DIFF_SINGLE_HUNK_WITH_ANSI_ESCAPE_SEQUENCES: &str = "\ commit 94907c0f136f46dc46ffae2dc92dca9af7eb7c2e Author: Dan Davison Date: Thu May 14 11:13:17 2020 -0400 rustfmt diff --git a/src/align.rs b/src/align.rs index 8e37a9e..6ce4863 100644 --- a/src/align.rs +++ b/src/align.rs @@ -71,11 +71,8 @@ impl<'a> Alignment<'a> {  for (i, x_i) in self.x.iter().enumerate() { for (j, y_j) in self.y.iter().enumerate() { - let (left, diag, up) = ( - self.index(i, j + 1), - self.index(i, j), - self.index(i + 1, j), - ); + let (left, diag, up) = + (self.index(i, j + 1), self.index(i, j), self.index(i + 1, j)); let candidates = [ Cell { parent: left, diff --git a/src/bat/mod.rs b/src/bat/mod.rs index 362ba77..7812e7c 100644 --- a/src/bat/mod.rs +++ b/src/bat/mod.rs @@ -1,5 +1,5 @@ pub mod assets; pub mod dirs; +mod less; pub mod output; pub mod terminal; -mod less; diff --git a/src/bat/output.rs b/src/bat/output.rs index d23f5e8..e4ed702 100644 --- a/src/bat/output.rs +++ b/src/bat/output.rs @@ -8,8 +8,8 @@ use std::process::{Child, Command, Stdio};  use shell_words;  -use crate::env; use super::less::retrieve_less_version; +use crate::env;  #[derive(Debug, Clone, Copy, PartialEq)] #[allow(dead_code)] "; const GIT_DIFF_SINGLE_HUNK_WITH_SEQUENCE_OF_CR_ESCAPE_SEQUENCES_LF: &str = "\ diff --git a/src/main.rs b/src/main.rs index f346a8c..e443b63 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,4 @@ -deleted line\r -\r fn main() {\r println!(\"existing line\");\r + println!(\"added line\");\r }\r "; const DIFF_IN_DIFF: &str = "\ diff --git a/0001-Init.patch b/0001-Init.patch deleted file mode 100644 index 5e35a67..0000000 --- a/0001-Init.patch +++ /dev/null @@ -1,22 +0,0 @@ -From d3a8fe3e62be67484729c19e9d8db071f8b1d60c Mon Sep 17 00:00:00 2001 -From: Maximilian Bosch -Date: Sat, 28 Dec 2019 15:51:48 +0100 -Subject: [PATCH] Init - ---- - README.md | 3 +++ - 1 file changed, 3 insertions(+) - create mode 100644 README.md - -diff --git a/README.md b/README.md -new file mode 100644 -index 0000000..2e6ca05 ---- /dev/null -+++ b/README.md -@@ -0,0 +1,3 @@ -+# Test -+ -+abc --- -2.23.1 - diff --git a/README.md b/README.md index 2e6ca05..8ae0569 100644 --- a/README.md +++ b/README.md @@ -1,3 +1 @@ # Test - -abc "; const ADDED_FILE_INPUT: &str = "\ commit d28dc1ac57e53432567ec5bf19ad49ff90f0f7a5 Author: Dan Davison Date: Thu Jul 11 10:41:11 2019 -0400 . diff --git a/a.py b/a.py new file mode 100644 index 0000000..8c55b7d --- /dev/null +++ b/a.py @@ -0,0 +1,3 @@ +# hello +class X: + pass"; const ADDED_EMPTY_FILE: &str = " commit c0a18433cb6e0ca8f796bfae9e31d95b06b91597 (HEAD -> master) Author: Dan Davison Date: Sun Apr 26 16:32:58 2020 -0400 Initial commit diff --git a/file b/file new file mode 100644 index 0000000..e69de29 "; const ADDED_FILES_DIRECTORY_PATH_CONTAINING_SPACE: &str = " commit 654e180c8d5329904d584c44b661149f68bd2911 (HEAD -> master) Author: Dan Davison Date: Sun Apr 26 16:30:58 2020 -0400 Initial commit diff --git a/nospace/file2 b/nospace/file2 new file mode 100644 index 0000000..af1b8ae --- /dev/null +++ b/nospace/file2 @@ -0,0 +1 @@ +file2 contents diff --git a/with space/file1 b/with space/file1 new file mode 100644 index 0000000..84d55c5 --- /dev/null +++ b/with space/file1 @@ -0,0 +1 @@ +file1 contents "; const MODIFIED_BASH_AND_CSHARP_FILES: &str = "\ diff --git a/a b/a index 8c4ae06..0a37de7 100644 --- a/a +++ b/a @@ -9,7 +9,7 @@ foobar() dst=$(winpath $2) # List the directory. - ls -l $src + ls -la $src echo $src '->' $dst rsync -avu --delete $src/ $dst diff --git a/b.cs b/b.cs index 2e73468..8d8b89d 100644 --- a/b.cs +++ b/b.cs @@ -6,7 +6,7 @@ class Program { static void Main(string[] args) { - int message = 123; + int message = 456; Console.WriteLine(message); } "; const MODIFIED_DOCKER_AND_RS_FILES: &str = "\ diff --git a/Dockerfile b/Dockerfile index 0123456..1234567 100644 --- a/Dockerfile +++ b/Dockerfile @@ -0,0 +2 @@ +FROM foo +COPY bar baz diff --git a/rs b/rs index 0123456..1234567 100644 --- a/rs +++ b/rs @@ -0,0 +2 @@ +fn foobar() -> i8 { + 8 +} "; const RENAMED_FILE_INPUT: &str = "\ commit 1281650789680f1009dfff2497d5ccfbe7b96526 Author: Dan Davison Date: Wed Jul 17 20:40:23 2019 -0400 rename diff --git a/a.py b/b.py similarity index 100% rename from a.py rename to b.py "; const RENAMED_FILE_WITH_CHANGES_INPUT: &str = "\ commit 5a6dd572797813525199c32e26471e88732cae1f Author: Waldir Pimenta Date: Sat Jul 11 19:14:43 2020 +0100 Rename font-dejavusansmono-nerd-font→font-dejavu-sans-mono-nerd-font This makes the filename more readable, and is consistent with `font-dejavu-sans-mono-for-powerline`. diff --git a/Casks/font-dejavusansmono-nerd-font.rb b/Casks/font-dejavu-sans-mono-nerd-font.rb similarity index 95% rename from Casks/font-dejavusansmono-nerd-font.rb rename to Casks/font-dejavu-sans-mono-nerd-font.rb index 2c8b440f..d1c1b0f3 100644 --- a/Casks/font-dejavusansmono-nerd-font.rb +++ b/Casks/font-dejavu-sans-mono-nerd-font.rb @@ -1,4 +1,4 @@ -cask 'font-dejavusansmono-nerd-font' do +cask 'font-dejavu-sans-mono-nerd-font' do version '2.1.0' sha256 '3fbcc4904c88f68d24c8b479784a1aba37f2d78b1162d21f6fc85a58ffcc0e0f' "; const DIFF_UNIFIED_TWO_FILES: &str = "\ --- one.rs 2019-11-20 06:16:08.000000000 +0100 +++ src/two.rs 2019-11-18 18:41:16.000000000 +0100 @@ -5,3 +5,3 @@ println!(\"Hello world\"); -println!(\"Hello rust\"); +println!(\"Hello ruster\"); @@ -43,6 +43,6 @@ // Some more changes -Change one Unchanged +Change two Unchanged -Change three +Change four Unchanged "; const DIFF_UNIFIED_TWO_DIRECTORIES: &str = "\ diff -u a/different b/different --- a/different 2019-11-20 06:47:56.000000000 +0100 +++ b/different 2019-11-20 06:47:56.000000000 +0100 @@ -1,3 +1,3 @@ A simple file for testing the diff command in unified mode -This is different from b +This is different from a Only in a/: just_a Only in b/: just_b --- a/more_difference 2019-11-20 06:47:56.000000000 +0100 +++ b/more_difference 2019-11-20 06:47:56.000000000 +0100 @@ -1,3 +1,3 @@ Another different file with a name that start with 'm' making it come after the 'Only in' -This is different from b +This is different from a "; const DIFF_UNIFIED_CONCATENATED: &str = "\ --- 1/x 2022-03-06 11:16:06.313403500 -0800 +++ 2/x 2022-03-06 11:18:14.083403500 -0800 @@ -1,5 +1,5 @@ This -is +IS a few -lines. +LINES. --- 1/y 2022-03-06 11:16:44.483403500 -0800 +++ 2/y 2022-03-06 11:16:55.213403500 -0800 @@ -1,4 +1,4 @@ This is -another +ANOTHER test. "; const NOT_A_DIFF_OUTPUT: &str = "\ Hello world This is a regular file that contains: --- some/file/here 06:47:56.000000000 +0100 +++ some/file/there 06:47:56.000000000 +0100 Some text here -Some text with a minus +Some text with a plus "; const SUBMODULE_DIRTY: &str = "\ diff --git a/some_submodule b/some_submodule index ca030fd1a0..803be42ca4 160000 --- a/some_submodule +++ b/some_submodule @@ -1 +1 @@ -Subproject commit ca030fd1a02225a6fc1a834c480276d9c97a8c6f +Subproject commit 803be42ca46af0fbc65b54a9abfb499389516939-dirty "; // See etc/examples/662-submodules // diff.submodule = log const SUBMODULE_DIFF_LOG: &str = "\ commit ccb444baa861fdcb14d411b471a74614ed28776d Author: Dan Davison Date: Sat Aug 21 18:56:34 2021 -0700 Update all submodules Submodule submoduleA f4f55af..310b551 (rewind): < Submodule A extra change 2 < Submodule A extra change 1 < Submodule A initial commit 4 < Submodule A initial commit 3 Submodule submoduleB 0ffa700..0c8b00d: > Submodule B stage change 3 > Submodule B stage change 2 > Submodule B stage change 1 Submodule submoduleC 9f3b744...e04f848: > Submodule C stage change 3 > Submodule C stage change 2 < Submodule C extra change 2 > Submodule C stage change 1 < Submodule C extra change 1 "; const SUBMODULE_DIFF_LOG_EXPECTED_OUTPUT: &str = "\ commit ccb444baa861fdcb14d411b471a74614ed28776d Author: Dan Davison Date: Sat Aug 21 18:56:34 2021 -0700 Update all submodules Submodule submoduleA f4f55af..310b551 (rewind): ───────────────────────────────────────────────── < Submodule A extra change 2 < Submodule A extra change 1 < Submodule A initial commit 4 < Submodule A initial commit 3 Submodule submoduleB 0ffa700..0c8b00d: ───────────────────────────────────────────────── > Submodule B stage change 3 > Submodule B stage change 2 > Submodule B stage change 1 Submodule submoduleC 9f3b744...e04f848: ───────────────────────────────────────────────── > Submodule C stage change 3 > Submodule C stage change 2 < Submodule C extra change 2 > Submodule C stage change 1 < Submodule C extra change 1 "; const SUBMODULE_CONTAINS_UNTRACKED_CONTENT_INPUT: &str = "\ --- a +++ b @@ -2,3 +2,4 @@ x y z -a +b z y x Submodule x/y/z contains untracked content "; const TRIPLE_DASH_AT_BEGINNING_OF_LINE_IN_CODE: &str = "\ commit d481eaa8a249c6daecb05a97e8af1b926b0c02be Author: FirstName LastName Date: Thu Feb 6 14:02:49 2020 -0500 Reorganize diff --git a/src/Category/Coproduct.hs b/src/Category/Coproduct.hs deleted file mode 100644 index ba28bfd..0000000 --- a/src/Category/Coproduct.hs +++ /dev/null @@ -1,18 +0,0 @@ -{-# LANGUAGE InstanceSigs #-} -module Category.Coproduct where - -import Prelude hiding ((.), id) - -import Control.Category - -import Category.Hacks - --- data (p ∨ q) (a :: (k, k)) (b :: (k, k)) where --- (:<:) :: p a b -> (∨) p q '(a, c) '(b, d) --- (:>:) :: q c d -> (∨) p q '(a, c) '(b, d) --- --- instance (Category p, Category q) => Category (p ∧ q) where --- (p1 :×: q1) . (p2 :×: q2) = (p1 . p2) :×: (q1 . q2) --- --- id :: forall a. (p ∧ q) a a --- id | IsTup <- isTup @a = id :×: id "; const BINARY_FILES_DIFFER: &str = " commit 7d58b736b09788d65392cef1bf3dcc647165f7e7 (HEAD -> main) Author: Sondeyy Date: Sat Aug 5 16:22:38 2023 +0200 modified bin file diff --git a/foo b/foo index c9bbb35..5fc172d 100644 Binary files a/foo and b/foo differ "; const BINARY_FILE_ADDED: &str = " commit 7d58b736b09788d65392cef1bf3dcc647165f7e7 (HEAD -> main) Author: Sondeyy Date: Sat Aug 5 16:22:38 2023 +0200 added binary file diff --git a/foo b/foo new file mode 100644 index c9bbb35..5fc172d 100644 Binary files /dev/null and b/foo differ "; const BINARY_FILE_REMOVED: &str = " commit 7d58b736b09788d65392cef1bf3dcc647165f7e7 (HEAD -> main) Author: Sondeyy Date: Sat Aug 5 16:22:38 2023 +0200 removed binary file diff --git a/foo b/foo deleted file mode 100644 index c9bbb35..5fc172d 100644 Binary files a/foo and /dev/null differ "; const BINARY_FILES_DIFFER_AFTER_OTHER: &str = " diff --git a/foo b/bar similarity index 100% rename from foo rename to bar diff --git a/qux b/qux index 00de669..d47cd84 100644 Binary files a/qux and b/qux differ "; const BINARY_FILES_DIFFER_BETWEEN_OTHER: &str = "\ diff --git a/foo b/foo index 7b57bd29ea8a..4d3b8c11a4a2 100644 --- a/foo +++ b/foo @@ -1 +1 @@ -abc +def diff --git a/qux b/qux index 00de669..d47cd84 100644 Binary files a/qux and b/qux differ diff --git a/bar b/bar index 7b57bd29ea8a..4d3b8c11a4a2 100644 --- a/bar +++ b/bar @@ -1 +1 @@ -123 +456 "; const DIFF_NO_INDEX_BINARY_FILES_DIFFER: &str = "\ diff --git foo bar sub dir/foo bar baz index 329fbf5..481817c 100644 Binary files foo bar and sub dir/foo bar baz differ "; const GIT_DIFF_WITH_COPIED_FILE: &str = " commit f600ed5ced4d98295ffa97571ed240cd86c34ac6 (HEAD -> master) Author: Dan Davison Date: Fri Nov 20 20:18:30 2020 -0500 copy diff --git a/first_file b/copied_file similarity index 100% copy from first_file copy to copied_file "; // git --no-pager show -p --cc --format= --numstat --stat // #121 const DIFF_WITH_UNRECOGNIZED_PRECEDING_MATERIAL_1: &str = " 1 5 src/delta.rs src/delta.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/delta.rs b/src/delta.rs index da10d2b..39cff42 100644 --- a/src/delta.rs +++ b/src/delta.rs @@ -67,11 +67,6 @@ where let source = detect_source(&mut lines_peekable); for raw_line in lines_peekable { - if source == Source::Unknown { - writeln!(painter.writer, \"{}\", raw_line)?; - continue; - } - let line = strip_ansi_codes(&raw_line).to_string(); if line.starts_with(\"commit \") { painter.paint_buffered_lines(); @@ -674,6 +669,7 @@ mod tests { } #[test] + #[ignore] // Ideally, delta would make this test pass. fn test_delta_ignores_non_diff_input() { let options = get_command_line_options(); let output = strip_ansi_codes(&run_delta(NOT_A_DIFF_OUTPUT, &options)).to_string(); "; // git stash show --stat --patch // #100 const DIFF_WITH_UNRECOGNIZED_PRECEDING_MATERIAL_2: &str = " src/cli.rs | 2 ++ src/config.rs | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/cli.rs b/src/cli.rs index bd5f1d5..55ba315 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -286,6 +286,8 @@ pub fn process_command_line_arguments<'a>( } }; + println!(\"true_color is {}\", true_color); + config::get_config( opt, &assets.syntax_set, diff --git a/src/config.rs b/src/config.rs index cba6064..ba1a4de 100644 --- a/src/config.rs +++ b/src/config.rs @@ -181,7 +181,9 @@ fn color_from_rgb_or_ansi_code(s: &str) -> Color { process::exit(1); }; if s.starts_with(\"#\") { - Color::from_str(s).unwrap_or_else(|_| die()) + let col = Color::from_str(s).unwrap_or_else(|_| die()); + println!(\"{} => {} {} {} {}\", s, col.r, col.g, col.b, col.a); + col } else { s.parse::() .ok() "; const DIFF_WITH_MERGE_CONFLICT: &str = r#" diff --cc Makefile index 759070d,3daf9eb..0000000 --- a/Makefile +++ b/Makefile @@@ -4,13 -4,16 +4,37 @@@ build lint: cargo clippy ++<<<<<<< Updated upstream +test: unit-test end-to-end-test + +unit-test: + cargo test + +end-to-end-test: build + bash -c "diff -u <(git log -p) <(git log -p | target/release/delta --color-only | perl -pe 's/\e\[[0-9;]*m//g')" ++||||||| constructed merge base ++test: ++ cargo test ++ bash -c "diff -u <(git log -p) \ ++ <(git log -p | delta --width variable \ ++ --tabs 0 \ ++ --retain-plus-minus-markers \ ++ --commit-style plain \ ++ --file-style plain \ ++ --hunk-style plain \ ++ | ansifilter)" ++======= + test: + cargo test --release + bash -c "diff -u <(git log -p) \ + <(git log -p | target/release/delta --width variable \ + --tabs 0 \ + --retain-plus-minus-markers \ + --commit-style plain \ + --file-style plain \ + --hunk-style plain \ + | ansifilter)" > /dev/null ++>>>>>>> Stashed changes release: @make -f release.Makefile release "#; // A bug appeared with the change to the tokenization regex in // b5d87819a1f76de9ef8f16f1bfb413468af50b62. The bug was triggered by this diff. const DIFF_EXHIBITING_TRUNCATION_BUG: &str = r#" diff --git a/a.rs b/b.rs index cba6064..ba1a4de 100644 --- a/a.rs +++ b/b.rs @@ -1,1 +1,1 @@ - Co + let col = Co "#; // A bug appeared with the change to the state machine parser in // 5adc445ec38142046fc4cc4518e7019fe54f2e35. The bug was triggered by this diff. The bug was // present prior to that commit. const DIFF_EXHIBITING_STATE_MACHINE_PARSER_BUG: &str = r" diff --git a/src/delta.rs b/src/delta.rs index 20aef29..20416c0 100644 --- a/src/delta.rs +++ b/src/delta.rs @@ -994,0 +1014,2 @@ index cba6064..ba1a4de 100644 +++ a +++ b "; const DIFF_EXHIBITING_PARSE_FILE_NAME_BUG: &str = r" diff --git c/a i/a new file mode 100644 index 0000000..eea55b6 --- /dev/null +++ i/a @@ -0,0 +1 @@ +++ a "; const DIFF_WITH_REMOVED_EMPTY_LINE: &str = r" diff --git i/a w/a index 8b13789..e69de29 100644 --- i/a +++ w/a @@ -1 +0,0 @@ - "; const DIFF_WITH_ADDED_EMPTY_LINE: &str = r" diff --git i/a w/a index e69de29..8b13789 100644 --- i/a +++ w/a @@ -0,0 +1 @@ + "; const DIFF_WITH_SINGLE_CHARACTER_LINE: &str = r" diff --git a/Person.java b/Person.java new file mode 100644 index 0000000..c6c830c --- /dev/null +++ b/Person.java @@ -0,0 +1,7 @@ +import lombok.Data; + +@Data +public class Person { + private Long id; + private String name; +} "; const DIFF_WITH_WHITESPACE_ERROR: &str = r" diff --git c/a i/a new file mode 100644 index 0000000..8d1c8b6 --- /dev/null +++ i/a @@ -0,0 +1 @@ + "; const DIFF_WITH_REMOVED_WHITESPACE_ERROR: &str = r" diff --git i/a w/a index 8d1c8b6..8b13789 100644 --- i/a +++ w/a @@ -1 +1 @@ - + "; const DIFF_WITH_WHITESPACE_UNRELATED_EDIT_ERROR: &str = r" diff --git a/foo b/foo index 8d1c8b6..8b13789 100644 --- a/foo +++ b/foo @@ -1 +1 @@ -some line with trailing spaces +some new line with trailing spaces "; const DIFF_WITH_WHITESPACE_EDIT_ERROR: &str = r" diff --git a/foo b/foo index 8d1c8b6..8b13789 100644 --- a/foo +++ b/foo @@ -1 +1 @@ -same line with different number of trailing spaces +same line with different number of trailing spaces "; const DIFF_WITH_WHITESPACE_AFTER_TEXT_ERROR: &str = r" diff --git c/a i/a new file mode 100644 index 0000000..8d1c8b6 --- /dev/null +++ i/a @@ -0,0 +1 @@ +foo bar "; const DIFF_WITH_REMOVED_WHITESPACE_AFTER_TEXT_ERROR: &str = r" diff --git i/a w/a index 8d1c8b6..8b13789 100644 --- i/a +++ w/a @@ -1 +0,0 @@ -foo bar "; const DIFF_WITH_ADDED_WHITESPACE_EMPTY_LINE_ERROR: &str = r" diff --git a/a b/a index 0ec702f..8c75341 100644 --- a/a +++ b/a @@ -1,0 +1,0 @@ - + "; // Delta handling is different for each of theses cases: // * Only space in the line is added or partially removed // * Space after text added or partially removed // * Space in a unmodified part of the line // This test regroup theses 5 cases. const DIFF_WITH_WHITESPACE_COMPLEX_ERROR: &str = r" diff --git a/a b/a index 0ec702f..8c75341 100644 --- a/a +++ b/a @@ -1,5 +1,5 @@ - - - foo0 - foo1 - bar + + + foo0 + foo1 + bAr "; const DIFF_WITH_TWO_ADDED_LINES: &str = r#" diff --git a/example.c b/example.c index 386f291a..22666f79 100644 --- a/example.c +++ b/example.c @@ -1,6 +1,8 @@ int other_routine() { + return 0; } int main() { puts("Hello, world!"); + return 0; } "#; const DIFF_WITH_TWO_ADDED_LINES_CREATED_BY_GIT_DIFF_U0: &str = r#" diff --git a/example.c b/example.c index 386f291a..22666f79 100644 --- a/example.c +++ b/example.c @@ -1,0 +2 @@ int other_routine() { + return 0; @@ -5,0 +7 @@ int main() { + return 0; "#; const GIT_DIFF_UNDER_COLOR_MOVED_DIMMED_ZEBRA_WITH_ANSI_ESCAPE_SEQUENCES: &str = r#" commit 8406b1996daa176ca677ac33b18f071b766c87a5 Author: Dan Davison Date: Sun Nov 1 15:28:53 2020 -0500 A change to investigate color-moved behavior, see #371 diff --git a/etc/performance/all-benchmarks.json b/etc/performance/all-benchmarks.json index f86240e7..f707e5fd 100644 --- a/etc/performance/all-benchmarks.json +++ b/etc/performance/all-benchmarks.json @@ -7,9 +7,9 @@ "median": 0.004928057465000001, "message": "cargo new delta\n", "min": 0.003220796465, - "stddev": 0.004157057519168492, "system": 0.0016010150000000001, "time": 0.013288195465, + "stddev": 0.004157057519168492, "user": 0.0013687749999999996 }, { @@ -26649,4 +26649,4 @@ "time": 1.8524859272050003, "user": 1.8240279649999998 } -] \ No newline at end of file +] "#; const GIT_DIFF_FILE_MODE_CHANGE_WITH_RENAME: &str = " diff --git a/old-longer-name b/shorter-name old mode 100644 new mode 100755 similarity index 100% rename from old-longer-name rename to shorter-name "; const GIT_DIFF_FILE_MODE_CHANGE_GAIN_EXECUTABLE_BIT: &str = " diff --git a/src/delta.rs b/src/delta.rs old mode 100644 new mode 100755 "; const GIT_DIFF_FILE_MODE_CHANGE_LOSE_EXECUTABLE_BIT: &str = " diff --git a/src/delta.rs b/src/delta.rs old mode 100755 new mode 100644 "; const GIT_DIFF_FILE_MODE_CHANGE_UNEXPECTED_BITS: &str = " diff --git a/src/delta.rs b/src/delta.rs old mode 100700 new mode 100644 "; // This output can be generated with `git diff -D` const GIT_DIFF_FILE_DELETED_WITHOUT_PREIMAGE: &str = " diff --git a/foo.bar b/foo.bar deleted file mode 100644 index e019be0..0000000 "; // This output can be generated with `git diff -D` const GIT_DIFF_FILES_DELETED_WITHOUT_PREIMAGE: &str = " diff --git a/foo b/foo deleted file mode 100644 index e019be0..0000000 diff --git a/bar b/bar deleted file mode 100644 index e019be0..0000000 "; const GIT_DIFF_FILE_MODE_CHANGE_WITH_DIFF: &str = " diff --git a/src/script b/src/script old mode 100644 new mode 100755 index d00491f..0cfbf08 100644 --- a/src/script +++ b/src/script @@ -1 +1 @@ -#!/bin/sh +#!/bin/bash "; const GIT_DIFF_NO_INDEX_FILENAMES_WITH_SPACES: &str = " diff --git a/a b b/c d index d00491f..0cfbf08 100644 --- a/a b +++ b/c d @@ -1 +1 @@ -1 +2 "; const GIT_LOG_FILE_REMOVAL_IN_FIRST_COMMIT: &str = " commit 4117f616160180c0c57ea64840eadd08b7fa32a4 Author: Björn Steinbrink Date: Tue Jun 21 14:51:59 2022 +0200 remove file diff --git a a deleted file mode 100644 index e69de29..0000000 commit 190cce5dffeb9050fd6a27780f16d84b19c07dc0 Author: Björn Steinbrink Date: Tue Jun 21 14:48:20 2022 +0200 add file diff --git a a new file mode 100644 index 0000000..e69de29 "; const GIT_DIFF_ALL_UNICODE_W_FULLWIDTH: &str = " diff --git a/src/a b/src/a index 53f98b6..14d6caa 100644 --- a/src/a +++ b/src/a @@ -1,7 +1,7 @@ 一æäöø€ÆÄÖ〇Øß一 一æäöø€ÆÄÖ〇Øß一 -二æäöø¢ÆÄÖ〇Øß二 -二æäöø¢ÆÄÖ〇Øß二 +二æäöø€ÆÄÖ〇Øß二 +二æäöø€ÆÄÖ〇Øß二 三æäöø€ÆÄÖ〇Øß三 三æäöø€ÆÄÖ〇Øß三 ¶ "; }