mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
Run cargo fmt on the tree
This commit is contained in:
parent
36dd968c9a
commit
a85539f530
189 changed files with 841 additions and 782 deletions
|
@ -22,12 +22,14 @@ fn test_help() {
|
|||
#[test]
|
||||
fn test_version() {
|
||||
for version_flg in ["-V", "--version"] {
|
||||
assert!(new_ucmd!()
|
||||
.arg(version_flg)
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.stdout_str()
|
||||
.starts_with("basename"));
|
||||
assert!(
|
||||
new_ucmd!()
|
||||
.arg(version_flg)
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.stdout_str()
|
||||
.starts_with("basename")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -97,12 +99,14 @@ fn test_zero_param() {
|
|||
}
|
||||
|
||||
fn expect_error(input: &[&str]) {
|
||||
assert!(!new_ucmd!()
|
||||
.args(input)
|
||||
.fails()
|
||||
.no_stdout()
|
||||
.stderr_str()
|
||||
.is_empty());
|
||||
assert!(
|
||||
!new_ucmd!()
|
||||
.args(input)
|
||||
.fails()
|
||||
.no_stdout()
|
||||
.stderr_str()
|
||||
.is_empty()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
// file that was distributed with this source code.
|
||||
// spell-checker:ignore NOFILE nonewline cmdline
|
||||
|
||||
use crate::common::util::TestScenario;
|
||||
#[cfg(not(windows))]
|
||||
use crate::common::util::vec_of_size;
|
||||
use crate::common::util::TestScenario;
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
use rlimit::Resource;
|
||||
#[cfg(target_os = "linux")]
|
||||
|
|
|
@ -124,8 +124,7 @@ fn test_preserve_root_symlink() {
|
|||
] {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
at.symlink_file(d, file);
|
||||
let expected_error =
|
||||
"chgrp: it is dangerous to operate recursively on 'test_chgrp_symlink2root' (same as '/')\nchgrp: use --no-preserve-root to override this failsafe\n";
|
||||
let expected_error = "chgrp: it is dangerous to operate recursively on 'test_chgrp_symlink2root' (same as '/')\nchgrp: use --no-preserve-root to override this failsafe\n";
|
||||
ucmd.arg("--preserve-root")
|
||||
.arg("-HR")
|
||||
.arg("bin")
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
// file that was distributed with this source code.
|
||||
|
||||
use crate::common::util::{AtPath, TestScenario, UCommand};
|
||||
use std::fs::{metadata, set_permissions, OpenOptions, Permissions};
|
||||
use std::fs::{OpenOptions, Permissions, metadata, set_permissions};
|
||||
use std::os::unix::fs::{OpenOptionsExt, PermissionsExt};
|
||||
|
||||
static TEST_FILE: &str = "file";
|
||||
|
@ -238,8 +238,7 @@ fn test_chmod_ugoa() {
|
|||
fn test_chmod_umask_expected() {
|
||||
let current_umask = uucore::mode::get_umask();
|
||||
assert_eq!(
|
||||
current_umask,
|
||||
0o022,
|
||||
current_umask, 0o022,
|
||||
"Unexpected umask value: expected 022 (octal), but got {:03o}. Please adjust the test environment.",
|
||||
current_umask
|
||||
);
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
// file that was distributed with this source code.
|
||||
// spell-checker:ignore (words) agroupthatdoesntexist auserthatdoesntexist cuuser groupname notexisting passgrp
|
||||
|
||||
use crate::common::util::{is_ci, run_ucmd_as_root, CmdResult, TestScenario};
|
||||
use crate::common::util::{CmdResult, TestScenario, is_ci, run_ucmd_as_root};
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
use uucore::process::geteuid;
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#[cfg(not(target_os = "android"))]
|
||||
use crate::common::util::is_ci;
|
||||
use crate::common::util::{run_ucmd_as_root, TestScenario};
|
||||
use crate::common::util::{TestScenario, run_ucmd_as_root};
|
||||
|
||||
#[test]
|
||||
fn test_invalid_arg() {
|
||||
|
@ -17,9 +17,11 @@ fn test_invalid_arg() {
|
|||
fn test_missing_operand() {
|
||||
let result = new_ucmd!().fails_with_code(125);
|
||||
|
||||
assert!(result
|
||||
.stderr_str()
|
||||
.starts_with("error: the following required arguments were not provided"));
|
||||
assert!(
|
||||
result
|
||||
.stderr_str()
|
||||
.starts_with("error: the following required arguments were not provided")
|
||||
);
|
||||
|
||||
assert!(result.stderr_str().contains("<newroot>"));
|
||||
}
|
||||
|
@ -33,9 +35,11 @@ fn test_enter_chroot_fails() {
|
|||
at.mkdir("jail");
|
||||
|
||||
let result = ucmd.arg("jail").fails_with_code(125);
|
||||
assert!(result
|
||||
.stderr_str()
|
||||
.starts_with("chroot: cannot chroot to 'jail': Operation not permitted (os error 1)"));
|
||||
assert!(
|
||||
result
|
||||
.stderr_str()
|
||||
.starts_with("chroot: cannot chroot to 'jail': Operation not permitted (os error 1)")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -966,29 +966,41 @@ fn test_cksum_check_failed() {
|
|||
.arg("CHECKSUM")
|
||||
.fails();
|
||||
|
||||
assert!(result
|
||||
.stderr_str()
|
||||
.contains("input: No such file or directory"));
|
||||
assert!(result
|
||||
.stderr_str()
|
||||
.contains("2 lines are improperly formatted\n"));
|
||||
assert!(result
|
||||
.stderr_str()
|
||||
.contains("1 listed file could not be read\n"));
|
||||
assert!(
|
||||
result
|
||||
.stderr_str()
|
||||
.contains("input: No such file or directory")
|
||||
);
|
||||
assert!(
|
||||
result
|
||||
.stderr_str()
|
||||
.contains("2 lines are improperly formatted\n")
|
||||
);
|
||||
assert!(
|
||||
result
|
||||
.stderr_str()
|
||||
.contains("1 listed file could not be read\n")
|
||||
);
|
||||
assert!(result.stdout_str().contains("f: OK\n"));
|
||||
|
||||
// without strict
|
||||
let result = scene.ucmd().arg("--check").arg("CHECKSUM").fails();
|
||||
|
||||
assert!(result
|
||||
.stderr_str()
|
||||
.contains("input: No such file or directory"));
|
||||
assert!(result
|
||||
.stderr_str()
|
||||
.contains("2 lines are improperly formatted\n"));
|
||||
assert!(result
|
||||
.stderr_str()
|
||||
.contains("1 listed file could not be read\n"));
|
||||
assert!(
|
||||
result
|
||||
.stderr_str()
|
||||
.contains("input: No such file or directory")
|
||||
);
|
||||
assert!(
|
||||
result
|
||||
.stderr_str()
|
||||
.contains("2 lines are improperly formatted\n")
|
||||
);
|
||||
assert!(
|
||||
result
|
||||
.stderr_str()
|
||||
.contains("1 listed file could not be read\n")
|
||||
);
|
||||
assert!(result.stdout_str().contains("f: OK\n"));
|
||||
|
||||
// tests with two files
|
||||
|
@ -1010,15 +1022,21 @@ fn test_cksum_check_failed() {
|
|||
.fails();
|
||||
println!("result.stderr_str() {}", result.stderr_str());
|
||||
println!("result.stdout_str() {}", result.stdout_str());
|
||||
assert!(result
|
||||
.stderr_str()
|
||||
.contains("input2: No such file or directory"));
|
||||
assert!(result
|
||||
.stderr_str()
|
||||
.contains("4 lines are improperly formatted\n"));
|
||||
assert!(result
|
||||
.stderr_str()
|
||||
.contains("2 listed files could not be read\n"));
|
||||
assert!(
|
||||
result
|
||||
.stderr_str()
|
||||
.contains("input2: No such file or directory")
|
||||
);
|
||||
assert!(
|
||||
result
|
||||
.stderr_str()
|
||||
.contains("4 lines are improperly formatted\n")
|
||||
);
|
||||
assert!(
|
||||
result
|
||||
.stderr_str()
|
||||
.contains("2 listed files could not be read\n")
|
||||
);
|
||||
assert!(result.stdout_str().contains("f: OK\n"));
|
||||
assert!(result.stdout_str().contains("2: OK\n"));
|
||||
}
|
||||
|
@ -1088,9 +1106,11 @@ fn test_cksum_mixed() {
|
|||
println!("result.stderr_str() {}", result.stderr_str());
|
||||
println!("result.stdout_str() {}", result.stdout_str());
|
||||
assert!(result.stdout_str().contains("f: OK"));
|
||||
assert!(result
|
||||
.stderr_str()
|
||||
.contains("3 lines are improperly formatted"));
|
||||
assert!(
|
||||
result
|
||||
.stderr_str()
|
||||
.contains("3 lines are improperly formatted")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1221,9 +1241,7 @@ fn test_check_directory_error() {
|
|||
|
||||
#[test]
|
||||
fn test_check_base64_hashes() {
|
||||
let hashes =
|
||||
"MD5 (empty) = 1B2M2Y8AsgTpgAmY7PhCfg==\nSHA256 (empty) = 47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=\nBLAKE2b (empty) = eGoC90IBWQPGxv2FJVLScpEvR0DhWEdhiobiF/cfVBnSXhAxr+5YUxOJZESTTrBLkDpoWxRIt1XVb3Aa/pvizg==\n"
|
||||
;
|
||||
let hashes = "MD5 (empty) = 1B2M2Y8AsgTpgAmY7PhCfg==\nSHA256 (empty) = 47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=\nBLAKE2b (empty) = eGoC90IBWQPGxv2FJVLScpEvR0DhWEdhiobiF/cfVBnSXhAxr+5YUxOJZESTTrBLkDpoWxRIt1XVb3Aa/pvizg==\n";
|
||||
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
|
@ -1680,11 +1698,11 @@ mod gnu_cksum_base64 {
|
|||
),
|
||||
(
|
||||
"sha512",
|
||||
"z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg/SpIdNs6c5H0NE8XYXysP+DGNKHfuwvY7kxvUdBeoGlODJ6+SfaPg=="
|
||||
"z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg/SpIdNs6c5H0NE8XYXysP+DGNKHfuwvY7kxvUdBeoGlODJ6+SfaPg==",
|
||||
),
|
||||
(
|
||||
"blake2b",
|
||||
"eGoC90IBWQPGxv2FJVLScpEvR0DhWEdhiobiF/cfVBnSXhAxr+5YUxOJZESTTrBLkDpoWxRIt1XVb3Aa/pvizg=="
|
||||
"eGoC90IBWQPGxv2FJVLScpEvR0DhWEdhiobiF/cfVBnSXhAxr+5YUxOJZESTTrBLkDpoWxRIt1XVb3Aa/pvizg==",
|
||||
),
|
||||
("sm3", "GrIdg1XPoX+OYRlIMegajyK+yMco/vt0ftA161CCqis="),
|
||||
];
|
||||
|
|
|
@ -1337,13 +1337,15 @@ fn test_cp_deref() {
|
|||
.join(TEST_COPY_TO_FOLDER)
|
||||
.join(TEST_HELLO_WORLD_SOURCE_SYMLINK);
|
||||
// unlike -P/--no-deref, we expect a file, not a link
|
||||
assert!(at.file_exists(
|
||||
path_to_new_symlink
|
||||
.clone()
|
||||
.into_os_string()
|
||||
.into_string()
|
||||
.unwrap()
|
||||
));
|
||||
assert!(
|
||||
at.file_exists(
|
||||
path_to_new_symlink
|
||||
.clone()
|
||||
.into_os_string()
|
||||
.into_string()
|
||||
.unwrap()
|
||||
)
|
||||
);
|
||||
// Check the content of the destination file that was copied.
|
||||
assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");
|
||||
let path_to_check = path_to_new_symlink.to_str().unwrap();
|
||||
|
@ -1374,13 +1376,15 @@ fn test_cp_no_deref() {
|
|||
.subdir
|
||||
.join(TEST_COPY_TO_FOLDER)
|
||||
.join(TEST_HELLO_WORLD_SOURCE_SYMLINK);
|
||||
assert!(at.is_symlink(
|
||||
&path_to_new_symlink
|
||||
.clone()
|
||||
.into_os_string()
|
||||
.into_string()
|
||||
.unwrap()
|
||||
));
|
||||
assert!(
|
||||
at.is_symlink(
|
||||
&path_to_new_symlink
|
||||
.clone()
|
||||
.into_os_string()
|
||||
.into_string()
|
||||
.unwrap()
|
||||
)
|
||||
);
|
||||
// Check the content of the destination file that was copied.
|
||||
assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");
|
||||
let path_to_check = path_to_new_symlink.to_str().unwrap();
|
||||
|
@ -1421,14 +1425,16 @@ fn test_cp_no_deref_link_onto_link() {
|
|||
.succeeds();
|
||||
|
||||
// Ensure that the target of the destination was not modified.
|
||||
assert!(!at
|
||||
.symlink_metadata(TEST_HELLO_WORLD_DEST)
|
||||
.file_type()
|
||||
.is_symlink());
|
||||
assert!(at
|
||||
.symlink_metadata(TEST_HELLO_WORLD_DEST_SYMLINK)
|
||||
.file_type()
|
||||
.is_symlink());
|
||||
assert!(
|
||||
!at.symlink_metadata(TEST_HELLO_WORLD_DEST)
|
||||
.file_type()
|
||||
.is_symlink()
|
||||
);
|
||||
assert!(
|
||||
at.symlink_metadata(TEST_HELLO_WORLD_DEST_SYMLINK)
|
||||
.file_type()
|
||||
.is_symlink()
|
||||
);
|
||||
assert_eq!(at.read(TEST_HELLO_WORLD_DEST_SYMLINK), "Hello, World!\n");
|
||||
}
|
||||
|
||||
|
@ -2060,13 +2066,15 @@ fn test_cp_deref_folder_to_folder() {
|
|||
.subdir
|
||||
.join(TEST_COPY_TO_FOLDER_NEW)
|
||||
.join(TEST_HELLO_WORLD_SOURCE_SYMLINK);
|
||||
assert!(at.file_exists(
|
||||
path_to_new_symlink
|
||||
.clone()
|
||||
.into_os_string()
|
||||
.into_string()
|
||||
.unwrap()
|
||||
));
|
||||
assert!(
|
||||
at.file_exists(
|
||||
path_to_new_symlink
|
||||
.clone()
|
||||
.into_os_string()
|
||||
.into_string()
|
||||
.unwrap()
|
||||
)
|
||||
);
|
||||
|
||||
let path_to_new = at.subdir.join(TEST_COPY_TO_FOLDER_NEW_FILE);
|
||||
|
||||
|
@ -2156,13 +2164,15 @@ fn test_cp_no_deref_folder_to_folder() {
|
|||
.subdir
|
||||
.join(TEST_COPY_TO_FOLDER_NEW)
|
||||
.join(TEST_HELLO_WORLD_SOURCE_SYMLINK);
|
||||
assert!(at.is_symlink(
|
||||
&path_to_new_symlink
|
||||
.clone()
|
||||
.into_os_string()
|
||||
.into_string()
|
||||
.unwrap()
|
||||
));
|
||||
assert!(
|
||||
at.is_symlink(
|
||||
&path_to_new_symlink
|
||||
.clone()
|
||||
.into_os_string()
|
||||
.into_string()
|
||||
.unwrap()
|
||||
)
|
||||
);
|
||||
|
||||
let path_to_new = at.subdir.join(TEST_COPY_TO_FOLDER_NEW_FILE);
|
||||
|
||||
|
@ -2254,18 +2264,22 @@ fn test_cp_archive_recursive() {
|
|||
assert!(at.file_exists(at.subdir.join(TEST_COPY_TO_FOLDER_NEW).join("1")));
|
||||
assert!(at.file_exists(at.subdir.join(TEST_COPY_TO_FOLDER_NEW).join("2")));
|
||||
|
||||
assert!(at.is_symlink(
|
||||
&at.subdir
|
||||
.join(TEST_COPY_TO_FOLDER_NEW)
|
||||
.join("1.link")
|
||||
.to_string_lossy()
|
||||
));
|
||||
assert!(at.is_symlink(
|
||||
&at.subdir
|
||||
.join(TEST_COPY_TO_FOLDER_NEW)
|
||||
.join("2.link")
|
||||
.to_string_lossy()
|
||||
));
|
||||
assert!(
|
||||
at.is_symlink(
|
||||
&at.subdir
|
||||
.join(TEST_COPY_TO_FOLDER_NEW)
|
||||
.join("1.link")
|
||||
.to_string_lossy()
|
||||
)
|
||||
);
|
||||
assert!(
|
||||
at.is_symlink(
|
||||
&at.subdir
|
||||
.join(TEST_COPY_TO_FOLDER_NEW)
|
||||
.join("2.link")
|
||||
.to_string_lossy()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -3974,13 +3988,17 @@ fn test_cp_seen_file() {
|
|||
|
||||
let result = ts.ucmd().arg("a/f").arg("b/f").arg("c").fails();
|
||||
#[cfg(not(unix))]
|
||||
assert!(result
|
||||
.stderr_str()
|
||||
.contains("will not overwrite just-created 'c\\f' with 'b/f'"));
|
||||
assert!(
|
||||
result
|
||||
.stderr_str()
|
||||
.contains("will not overwrite just-created 'c\\f' with 'b/f'")
|
||||
);
|
||||
#[cfg(unix)]
|
||||
assert!(result
|
||||
.stderr_str()
|
||||
.contains("will not overwrite just-created 'c/f' with 'b/f'"));
|
||||
assert!(
|
||||
result
|
||||
.stderr_str()
|
||||
.contains("will not overwrite just-created 'c/f' with 'b/f'")
|
||||
);
|
||||
|
||||
assert!(at.plus("c").join("f").exists());
|
||||
|
||||
|
@ -6073,11 +6091,13 @@ fn test_cp_preserve_xattr_readonly_source() {
|
|||
);
|
||||
|
||||
at.set_readonly(source_file);
|
||||
assert!(scene
|
||||
.fixtures
|
||||
.metadata(source_file)
|
||||
.permissions()
|
||||
.readonly());
|
||||
assert!(
|
||||
scene
|
||||
.fixtures
|
||||
.metadata(source_file)
|
||||
.permissions()
|
||||
.readonly()
|
||||
);
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
|
|
|
@ -266,9 +266,11 @@ fn test_date_set_mac_unavailable() {
|
|||
.arg("2020-03-11 21:45:00+08:00")
|
||||
.fails();
|
||||
result.no_stdout();
|
||||
assert!(result
|
||||
.stderr_str()
|
||||
.starts_with("date: setting the date is not supported by macOS"));
|
||||
assert!(
|
||||
result
|
||||
.stderr_str()
|
||||
.starts_with("date: setting the date is not supported by macOS")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
// file that was distributed with this source code.
|
||||
// spell-checker:ignore fname, tname, fpath, specfile, testfile, unspec, ifile, ofile, outfile, fullblock, urand, fileio, atoe, atoibm, availible, behaviour, bmax, bremain, btotal, cflags, creat, ctable, ctty, datastructures, doesnt, etoa, fileout, fname, gnudd, iconvflags, iseek, nocache, noctty, noerror, nofollow, nolinks, nonblock, oconvflags, oseek, outfile, parseargs, rlen, rmax, rposition, rremain, rsofar, rstat, sigusr, sigval, wlen, wstat abcdefghijklm abcdefghi nabcde nabcdefg abcdefg fifoname seekable
|
||||
|
||||
use crate::common::util::TestScenario;
|
||||
#[cfg(all(unix, not(feature = "feat_selinux")))]
|
||||
use crate::common::util::run_ucmd_as_root_with_stdin_stdout;
|
||||
use crate::common::util::TestScenario;
|
||||
#[cfg(all(not(windows), feature = "printf"))]
|
||||
use crate::common::util::{UCommand, TESTS_BINARY};
|
||||
use crate::common::util::{TESTS_BINARY, UCommand};
|
||||
|
||||
use regex::Regex;
|
||||
use uucore::io::OwnedFileDescriptorOrHandle;
|
||||
|
@ -30,21 +30,15 @@ use std::time::Duration;
|
|||
use tempfile::tempfile;
|
||||
|
||||
macro_rules! inf {
|
||||
($fname:expr) => {{
|
||||
&format!("if={}", $fname)
|
||||
}};
|
||||
($fname:expr) => {{ &format!("if={}", $fname) }};
|
||||
}
|
||||
|
||||
macro_rules! of {
|
||||
($fname:expr) => {{
|
||||
&format!("of={}", $fname)
|
||||
}};
|
||||
($fname:expr) => {{ &format!("of={}", $fname) }};
|
||||
}
|
||||
|
||||
macro_rules! fixture_path {
|
||||
($fname:expr) => {{
|
||||
PathBuf::from(format!("./tests/fixtures/dd/{}", $fname))
|
||||
}};
|
||||
($fname:expr) => {{ PathBuf::from(format!("./tests/fixtures/dd/{}", $fname)) }};
|
||||
}
|
||||
|
||||
macro_rules! assert_fixture_exists {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
// spell-checker:ignore overridable colorterm
|
||||
use crate::common::util::TestScenario;
|
||||
|
||||
use dircolors::{guess_syntax, OutputFmt, StrUtils};
|
||||
use dircolors::{OutputFmt, StrUtils, guess_syntax};
|
||||
|
||||
#[test]
|
||||
fn test_invalid_arg() {
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
#[cfg(not(windows))]
|
||||
use regex::Regex;
|
||||
|
||||
use crate::common::util::TestScenario;
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
use crate::common::util::expected_result;
|
||||
use crate::common::util::TestScenario;
|
||||
|
||||
#[cfg(not(target_os = "openbsd"))]
|
||||
const SUB_DIR: &str = "subdir/deeper";
|
||||
|
|
|
@ -1013,7 +1013,7 @@ mod tests_split_iterator {
|
|||
|
||||
use std::ffi::OsString;
|
||||
|
||||
use env::native_int_str::{from_native_int_representation_owned, Convert, NCvt};
|
||||
use env::native_int_str::{Convert, NCvt, from_native_int_representation_owned};
|
||||
use env::parse_error::ParseError;
|
||||
|
||||
fn split(input: &str) -> Result<Vec<OsString>, ParseError> {
|
||||
|
@ -1250,8 +1250,8 @@ mod test_raw_string_parser {
|
|||
|
||||
use env::{
|
||||
native_int_str::{
|
||||
from_native_int_representation, from_native_int_representation_owned,
|
||||
to_native_int_representation, NativeStr,
|
||||
NativeStr, from_native_int_representation, from_native_int_representation_owned,
|
||||
to_native_int_representation,
|
||||
},
|
||||
string_expander::StringExpander,
|
||||
string_parser,
|
||||
|
|
|
@ -15,7 +15,7 @@ use crate::common::util::TestScenario;
|
|||
use std::time::{Duration, SystemTime};
|
||||
|
||||
use rand::distr::{Distribution, Uniform};
|
||||
use rand::{rngs::SmallRng, Rng, SeedableRng};
|
||||
use rand::{Rng, SeedableRng, rngs::SmallRng};
|
||||
|
||||
const NUM_PRIMES: usize = 10000;
|
||||
const NUM_TESTS: usize = 100;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
//spell-checker: ignore coreutil
|
||||
|
||||
use crate::common::util::{check_coreutil_version, expected_result, whoami, TestScenario};
|
||||
use crate::common::util::{TestScenario, check_coreutil_version, expected_result, whoami};
|
||||
|
||||
const VERSION_MIN_MULTIPLE_USERS: &str = "8.31"; // this feature was introduced in GNU's coreutils 8.31
|
||||
|
||||
|
|
|
@ -1009,14 +1009,15 @@ fn test_sha256_binary() {
|
|||
let ts = TestScenario::new(util_name!());
|
||||
assert_eq!(
|
||||
ts.fixtures.read("binary.sha256.expected"),
|
||||
get_hash!(ts
|
||||
.ucmd()
|
||||
.arg("--sha256")
|
||||
.arg("--bits=256")
|
||||
.arg("binary.png")
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.stdout_str())
|
||||
get_hash!(
|
||||
ts.ucmd()
|
||||
.arg("--sha256")
|
||||
.arg("--bits=256")
|
||||
.arg("binary.png")
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.stdout_str()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1025,14 +1026,15 @@ fn test_sha256_stdin_binary() {
|
|||
let ts = TestScenario::new(util_name!());
|
||||
assert_eq!(
|
||||
ts.fixtures.read("binary.sha256.expected"),
|
||||
get_hash!(ts
|
||||
.ucmd()
|
||||
.arg("--sha256")
|
||||
.arg("--bits=256")
|
||||
.pipe_in_fixture("binary.png")
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.stdout_str())
|
||||
get_hash!(
|
||||
ts.ucmd()
|
||||
.arg("--sha256")
|
||||
.arg("--bits=256")
|
||||
.pipe_in_fixture("binary.png")
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.stdout_str()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
// spell-checker:ignore (ToDO) coreutil
|
||||
|
||||
use crate::common::util::{check_coreutil_version, expected_result, is_ci, whoami, TestScenario};
|
||||
use crate::common::util::{TestScenario, check_coreutil_version, expected_result, is_ci, whoami};
|
||||
|
||||
const VERSION_MIN_MULTIPLE_USERS: &str = "8.31"; // this feature was introduced in GNU's coreutils 8.31
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
// file that was distributed with this source code.
|
||||
// spell-checker:ignore (words) helloworld nodir objdump n'source
|
||||
|
||||
use crate::common::util::{is_ci, run_ucmd_as_root, TestScenario};
|
||||
use crate::common::util::{TestScenario, is_ci, run_ucmd_as_root};
|
||||
#[cfg(not(target_os = "openbsd"))]
|
||||
use filetime::FileTime;
|
||||
use std::fs;
|
||||
|
|
|
@ -337,11 +337,13 @@ fn test_symlink_overwrite_dir_fail() {
|
|||
at.touch(path_a);
|
||||
at.mkdir(path_b);
|
||||
|
||||
assert!(!ucmd
|
||||
.args(&["-s", "-T", path_a, path_b])
|
||||
.fails()
|
||||
.stderr_str()
|
||||
.is_empty());
|
||||
assert!(
|
||||
!ucmd
|
||||
.args(&["-s", "-T", path_a, path_b])
|
||||
.fails()
|
||||
.stderr_str()
|
||||
.is_empty()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -391,11 +393,13 @@ fn test_symlink_target_only() {
|
|||
|
||||
at.mkdir(dir);
|
||||
|
||||
assert!(!ucmd
|
||||
.args(&["-s", "-t", dir])
|
||||
.fails()
|
||||
.stderr_str()
|
||||
.is_empty());
|
||||
assert!(
|
||||
!ucmd
|
||||
.args(&["-s", "-t", dir])
|
||||
.fails()
|
||||
.stderr_str()
|
||||
.is_empty()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -797,13 +801,17 @@ fn test_ln_seen_file() {
|
|||
let result = ts.ucmd().arg("a/f").arg("b/f").arg("c").fails();
|
||||
|
||||
#[cfg(not(unix))]
|
||||
assert!(result
|
||||
.stderr_str()
|
||||
.contains("will not overwrite just-created 'c\\f' with 'b/f'"));
|
||||
assert!(
|
||||
result
|
||||
.stderr_str()
|
||||
.contains("will not overwrite just-created 'c\\f' with 'b/f'")
|
||||
);
|
||||
#[cfg(unix)]
|
||||
assert!(result
|
||||
.stderr_str()
|
||||
.contains("will not overwrite just-created 'c/f' with 'b/f'"));
|
||||
assert!(
|
||||
result
|
||||
.stderr_str()
|
||||
.contains("will not overwrite just-created 'c/f' with 'b/f'")
|
||||
);
|
||||
|
||||
assert!(at.plus("c").join("f").exists());
|
||||
// b/f still exists
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// For the full copyright and license information, please view the LICENSE
|
||||
// file that was distributed with this source code.
|
||||
use crate::common::util::{is_ci, TestScenario};
|
||||
use crate::common::util::{TestScenario, is_ci};
|
||||
use std::env;
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -10,9 +10,9 @@
|
|||
clippy::cast_possible_truncation
|
||||
)]
|
||||
|
||||
use crate::common::util::TestScenario;
|
||||
#[cfg(any(unix, feature = "feat_selinux"))]
|
||||
use crate::common::util::expected_result;
|
||||
use crate::common::util::TestScenario;
|
||||
#[cfg(all(unix, feature = "chmod"))]
|
||||
use nix::unistd::{close, dup};
|
||||
use regex::Regex;
|
||||
|
@ -1033,9 +1033,10 @@ fn test_ls_zero() {
|
|||
);
|
||||
|
||||
let result = scene.ucmd().args(&["--zero", "--color=always"]).succeeds();
|
||||
assert_eq!(result.stdout_str(),
|
||||
"\u{1b}[0m\u{1b}[01;34m0-test-zero\x1b[0m\x001\ntest-zero\x002-test-zero\x003-test-zero\x00",
|
||||
);
|
||||
assert_eq!(
|
||||
result.stdout_str(),
|
||||
"\u{1b}[0m\u{1b}[01;34m0-test-zero\x1b[0m\x001\ntest-zero\x002-test-zero\x003-test-zero\x00",
|
||||
);
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
|
@ -5029,15 +5030,19 @@ fn test_ls_hyperlink() {
|
|||
|
||||
let result = scene.ucmd().arg("--hyperlink").succeeds();
|
||||
assert!(result.stdout_str().contains("\x1b]8;;file://"));
|
||||
assert!(result
|
||||
.stdout_str()
|
||||
.contains(&format!("{path}{separator}{file}\x07{file}\x1b]8;;\x07")));
|
||||
assert!(
|
||||
result
|
||||
.stdout_str()
|
||||
.contains(&format!("{path}{separator}{file}\x07{file}\x1b]8;;\x07"))
|
||||
);
|
||||
|
||||
let result = scene.ucmd().arg("--hyperlink=always").succeeds();
|
||||
assert!(result.stdout_str().contains("\x1b]8;;file://"));
|
||||
assert!(result
|
||||
.stdout_str()
|
||||
.contains(&format!("{path}{separator}{file}\x07{file}\x1b]8;;\x07")));
|
||||
assert!(
|
||||
result
|
||||
.stdout_str()
|
||||
.contains(&format!("{path}{separator}{file}\x07{file}\x1b]8;;\x07"))
|
||||
);
|
||||
|
||||
for argument in [
|
||||
"--hyperlink=never",
|
||||
|
@ -5069,19 +5074,27 @@ fn test_ls_hyperlink_encode_link() {
|
|||
let result = ucmd.arg("--hyperlink").succeeds();
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
assert!(result
|
||||
.stdout_str()
|
||||
.contains("back%5cslash\x07back\\slash\x1b]8;;\x07"));
|
||||
assert!(result
|
||||
.stdout_str()
|
||||
.contains("ques%3ftion\x07ques?tion\x1b]8;;\x07"));
|
||||
assert!(
|
||||
result
|
||||
.stdout_str()
|
||||
.contains("back%5cslash\x07back\\slash\x1b]8;;\x07")
|
||||
);
|
||||
assert!(
|
||||
result
|
||||
.stdout_str()
|
||||
.contains("ques%3ftion\x07ques?tion\x1b]8;;\x07")
|
||||
);
|
||||
}
|
||||
assert!(result
|
||||
.stdout_str()
|
||||
.contains("encoded%253Fquestion\x07encoded%3Fquestion\x1b]8;;\x07"));
|
||||
assert!(result
|
||||
.stdout_str()
|
||||
.contains("sp%20ace\x07sp ace\x1b]8;;\x07"));
|
||||
assert!(
|
||||
result
|
||||
.stdout_str()
|
||||
.contains("encoded%253Fquestion\x07encoded%3Fquestion\x1b]8;;\x07")
|
||||
);
|
||||
assert!(
|
||||
result
|
||||
.stdout_str()
|
||||
.contains("sp%20ace\x07sp ace\x1b]8;;\x07")
|
||||
);
|
||||
}
|
||||
// spell-checker: enable
|
||||
|
||||
|
@ -5106,19 +5119,23 @@ fn test_ls_hyperlink_dirs() {
|
|||
.succeeds();
|
||||
|
||||
assert!(result.stdout_str().contains("\x1b]8;;file://"));
|
||||
assert!(result
|
||||
.stdout_str()
|
||||
.lines()
|
||||
.next()
|
||||
.unwrap()
|
||||
.contains(&format!("{path}{separator}{dir_a}\x07{dir_a}\x1b]8;;\x07:")));
|
||||
assert!(
|
||||
result
|
||||
.stdout_str()
|
||||
.lines()
|
||||
.next()
|
||||
.unwrap()
|
||||
.contains(&format!("{path}{separator}{dir_a}\x07{dir_a}\x1b]8;;\x07:"))
|
||||
);
|
||||
assert_eq!(result.stdout_str().lines().nth(1).unwrap(), "");
|
||||
assert!(result
|
||||
.stdout_str()
|
||||
.lines()
|
||||
.nth(2)
|
||||
.unwrap()
|
||||
.contains(&format!("{path}{separator}{dir_b}\x07{dir_b}\x1b]8;;\x07:")));
|
||||
assert!(
|
||||
result
|
||||
.stdout_str()
|
||||
.lines()
|
||||
.nth(2)
|
||||
.unwrap()
|
||||
.contains(&format!("{path}{separator}{dir_b}\x07{dir_b}\x1b]8;;\x07:"))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -23,12 +23,14 @@ fn test_mknod_help() {
|
|||
#[test]
|
||||
#[cfg(not(windows))]
|
||||
fn test_mknod_version() {
|
||||
assert!(new_ucmd!()
|
||||
.arg("--version")
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.stdout_str()
|
||||
.starts_with("mknod"));
|
||||
assert!(
|
||||
new_ucmd!()
|
||||
.arg("--version")
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.stdout_str()
|
||||
.starts_with("mknod")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -8,9 +8,9 @@ use crate::common::util::TestScenario;
|
|||
|
||||
use uucore::display::Quotable;
|
||||
|
||||
use std::path::PathBuf;
|
||||
#[cfg(not(windows))]
|
||||
use std::path::MAIN_SEPARATOR;
|
||||
use std::path::PathBuf;
|
||||
use tempfile::tempdir;
|
||||
|
||||
#[cfg(unix)]
|
||||
|
|
|
@ -112,7 +112,7 @@ fn test_more_dir_arg() {
|
|||
#[test]
|
||||
#[cfg(target_family = "unix")]
|
||||
fn test_more_invalid_file_perms() {
|
||||
use std::fs::{set_permissions, Permissions};
|
||||
use std::fs::{Permissions, set_permissions};
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
|
||||
if std::io::stdout().is_terminal() {
|
||||
|
|
|
@ -1377,13 +1377,15 @@ fn test_mv_errors() {
|
|||
// $ at.mkdir dir && at.touch file
|
||||
// $ mv dir file
|
||||
// err == mv: cannot overwrite non-directory 'file' with directory 'dir'
|
||||
assert!(!scene
|
||||
.ucmd()
|
||||
.arg(dir)
|
||||
.arg(file_a)
|
||||
.fails()
|
||||
.stderr_str()
|
||||
.is_empty());
|
||||
assert!(
|
||||
!scene
|
||||
.ucmd()
|
||||
.arg(dir)
|
||||
.arg(file_a)
|
||||
.fails()
|
||||
.stderr_str()
|
||||
.is_empty()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1448,15 +1450,17 @@ fn test_mv_interactive_error() {
|
|||
// $ at.mkdir dir && at.touch file
|
||||
// $ mv -i dir file
|
||||
// err == mv: cannot overwrite non-directory 'file' with directory 'dir'
|
||||
assert!(!scene
|
||||
.ucmd()
|
||||
.arg("-i")
|
||||
.arg(dir)
|
||||
.arg(file_a)
|
||||
.pipe_in("y")
|
||||
.fails()
|
||||
.stderr_str()
|
||||
.is_empty());
|
||||
assert!(
|
||||
!scene
|
||||
.ucmd()
|
||||
.arg("-i")
|
||||
.arg(dir)
|
||||
.arg(file_a)
|
||||
.pipe_in("y")
|
||||
.fails()
|
||||
.stderr_str()
|
||||
.is_empty()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1581,13 +1585,17 @@ fn test_mv_seen_file() {
|
|||
let result = ts.ucmd().arg("a/f").arg("b/f").arg("c").fails();
|
||||
|
||||
#[cfg(not(unix))]
|
||||
assert!(result
|
||||
.stderr_str()
|
||||
.contains("will not overwrite just-created 'c\\f' with 'b/f'"));
|
||||
assert!(
|
||||
result
|
||||
.stderr_str()
|
||||
.contains("will not overwrite just-created 'c\\f' with 'b/f'")
|
||||
);
|
||||
#[cfg(unix)]
|
||||
assert!(result
|
||||
.stderr_str()
|
||||
.contains("will not overwrite just-created 'c/f' with 'b/f'"));
|
||||
assert!(
|
||||
result
|
||||
.stderr_str()
|
||||
.contains("will not overwrite just-created 'c/f' with 'b/f'")
|
||||
);
|
||||
|
||||
// a/f has been moved into c/f
|
||||
assert!(at.plus("c").join("f").exists());
|
||||
|
@ -1611,13 +1619,17 @@ fn test_mv_seen_multiple_files_to_directory() {
|
|||
|
||||
let result = ts.ucmd().arg("a/f").arg("b/f").arg("b/g").arg("c").fails();
|
||||
#[cfg(not(unix))]
|
||||
assert!(result
|
||||
.stderr_str()
|
||||
.contains("will not overwrite just-created 'c\\f' with 'b/f'"));
|
||||
assert!(
|
||||
result
|
||||
.stderr_str()
|
||||
.contains("will not overwrite just-created 'c\\f' with 'b/f'")
|
||||
);
|
||||
#[cfg(unix)]
|
||||
assert!(result
|
||||
.stderr_str()
|
||||
.contains("will not overwrite just-created 'c/f' with 'b/f'"));
|
||||
assert!(
|
||||
result
|
||||
.stderr_str()
|
||||
.contains("will not overwrite just-created 'c/f' with 'b/f'")
|
||||
);
|
||||
|
||||
assert!(!at.plus("a").join("f").exists());
|
||||
assert!(at.plus("b").join("f").exists());
|
||||
|
@ -1756,7 +1768,7 @@ fn test_move_should_not_fallback_to_copy() {
|
|||
mod inter_partition_copying {
|
||||
use crate::common::util::TestScenario;
|
||||
use std::fs::{read_to_string, set_permissions, write};
|
||||
use std::os::unix::fs::{symlink, PermissionsExt};
|
||||
use std::os::unix::fs::{PermissionsExt, symlink};
|
||||
use tempfile::TempDir;
|
||||
|
||||
// Ensure that the copying code used in an inter-partition move unlinks the destination symlink.
|
||||
|
|
|
@ -24,9 +24,10 @@ fn test_negative_adjustment() {
|
|||
// correctly.
|
||||
|
||||
let res = new_ucmd!().args(&["-n", "-1", "true"]).succeeds();
|
||||
assert!(res
|
||||
.stderr_str()
|
||||
.starts_with("nice: warning: setpriority: Permission denied")); // spell-checker:disable-line
|
||||
assert!(
|
||||
res.stderr_str()
|
||||
.starts_with("nice: warning: setpriority: Permission denied")
|
||||
); // spell-checker:disable-line
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#[cfg(target_os = "openbsd")]
|
||||
use crate::common::util::TestScenario;
|
||||
#[cfg(not(target_os = "openbsd"))]
|
||||
use crate::common::util::{expected_result, TestScenario};
|
||||
use crate::common::util::{TestScenario, expected_result};
|
||||
use pinky::Capitalize;
|
||||
#[cfg(not(target_os = "openbsd"))]
|
||||
use uucore::entries::{Locate, Passwd};
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// For the full copyright and license information, please view the LICENSE
|
||||
// file that was distributed with this source code.
|
||||
// spell-checker:ignore regfile
|
||||
use crate::common::util::{get_root_path, TestScenario};
|
||||
use crate::common::util::{TestScenario, get_root_path};
|
||||
|
||||
static GIBBERISH: &str = "supercalifragilisticexpialidocious";
|
||||
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
// For the full copyright and license information, please view the LICENSE
|
||||
// file that was distributed with this source code.
|
||||
// spell-checker:ignore nusr
|
||||
use crate::common::util::{get_root_path, TestScenario};
|
||||
use crate::common::util::{TestScenario, get_root_path};
|
||||
|
||||
#[cfg(windows)]
|
||||
use regex::Regex;
|
||||
use std::path::{Path, MAIN_SEPARATOR};
|
||||
use std::path::{MAIN_SEPARATOR, Path};
|
||||
|
||||
static GIBBERISH: &str = "supercalifragilisticexpialidocious";
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
// spell-checker:ignore xzaaa sixhundredfiftyonebytes ninetyonebytes threebytes asciilowercase ghijkl mnopq rstuv wxyz fivelines twohundredfortyonebytes onehundredlines nbbbb dxen ncccc rlimit NOFILE
|
||||
|
||||
use crate::common::util::{AtPath, TestScenario};
|
||||
use rand::{rng, Rng, SeedableRng};
|
||||
use rand::{Rng, SeedableRng, rng};
|
||||
use regex::Regex;
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
use rlimit::Resource;
|
||||
|
@ -13,7 +13,7 @@ use rlimit::Resource;
|
|||
use std::env;
|
||||
use std::path::Path;
|
||||
use std::{
|
||||
fs::{read_dir, File},
|
||||
fs::{File, read_dir},
|
||||
io::{BufWriter, Read, Write},
|
||||
};
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// For the full copyright and license information, please view the LICENSE
|
||||
// file that was distributed with this source code.
|
||||
|
||||
use crate::common::util::{expected_result, TestScenario};
|
||||
use crate::common::util::{TestScenario, expected_result};
|
||||
|
||||
#[test]
|
||||
fn test_invalid_arg() {
|
||||
|
|
|
@ -14,11 +14,11 @@
|
|||
)]
|
||||
|
||||
use crate::common::random::{AlphanumericNewline, RandomizedString};
|
||||
use crate::common::util::TestScenario;
|
||||
#[cfg(unix)]
|
||||
use crate::common::util::expected_result;
|
||||
#[cfg(not(windows))]
|
||||
use crate::common::util::is_ci;
|
||||
use crate::common::util::TestScenario;
|
||||
use pretty_assertions::assert_eq;
|
||||
use rand::distr::Alphanumeric;
|
||||
use rstest::rstest;
|
||||
|
|
|
@ -274,8 +274,10 @@ mod linux_only {
|
|||
name,
|
||||
contents.len()
|
||||
);
|
||||
assert!(contents.starts_with(&compare),
|
||||
"Expected truncated output to be a prefix of the correct output, but it isn't.\n Correct: {contents}\n Compare: {compare}");
|
||||
assert!(
|
||||
contents.starts_with(&compare),
|
||||
"Expected truncated output to be a prefix of the correct output, but it isn't.\n Correct: {contents}\n Compare: {compare}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
// spell-checker:ignore (formats) cymdhm cymdhms mdhm mdhms ymdhm ymdhms datetime mktime
|
||||
|
||||
use crate::common::util::{AtPath, TestScenario};
|
||||
use filetime::FileTime;
|
||||
#[cfg(not(target_os = "freebsd"))]
|
||||
use filetime::set_symlink_file_times;
|
||||
use filetime::FileTime;
|
||||
use std::fs::remove_file;
|
||||
use std::path::PathBuf;
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// For the full copyright and license information, please view the LICENSE
|
||||
// file that was distributed with this source code.
|
||||
|
||||
use crate::common::util::{vec_of_size, TestScenario};
|
||||
use crate::common::util::{TestScenario, vec_of_size};
|
||||
|
||||
// spell-checker:ignore (flags) lwmcL clmwL ; (path) bogusfile emptyfile manyemptylines moby notrailingnewline onelongemptyline onelongword weirdchars
|
||||
#[test]
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
// spell-checker:ignore (flags) runlevel mesg
|
||||
|
||||
use crate::common::util::{expected_result, TestScenario};
|
||||
use crate::common::util::{TestScenario, expected_result};
|
||||
|
||||
#[test]
|
||||
fn test_invalid_arg() {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#[cfg(unix)]
|
||||
use crate::common::util::expected_result;
|
||||
use crate::common::util::{is_ci, whoami, TestScenario};
|
||||
use crate::common::util::{TestScenario, is_ci, whoami};
|
||||
|
||||
#[test]
|
||||
fn test_invalid_arg() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue