#![allow(clippy::unwrap_used, clippy::expect_used)]
#![cfg(feature = "localfs")]
mod common;
use std::fs;
use tempfile::tempdir;
use common::{kernel_at, run};
#[tokio::test]
async fn tail_c_no_plus_returns_last_n_bytes() {
let dir = tempdir().unwrap();
fs::write(dir.path().join("bytes.txt"), b"abcdefgh").unwrap();
let kernel = kernel_at(dir.path());
let (out, code) = run(&kernel, "tail -c 3 bytes.txt").await;
assert_eq!(code, 0, "tail -c 3 should succeed: {out:?}");
assert_eq!(out.trim(), "fgh", "tail -c 3 should return last 3 bytes: {out:?}");
}
#[tokio::test]
async fn tail_c_plus_returns_bytes_from_offset() {
let dir = tempdir().unwrap();
fs::write(dir.path().join("bytes.txt"), b"abcdefgh").unwrap();
let kernel = kernel_at(dir.path());
let (out, code) = run(&kernel, "tail -c +3 bytes.txt").await;
assert_eq!(code, 0, "tail -c +3 should succeed: {out:?}");
assert_eq!(out.trim(), "cdefgh", "tail -c +3 should return bytes from offset 3 to end: {out:?}");
}
#[tokio::test]
async fn tail_c_plus_one_returns_entire_file() {
let dir = tempdir().unwrap();
fs::write(dir.path().join("bytes.txt"), b"hello").unwrap();
let kernel = kernel_at(dir.path());
let (out, code) = run(&kernel, "tail -c +1 bytes.txt").await;
assert_eq!(code, 0, "tail -c +1 should succeed: {out:?}");
assert_eq!(out.trim(), "hello", "tail -c +1 should return entire file: {out:?}");
}
#[tokio::test]
async fn tail_c_plus_past_end_returns_empty() {
let dir = tempdir().unwrap();
fs::write(dir.path().join("bytes.txt"), b"hi").unwrap();
let kernel = kernel_at(dir.path());
let (out, code) = run(&kernel, "tail -c +100 bytes.txt").await;
assert_eq!(code, 0, "tail -c +100 past end should succeed: {out:?}");
assert!(out.trim().is_empty(), "tail -c +100 past end should return empty: {out:?}");
}
#[tokio::test]
async fn tail_c_negative_still_means_last_n_bytes() {
let dir = tempdir().unwrap();
fs::write(dir.path().join("bytes.txt"), b"abcdefgh").unwrap();
let kernel = kernel_at(dir.path());
let (out, code) = run(&kernel, "tail -c 3 bytes.txt").await;
assert_eq!(code, 0);
assert_eq!(out.trim(), "fgh", "tail -c 3 (last 3) should return 'fgh': {out:?}");
}
#[tokio::test]
async fn tail_c_plus_and_no_plus_differ() {
let dir = tempdir().unwrap();
fs::write(dir.path().join("digits.txt"), b"0123456789").unwrap();
let kernel = kernel_at(dir.path());
let (out_last, code_last) = run(&kernel, "tail -c 3 digits.txt").await;
assert_eq!(code_last, 0);
assert_eq!(out_last.trim(), "789", "tail -c 3 should be last 3: {out_last:?}");
let (out_from, code_from) = run(&kernel, "tail -c +3 digits.txt").await;
assert_eq!(code_from, 0);
assert_eq!(out_from.trim(), "23456789", "tail -c +3 should be from byte 3: {out_from:?}");
assert_ne!(
out_last.trim(),
out_from.trim(),
"tail -c 3 and tail -c +3 must produce different output (the bug made them equal)"
);
}
#[tokio::test]
async fn tree_nonexistent_path_exits_nonzero() {
let dir = tempdir().unwrap();
let kernel = kernel_at(dir.path());
let (out, code) = run(&kernel, "tree nonexistent_xyz_kaish_test").await;
assert_ne!(code, 0, "tree on nonexistent path should exit non-zero, got code={code} out={out:?}");
}
#[tokio::test]
async fn tree_existing_path_exits_zero() {
let dir = tempdir().unwrap();
fs::create_dir_all(dir.path().join("subdir")).unwrap();
fs::write(dir.path().join("subdir/file.txt"), b"hello").unwrap();
let kernel = kernel_at(dir.path());
let (out, code) = run(&kernel, "tree subdir").await;
assert_eq!(code, 0, "tree on existing dir should succeed: {out:?}");
assert!(out.contains("subdir") || out.contains("file.txt"), "output should mention the tree: {out:?}");
}
#[tokio::test]
async fn tree_default_cwd_exits_zero() {
let dir = tempdir().unwrap();
fs::write(dir.path().join("readme.txt"), b"hi").unwrap();
let kernel = kernel_at(dir.path());
let (out, code) = run(&kernel, "tree").await;
assert_eq!(code, 0, "tree with no args should succeed: {out:?}");
assert!(!out.is_empty(), "tree with no args should produce some output: {out:?}");
}