mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-27 11:07:44 +00:00
Merge pull request #7765 from aaron-ang/more-mem-constant
more: constant memory initialization overhead
This commit is contained in:
commit
9fbb6aca3c
5 changed files with 850 additions and 653 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -3031,6 +3031,7 @@ dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"crossterm",
|
"crossterm",
|
||||||
"nix",
|
"nix",
|
||||||
|
"tempfile",
|
||||||
"unicode-segmentation",
|
"unicode-segmentation",
|
||||||
"unicode-width 0.2.0",
|
"unicode-width 0.2.0",
|
||||||
"uucore",
|
"uucore",
|
||||||
|
|
|
@ -342,7 +342,6 @@ thiserror = "2.0.3"
|
||||||
time = { version = "0.3.36" }
|
time = { version = "0.3.36" }
|
||||||
unicode-segmentation = "1.11.0"
|
unicode-segmentation = "1.11.0"
|
||||||
unicode-width = "0.2.0"
|
unicode-width = "0.2.0"
|
||||||
utf-8 = "0.7.6"
|
|
||||||
utmp-classic = "0.1.6"
|
utmp-classic = "0.1.6"
|
||||||
uutils_term_grid = "0.7"
|
uutils_term_grid = "0.7"
|
||||||
walkdir = "2.5"
|
walkdir = "2.5"
|
||||||
|
|
|
@ -33,3 +33,6 @@ crossterm = { workspace = true, features = ["use-dev-tty"] }
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "more"
|
name = "more"
|
||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
tempfile = { workspace = true }
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -2,58 +2,60 @@
|
||||||
//
|
//
|
||||||
// For the full copyright and license information, please view the LICENSE
|
// For the full copyright and license information, please view the LICENSE
|
||||||
// file that was distributed with this source code.
|
// file that was distributed with this source code.
|
||||||
use std::io::IsTerminal;
|
|
||||||
#[cfg(target_family = "unix")]
|
|
||||||
use uutests::at_and_ucmd;
|
|
||||||
use uutests::new_ucmd;
|
|
||||||
use uutests::util::TestScenario;
|
|
||||||
use uutests::util_name;
|
|
||||||
|
|
||||||
|
use std::io::IsTerminal;
|
||||||
|
|
||||||
|
use uutests::{at_and_ucmd, new_ucmd, util::TestScenario, util_name};
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_more_no_arg() {
|
fn test_no_arg() {
|
||||||
if std::io::stdout().is_terminal() {
|
if std::io::stdout().is_terminal() {
|
||||||
new_ucmd!().fails().stderr_contains("more: bad usage");
|
new_ucmd!()
|
||||||
|
.terminal_simulation(true)
|
||||||
|
.fails()
|
||||||
|
.stderr_contains("more: bad usage");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_valid_arg() {
|
fn test_valid_arg() {
|
||||||
if std::io::stdout().is_terminal() {
|
if std::io::stdout().is_terminal() {
|
||||||
let scene = TestScenario::new(util_name!());
|
let args_list: Vec<&[&str]> = vec![
|
||||||
let at = &scene.fixtures;
|
&["-c"],
|
||||||
|
&["--clean-print"],
|
||||||
let file = "test_file";
|
&["-p"],
|
||||||
at.touch(file);
|
&["--print-over"],
|
||||||
|
&["-s"],
|
||||||
scene.ucmd().arg(file).arg("-c").succeeds();
|
&["--squeeze"],
|
||||||
scene.ucmd().arg(file).arg("--print-over").succeeds();
|
&["-u"],
|
||||||
|
&["--plain"],
|
||||||
scene.ucmd().arg(file).arg("-p").succeeds();
|
&["-n", "10"],
|
||||||
scene.ucmd().arg(file).arg("--clean-print").succeeds();
|
&["--lines", "0"],
|
||||||
|
&["--number", "0"],
|
||||||
scene.ucmd().arg(file).arg("-s").succeeds();
|
&["-F", "10"],
|
||||||
scene.ucmd().arg(file).arg("--squeeze").succeeds();
|
&["--from-line", "0"],
|
||||||
|
&["-P", "something"],
|
||||||
scene.ucmd().arg(file).arg("-u").succeeds();
|
&["--pattern", "-1"],
|
||||||
scene.ucmd().arg(file).arg("--plain").succeeds();
|
];
|
||||||
|
for args in args_list {
|
||||||
scene.ucmd().arg(file).arg("-n").arg("10").succeeds();
|
test_alive(args);
|
||||||
scene.ucmd().arg(file).arg("--lines").arg("0").succeeds();
|
}
|
||||||
scene.ucmd().arg(file).arg("--number").arg("0").succeeds();
|
|
||||||
|
|
||||||
scene.ucmd().arg(file).arg("-F").arg("10").succeeds();
|
|
||||||
scene
|
|
||||||
.ucmd()
|
|
||||||
.arg(file)
|
|
||||||
.arg("--from-line")
|
|
||||||
.arg("0")
|
|
||||||
.succeeds();
|
|
||||||
|
|
||||||
scene.ucmd().arg(file).arg("-P").arg("something").succeeds();
|
|
||||||
scene.ucmd().arg(file).arg("--pattern").arg("-1").succeeds();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_alive(args: &[&str]) {
|
||||||
|
let (at, mut ucmd) = at_and_ucmd!();
|
||||||
|
let file = "test_file";
|
||||||
|
at.touch(file);
|
||||||
|
|
||||||
|
ucmd.args(args)
|
||||||
|
.arg(file)
|
||||||
|
.run_no_wait()
|
||||||
|
.make_assertion()
|
||||||
|
.is_alive();
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_invalid_arg() {
|
fn test_invalid_arg() {
|
||||||
if std::io::stdout().is_terminal() {
|
if std::io::stdout().is_terminal() {
|
||||||
|
@ -67,59 +69,46 @@ fn test_invalid_arg() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_argument_from_file() {
|
fn test_file_arg() {
|
||||||
if std::io::stdout().is_terminal() {
|
|
||||||
let scene = TestScenario::new(util_name!());
|
|
||||||
let at = &scene.fixtures;
|
|
||||||
|
|
||||||
let file = "test_file";
|
|
||||||
|
|
||||||
at.write(file, "1\n2");
|
|
||||||
|
|
||||||
// output all lines
|
|
||||||
scene
|
|
||||||
.ucmd()
|
|
||||||
.arg("-F")
|
|
||||||
.arg("0")
|
|
||||||
.arg(file)
|
|
||||||
.succeeds()
|
|
||||||
.no_stderr()
|
|
||||||
.stdout_contains("1")
|
|
||||||
.stdout_contains("2");
|
|
||||||
|
|
||||||
// output only the second line
|
|
||||||
scene
|
|
||||||
.ucmd()
|
|
||||||
.arg("-F")
|
|
||||||
.arg("2")
|
|
||||||
.arg(file)
|
|
||||||
.succeeds()
|
|
||||||
.no_stderr()
|
|
||||||
.stdout_contains("2")
|
|
||||||
.stdout_does_not_contain("1");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_more_dir_arg() {
|
|
||||||
// Run the test only if there's a valid terminal, else do nothing
|
// Run the test only if there's a valid terminal, else do nothing
|
||||||
// Maybe we could capture the error, i.e. "Device not found" in that case
|
// Maybe we could capture the error, i.e. "Device not found" in that case
|
||||||
// but I am leaving this for later
|
// but I am leaving this for later
|
||||||
if std::io::stdout().is_terminal() {
|
if std::io::stdout().is_terminal() {
|
||||||
new_ucmd!()
|
// Directory as argument
|
||||||
.arg(".")
|
let mut ucmd = TestScenario::new(util_name!()).ucmd();
|
||||||
|
ucmd.arg(".")
|
||||||
.succeeds()
|
.succeeds()
|
||||||
.stderr_contains("'.' is a directory.");
|
.stderr_contains("'.' is a directory.");
|
||||||
|
|
||||||
|
// Single argument errors
|
||||||
|
let (at, mut ucmd) = at_and_ucmd!();
|
||||||
|
at.mkdir_all("folder");
|
||||||
|
ucmd.arg("folder")
|
||||||
|
.succeeds()
|
||||||
|
.stderr_contains("is a directory");
|
||||||
|
|
||||||
|
ucmd = TestScenario::new(util_name!()).ucmd();
|
||||||
|
ucmd.arg("nonexistent_file")
|
||||||
|
.succeeds()
|
||||||
|
.stderr_contains("No such file or directory");
|
||||||
|
|
||||||
|
// Multiple nonexistent files
|
||||||
|
ucmd = TestScenario::new(util_name!()).ucmd();
|
||||||
|
ucmd.arg("file2")
|
||||||
|
.arg("file3")
|
||||||
|
.succeeds()
|
||||||
|
.stderr_contains("file2")
|
||||||
|
.stderr_contains("file3");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(target_family = "unix")]
|
#[cfg(target_family = "unix")]
|
||||||
fn test_more_invalid_file_perms() {
|
fn test_invalid_file_perms() {
|
||||||
use std::fs::{Permissions, set_permissions};
|
|
||||||
use std::os::unix::fs::PermissionsExt;
|
|
||||||
|
|
||||||
if std::io::stdout().is_terminal() {
|
if std::io::stdout().is_terminal() {
|
||||||
|
use std::fs::{Permissions, set_permissions};
|
||||||
|
use std::os::unix::fs::PermissionsExt;
|
||||||
|
|
||||||
let (at, mut ucmd) = at_and_ucmd!();
|
let (at, mut ucmd) = at_and_ucmd!();
|
||||||
let permissions = Permissions::from_mode(0o244);
|
let permissions = Permissions::from_mode(0o244);
|
||||||
at.make_file("invalid-perms.txt");
|
at.make_file("invalid-perms.txt");
|
||||||
|
@ -129,89 +118,3 @@ fn test_more_invalid_file_perms() {
|
||||||
.stderr_contains("permission denied");
|
.stderr_contains("permission denied");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_more_error_on_single_arg() {
|
|
||||||
if std::io::stdout().is_terminal() {
|
|
||||||
let ts = TestScenario::new("more");
|
|
||||||
ts.fixtures.mkdir_all("folder");
|
|
||||||
ts.ucmd()
|
|
||||||
.arg("folder")
|
|
||||||
.succeeds()
|
|
||||||
.stderr_contains("is a directory");
|
|
||||||
ts.ucmd()
|
|
||||||
.arg("file1")
|
|
||||||
.succeeds()
|
|
||||||
.stderr_contains("No such file or directory");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_more_error_on_multiple_files() {
|
|
||||||
if std::io::stdout().is_terminal() {
|
|
||||||
let ts = TestScenario::new("more");
|
|
||||||
ts.fixtures.mkdir_all("folder");
|
|
||||||
ts.fixtures.make_file("file1");
|
|
||||||
ts.ucmd()
|
|
||||||
.arg("folder")
|
|
||||||
.arg("file2")
|
|
||||||
.arg("file1")
|
|
||||||
.succeeds()
|
|
||||||
.stderr_contains("folder")
|
|
||||||
.stderr_contains("file2")
|
|
||||||
.stdout_contains("file1");
|
|
||||||
ts.ucmd()
|
|
||||||
.arg("file2")
|
|
||||||
.arg("file3")
|
|
||||||
.succeeds()
|
|
||||||
.stderr_contains("file2")
|
|
||||||
.stderr_contains("file3");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_more_pattern_found() {
|
|
||||||
if std::io::stdout().is_terminal() {
|
|
||||||
let scene = TestScenario::new(util_name!());
|
|
||||||
let at = &scene.fixtures;
|
|
||||||
|
|
||||||
let file = "test_file";
|
|
||||||
|
|
||||||
at.write(file, "line1\nline2");
|
|
||||||
|
|
||||||
// output only the second line "line2"
|
|
||||||
scene
|
|
||||||
.ucmd()
|
|
||||||
.arg("-P")
|
|
||||||
.arg("line2")
|
|
||||||
.arg(file)
|
|
||||||
.succeeds()
|
|
||||||
.no_stderr()
|
|
||||||
.stdout_does_not_contain("line1")
|
|
||||||
.stdout_contains("line2");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_more_pattern_not_found() {
|
|
||||||
if std::io::stdout().is_terminal() {
|
|
||||||
let scene = TestScenario::new(util_name!());
|
|
||||||
let at = &scene.fixtures;
|
|
||||||
|
|
||||||
let file = "test_file";
|
|
||||||
|
|
||||||
let file_content = "line1\nline2";
|
|
||||||
at.write(file, file_content);
|
|
||||||
|
|
||||||
scene
|
|
||||||
.ucmd()
|
|
||||||
.arg("-P")
|
|
||||||
.arg("something")
|
|
||||||
.arg(file)
|
|
||||||
.succeeds()
|
|
||||||
.no_stderr()
|
|
||||||
.stdout_contains("Pattern not found")
|
|
||||||
.stdout_contains("line1")
|
|
||||||
.stdout_contains("line2");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue