+
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 104 additions & 0 deletions src/find/matchers/empty.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// Copyright 2021 Collabora, Ltd.
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.

use std::{
fs::read_dir,
io::{stderr, Write},
};

use super::Matcher;

pub struct EmptyMatcher;

impl EmptyMatcher {
pub fn new() -> EmptyMatcher {
EmptyMatcher
}

pub fn new_box() -> Box<dyn Matcher> {
Box::new(EmptyMatcher::new())
}
}

impl Matcher for EmptyMatcher {
fn matches(&self, file_info: &walkdir::DirEntry, _: &mut super::MatcherIO) -> bool {
if file_info.file_type().is_file() {
match file_info.metadata() {
Ok(meta) => meta.len() == 0,
Err(err) => {
writeln!(
&mut stderr(),
"Error getting size for {}: {}",
file_info.path().display(),
err
)
.unwrap();
false
}
}
} else if file_info.file_type().is_dir() {
match read_dir(file_info.path()) {
Ok(mut it) => it.next().is_none(),
Err(err) => {
writeln!(
&mut stderr(),
"Error getting contents of {}: {}",
file_info.path().display(),
err
)
.unwrap();
false
}
}
} else {
false
}
}
}

#[cfg(test)]
mod tests {
use tempfile::Builder;

use super::*;
use crate::find::matchers::tests::get_dir_entry_for;
use crate::find::matchers::Matcher;
use crate::find::tests::FakeDependencies;

#[test]
fn empty_files() {
let empty_file_info = get_dir_entry_for("test_data/simple", "abbbc");
let nonempty_file_info = get_dir_entry_for("test_data/size", "512bytes");

let matcher = EmptyMatcher::new();
let deps = FakeDependencies::new();

assert!(matcher.matches(&empty_file_info, &mut deps.new_matcher_io()));
assert!(!matcher.matches(&nonempty_file_info, &mut deps.new_matcher_io()));
}

#[test]
fn empty_directories() {
let temp_dir = Builder::new()
.prefix("empty_directories")
.tempdir()
.unwrap();
let temp_dir_path = temp_dir.path().to_string_lossy();
let subdir_name = "subdir";
std::fs::create_dir(temp_dir.path().join(subdir_name)).unwrap();

let matcher = EmptyMatcher::new();
let deps = FakeDependencies::new();

let file_info = get_dir_entry_for(&temp_dir_path, subdir_name);
assert!(matcher.matches(&file_info, &mut deps.new_matcher_io()));

std::fs::File::create(temp_dir.path().join(subdir_name).join("a")).unwrap();

let file_info = get_dir_entry_for(&temp_dir_path, subdir_name);
assert!(!matcher.matches(&file_info, &mut deps.new_matcher_io()));
}
}
2 changes: 2 additions & 0 deletions src/find/matchers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// https://opensource.org/licenses/MIT.

mod delete;
mod empty;
pub mod exec;
mod logical_matchers;
mod name;
Expand Down Expand Up @@ -301,6 +302,7 @@ fn build_matcher_tree(
i += 1;
Some(size::SizeMatcher::new_box(size, &unit)?)
}
"-empty" => Some(empty::EmptyMatcher::new_box()),
"-exec" | "-execdir" => {
let mut arg_index = i + 1;
while arg_index < args.len() && args[arg_index] != ";" {
Expand Down
58 changes: 58 additions & 0 deletions tests/find_cmd_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use assert_cmd::Command;
use predicates::prelude::*;
use serial_test::serial;
use std::fs::File;
use std::io::Write;
use std::{env, io::ErrorKind};
use tempfile::Builder;

Expand Down Expand Up @@ -191,6 +192,63 @@ fn regex_types() {
.stdout(predicate::str::contains("teeest"));
}

#[test]
fn empty_files() {
let temp_dir = Builder::new().prefix("find_cmd_").tempdir().unwrap();
let temp_dir_path = temp_dir.path().to_string_lossy();

Command::cargo_bin("find")
.expect("found binary")
.args(&[&temp_dir_path, "-empty"])
.assert()
.success()
.stderr(predicate::str::is_empty())
.stdout(fix_up_slashes(&format!("{}\n", temp_dir_path)));

let test_file_path = temp_dir.path().join("test");
let mut test_file = File::create(&test_file_path).unwrap();

Command::cargo_bin("find")
.expect("found binary")
.args(&[&temp_dir_path, "-empty"])
.assert()
.success()
.stderr(predicate::str::is_empty())
.stdout(fix_up_slashes(&format!(
"{}\n",
test_file_path.to_string_lossy()
)));

let subdir_path = temp_dir.path().join("subdir");
std::fs::create_dir(&subdir_path).unwrap();

Command::cargo_bin("find")
.expect("found binary")
.args(&[&temp_dir_path, "-empty", "-sorted"])
.assert()
.success()
.stderr(predicate::str::is_empty())
.stdout(fix_up_slashes(&format!(
"{}\n{}\n",
subdir_path.to_string_lossy(),
test_file_path.to_string_lossy()
)));

write!(test_file, "x").unwrap();
test_file.sync_all().unwrap();

Command::cargo_bin("find")
.expect("found binary")
.args(&[&temp_dir_path, "-empty", "-sorted"])
.assert()
.success()
.stderr(predicate::str::is_empty())
.stdout(fix_up_slashes(&format!(
"{}\n",
subdir_path.to_string_lossy(),
)));
}

#[serial(working_dir)]
#[test]
fn find_printf() {
Expand Down
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载