#![allow(clippy::unwrap_used, clippy::expect_used)]
#![cfg(feature = "localfs")]
mod common;
use common::{kernel_at, run};
use std::fs;
fn seed(dir: &std::path::Path) {
fs::write(dir.join("visible.txt"), b"v").unwrap();
fs::write(dir.join(".env"), b"e").unwrap();
fs::write(dir.join(".npmrc"), b"n").unwrap();
fs::create_dir(dir.join(".github")).unwrap();
fs::write(dir.join(".github/config.yml"), b"c").unwrap();
fs::write(dir.join(".github/.secret"), b"s").unwrap();
}
#[tokio::test]
async fn star_skips_dotfiles_in_shell_expansion() {
let tmp = tempfile::tempdir().unwrap();
seed(tmp.path());
let kernel = kernel_at(tmp.path());
let (out, code) = run(&kernel, "for f in *; do echo $f; done").await;
assert_eq!(code, 0);
assert!(out.contains("visible.txt"), "got: {out}");
assert!(!out.contains(".env"), "`*` must not match dotfiles: {out}");
assert!(!out.contains(".github"), "`*` must not match dot dirs: {out}");
}
#[tokio::test]
async fn dot_star_matches_dotfiles_in_shell_expansion() {
let tmp = tempfile::tempdir().unwrap();
seed(tmp.path());
let kernel = kernel_at(tmp.path());
let (out, code) = run(&kernel, "for f in .*; do echo $f; done").await;
assert_eq!(code, 0, "`.*` should expand, not error: {out}");
assert!(out.contains(".env"), "got: {out}");
assert!(out.contains(".npmrc"), "got: {out}");
assert!(!out.contains("visible.txt"), "`.*` must not match non-dot: {out}");
}
#[tokio::test]
async fn explicit_dotdir_glob_reaches_children() {
let tmp = tempfile::tempdir().unwrap();
seed(tmp.path());
let kernel = kernel_at(tmp.path());
let (out, code) = run(&kernel, "for f in .github/*; do echo $f; done").await;
assert_eq!(code, 0, "got: {out}");
assert!(out.contains("config.yml"), "got: {out}");
assert!(!out.contains(".secret"), "nested dotfile must stay hidden: {out}");
}
#[tokio::test]
async fn glob_builtin_dot_star_matches_without_flag() {
let tmp = tempfile::tempdir().unwrap();
seed(tmp.path());
let kernel = kernel_at(tmp.path());
let (out, code) = run(&kernel, "glob '.*'").await;
assert_eq!(code, 0, "got: {out}");
assert!(out.contains(".env"), "got: {out}");
assert!(out.contains(".npmrc"), "got: {out}");
}
#[tokio::test]
async fn globstar_reaches_explicit_dotfile() {
let tmp = tempfile::tempdir().unwrap();
seed(tmp.path());
fs::write(tmp.path().join(".github/.env"), b"hidden").unwrap();
fs::create_dir(tmp.path().join("sub")).unwrap();
fs::write(tmp.path().join("sub/.env"), b"s").unwrap();
let kernel = kernel_at(tmp.path());
let (out, code) = run(&kernel, "glob '**/.env'").await;
assert_eq!(code, 0, "got: {out}");
assert!(out.contains("sub/.env"), "got: {out}");
assert!(!out.contains(".github/.env"), "`**` must not enter hidden dir: {out}");
}
#[tokio::test]
async fn glob_builtin_star_hides_dotfiles() {
let tmp = tempfile::tempdir().unwrap();
seed(tmp.path());
let kernel = kernel_at(tmp.path());
let (out, code) = run(&kernel, "glob '*'").await;
assert_eq!(code, 0, "got: {out}");
assert!(out.contains("visible.txt"), "got: {out}");
assert!(!out.contains(".env"), "got: {out}");
}