#[macro_use]
mod util;
mod status_parse;
use std::os::unix;
use util::*;
test!(staging_files_with_numbers, |t: &Test| {
sh!(t, "git init");
sh!(t, "touch A B C D E F G");
gitnu!(t, status);
let app = gitnu!(t, ["add", "2-4", "6"]);
assert_args!(&app, ["git", "add", "B", "C", "D", "F"]);
});
test!(range_overlap, |t: &Test| {
sh!(t, "git init");
sh!(t, "touch A B C D E F");
gitnu!(t, status);
let app = gitnu!(t, ["add", "2-4", "3-5"]);
assert_args!(&app, ["git", "add", "B", "C", "D", "C", "D", "E"]);
});
test!(add_unindexed_number, |t: &Test| {
sh!(t, "git init");
sh!(t, "touch A B C");
gitnu!(t, status);
let app = gitnu!(t, ["add", "2-5"]);
assert_args!(&app, ["git", "add", "B", "C", "4", "5"]);
});
test!(not_at_workspace_root, |t: &Test| {
sh!(t, "git init");
sh!(t, "mkdir src");
sh!(t, "touch A B src/C src/D");
gitnu!(t, "src", ["status"]).run().ok();
let app = gitnu!(t, "src", ["add", "2", "3"]);
assert_args!(&app, ["git", "add", "../B", "./"]);
});
test!(add_and_status_diff_dirs, |t: &Test| {
sh!(t, "git init");
sh!(t, "mkdir src");
sh!(t, "touch A B src/C src/D");
gitnu!(t, status);
let app = gitnu!(t, "src", ["add", "2", "3"]);
assert_args!(&app, ["git", "add", "../B", "../src/"]);
});
test!(dont_create_cache_file_without_repo, |t: &Test| {
gitnu!(t, status);
assert_eq_pretty!(sh!(t, "ls -lA").stdout.trim(), "total 0");
});
test!(skip_flags, |t: &Test| {
sh!(t, "git init");
sh!(t, "touch A B C");
gitnu!(t, status);
let app = gitnu!(t, ["log", "-n", "2", "--oneline", "3"]);
assert_args!(&app, ["git", "log", "-n", "2", "--oneline", "C"]);
});
test!(status_display, |t: &Test| {
sh!(t, "git init");
for file in "A B C D E F G H I".split(' ') {
write(t, file, &format!("contents::{file}"));
}
sh!(t, "git add B C D E G H I");
sh!(t, "git commit -m pre");
fs::write(t.dir.join("B"), b"modify::B").unwrap();
fs::write(t.dir.join("G"), b"modify::G").unwrap();
fs::remove_file(t.dir.join("C")).unwrap();
fs::rename(t.dir.join("E"), t.dir.join("_E")).unwrap();
fs::rename(t.dir.join("I"), t.dir.join("_I")).unwrap();
fs::remove_file(t.dir.join("D")).unwrap();
fs::remove_file(t.dir.join("H")).unwrap();
unix::fs::symlink(t.dir.join("A"), t.dir.join("D")).unwrap();
unix::fs::symlink(t.dir.join("A"), t.dir.join("H")).unwrap();
sh!(t, "git add A B C D E _E");
let output = sh!(t, format!("git nu status"));
assert_eq_pretty!(
output.stdout,
"\
On branch main
Changes to be committed:
1 new file: A
2 modified: B
3 deleted: C
4 typechange: D
5 renamed: E -> _E
Changes not staged for commit:
6 modified: G
7 typechange: H
8 deleted: I
Untracked files:
9 F
10 _I
"
);
});
test!(merge_conflict_display, |t: &Test| {
sh!(t, "git init");
sh!(t, "touch base");
sh!(t, "git add --all");
sh!(t, "git commit -m 'base commit'");
sh!(t, "git branch -m LEFT");
fs::write(t.dir.join("conflict_file"), b"left").unwrap();
sh!(t, "git add conflict_file");
sh!(t, "git commit -m 'left commit'");
sh!(t, "git checkout -b RIGHT");
sh!(t, "git reset --hard HEAD~1");
fs::write(t.dir.join("conflict_file"), b"right").unwrap();
sh!(t, "git add conflict_file");
sh!(t, "git commit -m 'right commit'");
sh!(t, "git merge LEFT");
sh!(t, "touch fresh");
sh!(t, "git add fresh");
gitnu!(t, status);
gitnu!(t, ["add", "2"]).run().ok();
let output = sh!(t, format!("git nu status"));
assert_eq_pretty!(
output.stdout,
"\
On branch RIGHT
All conflicts fixed but you are still merging.
Changes to be committed:
1 modified: conflict_file
2 new file: fresh
"
);
});
test!(detached_head_display, |t: &Test| {
sh!(t, "git init");
sh!(t, "touch A && git add A && git commit -m 'A'");
sh!(t, "touch B && git add B && git commit -m 'B'");
sh!(t, "git checkout HEAD~1");
sh!(t, "touch gold silver");
let sha = sh!(t, "git rev-parse --short HEAD");
let sha = sha.stdout.trim();
let output = sh!(t, format!("git nu status"));
assert_eq_pretty!(
output.stdout,
format!(
"\
HEAD detached at {sha}
Untracked files:
1 gold
2 silver
nothing added to commit but untracked files present
"
)
);
});
test!(exit_codes, |t: &Test| {
macro_rules! assert_code {
($cmd:expr, $code:expr) => {
assert_eq!(sh!(t, $cmd).exit_code, Some($code));
};
}
assert_code!("git status", 128);
assert_code!("git nu status", 128);
assert_code!("git status --bad-flag", 128);
assert_code!("git nu status --bad-flag", 128);
assert_code!("git stat", 1);
assert_code!("git nu stat", 1);
sh!(t, "git init");
assert_code!("git status", 0);
assert_code!("git nu status", 0);
});
test!(different_workspace, |t: &Test| {
sh!(t, "mkdir one two");
sh!(t, "one", "git init && git branch -m one");
sh!(t, "two", "git init && git branch -m two");
sh!(t, "one", "touch gold silver");
sh!(t, "two", "git -C ../one nu status");
sh!(t, "two", "git -C ../one nu add 1");
let status = sh!(t, "two", "git -C ../one nu status");
assert_eq_pretty!(
status.stdout,
"\
On branch one
No commits yet
Changes to be committed:
1 new file: gold
Untracked files:
2 silver
"
);
});
test!(max_cache_size_exceeded, |t: &Test| {
sh!(t, "git init");
let mut touch_args = "touch".to_string();
(1..25).for_each(|i| touch_args += &format!(" f{i:0>2}"));
sh!(t, &touch_args);
gitnu!(t, status);
let output = sh!(t, "git nu status");
assert_eq_pretty!(
output.stdout,
"\
On branch main
No commits yet
Untracked files:
1 f01
2 f02
3 f03
4 f04
5 f05
6 f06
7 f07
8 f08
9 f09
10 f10
11 f11
12 f12
13 f13
14 f14
15 f15
16 f16
17 f17
18 f18
19 f19
20 f20
f21
f22
f23
f24
nothing added to commit but untracked files present
"
);
});
test!(reset_hard_on_numeric_sha, |t: &Test| {
sh!(t, "git init");
sh!(t, "git branch -m 1234567");
sh!(t, "touch A && git add A && git commit -m 'first'");
sh!(t, "git checkout -b main");
sh!(t, "touch B && git add B && git commit -m 'second'");
sh!(t, "git branch");
sh!(t, "git nu reset --hard 1234567");
let app = gitnu!(t, ["reset", "--hard", "1234567"]);
assert_args!(&app, ["git", "reset", "--hard", "1234567"]);
});