diff --git a/src/main.rs b/src/main.rs index 76061c2..a8cc78e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -255,15 +255,14 @@ fn real_main(args: CliArgs) -> Result { language.as_deref(), Some(&working_dir), ); + let result_with_imitated_newlines = + imitate_cr_lf_from_input(&original_contents_left, &merge_result.contents); if let Some(fname_out) = output { - write_string_to_file(&fname_out, &merge_result.contents)?; + write_string_to_file(&fname_out, &result_with_imitated_newlines)?; } else if git { - write_string_to_file(fname_left, &merge_result.contents)?; + write_string_to_file(fname_left, &result_with_imitated_newlines)?; } else { - print!( - "{}", - imitate_cr_lf_from_input(&original_contents_left, &merge_result.contents) - ); + print!("{}", result_with_imitated_newlines); } if merge_result.conflict_count > 0 { @@ -331,17 +330,16 @@ fn real_main(args: CliArgs) -> Result { ); match postprocessed { Ok(merged) => { + let result_with_imitated_newlines = + imitate_cr_lf_from_input(&original_conflict_contents, &merged.contents); if stdout { - print!( - "{}", - imitate_cr_lf_from_input(&original_conflict_contents, &merged.contents) - ); + print!("{}", result_with_imitated_newlines); } else { - write_string_to_file(&fname_conflicts, &merged.contents)?; + write_string_to_file(&fname_conflicts, &result_with_imitated_newlines)?; if keep_backup { write_string_to_file( fname_conflicts.with_added_extension("orig"), - &conflict_contents, + &original_conflict_contents, )?; } }; @@ -551,31 +549,58 @@ mod test { assert!(test_file_orig_file_path.exists()); } - fn create_file_for_solve(repo_path: &Path) -> PathBuf { + fn create_file_for_solve(repo_path: &Path, cr_lf: bool) -> PathBuf { let test_file_name = "test.txt"; - + let mut contents = "<<<<<<< LEFT\n[1, 2, 3, 4]\n||||||| BASE\n[1, 2, 3]\n=======\n[0, 1, 2, 3]\n>>>>>>> RIGHT\n".to_string(); + if cr_lf { + contents = contents.replace("\n", "\r\n"); + } let test_file_abs_path = repo_path.join(test_file_name); - fs::write(&test_file_abs_path, "<<<<<<< LEFT\n[1, 2, 3, 4]\n||||||| BASE\n[1, 2, 3]\n=======\n[0, 1, 2, 3]\n>>>>>>> RIGHT\n") + fs::write(&test_file_abs_path, contents) .expect("failed to write test file to git repository"); test_file_abs_path } - fn create_files_for_merge(repo_path: &Path) -> (PathBuf, PathBuf, PathBuf, PathBuf) { + fn create_files_for_merge( + repo_path: &Path, + cr_lf: bool, + ) -> (PathBuf, PathBuf, PathBuf, PathBuf) { let base_file_name = "base.txt"; let left_file_name = "left.txt"; let right_file_name = "right.txt"; let output_file_name = "output.txt"; let base_file_abs_path = repo_path.join(base_file_name); - fs::write(&base_file_abs_path, "[1, 2, 3]\n") - .expect("failed to write test base file to git repository"); + fs::write( + &base_file_abs_path, + if cr_lf { + "[1, 2, 3]\r\n" + } else { + "[1, 2, 3]\n" + }, + ) + .expect("failed to write test base file to git repository"); let left_file_abs_path = repo_path.join(left_file_name); - fs::write(&left_file_abs_path, "[1, 2, 3, 4]\n") - .expect("failed to write test left file to git repository"); + fs::write( + &left_file_abs_path, + if cr_lf { + "[1, 2, 3, 4]\r\n" + } else { + "[1, 2, 3, 4]\n" + }, + ) + .expect("failed to write test left file to git repository"); let right_file_abs_path = repo_path.join(right_file_name); - fs::write(&right_file_abs_path, "[0, 1, 2, 3]\n") - .expect("failed to write test right file to git repository"); + fs::write( + &right_file_abs_path, + if cr_lf { + "[0, 1, 2, 3]\r\n" + } else { + "[0, 1, 2, 3]\n" + }, + ) + .expect("failed to write test right file to git repository"); let output_file_abs_path = repo_path.join(output_file_name); ( @@ -591,7 +616,7 @@ mod test { let repo_dir = tempfile::tempdir().expect("failed to create the temp dir"); let repo_path = repo_dir.path(); - let test_file_abs_path = create_file_for_solve(repo_path); + let test_file_abs_path = create_file_for_solve(repo_path, false); // first try without specifying a language let return_code = real_main(CliArgs::parse_from([ @@ -629,7 +654,7 @@ mod test { let repo_path = repo_dir.path(); let (base_file_abs_path, left_file_abs_path, right_file_abs_path, output_file_abs_path) = - create_files_for_merge(repo_path); + create_files_for_merge(repo_path, false); // first try without specifying a language let return_code = real_main(CliArgs::parse_from([ @@ -674,7 +699,7 @@ mod test { let repo_dir = tempfile::tempdir().expect("failed to create the temp dir"); let repo_path = repo_dir.path(); - let test_file_abs_path = create_file_for_solve(repo_path); + let test_file_abs_path = create_file_for_solve(repo_path, false); let debug_dir = tempfile::tempdir().unwrap(); let debug_dir_path = debug_dir.path().to_path_buf(); @@ -699,7 +724,7 @@ mod test { let repo_path = repo_dir.path(); let (base_file_abs_path, left_file_abs_path, right_file_abs_path, _) = - create_files_for_merge(repo_path); + create_files_for_merge(repo_path, false); let debug_dir = tempfile::tempdir().unwrap(); let debug_dir_path = debug_dir.path().to_path_buf(); @@ -719,4 +744,61 @@ mod test { assert!(fs::exists(debug_dir_path).unwrap()); } + + #[test] + fn line_ending_preservation_for_solve() { + let repo_dir = tempfile::tempdir().expect("failed to create the temp dir"); + let repo_path = repo_dir.path(); + + let test_file_abs_path = create_file_for_solve(repo_path, true); + + let return_code = real_main(CliArgs::parse_from([ + "mergiraf", + "solve", + "--language=json", + test_file_abs_path.clone().to_str().unwrap(), + ])) + .expect("failed to execute `mergiraf solve`"); + assert_eq!( + return_code, 0, + "`mergiraf solve` should execute successfully" + ); + + let merge_result = + fs::read_to_string(&test_file_abs_path).expect("couldn't read the merge result"); + assert_eq!(merge_result, "[0, 1, 2, 3, 4]\r\n"); + + let backup_contents = fs::read_to_string(test_file_abs_path.with_extension("txt.orig")) + .expect("couldn't read the backup file"); + assert!(backup_contents.contains("\r\n")); + } + + #[test] + fn line_ending_preservation_for_merge() { + let repo_dir = tempfile::tempdir().expect("failed to create the temp dir"); + let repo_path = repo_dir.path(); + + let (base_file_abs_path, left_file_abs_path, right_file_abs_path, output_file_abs_path) = + create_files_for_merge(repo_path, true); + + let return_code = real_main(CliArgs::parse_from([ + "mergiraf", + "merge", + "--language=json", + base_file_abs_path.to_str().unwrap(), + left_file_abs_path.to_str().unwrap(), + right_file_abs_path.to_str().unwrap(), + "--output", + output_file_abs_path.to_str().unwrap(), + ])) + .expect("failed to execute `mergiraf merge`"); + assert_eq!( + return_code, 0, + "`mergiraf merge` should execute successfully with a specified language" + ); + + let merge_result = + fs::read_to_string(output_file_abs_path).expect("couldn't read the merge result"); + assert_eq!(merge_result, "[0, 1, 2, 3, 4]\r\n"); + } }