1use crate::config::{Config, ExecKind, FileKind, RecentKind};
2use crate::error::MyResult;
3use crate::fs::file::{File, Signature};
4use crate::fs::total::Total;
5use crate::git::flags::GitFlags;
6use crate::regex;
7use crate::util::calendar::Calendar;
8use crate::util::color::ColorMap;
9use chrono::*;
10#[cfg(windows)]
11use regex::Captures;
12use std::collections::HashMap;
13use std::ffi::OsStr;
14use std::path::{Component, Path, PathBuf};
15#[cfg(unix)]
16use std::rc::Rc;
17use std::{cmp, path};
18use termcolor::WriteColor;
19
20const MODE_WIDTH: usize = 10; const GIT_WIDTH: usize = 5; const TIME_WIDTH: usize = 24; const MONTH_WIDTH: usize = 8; const SIG_WIDTH: usize = 13; const PAD_WIDTH: usize = 2; pub struct IndentChars {
28 pub branching: char,
29 pub terminating: char,
30 pub horizontal: char,
31 pub vertical: char,
32}
33
34enum IndentToken {
35 BranchMiddle,
36 BranchFinal,
37 SpaceMiddle,
38 SpaceFinal,
39}
40
41#[allow(dead_code)]
42pub struct Printer<'a, W: WriteColor> {
43 config: &'a Config,
44 calendar: Calendar,
45 writer: W,
46 counter: HashMap<PathBuf, isize>,
47 colors: ColorMap,
48 chars: IndentChars,
49 git_bash: bool,
50 separator: char,
51 separator_str: String,
52}
53
54impl<'a, W: WriteColor> Printer<'a, W> {
55 pub fn new<Tz: TimeZone>(
56 config: &'a Config,
57 zone: &Tz,
58 writer: W,
59 colors: ColorMap,
60 chars: IndentChars,
61 git_bash: bool,
62 ) -> Self {
63 let calendar = Calendar::from_time(&config.curr_time, zone);
64 let counter = HashMap::new();
65 #[cfg(windows)]
66 let git_bash = git_bash && !config.win_path;
67 let separator = if git_bash { '/' } else { path::MAIN_SEPARATOR };
68 let separator_str = separator.to_string();
69 Self {
70 config,
71 calendar,
72 writer,
73 counter,
74 colors,
75 chars,
76 git_bash,
77 separator,
78 separator_str,
79 }
80 }
81
82 pub fn print_files<Tz: TimeZone>(
83 &mut self,
84 files: &Vec<File>,
85 total: &Total,
86 zone: &Tz,
87 ) -> MyResult<()> {
88 if self.config.show_indent {
89 self.count_parents(files);
90 }
91 if self.config.only_path {
92 for file in files {
93 self.print_path(file, false)?;
94 self.print_newline()?;
95 }
96 } else {
97 let mode_width = measure_mode(self.config);
98 let size_width = if self.config.show_total {
99 measure_size(self.config, total.total_size)
100 } else {
101 measure_size(self.config, total.max_size)
102 };
103 let time_width = measure_time(self.config);
104 if self.config.filter_recent != RecentKind::None {
105 self.print_start(total, zone, mode_width, size_width, time_width)?;
106 }
107 for file in files {
108 self.print_file(file, total, zone, size_width)?;
109 }
110 if self.config.show_total {
111 self.print_total(total, mode_width, size_width, time_width)?;
112 }
113 }
114 Ok(())
115 }
116
117 #[allow(unused_mut)]
118 fn print_start<Tz: TimeZone>(
119 &mut self,
120 total: &Total,
121 zone: &Tz,
122 mode_width: usize,
123 size_width: usize,
124 time_width: usize,
125 ) -> MyResult<()> {
126 if let Some(start_time) = &total.start_time {
127 let mut combined_width = mode_width + PAD_WIDTH + size_width;
128 if self.config.filter_git.is_some() {
129 combined_width += 1 + GIT_WIDTH;
130 }
131 #[cfg(unix)]
132 if self.config.show_owner {
133 combined_width += PAD_WIDTH + total.user_width + 1 + total.group_width;
134 }
135 self.print_text("Start", combined_width)?;
136 self.print_time(start_time, zone, false)?;
137 writeln!(self.writer)?;
138 self.print_hyphens(combined_width + PAD_WIDTH + time_width)?;
139 }
140 Ok(())
141 }
142
143 fn print_file<Tz: TimeZone>(
144 &mut self,
145 file: &File,
146 total: &Total,
147 zone: &Tz,
148 size_width: usize,
149 ) -> MyResult<()> {
150 self.print_mode(file.file_type, file.file_mode, file.zip_depth)?;
151 self.print_git(file.git_flags)?;
152 #[cfg(unix)]
153 self.print_owner(&file.owner_user, &file.owner_group, total.user_width, total.group_width)?;
154 self.print_size(file.file_size, size_width)?;
155 self.print_time(&file.file_time, zone, true)?;
156 self.print_sig(file.file_sig)?;
157 #[cfg(windows)]
158 self.print_version(&file.file_ver, total.ver_width)?;
159 self.print_ext(&file.file_ext, total.ext_width)?;
160 #[cfg(debug_assertions)]
161 self.print_debug(file.file_depth, file.zip_depth)?;
162 self.print_path(file, true)?;
163 writeln!(self.writer)?;
164 Ok(())
165 }
166
167 #[allow(unused_mut)]
168 fn print_total(
169 &mut self,
170 total: &Total,
171 mode_width: usize,
172 size_width: usize,
173 time_width: usize,
174 ) -> MyResult<()> {
175 let mut combined_width = mode_width;
176 if self.config.filter_git.is_some() {
177 combined_width += 1 + GIT_WIDTH;
178 }
179 #[cfg(unix)]
180 if self.config.show_owner {
181 combined_width += PAD_WIDTH + total.user_width + 1 + total.group_width;
182 }
183 self.print_hyphens(combined_width + PAD_WIDTH + size_width + PAD_WIDTH + time_width)?;
184 self.print_text("Total", combined_width)?;
185 self.print_size(total.total_size, size_width)?;
186 self.print_spaces(PAD_WIDTH + PAD_WIDTH + time_width)?;
187 if self.config.show_sig {
188 self.print_spaces(PAD_WIDTH + SIG_WIDTH)?;
189 }
190 if total.ext_width > 0 {
191 self.print_spaces(PAD_WIDTH + total.ext_width)?;
192 }
193 self.print_summary(total)?;
194 writeln!(self.writer)?;
195 Ok(())
196 }
197
198 fn print_summary(
199 &mut self,
200 total: &Total,
201 ) -> MyResult<()> {
202 let files = if total.num_files == 1 { "file" } else { "files" };
203 let dirs = if total.num_dirs == 1 { "directory" } else { "directories" };
204 write!(
205 self.writer,
206 "{num_files} {files} {num_dirs} {dirs}",
207 num_files = total.num_files,
208 num_dirs = total.num_dirs,
209 )?;
210 Ok(())
211 }
212
213 fn print_mode(
214 &mut self,
215 file_type: FileKind,
216 file_mode: u32,
217 zip_depth: Option<usize>,
218 ) -> MyResult<()> {
219 if self.config.zip_expand {
220 if zip_depth.is_some() {
221 write!(self.writer, "z")?;
222 } else {
223 write!(self.writer, "-")?;
224 }
225 }
226 match file_type {
227 FileKind::File(_) => write!(self.writer, "-")?,
228 FileKind::Dir => write!(self.writer, "d")?,
229 FileKind::Link(_) => write!(self.writer, "l")?,
230 FileKind::Other => write!(self.writer, "?")?,
231 };
232 for shift in [6, 3, 0] {
233 let file_mode = file_mode >> shift;
234 if (file_mode & 4) != 0 {
235 write!(self.writer, "r")?;
236 } else {
237 write!(self.writer, "-")?;
238 }
239 if (file_mode & 2) != 0 {
240 write!(self.writer, "w")?;
241 } else {
242 write!(self.writer, "-")?;
243 }
244 if (file_mode & 1) != 0 {
245 write!(self.writer, "x")?;
246 } else {
247 write!(self.writer, "-")?;
248 }
249 }
250 Ok(())
251 }
252
253 fn print_git(
254 &mut self,
255 git_flags: Option<GitFlags>,
256 ) -> MyResult<()> {
257 if self.config.filter_git.is_some() {
258 if let Some(git_flags) = git_flags {
259 write!(self.writer, " ")?;
260 write!(self.writer, "{}", if git_flags.added { 'A' } else { '-' })?;
261 write!(self.writer, "{}", if git_flags.modified { 'M' } else { '-' })?;
262 write!(self.writer, "{}", if git_flags.renamed { 'R' } else { '-' })?;
263 write!(self.writer, "{}", if git_flags.untracked { 'U' } else { '-' })?;
264 write!(self.writer, "{}", if git_flags.ignored { 'I' } else { '-' })?;
265 } else {
266 write!(self.writer, " -----")?;
267 }
268 }
269 Ok(())
270 }
271
272 #[cfg(unix)]
273 fn print_owner(
274 &mut self,
275 owner_user: &Option<Rc<String>>,
276 owner_group: &Option<Rc<String>>,
277 user_width: usize,
278 group_width: usize,
279 ) -> MyResult<()> {
280 if self.config.show_owner {
281 self.print_spaces(PAD_WIDTH)?;
282 if let Some(user) = owner_user {
283 write!(self.writer, "{0:1$}", user, user_width + 1)?;
284 } else {
285 write!(self.writer, "{0:1$}", "-", user_width + 1)?;
286 }
287 if let Some(group) = owner_group {
288 write!(self.writer, "{0:1$}", group, group_width)?;
289 } else {
290 write!(self.writer, "{0:1$}", "-", group_width)?;
291 }
292 }
293 Ok(())
294 }
295
296 fn print_size(
297 &mut self,
298 file_size: u64,
299 size_width: usize,
300 ) -> MyResult<()> {
301 self.print_spaces(PAD_WIDTH)?;
302 if self.config.show_pretty {
303 if file_size < 1_000 {
304 write!(self.writer, "{0:3} B ", file_size)?;
305 } else if file_size < 1_000_000 {
306 write!(self.writer, "{0:3} KB", file_size / 1_000)?;
307 } else if file_size < 1_000_000_000 {
308 write!(self.writer, "{0:3} MB", file_size / 1_000_000)?;
309 } else if file_size < 1_000_000_000_000 {
310 write!(self.writer, "{0:3} GB", file_size / 1_000_000_000)?;
311 } else if file_size < 1_000_000_000_000_000 {
312 write!(self.writer, "{0:3} TB", file_size / 1_000_000_000_000)?;
313 } else if file_size < 1_000_000_000_000_000_000 {
314 write!(self.writer, "{0:3} PB", file_size / 1_000_000_000_000_000)?;
315 } else {
316 write!(self.writer, "{0:3} EB", file_size / 1_000_000_000_000_000_000)?;
317 }
318 } else {
319 self.print_thousand(file_size, size_width)?;
320 }
321 Ok(())
322 }
323
324 fn print_thousand(
325 &mut self,
326 file_size: u64,
327 size_width: usize,
328 ) -> MyResult<()> {
329 if file_size < 1000 {
330 write!(self.writer, "{0:1$}", file_size, size_width)?;
331 } else {
332 self.print_thousand(file_size / 1000, cmp::max(size_width, 4) - 4)?;
333 write!(self.writer, ",{0:03}", file_size % 1000)?;
334 }
335 Ok(())
336 }
337
338 fn print_time<Tz: TimeZone>(
339 &mut self,
340 file_time: &DateTime<Utc>,
341 zone: &Tz,
342 padding: bool,
343 ) -> MyResult<()> {
344 self.print_spaces(PAD_WIDTH)?;
345 if self.config.show_pretty {
346 if file_time.timestamp() != 0 {
347 let recent = RecentKind::from_times(&file_time, &self.config.curr_time, &self.calendar, zone);
348 match recent {
349 RecentKind::None => write!(self.writer, " future")?,
350 RecentKind::Sec(count) => write!(self.writer, "{:2} sec", count)?,
351 RecentKind::Min(count) => write!(self.writer, "{:2} min", count)?,
352 RecentKind::Hour(count) => write!(self.writer, "{:2} hour", count)?,
353 RecentKind::Day(count) => write!(self.writer, "{:2} day", count)?,
354 RecentKind::Week(count) => write!(self.writer, "{:2} week", count)?,
355 RecentKind::Month(count) => write!(self.writer, "{:2} month", count)?,
356 RecentKind::Year(count) => write!(self.writer, "{:2} year", count)?,
357 }
358 if padding {
359 match recent {
360 RecentKind::None => write!(self.writer, " ")?,
361 RecentKind::Sec(_) => write!(self.writer, " ")?,
362 RecentKind::Min(_) => write!(self.writer, " ")?,
363 RecentKind::Hour(_) => write!(self.writer, " ")?,
364 RecentKind::Day(_) => write!(self.writer, " ")?,
365 RecentKind::Week(_) => write!(self.writer, " ")?,
366 RecentKind::Month(_) => (),
367 RecentKind::Year(_) => write!(self.writer, " ")?,
368 }
369 }
370 } else {
371 write!(self.writer, "{0:-<1$}", "", MONTH_WIDTH)?;
372 }
373 } else {
374 if file_time.timestamp() != 0 {
375 let file_time = file_time.with_timezone(zone);
376 let weekday = convert_weekday(file_time.weekday());
377 let day = file_time.day();
378 let month = convert_month(file_time.month());
379 let year = file_time.year();
380 let hour = file_time.hour();
381 let minute = file_time.minute();
382 let second = file_time.second();
383 write!(self.writer, "{weekday} {day:02}-{month}-{year:04} {hour:02}:{minute:02}:{second:02}")?;
384 if self.config.show_utc {
385 write!(self.writer, "Z")?;
386 }
387 } else {
388 write!(self.writer, "{0:-<1$}", "", TIME_WIDTH)?;
389 if self.config.show_utc {
390 write!(self.writer, "-")?;
391 }
392 }
393 }
394 Ok(())
395 }
396
397 fn print_sig(&mut self, file_sig: Signature) -> MyResult<()> {
398 if self.config.show_sig {
399 self.print_spaces(PAD_WIDTH)?;
400 for byte in file_sig {
401 write!(self.writer, "{:02x}", byte)?;
402 }
403 write!(self.writer, " ")?;
404 for byte in file_sig {
405 write!(self.writer, "{}", printable_char(byte))?;
406 }
407 }
408 Ok(())
409 }
410
411 #[cfg(windows)]
412 fn print_version(
413 &mut self,
414 file_ver: &Option<String>,
415 ver_width: usize,
416 ) -> MyResult<()> {
417 if ver_width > 0 {
418 self.print_spaces(PAD_WIDTH)?;
419 if let Some(file_ver) = file_ver {
420 write!(self.writer, "{0:1$}", file_ver, ver_width)?;
421 } else {
422 self.print_spaces(ver_width)?;
423 }
424 }
425 Ok(())
426 }
427
428 fn print_ext(
429 &mut self,
430 file_ext: &str,
431 ext_width: usize,
432 ) -> MyResult<()> {
433 if ext_width > 0 {
434 self.print_spaces(PAD_WIDTH)?;
435 write!(self.writer, "{0:1$}", file_ext, ext_width)?;
436 }
437 Ok(())
438 }
439
440 #[cfg(debug_assertions)]
441 fn print_debug(
442 &mut self,
443 file_depth: usize,
444 zip_depth: Option<usize>,
445 ) -> MyResult<()> {
446 if self.config.show_debug {
447 self.writer.set_color(&self.colors.debug_color)?;
448 if self.config.zip_expand {
449 let zip_depth = zip_depth
450 .map(|depth| depth.to_string())
451 .unwrap_or_else(|| "-".to_string());
452 write!(self.writer, "[{}][{}]", file_depth, zip_depth)?;
453 } else {
454 write!(self.writer, "[{}]", file_depth)?;
455 }
456 self.writer.reset()?;
457 write!(self.writer, " ")?;
458 }
459 Ok(())
460 }
461
462 fn print_path(
463 &mut self,
464 file: &File,
465 padding: bool,
466 ) -> MyResult<()> {
467 if padding {
468 self.print_spaces(PAD_WIDTH)?;
469 }
470 if self.config.show_indent {
471 self.print_prefix(file)?;
472 if file.file_type == FileKind::Dir {
473 self.indent_dir(&file.rel_dir, file.zip_depth, file.file_type.dir_offset())?;
474 } else {
475 self.print_name(&file.file_name, &file.file_ext, file.file_type)?;
476 }
477 self.print_link(&file.link_data)?;
478 } else {
479 let file_dir = file.select_dir(self.config.abs_path);
480 if self.config.order_name {
481 self.print_name(&file.file_name, &file.file_ext, file.file_type)?;
482 self.print_dir(file_dir, file.zip_depth, file.file_type.dir_offset(), true)?;
483 self.print_link(&file.link_data)?;
484 } else {
485 self.print_dir(file_dir, file.zip_depth, file.file_type.dir_offset(), false)?;
486 self.print_name(&file.file_name, &file.file_ext, file.file_type)?;
487 if !self.config.escape_path && !self.config.null_path {
488 self.print_link(&file.link_data)?;
489 }
490 }
491 }
492 Ok(())
493 }
494
495 fn print_dir(
496 &mut self,
497 file_dir: &Path,
498 zip_depth: Option<usize>,
499 zip_offset: usize,
500 order_name: bool,
501 ) -> MyResult<()> {
502 if !is_trivial(file_dir) {
503 if order_name {
504 write!(self.writer, " (")?;
505 self.iterate_dir(file_dir, zip_depth, zip_offset)?;
506 write!(self.writer, ")")?;
507 } else {
508 self.iterate_dir(file_dir, zip_depth, zip_offset)?;
509 }
510 }
511 Ok(())
512 }
513
514 fn iterate_dir(
515 &mut self,
516 file_dir: &Path,
517 zip_depth: Option<usize>,
518 zip_offset: usize,
519 ) -> MyResult<()> {
520 self.writer.set_color(&self.colors.dir_color)?;
521 let components = file_dir.components().into_iter().collect::<Vec<_>>();
522 let count = components.len();
523 for (index, component) in components.iter().enumerate() {
524 if let Some(text) = component.as_os_str().to_str() {
525 let color = zip_depth
526 .is_some_and(|depth| depth + zip_offset + index == count)
527 .then(|| get_extension(component))
528 .and_then(|ext| self.colors.find_color(ext));
529 if let Some(color) = color {
530 self.writer.set_color(color)?;
531 self.escape_dir(text)?;
532 self.writer.set_color(&self.colors.dir_color)?;
533 } else {
534 self.escape_dir(text)?;
535 }
536 if is_joinable(&component) {
537 write!(self.writer, "{}", self.separator)?;
538 }
539 }
540 }
541 self.writer.reset()?;
542 Ok(())
543 }
544
545 fn indent_dir(
546 &mut self,
547 file_dir: &Path,
548 zip_depth: Option<usize>,
549 zip_offset: usize,
550 ) -> MyResult<()> {
551 if let Some(component) = file_dir.components().last() {
552 if let Some(text) = component.as_os_str().to_str() {
553 let color = zip_depth
554 .is_some_and(|depth| depth + zip_offset == 1)
555 .then(|| get_extension(&component))
556 .and_then(|ext| self.colors.find_color(ext))
557 .unwrap_or(&self.colors.dir_color);
558 self.writer.set_color(color)?;
559 self.escape_dir(text)?;
560 self.writer.reset()?;
561 }
562 }
563 Ok(())
564 }
565
566 #[cfg(windows)]
567 fn escape_dir(
568 &mut self,
569 file_dir: &str,
570 ) -> MyResult<()> {
571 if self.git_bash {
572 let drive_regex = regex!(r#"^([A-Z]):(.*)$"#);
573 let file_dir = file_dir.replace(path::MAIN_SEPARATOR, &self.separator_str);
574 let file_dir = drive_regex.replace(&file_dir, |caps: &Captures| {
575 format!("{}{}{}", self.separator, &caps[1].to_lowercase(), &caps[2])
576 });
577 if self.config.escape_path {
578 let escape_regex = regex!(r#"([\s"'])"#);
579 let file_dir = escape_regex.replace_all(&file_dir, "\\$1");
580 write!(self.writer, "{file_dir}")?;
581 } else {
582 write!(self.writer, "{file_dir}")?;
583 }
584 } else {
585 write!(self.writer, "{file_dir}")?;
586 }
587 Ok(())
588 }
589
590 #[cfg(not(windows))]
591 fn escape_dir(
592 &mut self,
593 file_dir: &str,
594 ) -> MyResult<()> {
595 if self.config.escape_path {
596 let escape_regex = regex!(r#"([\s"'\\])"#);
597 let file_dir = escape_regex.replace_all(file_dir, "\\$1");
598 write!(self.writer, "{file_dir}")?;
599 } else {
600 write!(self.writer, "{file_dir}")?;
601 }
602 Ok(())
603 }
604
605 fn print_name(
606 &mut self,
607 file_name: &str,
608 file_ext: &str,
609 file_type: FileKind,
610 ) -> MyResult<()> {
611 if !file_name.is_empty() {
612 match file_type {
613 FileKind::File(exec) => {
614 if exec == ExecKind::User {
615 self.writer.set_color(&self.colors.exec_color)?;
616 self.escape_name(file_name)?;
617 self.writer.reset()?;
618 } else if exec == ExecKind::Other {
619 self.writer.set_color(&self.colors.exec_other)?;
620 self.escape_name(file_name)?;
621 self.writer.reset()?;
622 } else if let Some(color) = self.colors.find_color(file_ext) {
623 self.writer.set_color(color)?;
624 self.escape_name(file_name)?;
625 self.writer.reset()?;
626 } else {
627 self.escape_name(file_name)?;
628 }
629 }
630 FileKind::Dir => {
631 self.writer.set_color(&self.colors.dir_color)?;
632 self.escape_name(file_name)?;
633 write!(self.writer, "{}", self.separator)?;
634 self.writer.reset()?;
635 }
636 FileKind::Link(resolved) => {
637 if resolved {
638 self.writer.set_color(&self.colors.link_color)?;
639 } else {
640 self.writer.set_color(&self.colors.bad_color)?;
641 }
642 self.escape_name(file_name)?;
643 self.writer.reset()?;
644 }
645 FileKind::Other => {
646 self.escape_name(file_name)?;
647 }
648 }
649 }
650 Ok(())
651 }
652
653 #[cfg(windows)]
654 fn escape_name(
655 &mut self,
656 file_name: &str,
657 ) -> MyResult<()> {
658 if self.config.escape_path && self.git_bash {
659 let escape_regex = regex!(r#"([\s"'])"#);
660 let file_name = escape_regex.replace_all(file_name, "\\$1");
661 write!(self.writer, "{file_name}")?;
662 } else {
663 write!(self.writer, "{file_name}")?;
664 }
665 Ok(())
666 }
667
668 #[cfg(not(windows))]
669 fn escape_name(
670 &mut self,
671 file_name: &str,
672 ) -> MyResult<()> {
673 if self.config.escape_path {
674 let escape_regex = regex!(r#"([\s"'\\])"#);
675 let file_name = escape_regex.replace_all(file_name, "\\$1");
676 write!(self.writer, "{file_name}")?;
677 } else {
678 write!(self.writer, "{file_name}")?;
679 }
680 Ok(())
681 }
682
683 fn print_link(
684 &mut self,
685 link_data: &Option<(PathBuf, FileKind)>,
686 ) -> MyResult<()> {
687 if let Some((link_path, link_type)) = link_data {
688 if let Some(link_dir) = link_path.parent() {
689 if let Some(link_name) = link_path.file_name().and_then(OsStr::to_str) {
690 write!(self.writer, " -> ")?;
691 let link_ext = link_path.extension().and_then(OsStr::to_str).unwrap_or_default();
692 self.print_dir(link_dir, None, 0, false)?;
693 self.print_name(link_name, &link_ext, *link_type)?;
694 }
695 }
696 }
697 Ok(())
698 }
699
700 fn count_parents(&mut self, files: &Vec<File>) {
701 for file in files {
702 if file.file_depth > 1 {
703 if let Some(parent) = file.select_parent_for_indent() {
704 let entry = self.counter.entry(parent).or_insert(0);
705 *entry += 1;
706 }
707 }
708 }
709 }
710
711 fn print_prefix(&mut self, file: &File) -> MyResult<()> {
712 let tokens = self.create_prefix(file);
713 for token in tokens {
714 match token {
715 IndentToken::BranchMiddle => {
716 write!(self.writer, " ")?;
717 self.writer.set_color(&self.colors.dir_color)?;
718 write!(self.writer, "{}", self.chars.branching)?;
719 write!(self.writer, "{}", self.chars.horizontal)?;
720 self.writer.reset()?;
721 write!(self.writer, " ")?;
722 }
723 IndentToken::BranchFinal => {
724 write!(self.writer, " ")?;
725 self.writer.set_color(&self.colors.dir_color)?;
726 write!(self.writer, "{}", self.chars.terminating)?;
727 write!(self.writer, "{}", self.chars.horizontal)?;
728 self.writer.reset()?;
729 write!(self.writer, " ")?;
730 }
731 IndentToken::SpaceMiddle => {
732 write!(self.writer, " ")?;
733 self.writer.set_color(&self.colors.dir_color)?;
734 write!(self.writer, "{}", self.chars.vertical)?;
735 self.writer.reset()?;
736 write!(self.writer, " ")?;
737 }
738 IndentToken::SpaceFinal => {
739 write!(self.writer, " ")?;
740 }
741 }
742 }
743 Ok(())
744 }
745
746 fn create_prefix(&mut self, file: &File) -> Vec<IndentToken> {
747 let mut tokens = Vec::new();
748 if let Some(mut path) = file.select_parent_for_indent() {
749 if let Some(count) = self.counter.get_mut(&path) {
750 *count -= 1;
751 if *count > 0 {
752 tokens.push(IndentToken::BranchMiddle);
753 } else {
754 tokens.push(IndentToken::BranchFinal);
755 }
756 }
757 while let Some(parent) = path.parent() {
758 path = PathBuf::from(parent);
759 if let Some(count) = self.counter.get(&path) {
760 if *count > 0 {
761 tokens.push(IndentToken::SpaceMiddle);
762 } else {
763 tokens.push(IndentToken::SpaceFinal);
764 }
765 }
766 }
767 }
768 tokens.reverse();
769 tokens
770 }
771
772 fn print_text(&mut self, text: &str, width: usize) -> MyResult<()> {
773 write!(self.writer, "{0:<1$}", text, width)?;
774 Ok(())
775 }
776
777 fn print_spaces(&mut self, width: usize) -> MyResult<()> {
778 write!(self.writer, "{0:<1$}", "", width)?;
779 Ok(())
780 }
781
782 fn print_hyphens(&mut self, width: usize) -> MyResult<()> {
783 writeln!(self.writer, "{0:-<1$}", "", width)?;
784 Ok(())
785 }
786
787 fn print_newline(&mut self) -> MyResult<()> {
788 if self.config.null_path {
789 write!(self.writer, "\x00")?;
790 } else {
791 writeln!(self.writer)?;
792 }
793 Ok(())
794 }
795}
796
797fn measure_mode(config: &Config) -> usize {
798 if config.zip_expand {
799 MODE_WIDTH + 1
800 } else {
801 MODE_WIDTH
802 }
803}
804
805fn measure_size(config: &Config, size: u64) -> usize {
806 if config.show_pretty {
807 6
808 } else {
809 recurse_size(size)
810 }
811}
812
813fn recurse_size(size: u64) -> usize {
814 if size < 1000 {
815 3
816 } else {
817 recurse_size(size / 1000) + 4
818 }
819}
820
821fn measure_time(config: &Config) -> usize {
822 if config.show_pretty {
823 MONTH_WIDTH
824 } else if config.show_utc {
825 TIME_WIDTH + 1 } else {
827 TIME_WIDTH
828 }
829}
830
831fn convert_weekday(weekday: Weekday) -> &'static str {
832 match weekday {
833 Weekday::Mon => "Mon",
834 Weekday::Tue => "Tue",
835 Weekday::Wed => "Wed",
836 Weekday::Thu => "Thu",
837 Weekday::Fri => "Fri",
838 Weekday::Sat => "Sat",
839 Weekday::Sun => "Sun",
840 }
841}
842
843fn convert_month(month: u32) -> &'static str {
844 match month {
845 1 => "Jan",
846 2 => "Feb",
847 3 => "Mar",
848 4 => "Apr",
849 5 => "May",
850 6 => "Jun",
851 7 => "Jul",
852 8 => "Aug",
853 9 => "Sep",
854 10 => "Oct",
855 11 => "Nov",
856 12 => "Dec",
857 _ => "???",
858 }
859}
860
861#[inline]
862fn printable_char(byte: u8) -> char {
863 if byte >= 32 && byte <= 126 { byte as char } else { '.' }
864}
865
866fn is_trivial(file_dir: &Path) -> bool {
867 let file_dir = file_dir.to_str().unwrap_or_default();
868 file_dir.is_empty() || file_dir == "."
869}
870
871fn is_joinable(component: &Component) -> bool {
872 match component {
873 Component::Prefix(_) => false,
874 Component::RootDir => false,
875 Component::CurDir => true,
876 Component::ParentDir => true,
877 Component::Normal(_) => true,
878 }
879}
880
881fn get_extension<'a>(component: &'a Component) -> &'a str {
882 let component = component.as_os_str();
883 let (_, ext) = rsplit_file_at_dot(component);
884 ext.and_then(OsStr::to_str).unwrap_or_default()
885}
886
887fn rsplit_file_at_dot(file: &OsStr) -> (Option<&OsStr>, Option<&OsStr>) {
889 if file.as_encoded_bytes() == b".." {
890 (Some(file), None)
891 } else {
892 let mut iter = file.as_encoded_bytes().rsplitn(2, |b| *b == b'.');
897 let after = iter.next();
898 let before = iter.next();
899 if before == Some(b"") {
900 (Some(file), None)
901 } else {
902 unsafe {
903 let before = before.map(|s| OsStr::from_encoded_bytes_unchecked(s));
904 let after = after.map(|s| OsStr::from_encoded_bytes_unchecked(s));
905 (before, after)
906 }
907 }
908 }
909}
910
911#[cfg(test)]
912mod tests {
913 use super::*;
914 use crate::config::RecentKind;
915 use path_clean::PathClean;
916 use pretty_assertions::assert_eq;
917 use std::cmp::Ordering;
918 use std::io;
919 use std::io::Write;
920 use std::path::PathBuf;
921 use termcolor::{Color, ColorSpec};
922
923 #[test]
924 fn test_measures_mode_no_expand() {
925 let config = Config::default()
926 .with_zip_expand(false);
927 assert_eq!(10, measure_mode(&config));
928 }
929
930 #[test]
931 fn test_measures_mode_with_expand() {
932 let config = Config::default()
933 .with_zip_expand(true);
934 assert_eq!(11, measure_mode(&config));
935 }
936
937 #[test]
938 fn test_prints_type_no_expand() {
939 assert_eq!("----------", wrap_mode(false, None, 0o000, FileKind::File(ExecKind::None)));
940 assert_eq!("----------", wrap_mode(false, None, 0o000, FileKind::File(ExecKind::User)));
941 assert_eq!("----------", wrap_mode(false, None, 0o000, FileKind::File(ExecKind::Other)));
942 assert_eq!("d---------", wrap_mode(false, None, 0o000, FileKind::Dir));
943 assert_eq!("l---------", wrap_mode(false, None, 0o000, FileKind::Link(false)));
944 assert_eq!("l---------", wrap_mode(false, None, 0o000, FileKind::Link(true)));
945 assert_eq!("?---------", wrap_mode(false, None, 0o000, FileKind::Other));
946 assert_eq!("----------", wrap_mode(false, Some(0), 0o000, FileKind::File(ExecKind::None)));
947 assert_eq!("----------", wrap_mode(false, Some(0), 0o000, FileKind::File(ExecKind::User)));
948 assert_eq!("----------", wrap_mode(false, Some(0), 0o000, FileKind::File(ExecKind::Other)));
949 assert_eq!("d---------", wrap_mode(false, Some(0), 0o000, FileKind::Dir));
950 assert_eq!("l---------", wrap_mode(false, Some(0), 0o000, FileKind::Link(false)));
951 assert_eq!("l---------", wrap_mode(false, Some(0), 0o000, FileKind::Link(true)));
952 assert_eq!("?---------", wrap_mode(false, Some(0), 0o000, FileKind::Other));
953 }
954
955 #[test]
956 fn test_prints_type_with_expand() {
957 assert_eq!("-----------", wrap_mode(true, None, 0o000, FileKind::File(ExecKind::None)));
958 assert_eq!("-----------", wrap_mode(true, None, 0o000, FileKind::File(ExecKind::User)));
959 assert_eq!("-----------", wrap_mode(true, None, 0o000, FileKind::File(ExecKind::Other)));
960 assert_eq!("-d---------", wrap_mode(true, None, 0o000, FileKind::Dir));
961 assert_eq!("-l---------", wrap_mode(true, None, 0o000, FileKind::Link(false)));
962 assert_eq!("-l---------", wrap_mode(true, None, 0o000, FileKind::Link(true)));
963 assert_eq!("-?---------", wrap_mode(true, None, 0o000, FileKind::Other));
964 assert_eq!("z----------", wrap_mode(true, Some(0), 0o000, FileKind::File(ExecKind::None)));
965 assert_eq!("z----------", wrap_mode(true, Some(0), 0o000, FileKind::File(ExecKind::User)));
966 assert_eq!("z----------", wrap_mode(true, Some(0), 0o000, FileKind::File(ExecKind::Other)));
967 assert_eq!("zd---------", wrap_mode(true, Some(0), 0o000, FileKind::Dir));
968 assert_eq!("zl---------", wrap_mode(true, Some(0), 0o000, FileKind::Link(false)));
969 assert_eq!("zl---------", wrap_mode(true, Some(0), 0o000, FileKind::Link(true)));
970 assert_eq!("z?---------", wrap_mode(true, Some(0), 0o000, FileKind::Other));
971 }
972
973 #[test]
974 fn test_prints_mode_no_expand() {
975 assert_eq!("----------", wrap_mode(false, None, 0o000, FileKind::File(ExecKind::None)));
976 assert_eq!("-r--------", wrap_mode(false, None, 0o400, FileKind::File(ExecKind::None)));
977 assert_eq!("--w-------", wrap_mode(false, None, 0o200, FileKind::File(ExecKind::None)));
978 assert_eq!("---x------", wrap_mode(false, None, 0o100, FileKind::File(ExecKind::None)));
979 assert_eq!("----r-----", wrap_mode(false, None, 0o040, FileKind::File(ExecKind::None)));
980 assert_eq!("-----w----", wrap_mode(false, None, 0o020, FileKind::File(ExecKind::None)));
981 assert_eq!("------x---", wrap_mode(false, None, 0o010, FileKind::File(ExecKind::None)));
982 assert_eq!("-------r--", wrap_mode(false, None, 0o004, FileKind::File(ExecKind::None)));
983 assert_eq!("--------w-", wrap_mode(false, None, 0o002, FileKind::File(ExecKind::None)));
984 assert_eq!("---------x", wrap_mode(false, None, 0o001, FileKind::File(ExecKind::None)));
985 assert_eq!("-rwxrwxrwx", wrap_mode(false, None, 0o777, FileKind::File(ExecKind::None)));
986 assert_eq!("----------", wrap_mode(false, Some(0), 0o000, FileKind::File(ExecKind::None)));
987 assert_eq!("-r--------", wrap_mode(false, Some(0), 0o400, FileKind::File(ExecKind::None)));
988 assert_eq!("--w-------", wrap_mode(false, Some(0), 0o200, FileKind::File(ExecKind::None)));
989 assert_eq!("---x------", wrap_mode(false, Some(0), 0o100, FileKind::File(ExecKind::None)));
990 assert_eq!("----r-----", wrap_mode(false, Some(0), 0o040, FileKind::File(ExecKind::None)));
991 assert_eq!("-----w----", wrap_mode(false, Some(0), 0o020, FileKind::File(ExecKind::None)));
992 assert_eq!("------x---", wrap_mode(false, Some(0), 0o010, FileKind::File(ExecKind::None)));
993 assert_eq!("-------r--", wrap_mode(false, Some(0), 0o004, FileKind::File(ExecKind::None)));
994 assert_eq!("--------w-", wrap_mode(false, Some(0), 0o002, FileKind::File(ExecKind::None)));
995 assert_eq!("---------x", wrap_mode(false, Some(0), 0o001, FileKind::File(ExecKind::None)));
996 assert_eq!("-rwxrwxrwx", wrap_mode(false, Some(0), 0o777, FileKind::File(ExecKind::None)));
997 }
998
999 #[test]
1000 fn test_prints_mode_with_expand() {
1001 assert_eq!("-----------", wrap_mode(true, None, 0o000, FileKind::File(ExecKind::None)));
1002 assert_eq!("--r--------", wrap_mode(true, None, 0o400, FileKind::File(ExecKind::None)));
1003 assert_eq!("---w-------", wrap_mode(true, None, 0o200, FileKind::File(ExecKind::None)));
1004 assert_eq!("----x------", wrap_mode(true, None, 0o100, FileKind::File(ExecKind::None)));
1005 assert_eq!("-----r-----", wrap_mode(true, None, 0o040, FileKind::File(ExecKind::None)));
1006 assert_eq!("------w----", wrap_mode(true, None, 0o020, FileKind::File(ExecKind::None)));
1007 assert_eq!("-------x---", wrap_mode(true, None, 0o010, FileKind::File(ExecKind::None)));
1008 assert_eq!("--------r--", wrap_mode(true, None, 0o004, FileKind::File(ExecKind::None)));
1009 assert_eq!("---------w-", wrap_mode(true, None, 0o002, FileKind::File(ExecKind::None)));
1010 assert_eq!("----------x", wrap_mode(true, None, 0o001, FileKind::File(ExecKind::None)));
1011 assert_eq!("--rwxrwxrwx", wrap_mode(true, None, 0o777, FileKind::File(ExecKind::None)));
1012 assert_eq!("z----------", wrap_mode(true, Some(0), 0o000, FileKind::File(ExecKind::None)));
1013 assert_eq!("z-r--------", wrap_mode(true, Some(0), 0o400, FileKind::File(ExecKind::None)));
1014 assert_eq!("z--w-------", wrap_mode(true, Some(0), 0o200, FileKind::File(ExecKind::None)));
1015 assert_eq!("z---x------", wrap_mode(true, Some(0), 0o100, FileKind::File(ExecKind::None)));
1016 assert_eq!("z----r-----", wrap_mode(true, Some(0), 0o040, FileKind::File(ExecKind::None)));
1017 assert_eq!("z-----w----", wrap_mode(true, Some(0), 0o020, FileKind::File(ExecKind::None)));
1018 assert_eq!("z------x---", wrap_mode(true, Some(0), 0o010, FileKind::File(ExecKind::None)));
1019 assert_eq!("z-------r--", wrap_mode(true, Some(0), 0o004, FileKind::File(ExecKind::None)));
1020 assert_eq!("z--------w-", wrap_mode(true, Some(0), 0o002, FileKind::File(ExecKind::None)));
1021 assert_eq!("z---------x", wrap_mode(true, Some(0), 0o001, FileKind::File(ExecKind::None)));
1022 assert_eq!("z-rwxrwxrwx", wrap_mode(true, Some(0), 0o777, FileKind::File(ExecKind::None)));
1023 }
1024
1025 #[test]
1026 fn test_measures_size_for_integer() {
1027 let config = Config::default();
1028 assert_eq!(3, measure_size(&config, 0));
1029 assert_eq!(3, measure_size(&config, 999));
1030 assert_eq!(7, measure_size(&config, 1_000));
1031 assert_eq!(7, measure_size(&config, 999_999));
1032 assert_eq!(11, measure_size(&config, 1_000_000));
1033 assert_eq!(11, measure_size(&config, 999_999_999));
1034 }
1035
1036 #[test]
1037 fn test_measures_size_for_si_units() {
1038 let config = Config::default()
1039 .with_show_pretty(true);
1040 assert_eq!(6, measure_size(&config, 0));
1041 assert_eq!(6, measure_size(&config, 999));
1042 assert_eq!(6, measure_size(&config, 1_000));
1043 assert_eq!(6, measure_size(&config, 999_999));
1044 assert_eq!(6, measure_size(&config, 1_000_000));
1045 assert_eq!(6, measure_size(&config, 999_999_999));
1046 }
1047
1048 #[test]
1049 fn test_prints_unpadded_size_as_integer() {
1050 let config = Config::default();
1051 assert_eq!(" 0", wrap_size(&config, 0, 0));
1052 assert_eq!(" 9", wrap_size(&config, 9, 0));
1053 assert_eq!(" 10", wrap_size(&config, 10, 0));
1054 assert_eq!(" 99", wrap_size(&config, 99, 0));
1055 assert_eq!(" 100", wrap_size(&config, 100, 0));
1056 assert_eq!(" 999", wrap_size(&config, 999, 0));
1057 assert_eq!(" 1,000", wrap_size(&config, 1_000, 0));
1058 assert_eq!(" 9,999", wrap_size(&config, 9_999, 0));
1059 assert_eq!(" 10,000", wrap_size(&config, 10_000, 0));
1060 assert_eq!(" 99,999", wrap_size(&config, 99_999, 0));
1061 assert_eq!(" 100,000", wrap_size(&config, 100_000, 0));
1062 assert_eq!(" 999,999", wrap_size(&config, 999_999, 0));
1063 assert_eq!(" 1,000,000", wrap_size(&config, 1_000_000, 0));
1064 assert_eq!(" 9,999,999", wrap_size(&config, 9_999_999, 0));
1065 assert_eq!(" 10,000,000", wrap_size(&config, 10_000_000, 0));
1066 assert_eq!(" 99,999,999", wrap_size(&config, 99_999_999, 0));
1067 assert_eq!(" 100,000,000", wrap_size(&config, 100_000_000, 0));
1068 assert_eq!(" 999,999,999", wrap_size(&config, 999_999_999, 0));
1069 assert_eq!(" 1,000,000,000", wrap_size(&config, 1_000_000_000, 0));
1070 assert_eq!(" 9,999,999,999", wrap_size(&config, 9_999_999_999, 0));
1071 assert_eq!(" 10,000,000,000", wrap_size(&config, 10_000_000_000, 0));
1072 assert_eq!(" 99,999,999,999", wrap_size(&config, 99_999_999_999, 0));
1073 assert_eq!(" 100,000,000,000", wrap_size(&config, 100_000_000_000, 0));
1074 assert_eq!(" 999,999,999,999", wrap_size(&config, 999_999_999_999, 0));
1075 assert_eq!(" 1,000,000,000,000", wrap_size(&config, 1_000_000_000_000, 0));
1076 assert_eq!(" 9,999,999,999,999", wrap_size(&config, 9_999_999_999_999, 0));
1077 assert_eq!(" 10,000,000,000,000", wrap_size(&config, 10_000_000_000_000, 0));
1078 assert_eq!(" 99,999,999,999,999", wrap_size(&config, 99_999_999_999_999, 0));
1079 assert_eq!(" 100,000,000,000,000", wrap_size(&config, 100_000_000_000_000, 0));
1080 assert_eq!(" 999,999,999,999,999", wrap_size(&config, 999_999_999_999_999, 0));
1081 assert_eq!(" 1,000,000,000,000,000", wrap_size(&config, 1_000_000_000_000_000, 0));
1082 assert_eq!(" 9,999,999,999,999,999", wrap_size(&config, 9_999_999_999_999_999, 0));
1083 assert_eq!(" 10,000,000,000,000,000", wrap_size(&config, 10_000_000_000_000_000, 0));
1084 assert_eq!(" 99,999,999,999,999,999", wrap_size(&config, 99_999_999_999_999_999, 0));
1085 assert_eq!(" 100,000,000,000,000,000", wrap_size(&config, 100_000_000_000_000_000, 0));
1086 assert_eq!(" 999,999,999,999,999,999", wrap_size(&config, 999_999_999_999_999_999, 0));
1087 assert_eq!(" 1,000,000,000,000,000,000", wrap_size(&config, 1_000_000_000_000_000_000, 0));
1088 assert_eq!(" 9,999,999,999,999,999,999", wrap_size(&config, 9_999_999_999_999_999_999, 0));
1089 assert_eq!(" 10,000,000,000,000,000,000", wrap_size(&config, 10_000_000_000_000_000_000, 0));
1090 }
1091
1092 #[test]
1093 fn test_prints_padded_size_as_integer() {
1094 let config = Config::default();
1095 assert_eq!(" 0", wrap_size(&config, 0, 26));
1096 assert_eq!(" 9", wrap_size(&config, 9, 26));
1097 assert_eq!(" 10", wrap_size(&config, 10, 26));
1098 assert_eq!(" 99", wrap_size(&config, 99, 26));
1099 assert_eq!(" 100", wrap_size(&config, 100, 26));
1100 assert_eq!(" 999", wrap_size(&config, 999, 26));
1101 assert_eq!(" 1,000", wrap_size(&config, 1_000, 26));
1102 assert_eq!(" 9,999", wrap_size(&config, 9_999, 26));
1103 assert_eq!(" 10,000", wrap_size(&config, 10_000, 26));
1104 assert_eq!(" 99,999", wrap_size(&config, 99_999, 26));
1105 assert_eq!(" 100,000", wrap_size(&config, 100_000, 26));
1106 assert_eq!(" 999,999", wrap_size(&config, 999_999, 26));
1107 assert_eq!(" 1,000,000", wrap_size(&config, 1_000_000, 26));
1108 assert_eq!(" 9,999,999", wrap_size(&config, 9_999_999, 26));
1109 assert_eq!(" 10,000,000", wrap_size(&config, 10_000_000, 26));
1110 assert_eq!(" 99,999,999", wrap_size(&config, 99_999_999, 26));
1111 assert_eq!(" 100,000,000", wrap_size(&config, 100_000_000, 26));
1112 assert_eq!(" 999,999,999", wrap_size(&config, 999_999_999, 26));
1113 assert_eq!(" 1,000,000,000", wrap_size(&config, 1_000_000_000, 26));
1114 assert_eq!(" 9,999,999,999", wrap_size(&config, 9_999_999_999, 26));
1115 assert_eq!(" 10,000,000,000", wrap_size(&config, 10_000_000_000, 26));
1116 assert_eq!(" 99,999,999,999", wrap_size(&config, 99_999_999_999, 26));
1117 assert_eq!(" 100,000,000,000", wrap_size(&config, 100_000_000_000, 26));
1118 assert_eq!(" 999,999,999,999", wrap_size(&config, 999_999_999_999, 26));
1119 assert_eq!(" 1,000,000,000,000", wrap_size(&config, 1_000_000_000_000, 26));
1120 assert_eq!(" 9,999,999,999,999", wrap_size(&config, 9_999_999_999_999, 26));
1121 assert_eq!(" 10,000,000,000,000", wrap_size(&config, 10_000_000_000_000, 26));
1122 assert_eq!(" 99,999,999,999,999", wrap_size(&config, 99_999_999_999_999, 26));
1123 assert_eq!(" 100,000,000,000,000", wrap_size(&config, 100_000_000_000_000, 26));
1124 assert_eq!(" 999,999,999,999,999", wrap_size(&config, 999_999_999_999_999, 26));
1125 assert_eq!(" 1,000,000,000,000,000", wrap_size(&config, 1_000_000_000_000_000, 26));
1126 assert_eq!(" 9,999,999,999,999,999", wrap_size(&config, 9_999_999_999_999_999, 26));
1127 assert_eq!(" 10,000,000,000,000,000", wrap_size(&config, 10_000_000_000_000_000, 26));
1128 assert_eq!(" 99,999,999,999,999,999", wrap_size(&config, 99_999_999_999_999_999, 26));
1129 assert_eq!(" 100,000,000,000,000,000", wrap_size(&config, 100_000_000_000_000_000, 26));
1130 assert_eq!(" 999,999,999,999,999,999", wrap_size(&config, 999_999_999_999_999_999, 26));
1131 assert_eq!(" 1,000,000,000,000,000,000", wrap_size(&config, 1_000_000_000_000_000_000, 26));
1132 assert_eq!(" 9,999,999,999,999,999,999", wrap_size(&config, 9_999_999_999_999_999_999, 26));
1133 assert_eq!(" 10,000,000,000,000,000,000", wrap_size(&config, 10_000_000_000_000_000_000, 26));
1134 }
1135
1136 #[test]
1137 fn test_prints_unpadded_size_in_si_units() {
1138 let config = Config::default()
1139 .with_show_pretty(true);
1140 assert_eq!(" 0 B ", wrap_size(&config, 0, 0));
1141 assert_eq!(" 9 B ", wrap_size(&config, 9, 0));
1142 assert_eq!(" 10 B ", wrap_size(&config, 10, 0));
1143 assert_eq!(" 99 B ", wrap_size(&config, 99, 0));
1144 assert_eq!(" 100 B ", wrap_size(&config, 100, 0));
1145 assert_eq!(" 999 B ", wrap_size(&config, 999, 0));
1146 assert_eq!(" 1 KB", wrap_size(&config, 1_000, 0));
1147 assert_eq!(" 9 KB", wrap_size(&config, 9_999, 0));
1148 assert_eq!(" 10 KB", wrap_size(&config, 10_000, 0));
1149 assert_eq!(" 99 KB", wrap_size(&config, 99_999, 0));
1150 assert_eq!(" 100 KB", wrap_size(&config, 100_000, 0));
1151 assert_eq!(" 999 KB", wrap_size(&config, 999_999, 0));
1152 assert_eq!(" 1 MB", wrap_size(&config, 1_000_000, 0));
1153 assert_eq!(" 9 MB", wrap_size(&config, 9_999_999, 0));
1154 assert_eq!(" 10 MB", wrap_size(&config, 10_000_000, 0));
1155 assert_eq!(" 99 MB", wrap_size(&config, 99_999_999, 0));
1156 assert_eq!(" 100 MB", wrap_size(&config, 100_000_000, 0));
1157 assert_eq!(" 999 MB", wrap_size(&config, 999_999_999, 0));
1158 assert_eq!(" 1 GB", wrap_size(&config, 1_000_000_000, 0));
1159 assert_eq!(" 9 GB", wrap_size(&config, 9_999_999_999, 0));
1160 assert_eq!(" 10 GB", wrap_size(&config, 10_000_000_000, 0));
1161 assert_eq!(" 99 GB", wrap_size(&config, 99_999_999_999, 0));
1162 assert_eq!(" 100 GB", wrap_size(&config, 100_000_000_000, 0));
1163 assert_eq!(" 999 GB", wrap_size(&config, 999_999_999_999, 0));
1164 assert_eq!(" 1 TB", wrap_size(&config, 1_000_000_000_000, 0));
1165 assert_eq!(" 9 TB", wrap_size(&config, 9_999_999_999_999, 0));
1166 assert_eq!(" 10 TB", wrap_size(&config, 10_000_000_000_000, 0));
1167 assert_eq!(" 99 TB", wrap_size(&config, 99_999_999_999_999, 0));
1168 assert_eq!(" 100 TB", wrap_size(&config, 100_000_000_000_000, 0));
1169 assert_eq!(" 999 TB", wrap_size(&config, 999_999_999_999_999, 0));
1170 assert_eq!(" 1 PB", wrap_size(&config, 1_000_000_000_000_000, 0));
1171 assert_eq!(" 9 PB", wrap_size(&config, 9_999_999_999_999_999, 0));
1172 assert_eq!(" 10 PB", wrap_size(&config, 10_000_000_000_000_000, 0));
1173 assert_eq!(" 99 PB", wrap_size(&config, 99_999_999_999_999_999, 0));
1174 assert_eq!(" 100 PB", wrap_size(&config, 100_000_000_000_000_000, 0));
1175 assert_eq!(" 999 PB", wrap_size(&config, 999_999_999_999_999_999, 0));
1176 assert_eq!(" 1 EB", wrap_size(&config, 1_000_000_000_000_000_000, 0));
1177 assert_eq!(" 9 EB", wrap_size(&config, 9_999_999_999_999_999_999, 0));
1178 assert_eq!(" 10 EB", wrap_size(&config, 10_000_000_000_000_000_000, 0));
1179 }
1180
1181 #[test]
1182 fn test_prints_time_as_local_timestamp() {
1183 let config = Config::default()
1184 .with_curr_time(2024, 10, 10, 10, 10, 30)
1185 .with_show_utc(false);
1186 assert_eq!(" Wed 31-Jan-2024 00:00:00", wrap_time(&config, 2024, 1, 31, 0, 0, 0));
1187 assert_eq!(" Thu 29-Feb-2024 02:05:15", wrap_time(&config, 2024, 2, 29, 2, 5, 15));
1188 assert_eq!(" Sun 31-Mar-2024 04:10:30", wrap_time(&config, 2024, 3, 31, 4, 10, 30));
1189 assert_eq!(" Tue 30-Apr-2024 06:15:45", wrap_time(&config, 2024, 4, 30, 6, 15, 45));
1190 assert_eq!(" Fri 31-May-2024 08:20:00", wrap_time(&config, 2024, 5, 31, 8, 20, 0));
1191 assert_eq!(" Sun 30-Jun-2024 10:25:15", wrap_time(&config, 2024, 6, 30, 10, 25, 15));
1192 assert_eq!(" Wed 31-Jul-2024 12:30:30", wrap_time(&config, 2024, 7, 31, 12, 30, 30));
1193 assert_eq!(" Sat 31-Aug-2024 14:35:45", wrap_time(&config, 2024, 8, 31, 14, 35, 45));
1194 assert_eq!(" Mon 30-Sep-2024 16:40:00", wrap_time(&config, 2024, 9, 30, 16, 40, 0));
1195 assert_eq!(" Thu 31-Oct-2024 18:45:15", wrap_time(&config, 2024, 10, 31, 18, 45, 15));
1196 assert_eq!(" Sat 30-Nov-2024 20:50:30", wrap_time(&config, 2024, 11, 30, 20, 50, 30));
1197 assert_eq!(" Tue 31-Dec-2024 22:55:45", wrap_time(&config, 2024, 12, 31, 22, 55, 45));
1198 assert_eq!(" ------------------------", wrap_time(&config, 1970, 1, 1, 0, 0, 0));
1199 }
1200
1201 #[test]
1202 fn test_prints_time_as_utc_timestamp() {
1203 let config = Config::default()
1204 .with_curr_time(2024, 10, 10, 10, 10, 30)
1205 .with_show_utc(true);
1206 assert_eq!(" Wed 31-Jan-2024 00:00:00Z", wrap_time(&config, 2024, 1, 31, 0, 0, 0));
1207 assert_eq!(" Thu 29-Feb-2024 02:05:15Z", wrap_time(&config, 2024, 2, 29, 2, 5, 15));
1208 assert_eq!(" Sun 31-Mar-2024 04:10:30Z", wrap_time(&config, 2024, 3, 31, 4, 10, 30));
1209 assert_eq!(" Tue 30-Apr-2024 06:15:45Z", wrap_time(&config, 2024, 4, 30, 6, 15, 45));
1210 assert_eq!(" Fri 31-May-2024 08:20:00Z", wrap_time(&config, 2024, 5, 31, 8, 20, 0));
1211 assert_eq!(" Sun 30-Jun-2024 10:25:15Z", wrap_time(&config, 2024, 6, 30, 10, 25, 15));
1212 assert_eq!(" Wed 31-Jul-2024 12:30:30Z", wrap_time(&config, 2024, 7, 31, 12, 30, 30));
1213 assert_eq!(" Sat 31-Aug-2024 14:35:45Z", wrap_time(&config, 2024, 8, 31, 14, 35, 45));
1214 assert_eq!(" Mon 30-Sep-2024 16:40:00Z", wrap_time(&config, 2024, 9, 30, 16, 40, 0));
1215 assert_eq!(" Thu 31-Oct-2024 18:45:15Z", wrap_time(&config, 2024, 10, 31, 18, 45, 15));
1216 assert_eq!(" Sat 30-Nov-2024 20:50:30Z", wrap_time(&config, 2024, 11, 30, 20, 50, 30));
1217 assert_eq!(" Tue 31-Dec-2024 22:55:45Z", wrap_time(&config, 2024, 12, 31, 22, 55, 45));
1218 assert_eq!(" -------------------------", wrap_time(&config, 1970, 1, 1, 0, 0, 0));
1219 }
1220
1221 #[test]
1222 fn test_prints_time_as_duration() {
1223 let config = Config::default()
1224 .with_curr_time(2024, 10, 10, 10, 10, 30)
1225 .with_show_pretty(true);
1226 assert_eq!(" future ", wrap_time(&config, 2024, 10, 10, 10, 10, 31));
1227 assert_eq!(" 0 sec ", wrap_time(&config, 2024, 10, 10, 10, 10, 30));
1228 assert_eq!(" 1 sec ", wrap_time(&config, 2024, 10, 10, 10, 10, 29));
1229 assert_eq!(" 59 sec ", wrap_time(&config, 2024, 10, 10, 10, 9, 31));
1230 assert_eq!(" 1 min ", wrap_time(&config, 2024, 10, 10, 10, 9, 30));
1231 assert_eq!(" 1 min ", wrap_time(&config, 2024, 10, 10, 10, 9, 29));
1232 assert_eq!(" 1 min ", wrap_time(&config, 2024, 10, 10, 10, 8, 31));
1233 assert_eq!(" 2 min ", wrap_time(&config, 2024, 10, 10, 10, 8, 30));
1234 assert_eq!(" 2 min ", wrap_time(&config, 2024, 10, 10, 10, 8, 29));
1235 assert_eq!(" 58 min ", wrap_time(&config, 2024, 10, 10, 9, 11, 31));
1236 assert_eq!(" 59 min ", wrap_time(&config, 2024, 10, 10, 9, 11, 30));
1237 assert_eq!(" 59 min ", wrap_time(&config, 2024, 10, 10, 9, 11, 29));
1238 assert_eq!(" 59 min ", wrap_time(&config, 2024, 10, 10, 9, 10, 31));
1239 assert_eq!(" 1 hour ", wrap_time(&config, 2024, 10, 10, 9, 10, 30));
1240 assert_eq!(" 1 hour ", wrap_time(&config, 2024, 10, 10, 9, 10, 29));
1241 assert_eq!(" 1 hour ", wrap_time(&config, 2024, 10, 10, 8, 10, 31));
1242 assert_eq!(" 2 hour ", wrap_time(&config, 2024, 10, 10, 8, 10, 30));
1243 assert_eq!(" 2 hour ", wrap_time(&config, 2024, 10, 10, 8, 10, 29));
1244 assert_eq!(" 22 hour ", wrap_time(&config, 2024, 10, 9, 11, 10, 31));
1245 assert_eq!(" 23 hour ", wrap_time(&config, 2024, 10, 9, 11, 10, 30));
1246 assert_eq!(" 23 hour ", wrap_time(&config, 2024, 10, 9, 11, 10, 29));
1247 assert_eq!(" 23 hour ", wrap_time(&config, 2024, 10, 9, 10, 10, 31));
1248 assert_eq!(" 1 day ", wrap_time(&config, 2024, 10, 9, 10, 10, 30));
1249 assert_eq!(" 1 day ", wrap_time(&config, 2024, 10, 9, 10, 10, 29));
1250 assert_eq!(" 1 day ", wrap_time(&config, 2024, 10, 8, 10, 10, 31));
1251 assert_eq!(" 2 day ", wrap_time(&config, 2024, 10, 8, 10, 10, 30));
1252 assert_eq!(" 2 day ", wrap_time(&config, 2024, 10, 8, 10, 10, 29));
1253 assert_eq!(" 28 day ", wrap_time(&config, 2024, 9, 11, 10, 10, 31));
1254 assert_eq!(" 29 day ", wrap_time(&config, 2024, 9, 11, 10, 10, 30));
1255 assert_eq!(" 29 day ", wrap_time(&config, 2024, 9, 11, 10, 10, 29));
1256 assert_eq!(" 29 day ", wrap_time(&config, 2024, 9, 10, 10, 10, 31));
1257 assert_eq!(" 1 month", wrap_time(&config, 2024, 9, 10, 10, 10, 30));
1258 assert_eq!(" 1 month", wrap_time(&config, 2024, 9, 10, 10, 10, 29));
1259 assert_eq!(" 1 month", wrap_time(&config, 2024, 8, 10, 10, 10, 31));
1260 assert_eq!(" 2 month", wrap_time(&config, 2024, 8, 10, 10, 10, 30));
1261 assert_eq!(" 2 month", wrap_time(&config, 2024, 8, 10, 10, 10, 29));
1262 assert_eq!(" 10 month", wrap_time(&config, 2023, 11, 10, 10, 10, 31));
1263 assert_eq!(" 11 month", wrap_time(&config, 2023, 11, 10, 10, 10, 30));
1264 assert_eq!(" 11 month", wrap_time(&config, 2023, 11, 10, 10, 10, 29));
1265 assert_eq!(" 11 month", wrap_time(&config, 2023, 10, 10, 10, 10, 31));
1266 assert_eq!(" 1 year ", wrap_time(&config, 2023, 10, 10, 10, 10, 30));
1267 assert_eq!(" 1 year ", wrap_time(&config, 2023, 10, 10, 10, 10, 29));
1268 assert_eq!(" 1 year ", wrap_time(&config, 2022, 10, 10, 10, 10, 31));
1269 assert_eq!(" 2 year ", wrap_time(&config, 2022, 10, 10, 10, 10, 30));
1270 assert_eq!(" 2 year ", wrap_time(&config, 2022, 10, 10, 10, 10, 29));
1271 assert_eq!(" --------", wrap_time(&config, 1970, 1, 1, 0, 0, 0));
1272 }
1273
1274 #[test]
1275 #[cfg(windows)]
1276 fn test_prints_unpadded_version() {
1277 assert_eq!("", wrap_version(None, 0));
1278 assert_eq!("", wrap_version(Some(""), 0));
1279 assert_eq!("", wrap_version(Some("9.9.9.9"), 0));
1280 assert_eq!("", wrap_version(Some("999.999.999.999"), 0));
1281 }
1282
1283 #[test]
1284 #[cfg(windows)]
1285 fn test_prints_padded_version() {
1286 assert_eq!(" ", wrap_version(None, 10));
1287 assert_eq!(" ", wrap_version(Some(""), 10));
1288 assert_eq!(" 9.9.9.9 ", wrap_version(Some("9.9.9.9"), 10));
1289 assert_eq!(" 999.999.999.999", wrap_version(Some("999.999.999.999"), 10));
1290 }
1291
1292 #[test]
1293 fn test_prints_unpadded_ext() {
1294 assert_eq!("", wrap_ext("", 0));
1295 assert_eq!("", wrap_ext(".txt", 0));
1296 assert_eq!("", wrap_ext(".extension", 0));
1297 }
1298
1299 #[test]
1300 fn test_prints_padded_ext() {
1301 assert_eq!(" ", wrap_ext("", 6));
1302 assert_eq!(" .txt ", wrap_ext(".txt", 6));
1303 assert_eq!(" .extension", wrap_ext(".extension", 6));
1304 }
1305
1306 #[test]
1307 fn test_prints_total() {
1308 assert_eq!("0 files 0 directories", wrap_total(0, 0));
1309 assert_eq!("1 file 0 directories", wrap_total(1, 0));
1310 assert_eq!("2 files 0 directories", wrap_total(2, 0));
1311 assert_eq!("0 files 1 directory", wrap_total(0, 1));
1312 assert_eq!("0 files 2 directories", wrap_total(0, 2));
1313 }
1314
1315 #[test]
1316 #[cfg(windows)]
1317 fn test_prints_relative_paths_on_windows() {
1318 let expected = "\
1319drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example\\[Reset]
1320-rwxr-xr-x 10 Wed 01-Nov-2023 00:00:00 .sh [LtBlue]example\\[Reset][DkGreen]find.sh[Reset]
1321drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example\\files\\[Reset]
1322drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example\\files\\colours\\[Reset]
1323-rwxr--r-- 20 Sun 01-Oct-2023 00:00:00 .sh [LtBlue]example\\files\\colours\\[Reset][LtGreen]alpha.sh[Reset]
1324-rw-r--r-- 30 Fri 01-Sep-2023 00:00:00 .txt [LtBlue]example\\files\\colours\\[Reset]blue.txt
1325-rw-r--r-- 40 Tue 01-Aug-2023 00:00:00 .txt [LtBlue]example\\files\\colours\\[Reset]green.txt
1326-rw-r--r-- 50 Sat 01-Jul-2023 00:00:00 .txt [LtBlue]example\\files\\colours\\[Reset]red.txt
1327drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example\\files\\numbers\\[Reset]
1328lrwxr--r-- 60 Thu 01-Jun-2023 00:00:00 .sh [LtBlue]example\\files\\numbers\\[Reset][LtCyan]count.sh[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtGreen]count.sh[Reset]
1329lrw-r--r-- 999 Mon 01-May-2023 00:00:00 .gz [LtBlue]example\\files\\numbers\\[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtRed]googolplex.gz[Reset]
1330lrw-r--r-- 0 Sat 01-Apr-2023 00:00:00 [LtBlue]example\\files\\numbers\\[Reset][LtCyan]ordinals[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtBlue]ordinals\\[Reset]
1331drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example\\files\\numbers\\one two\\[Reset]
1332-rw-r--r-- 70 Wed 01-Mar-2023 00:00:00 .txt [LtBlue]example\\files\\numbers\\one two\\[Reset]\"three\" 'four'.txt
1333";
1334 let files = create_files("D:", "/root", "");
1335 let config = Config::default()
1336 .with_abs_path(false);
1337 assert_eq!(expected, wrap_files(&config, false, &files));
1338 }
1339
1340 #[test]
1341 #[cfg(windows)]
1342 fn test_prints_relative_paths_on_git_bash() {
1343 let expected = "\
1344drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/[Reset]
1345-rwxr-xr-x 10 Wed 01-Nov-2023 00:00:00 .sh [LtBlue]example/[Reset][DkGreen]find.sh[Reset]
1346drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/[Reset]
1347drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/colours/[Reset]
1348-rwxr--r-- 20 Sun 01-Oct-2023 00:00:00 .sh [LtBlue]example/files/colours/[Reset][LtGreen]alpha.sh[Reset]
1349-rw-r--r-- 30 Fri 01-Sep-2023 00:00:00 .txt [LtBlue]example/files/colours/[Reset]blue.txt
1350-rw-r--r-- 40 Tue 01-Aug-2023 00:00:00 .txt [LtBlue]example/files/colours/[Reset]green.txt
1351-rw-r--r-- 50 Sat 01-Jul-2023 00:00:00 .txt [LtBlue]example/files/colours/[Reset]red.txt
1352drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/numbers/[Reset]
1353lrwxr--r-- 60 Thu 01-Jun-2023 00:00:00 .sh [LtBlue]example/files/numbers/[Reset][LtCyan]count.sh[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtGreen]count.sh[Reset]
1354lrw-r--r-- 999 Mon 01-May-2023 00:00:00 .gz [LtBlue]example/files/numbers/[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
1355lrw-r--r-- 0 Sat 01-Apr-2023 00:00:00 [LtBlue]example/files/numbers/[Reset][LtCyan]ordinals[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
1356drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/numbers/one two/[Reset]
1357-rw-r--r-- 70 Wed 01-Mar-2023 00:00:00 .txt [LtBlue]example/files/numbers/one two/[Reset]\"three\" 'four'.txt
1358";
1359 let files = create_files("D:", "/root", "");
1360 let config = Config::default()
1361 .with_abs_path(false);
1362 assert_eq!(expected, wrap_files(&config, true, &files));
1363 }
1364
1365 #[test]
1366 #[cfg(not(windows))]
1367 fn test_prints_relative_paths_on_linux() {
1368 let expected = "\
1369drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/[Reset]
1370-rwxr-xr-x 10 Wed 01-Nov-2023 00:00:00 .sh [LtBlue]example/[Reset][DkGreen]find.sh[Reset]
1371drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/[Reset]
1372drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/colours/[Reset]
1373-rwxr--r-- 20 Sun 01-Oct-2023 00:00:00 .sh [LtBlue]example/files/colours/[Reset][LtGreen]alpha.sh[Reset]
1374-rw-r--r-- 30 Fri 01-Sep-2023 00:00:00 .txt [LtBlue]example/files/colours/[Reset]blue.txt
1375-rw-r--r-- 40 Tue 01-Aug-2023 00:00:00 .txt [LtBlue]example/files/colours/[Reset]green.txt
1376-rw-r--r-- 50 Sat 01-Jul-2023 00:00:00 .txt [LtBlue]example/files/colours/[Reset]red.txt
1377drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/numbers/[Reset]
1378lrwxr--r-- 60 Thu 01-Jun-2023 00:00:00 .sh [LtBlue]example/files/numbers/[Reset][LtCyan]count.sh[Reset] -> [LtBlue]/etc/numbers/[Reset][LtGreen]count.sh[Reset]
1379lrw-r--r-- 999 Mon 01-May-2023 00:00:00 .gz [LtBlue]example/files/numbers/[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
1380lrw-r--r-- 0 Sat 01-Apr-2023 00:00:00 [LtBlue]example/files/numbers/[Reset][LtCyan]ordinals[Reset] -> [LtBlue]/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
1381drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/numbers/one two/[Reset]
1382-rw-r--r-- 70 Wed 01-Mar-2023 00:00:00 .txt [LtBlue]example/files/numbers/one two/[Reset]\"three\" 'four'.txt
1383";
1384 let files = create_files("", "/root", "");
1385 let config = Config::default()
1386 .with_abs_path(false);
1387 assert_eq!(expected, wrap_files(&config, false, &files));
1388 }
1389
1390 #[test]
1391 #[cfg(windows)]
1392 fn test_prints_absolute_paths_on_windows() {
1393 let expected = "\
1394drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]D:\\root\\example\\[Reset]
1395-rwxr-xr-x 10 Wed 01-Nov-2023 00:00:00 .sh [LtBlue]D:\\root\\example\\[Reset][DkGreen]find.sh[Reset]
1396drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]D:\\root\\example\\files\\[Reset]
1397drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]D:\\root\\example\\files\\colours\\[Reset]
1398-rwxr--r-- 20 Sun 01-Oct-2023 00:00:00 .sh [LtBlue]D:\\root\\example\\files\\colours\\[Reset][LtGreen]alpha.sh[Reset]
1399-rw-r--r-- 30 Fri 01-Sep-2023 00:00:00 .txt [LtBlue]D:\\root\\example\\files\\colours\\[Reset]blue.txt
1400-rw-r--r-- 40 Tue 01-Aug-2023 00:00:00 .txt [LtBlue]D:\\root\\example\\files\\colours\\[Reset]green.txt
1401-rw-r--r-- 50 Sat 01-Jul-2023 00:00:00 .txt [LtBlue]D:\\root\\example\\files\\colours\\[Reset]red.txt
1402drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]D:\\root\\example\\files\\numbers\\[Reset]
1403lrwxr--r-- 60 Thu 01-Jun-2023 00:00:00 .sh [LtBlue]D:\\root\\example\\files\\numbers\\[Reset][LtCyan]count.sh[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtGreen]count.sh[Reset]
1404lrw-r--r-- 999 Mon 01-May-2023 00:00:00 .gz [LtBlue]D:\\root\\example\\files\\numbers\\[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtRed]googolplex.gz[Reset]
1405lrw-r--r-- 0 Sat 01-Apr-2023 00:00:00 [LtBlue]D:\\root\\example\\files\\numbers\\[Reset][LtCyan]ordinals[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtBlue]ordinals\\[Reset]
1406drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]D:\\root\\example\\files\\numbers\\one two\\[Reset]
1407-rw-r--r-- 70 Wed 01-Mar-2023 00:00:00 .txt [LtBlue]D:\\root\\example\\files\\numbers\\one two\\[Reset]\"three\" 'four'.txt
1408";
1409 let files = create_files("D:", "/root", "");
1410 let config = Config::default()
1411 .with_abs_path(true);
1412 assert_eq!(expected, wrap_files(&config, false, &files));
1413 }
1414
1415 #[test]
1416 #[cfg(windows)]
1417 fn test_prints_absolute_paths_on_git_bash() {
1418 let expected = "\
1419drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]/d/root/example/[Reset]
1420-rwxr-xr-x 10 Wed 01-Nov-2023 00:00:00 .sh [LtBlue]/d/root/example/[Reset][DkGreen]find.sh[Reset]
1421drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]/d/root/example/files/[Reset]
1422drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]/d/root/example/files/colours/[Reset]
1423-rwxr--r-- 20 Sun 01-Oct-2023 00:00:00 .sh [LtBlue]/d/root/example/files/colours/[Reset][LtGreen]alpha.sh[Reset]
1424-rw-r--r-- 30 Fri 01-Sep-2023 00:00:00 .txt [LtBlue]/d/root/example/files/colours/[Reset]blue.txt
1425-rw-r--r-- 40 Tue 01-Aug-2023 00:00:00 .txt [LtBlue]/d/root/example/files/colours/[Reset]green.txt
1426-rw-r--r-- 50 Sat 01-Jul-2023 00:00:00 .txt [LtBlue]/d/root/example/files/colours/[Reset]red.txt
1427drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]/d/root/example/files/numbers/[Reset]
1428lrwxr--r-- 60 Thu 01-Jun-2023 00:00:00 .sh [LtBlue]/d/root/example/files/numbers/[Reset][LtCyan]count.sh[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtGreen]count.sh[Reset]
1429lrw-r--r-- 999 Mon 01-May-2023 00:00:00 .gz [LtBlue]/d/root/example/files/numbers/[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
1430lrw-r--r-- 0 Sat 01-Apr-2023 00:00:00 [LtBlue]/d/root/example/files/numbers/[Reset][LtCyan]ordinals[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
1431drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]/d/root/example/files/numbers/one two/[Reset]
1432-rw-r--r-- 70 Wed 01-Mar-2023 00:00:00 .txt [LtBlue]/d/root/example/files/numbers/one two/[Reset]\"three\" 'four'.txt
1433";
1434 let files = create_files("D:", "/root", "");
1435 let config = Config::default()
1436 .with_abs_path(true);
1437 assert_eq!(expected, wrap_files(&config, true, &files));
1438 }
1439
1440 #[test]
1441 #[cfg(not(windows))]
1442 fn test_prints_absolute_paths_on_linux() {
1443 let expected = "\
1444drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]/root/example/[Reset]
1445-rwxr-xr-x 10 Wed 01-Nov-2023 00:00:00 .sh [LtBlue]/root/example/[Reset][DkGreen]find.sh[Reset]
1446drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]/root/example/files/[Reset]
1447drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]/root/example/files/colours/[Reset]
1448-rwxr--r-- 20 Sun 01-Oct-2023 00:00:00 .sh [LtBlue]/root/example/files/colours/[Reset][LtGreen]alpha.sh[Reset]
1449-rw-r--r-- 30 Fri 01-Sep-2023 00:00:00 .txt [LtBlue]/root/example/files/colours/[Reset]blue.txt
1450-rw-r--r-- 40 Tue 01-Aug-2023 00:00:00 .txt [LtBlue]/root/example/files/colours/[Reset]green.txt
1451-rw-r--r-- 50 Sat 01-Jul-2023 00:00:00 .txt [LtBlue]/root/example/files/colours/[Reset]red.txt
1452drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]/root/example/files/numbers/[Reset]
1453lrwxr--r-- 60 Thu 01-Jun-2023 00:00:00 .sh [LtBlue]/root/example/files/numbers/[Reset][LtCyan]count.sh[Reset] -> [LtBlue]/etc/numbers/[Reset][LtGreen]count.sh[Reset]
1454lrw-r--r-- 999 Mon 01-May-2023 00:00:00 .gz [LtBlue]/root/example/files/numbers/[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
1455lrw-r--r-- 0 Sat 01-Apr-2023 00:00:00 [LtBlue]/root/example/files/numbers/[Reset][LtCyan]ordinals[Reset] -> [LtBlue]/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
1456drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]/root/example/files/numbers/one two/[Reset]
1457-rw-r--r-- 70 Wed 01-Mar-2023 00:00:00 .txt [LtBlue]/root/example/files/numbers/one two/[Reset]\"three\" 'four'.txt
1458";
1459 let files = create_files("", "/root", "");
1460 let config = Config::default()
1461 .with_abs_path(true);
1462 assert_eq!(expected, wrap_files(&config, false, &files));
1463 }
1464
1465 #[test]
1466 #[cfg(windows)]
1467 fn test_prints_relative_paths_with_zip_on_windows() {
1468 let expected = "\
1469-drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example\\[Reset]
1470--rwxr-xr-x 10 Wed 01-Nov-2023 00:00:00 .sh [LtBlue]example\\[Reset][DkGreen]find.sh[Reset]
1471zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example\\[LtRed]files.zip[LtBlue]\\[Reset]
1472zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example\\[LtRed]files.zip[LtBlue]\\colours\\[Reset]
1473z-rwxr--r-- 20 Sun 01-Oct-2023 00:00:00 .sh [LtBlue]example\\[LtRed]files.zip[LtBlue]\\colours\\[Reset][LtGreen]alpha.sh[Reset]
1474z-rw-r--r-- 30 Fri 01-Sep-2023 00:00:00 .txt [LtBlue]example\\[LtRed]files.zip[LtBlue]\\colours\\[Reset]blue.txt
1475z-rw-r--r-- 40 Tue 01-Aug-2023 00:00:00 .txt [LtBlue]example\\[LtRed]files.zip[LtBlue]\\colours\\[Reset]green.txt
1476z-rw-r--r-- 50 Sat 01-Jul-2023 00:00:00 .txt [LtBlue]example\\[LtRed]files.zip[LtBlue]\\colours\\[Reset]red.txt
1477zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example\\[LtRed]files.zip[LtBlue]\\numbers\\[Reset]
1478zlrwxr--r-- 60 Thu 01-Jun-2023 00:00:00 .sh [LtBlue]example\\[LtRed]files.zip[LtBlue]\\numbers\\[Reset][LtCyan]count.sh[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtGreen]count.sh[Reset]
1479zlrw-r--r-- 999 Mon 01-May-2023 00:00:00 .gz [LtBlue]example\\[LtRed]files.zip[LtBlue]\\numbers\\[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtRed]googolplex.gz[Reset]
1480zlrw-r--r-- 0 Sat 01-Apr-2023 00:00:00 [LtBlue]example\\[LtRed]files.zip[LtBlue]\\numbers\\[Reset][LtCyan]ordinals[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtBlue]ordinals\\[Reset]
1481zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example\\[LtRed]files.zip[LtBlue]\\numbers\\one two\\[Reset]
1482z-rw-r--r-- 70 Wed 01-Mar-2023 00:00:00 .txt [LtBlue]example\\[LtRed]files.zip[LtBlue]\\numbers\\one two\\[Reset]\"three\" 'four'.txt
1483";
1484 let files = create_files("D:", "/root", "");
1485 let files = modify_files_for_zip(files);
1486 let config = Config::default()
1487 .with_zip_expand(true)
1488 .with_abs_path(false);
1489 assert_eq!(expected, wrap_files(&config, false, &files));
1490 }
1491
1492 #[test]
1493 #[cfg(windows)]
1494 fn test_prints_relative_paths_with_zip_on_git_bash() {
1495 let expected = "\
1496-drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/[Reset]
1497--rwxr-xr-x 10 Wed 01-Nov-2023 00:00:00 .sh [LtBlue]example/[Reset][DkGreen]find.sh[Reset]
1498zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/[LtRed]files.zip[LtBlue]/[Reset]
1499zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/[LtRed]files.zip[LtBlue]/colours/[Reset]
1500z-rwxr--r-- 20 Sun 01-Oct-2023 00:00:00 .sh [LtBlue]example/[LtRed]files.zip[LtBlue]/colours/[Reset][LtGreen]alpha.sh[Reset]
1501z-rw-r--r-- 30 Fri 01-Sep-2023 00:00:00 .txt [LtBlue]example/[LtRed]files.zip[LtBlue]/colours/[Reset]blue.txt
1502z-rw-r--r-- 40 Tue 01-Aug-2023 00:00:00 .txt [LtBlue]example/[LtRed]files.zip[LtBlue]/colours/[Reset]green.txt
1503z-rw-r--r-- 50 Sat 01-Jul-2023 00:00:00 .txt [LtBlue]example/[LtRed]files.zip[LtBlue]/colours/[Reset]red.txt
1504zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/[LtRed]files.zip[LtBlue]/numbers/[Reset]
1505zlrwxr--r-- 60 Thu 01-Jun-2023 00:00:00 .sh [LtBlue]example/[LtRed]files.zip[LtBlue]/numbers/[Reset][LtCyan]count.sh[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtGreen]count.sh[Reset]
1506zlrw-r--r-- 999 Mon 01-May-2023 00:00:00 .gz [LtBlue]example/[LtRed]files.zip[LtBlue]/numbers/[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
1507zlrw-r--r-- 0 Sat 01-Apr-2023 00:00:00 [LtBlue]example/[LtRed]files.zip[LtBlue]/numbers/[Reset][LtCyan]ordinals[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
1508zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/[LtRed]files.zip[LtBlue]/numbers/one two/[Reset]
1509z-rw-r--r-- 70 Wed 01-Mar-2023 00:00:00 .txt [LtBlue]example/[LtRed]files.zip[LtBlue]/numbers/one two/[Reset]\"three\" 'four'.txt
1510";
1511 let files = create_files("D:", "/root", "");
1512 let files = modify_files_for_zip(files);
1513 let config = Config::default()
1514 .with_zip_expand(true)
1515 .with_abs_path(false);
1516 assert_eq!(expected, wrap_files(&config, true, &files));
1517 }
1518
1519 #[test]
1520 #[cfg(not(windows))]
1521 fn test_prints_relative_paths_with_zip_on_linux() {
1522 let expected = "\
1523-drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/[Reset]
1524--rwxr-xr-x 10 Wed 01-Nov-2023 00:00:00 .sh [LtBlue]example/[Reset][DkGreen]find.sh[Reset]
1525zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/[LtRed]files.zip[LtBlue]/[Reset]
1526zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/[LtRed]files.zip[LtBlue]/colours/[Reset]
1527z-rwxr--r-- 20 Sun 01-Oct-2023 00:00:00 .sh [LtBlue]example/[LtRed]files.zip[LtBlue]/colours/[Reset][LtGreen]alpha.sh[Reset]
1528z-rw-r--r-- 30 Fri 01-Sep-2023 00:00:00 .txt [LtBlue]example/[LtRed]files.zip[LtBlue]/colours/[Reset]blue.txt
1529z-rw-r--r-- 40 Tue 01-Aug-2023 00:00:00 .txt [LtBlue]example/[LtRed]files.zip[LtBlue]/colours/[Reset]green.txt
1530z-rw-r--r-- 50 Sat 01-Jul-2023 00:00:00 .txt [LtBlue]example/[LtRed]files.zip[LtBlue]/colours/[Reset]red.txt
1531zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/[LtRed]files.zip[LtBlue]/numbers/[Reset]
1532zlrwxr--r-- 60 Thu 01-Jun-2023 00:00:00 .sh [LtBlue]example/[LtRed]files.zip[LtBlue]/numbers/[Reset][LtCyan]count.sh[Reset] -> [LtBlue]/etc/numbers/[Reset][LtGreen]count.sh[Reset]
1533zlrw-r--r-- 999 Mon 01-May-2023 00:00:00 .gz [LtBlue]example/[LtRed]files.zip[LtBlue]/numbers/[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
1534zlrw-r--r-- 0 Sat 01-Apr-2023 00:00:00 [LtBlue]example/[LtRed]files.zip[LtBlue]/numbers/[Reset][LtCyan]ordinals[Reset] -> [LtBlue]/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
1535zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/[LtRed]files.zip[LtBlue]/numbers/one two/[Reset]
1536z-rw-r--r-- 70 Wed 01-Mar-2023 00:00:00 .txt [LtBlue]example/[LtRed]files.zip[LtBlue]/numbers/one two/[Reset]\"three\" 'four'.txt
1537";
1538 let files = create_files("", "/root", "");
1539 let files = modify_files_for_zip(files);
1540 let config = Config::default()
1541 .with_zip_expand(true)
1542 .with_abs_path(false);
1543 assert_eq!(expected, wrap_files(&config, false, &files));
1544 }
1545
1546 #[test]
1547 #[cfg(windows)]
1548 fn test_prints_absolute_paths_with_zip_on_windows() {
1549 let expected = "\
1550-drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]D:\\root\\example\\[Reset]
1551--rwxr-xr-x 10 Wed 01-Nov-2023 00:00:00 .sh [LtBlue]D:\\root\\example\\[Reset][DkGreen]find.sh[Reset]
1552zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]D:\\root\\example\\[LtRed]files.zip[LtBlue]\\[Reset]
1553zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]D:\\root\\example\\[LtRed]files.zip[LtBlue]\\colours\\[Reset]
1554z-rwxr--r-- 20 Sun 01-Oct-2023 00:00:00 .sh [LtBlue]D:\\root\\example\\[LtRed]files.zip[LtBlue]\\colours\\[Reset][LtGreen]alpha.sh[Reset]
1555z-rw-r--r-- 30 Fri 01-Sep-2023 00:00:00 .txt [LtBlue]D:\\root\\example\\[LtRed]files.zip[LtBlue]\\colours\\[Reset]blue.txt
1556z-rw-r--r-- 40 Tue 01-Aug-2023 00:00:00 .txt [LtBlue]D:\\root\\example\\[LtRed]files.zip[LtBlue]\\colours\\[Reset]green.txt
1557z-rw-r--r-- 50 Sat 01-Jul-2023 00:00:00 .txt [LtBlue]D:\\root\\example\\[LtRed]files.zip[LtBlue]\\colours\\[Reset]red.txt
1558zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]D:\\root\\example\\[LtRed]files.zip[LtBlue]\\numbers\\[Reset]
1559zlrwxr--r-- 60 Thu 01-Jun-2023 00:00:00 .sh [LtBlue]D:\\root\\example\\[LtRed]files.zip[LtBlue]\\numbers\\[Reset][LtCyan]count.sh[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtGreen]count.sh[Reset]
1560zlrw-r--r-- 999 Mon 01-May-2023 00:00:00 .gz [LtBlue]D:\\root\\example\\[LtRed]files.zip[LtBlue]\\numbers\\[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtRed]googolplex.gz[Reset]
1561zlrw-r--r-- 0 Sat 01-Apr-2023 00:00:00 [LtBlue]D:\\root\\example\\[LtRed]files.zip[LtBlue]\\numbers\\[Reset][LtCyan]ordinals[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtBlue]ordinals\\[Reset]
1562zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]D:\\root\\example\\[LtRed]files.zip[LtBlue]\\numbers\\one two\\[Reset]
1563z-rw-r--r-- 70 Wed 01-Mar-2023 00:00:00 .txt [LtBlue]D:\\root\\example\\[LtRed]files.zip[LtBlue]\\numbers\\one two\\[Reset]\"three\" 'four'.txt
1564";
1565 let files = create_files("D:", "/root", "");
1566 let files = modify_files_for_zip(files);
1567 let config = Config::default()
1568 .with_zip_expand(true)
1569 .with_abs_path(true);
1570 assert_eq!(expected, wrap_files(&config, false, &files));
1571 }
1572
1573 #[test]
1574 #[cfg(windows)]
1575 fn test_prints_absolute_paths_with_zip_on_git_bash() {
1576 let expected = "\
1577-drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]/d/root/example/[Reset]
1578--rwxr-xr-x 10 Wed 01-Nov-2023 00:00:00 .sh [LtBlue]/d/root/example/[Reset][DkGreen]find.sh[Reset]
1579zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]/d/root/example/[LtRed]files.zip[LtBlue]/[Reset]
1580zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]/d/root/example/[LtRed]files.zip[LtBlue]/colours/[Reset]
1581z-rwxr--r-- 20 Sun 01-Oct-2023 00:00:00 .sh [LtBlue]/d/root/example/[LtRed]files.zip[LtBlue]/colours/[Reset][LtGreen]alpha.sh[Reset]
1582z-rw-r--r-- 30 Fri 01-Sep-2023 00:00:00 .txt [LtBlue]/d/root/example/[LtRed]files.zip[LtBlue]/colours/[Reset]blue.txt
1583z-rw-r--r-- 40 Tue 01-Aug-2023 00:00:00 .txt [LtBlue]/d/root/example/[LtRed]files.zip[LtBlue]/colours/[Reset]green.txt
1584z-rw-r--r-- 50 Sat 01-Jul-2023 00:00:00 .txt [LtBlue]/d/root/example/[LtRed]files.zip[LtBlue]/colours/[Reset]red.txt
1585zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]/d/root/example/[LtRed]files.zip[LtBlue]/numbers/[Reset]
1586zlrwxr--r-- 60 Thu 01-Jun-2023 00:00:00 .sh [LtBlue]/d/root/example/[LtRed]files.zip[LtBlue]/numbers/[Reset][LtCyan]count.sh[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtGreen]count.sh[Reset]
1587zlrw-r--r-- 999 Mon 01-May-2023 00:00:00 .gz [LtBlue]/d/root/example/[LtRed]files.zip[LtBlue]/numbers/[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
1588zlrw-r--r-- 0 Sat 01-Apr-2023 00:00:00 [LtBlue]/d/root/example/[LtRed]files.zip[LtBlue]/numbers/[Reset][LtCyan]ordinals[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
1589zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]/d/root/example/[LtRed]files.zip[LtBlue]/numbers/one two/[Reset]
1590z-rw-r--r-- 70 Wed 01-Mar-2023 00:00:00 .txt [LtBlue]/d/root/example/[LtRed]files.zip[LtBlue]/numbers/one two/[Reset]\"three\" 'four'.txt
1591";
1592 let files = create_files("D:", "/root", "");
1593 let files = modify_files_for_zip(files);
1594 let config = Config::default()
1595 .with_zip_expand(true)
1596 .with_abs_path(true);
1597 assert_eq!(expected, wrap_files(&config, true, &files));
1598 }
1599
1600 #[test]
1601 #[cfg(not(windows))]
1602 fn test_prints_absolute_paths_with_zip_on_linux() {
1603 let expected = "\
1604-drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]/root/example/[Reset]
1605--rwxr-xr-x 10 Wed 01-Nov-2023 00:00:00 .sh [LtBlue]/root/example/[Reset][DkGreen]find.sh[Reset]
1606zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]/root/example/[LtRed]files.zip[LtBlue]/[Reset]
1607zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]/root/example/[LtRed]files.zip[LtBlue]/colours/[Reset]
1608z-rwxr--r-- 20 Sun 01-Oct-2023 00:00:00 .sh [LtBlue]/root/example/[LtRed]files.zip[LtBlue]/colours/[Reset][LtGreen]alpha.sh[Reset]
1609z-rw-r--r-- 30 Fri 01-Sep-2023 00:00:00 .txt [LtBlue]/root/example/[LtRed]files.zip[LtBlue]/colours/[Reset]blue.txt
1610z-rw-r--r-- 40 Tue 01-Aug-2023 00:00:00 .txt [LtBlue]/root/example/[LtRed]files.zip[LtBlue]/colours/[Reset]green.txt
1611z-rw-r--r-- 50 Sat 01-Jul-2023 00:00:00 .txt [LtBlue]/root/example/[LtRed]files.zip[LtBlue]/colours/[Reset]red.txt
1612zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]/root/example/[LtRed]files.zip[LtBlue]/numbers/[Reset]
1613zlrwxr--r-- 60 Thu 01-Jun-2023 00:00:00 .sh [LtBlue]/root/example/[LtRed]files.zip[LtBlue]/numbers/[Reset][LtCyan]count.sh[Reset] -> [LtBlue]/etc/numbers/[Reset][LtGreen]count.sh[Reset]
1614zlrw-r--r-- 999 Mon 01-May-2023 00:00:00 .gz [LtBlue]/root/example/[LtRed]files.zip[LtBlue]/numbers/[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
1615zlrw-r--r-- 0 Sat 01-Apr-2023 00:00:00 [LtBlue]/root/example/[LtRed]files.zip[LtBlue]/numbers/[Reset][LtCyan]ordinals[Reset] -> [LtBlue]/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
1616zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]/root/example/[LtRed]files.zip[LtBlue]/numbers/one two/[Reset]
1617z-rw-r--r-- 70 Wed 01-Mar-2023 00:00:00 .txt [LtBlue]/root/example/[LtRed]files.zip[LtBlue]/numbers/one two/[Reset]\"three\" 'four'.txt
1618";
1619 let files = create_files("", "/root", "");
1620 let files = modify_files_for_zip(files);
1621 let config = Config::default()
1622 .with_zip_expand(true)
1623 .with_abs_path(true);
1624 assert_eq!(expected, wrap_files(&config, false, &files));
1625 }
1626
1627 #[test]
1628 #[cfg(windows)]
1629 fn test_prints_paths_with_start_header_on_windows() {
1630 let expected = "\
1631Start Sun 01-Jan-2023 00:00:00
1632-----------------------------------------
1633drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example\\[Reset]
1634-rwxr-xr-x 10 Wed 01-Nov-2023 00:00:00 .sh [LtBlue]example\\[Reset][DkGreen]find.sh[Reset]
1635drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example\\files\\[Reset]
1636drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example\\files\\colours\\[Reset]
1637-rwxr--r-- 20 Sun 01-Oct-2023 00:00:00 .sh [LtBlue]example\\files\\colours\\[Reset][LtGreen]alpha.sh[Reset]
1638-rw-r--r-- 30 Fri 01-Sep-2023 00:00:00 .txt [LtBlue]example\\files\\colours\\[Reset]blue.txt
1639-rw-r--r-- 40 Tue 01-Aug-2023 00:00:00 .txt [LtBlue]example\\files\\colours\\[Reset]green.txt
1640-rw-r--r-- 50 Sat 01-Jul-2023 00:00:00 .txt [LtBlue]example\\files\\colours\\[Reset]red.txt
1641drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example\\files\\numbers\\[Reset]
1642lrwxr--r-- 60 Thu 01-Jun-2023 00:00:00 .sh [LtBlue]example\\files\\numbers\\[Reset][LtCyan]count.sh[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtGreen]count.sh[Reset]
1643lrw-r--r-- 999 Mon 01-May-2023 00:00:00 .gz [LtBlue]example\\files\\numbers\\[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtRed]googolplex.gz[Reset]
1644lrw-r--r-- 0 Sat 01-Apr-2023 00:00:00 [LtBlue]example\\files\\numbers\\[Reset][LtCyan]ordinals[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtBlue]ordinals\\[Reset]
1645drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example\\files\\numbers\\one two\\[Reset]
1646-rw-r--r-- 70 Wed 01-Mar-2023 00:00:00 .txt [LtBlue]example\\files\\numbers\\one two\\[Reset]\"three\" 'four'.txt
1647";
1648 let files = create_files("D:", "/root", "");
1649 let config = Config::default()
1650 .with_filter_recent(RecentKind::Year(1))
1651 .with_abs_path(false);
1652 assert_eq!(expected, wrap_files(&config, false, &files));
1653 }
1654
1655 #[test]
1656 #[cfg(windows)]
1657 fn test_prints_paths_with_start_header_on_git_bash() {
1658 let expected = "\
1659Start Sun 01-Jan-2023 00:00:00
1660-----------------------------------------
1661drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/[Reset]
1662-rwxr-xr-x 10 Wed 01-Nov-2023 00:00:00 .sh [LtBlue]example/[Reset][DkGreen]find.sh[Reset]
1663drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/[Reset]
1664drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/colours/[Reset]
1665-rwxr--r-- 20 Sun 01-Oct-2023 00:00:00 .sh [LtBlue]example/files/colours/[Reset][LtGreen]alpha.sh[Reset]
1666-rw-r--r-- 30 Fri 01-Sep-2023 00:00:00 .txt [LtBlue]example/files/colours/[Reset]blue.txt
1667-rw-r--r-- 40 Tue 01-Aug-2023 00:00:00 .txt [LtBlue]example/files/colours/[Reset]green.txt
1668-rw-r--r-- 50 Sat 01-Jul-2023 00:00:00 .txt [LtBlue]example/files/colours/[Reset]red.txt
1669drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/numbers/[Reset]
1670lrwxr--r-- 60 Thu 01-Jun-2023 00:00:00 .sh [LtBlue]example/files/numbers/[Reset][LtCyan]count.sh[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtGreen]count.sh[Reset]
1671lrw-r--r-- 999 Mon 01-May-2023 00:00:00 .gz [LtBlue]example/files/numbers/[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
1672lrw-r--r-- 0 Sat 01-Apr-2023 00:00:00 [LtBlue]example/files/numbers/[Reset][LtCyan]ordinals[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
1673drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/numbers/one two/[Reset]
1674-rw-r--r-- 70 Wed 01-Mar-2023 00:00:00 .txt [LtBlue]example/files/numbers/one two/[Reset]\"three\" 'four'.txt
1675";
1676 let files = create_files("D:", "/root", "");
1677 let config = Config::default()
1678 .with_filter_recent(RecentKind::Year(1))
1679 .with_abs_path(false);
1680 assert_eq!(expected, wrap_files(&config, true, &files));
1681 }
1682
1683 #[test]
1684 #[cfg(not(windows))]
1685 fn test_prints_paths_with_start_header_on_linux() {
1686 let expected = "\
1687Start Sun 01-Jan-2023 00:00:00
1688-----------------------------------------
1689drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/[Reset]
1690-rwxr-xr-x 10 Wed 01-Nov-2023 00:00:00 .sh [LtBlue]example/[Reset][DkGreen]find.sh[Reset]
1691drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/[Reset]
1692drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/colours/[Reset]
1693-rwxr--r-- 20 Sun 01-Oct-2023 00:00:00 .sh [LtBlue]example/files/colours/[Reset][LtGreen]alpha.sh[Reset]
1694-rw-r--r-- 30 Fri 01-Sep-2023 00:00:00 .txt [LtBlue]example/files/colours/[Reset]blue.txt
1695-rw-r--r-- 40 Tue 01-Aug-2023 00:00:00 .txt [LtBlue]example/files/colours/[Reset]green.txt
1696-rw-r--r-- 50 Sat 01-Jul-2023 00:00:00 .txt [LtBlue]example/files/colours/[Reset]red.txt
1697drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/numbers/[Reset]
1698lrwxr--r-- 60 Thu 01-Jun-2023 00:00:00 .sh [LtBlue]example/files/numbers/[Reset][LtCyan]count.sh[Reset] -> [LtBlue]/etc/numbers/[Reset][LtGreen]count.sh[Reset]
1699lrw-r--r-- 999 Mon 01-May-2023 00:00:00 .gz [LtBlue]example/files/numbers/[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
1700lrw-r--r-- 0 Sat 01-Apr-2023 00:00:00 [LtBlue]example/files/numbers/[Reset][LtCyan]ordinals[Reset] -> [LtBlue]/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
1701drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/numbers/one two/[Reset]
1702-rw-r--r-- 70 Wed 01-Mar-2023 00:00:00 .txt [LtBlue]example/files/numbers/one two/[Reset]\"three\" 'four'.txt
1703";
1704 let files = create_files("", "/root", "");
1705 let config = Config::default()
1706 .with_filter_recent(RecentKind::Year(1))
1707 .with_abs_path(false);
1708 assert_eq!(expected, wrap_files(&config, false, &files));
1709 }
1710
1711 #[test]
1712 #[cfg(windows)]
1713 fn test_prints_paths_with_start_header_and_utc_on_windows() {
1714 let expected = "\
1715Start Sun 01-Jan-2023 00:00:00Z
1716------------------------------------------
1717drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00Z [LtBlue]example\\[Reset]
1718-rwxr-xr-x 10 Wed 01-Nov-2023 00:00:00Z .sh [LtBlue]example\\[Reset][DkGreen]find.sh[Reset]
1719drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00Z [LtBlue]example\\files\\[Reset]
1720drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00Z [LtBlue]example\\files\\colours\\[Reset]
1721-rwxr--r-- 20 Sun 01-Oct-2023 00:00:00Z .sh [LtBlue]example\\files\\colours\\[Reset][LtGreen]alpha.sh[Reset]
1722-rw-r--r-- 30 Fri 01-Sep-2023 00:00:00Z .txt [LtBlue]example\\files\\colours\\[Reset]blue.txt
1723-rw-r--r-- 40 Tue 01-Aug-2023 00:00:00Z .txt [LtBlue]example\\files\\colours\\[Reset]green.txt
1724-rw-r--r-- 50 Sat 01-Jul-2023 00:00:00Z .txt [LtBlue]example\\files\\colours\\[Reset]red.txt
1725drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00Z [LtBlue]example\\files\\numbers\\[Reset]
1726lrwxr--r-- 60 Thu 01-Jun-2023 00:00:00Z .sh [LtBlue]example\\files\\numbers\\[Reset][LtCyan]count.sh[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtGreen]count.sh[Reset]
1727lrw-r--r-- 999 Mon 01-May-2023 00:00:00Z .gz [LtBlue]example\\files\\numbers\\[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtRed]googolplex.gz[Reset]
1728lrw-r--r-- 0 Sat 01-Apr-2023 00:00:00Z [LtBlue]example\\files\\numbers\\[Reset][LtCyan]ordinals[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtBlue]ordinals\\[Reset]
1729drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00Z [LtBlue]example\\files\\numbers\\one two\\[Reset]
1730-rw-r--r-- 70 Wed 01-Mar-2023 00:00:00Z .txt [LtBlue]example\\files\\numbers\\one two\\[Reset]\"three\" 'four'.txt
1731";
1732 let files = create_files("D:", "/root", "");
1733 let config = Config::default()
1734 .with_filter_recent(RecentKind::Year(1))
1735 .with_show_utc(true)
1736 .with_abs_path(false);
1737 assert_eq!(expected, wrap_files(&config, false, &files));
1738 }
1739
1740 #[test]
1741 #[cfg(windows)]
1742 fn test_prints_paths_with_start_header_and_utc_on_git_bash() {
1743 let expected = "\
1744Start Sun 01-Jan-2023 00:00:00Z
1745------------------------------------------
1746drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00Z [LtBlue]example/[Reset]
1747-rwxr-xr-x 10 Wed 01-Nov-2023 00:00:00Z .sh [LtBlue]example/[Reset][DkGreen]find.sh[Reset]
1748drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00Z [LtBlue]example/files/[Reset]
1749drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00Z [LtBlue]example/files/colours/[Reset]
1750-rwxr--r-- 20 Sun 01-Oct-2023 00:00:00Z .sh [LtBlue]example/files/colours/[Reset][LtGreen]alpha.sh[Reset]
1751-rw-r--r-- 30 Fri 01-Sep-2023 00:00:00Z .txt [LtBlue]example/files/colours/[Reset]blue.txt
1752-rw-r--r-- 40 Tue 01-Aug-2023 00:00:00Z .txt [LtBlue]example/files/colours/[Reset]green.txt
1753-rw-r--r-- 50 Sat 01-Jul-2023 00:00:00Z .txt [LtBlue]example/files/colours/[Reset]red.txt
1754drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00Z [LtBlue]example/files/numbers/[Reset]
1755lrwxr--r-- 60 Thu 01-Jun-2023 00:00:00Z .sh [LtBlue]example/files/numbers/[Reset][LtCyan]count.sh[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtGreen]count.sh[Reset]
1756lrw-r--r-- 999 Mon 01-May-2023 00:00:00Z .gz [LtBlue]example/files/numbers/[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
1757lrw-r--r-- 0 Sat 01-Apr-2023 00:00:00Z [LtBlue]example/files/numbers/[Reset][LtCyan]ordinals[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
1758drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00Z [LtBlue]example/files/numbers/one two/[Reset]
1759-rw-r--r-- 70 Wed 01-Mar-2023 00:00:00Z .txt [LtBlue]example/files/numbers/one two/[Reset]\"three\" 'four'.txt
1760";
1761 let files = create_files("D:", "/root", "");
1762 let config = Config::default()
1763 .with_filter_recent(RecentKind::Year(1))
1764 .with_show_utc(true)
1765 .with_abs_path(false);
1766 assert_eq!(expected, wrap_files(&config, true, &files));
1767 }
1768
1769 #[test]
1770 #[cfg(not(windows))]
1771 fn test_prints_paths_with_start_header_and_utc_on_linux() {
1772 let expected = "\
1773Start Sun 01-Jan-2023 00:00:00Z
1774------------------------------------------
1775drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00Z [LtBlue]example/[Reset]
1776-rwxr-xr-x 10 Wed 01-Nov-2023 00:00:00Z .sh [LtBlue]example/[Reset][DkGreen]find.sh[Reset]
1777drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00Z [LtBlue]example/files/[Reset]
1778drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00Z [LtBlue]example/files/colours/[Reset]
1779-rwxr--r-- 20 Sun 01-Oct-2023 00:00:00Z .sh [LtBlue]example/files/colours/[Reset][LtGreen]alpha.sh[Reset]
1780-rw-r--r-- 30 Fri 01-Sep-2023 00:00:00Z .txt [LtBlue]example/files/colours/[Reset]blue.txt
1781-rw-r--r-- 40 Tue 01-Aug-2023 00:00:00Z .txt [LtBlue]example/files/colours/[Reset]green.txt
1782-rw-r--r-- 50 Sat 01-Jul-2023 00:00:00Z .txt [LtBlue]example/files/colours/[Reset]red.txt
1783drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00Z [LtBlue]example/files/numbers/[Reset]
1784lrwxr--r-- 60 Thu 01-Jun-2023 00:00:00Z .sh [LtBlue]example/files/numbers/[Reset][LtCyan]count.sh[Reset] -> [LtBlue]/etc/numbers/[Reset][LtGreen]count.sh[Reset]
1785lrw-r--r-- 999 Mon 01-May-2023 00:00:00Z .gz [LtBlue]example/files/numbers/[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
1786lrw-r--r-- 0 Sat 01-Apr-2023 00:00:00Z [LtBlue]example/files/numbers/[Reset][LtCyan]ordinals[Reset] -> [LtBlue]/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
1787drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00Z [LtBlue]example/files/numbers/one two/[Reset]
1788-rw-r--r-- 70 Wed 01-Mar-2023 00:00:00Z .txt [LtBlue]example/files/numbers/one two/[Reset]\"three\" 'four'.txt
1789";
1790 let files = create_files("", "/root", "");
1791 let config = Config::default()
1792 .with_filter_recent(RecentKind::Year(1))
1793 .with_show_utc(true)
1794 .with_abs_path(false);
1795 assert_eq!(expected, wrap_files(&config, false, &files));
1796 }
1797
1798 #[test]
1799 #[cfg(windows)]
1800 fn test_prints_paths_with_total_footer_on_windows() {
1801 let expected = "\
1802drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example\\[Reset]
1803-rwxr-xr-x 10 Wed 01-Nov-2023 00:00:00 .sh [LtBlue]example\\[Reset][DkGreen]find.sh[Reset]
1804drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example\\files\\[Reset]
1805drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example\\files\\colours\\[Reset]
1806-rwxr--r-- 20 Sun 01-Oct-2023 00:00:00 .sh [LtBlue]example\\files\\colours\\[Reset][LtGreen]alpha.sh[Reset]
1807-rw-r--r-- 30 Fri 01-Sep-2023 00:00:00 .txt [LtBlue]example\\files\\colours\\[Reset]blue.txt
1808-rw-r--r-- 40 Tue 01-Aug-2023 00:00:00 .txt [LtBlue]example\\files\\colours\\[Reset]green.txt
1809-rw-r--r-- 50 Sat 01-Jul-2023 00:00:00 .txt [LtBlue]example\\files\\colours\\[Reset]red.txt
1810drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example\\files\\numbers\\[Reset]
1811lrwxr--r-- 60 Thu 01-Jun-2023 00:00:00 .sh [LtBlue]example\\files\\numbers\\[Reset][LtCyan]count.sh[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtGreen]count.sh[Reset]
1812lrw-r--r-- 999 Mon 01-May-2023 00:00:00 .gz [LtBlue]example\\files\\numbers\\[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtRed]googolplex.gz[Reset]
1813lrw-r--r-- 0 Sat 01-Apr-2023 00:00:00 [LtBlue]example\\files\\numbers\\[Reset][LtCyan]ordinals[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtBlue]ordinals\\[Reset]
1814drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example\\files\\numbers\\one two\\[Reset]
1815-rw-r--r-- 70 Wed 01-Mar-2023 00:00:00 .txt [LtBlue]example\\files\\numbers\\one two\\[Reset]\"three\" 'four'.txt
1816---------------------------------------------
1817Total 1,279 9 files 5 directories
1818";
1819 let files = create_files("D:", "/root", "");
1820 let config = Config::default()
1821 .with_show_total(true)
1822 .with_abs_path(false);
1823 assert_eq!(expected, wrap_files(&config, false, &files));
1824 }
1825
1826 #[test]
1827 #[cfg(windows)]
1828 fn test_prints_paths_with_total_footer_on_git_bash() {
1829 let expected = "\
1830drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/[Reset]
1831-rwxr-xr-x 10 Wed 01-Nov-2023 00:00:00 .sh [LtBlue]example/[Reset][DkGreen]find.sh[Reset]
1832drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/[Reset]
1833drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/colours/[Reset]
1834-rwxr--r-- 20 Sun 01-Oct-2023 00:00:00 .sh [LtBlue]example/files/colours/[Reset][LtGreen]alpha.sh[Reset]
1835-rw-r--r-- 30 Fri 01-Sep-2023 00:00:00 .txt [LtBlue]example/files/colours/[Reset]blue.txt
1836-rw-r--r-- 40 Tue 01-Aug-2023 00:00:00 .txt [LtBlue]example/files/colours/[Reset]green.txt
1837-rw-r--r-- 50 Sat 01-Jul-2023 00:00:00 .txt [LtBlue]example/files/colours/[Reset]red.txt
1838drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/numbers/[Reset]
1839lrwxr--r-- 60 Thu 01-Jun-2023 00:00:00 .sh [LtBlue]example/files/numbers/[Reset][LtCyan]count.sh[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtGreen]count.sh[Reset]
1840lrw-r--r-- 999 Mon 01-May-2023 00:00:00 .gz [LtBlue]example/files/numbers/[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
1841lrw-r--r-- 0 Sat 01-Apr-2023 00:00:00 [LtBlue]example/files/numbers/[Reset][LtCyan]ordinals[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
1842drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/numbers/one two/[Reset]
1843-rw-r--r-- 70 Wed 01-Mar-2023 00:00:00 .txt [LtBlue]example/files/numbers/one two/[Reset]\"three\" 'four'.txt
1844---------------------------------------------
1845Total 1,279 9 files 5 directories
1846";
1847 let files = create_files("D:", "/root", "");
1848 let config = Config::default()
1849 .with_show_total(true)
1850 .with_abs_path(false);
1851 assert_eq!(expected, wrap_files(&config, true, &files));
1852 }
1853
1854 #[test]
1855 #[cfg(not(windows))]
1856 fn test_prints_paths_with_total_footer_on_linux() {
1857 let expected = "\
1858drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/[Reset]
1859-rwxr-xr-x 10 Wed 01-Nov-2023 00:00:00 .sh [LtBlue]example/[Reset][DkGreen]find.sh[Reset]
1860drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/[Reset]
1861drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/colours/[Reset]
1862-rwxr--r-- 20 Sun 01-Oct-2023 00:00:00 .sh [LtBlue]example/files/colours/[Reset][LtGreen]alpha.sh[Reset]
1863-rw-r--r-- 30 Fri 01-Sep-2023 00:00:00 .txt [LtBlue]example/files/colours/[Reset]blue.txt
1864-rw-r--r-- 40 Tue 01-Aug-2023 00:00:00 .txt [LtBlue]example/files/colours/[Reset]green.txt
1865-rw-r--r-- 50 Sat 01-Jul-2023 00:00:00 .txt [LtBlue]example/files/colours/[Reset]red.txt
1866drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/numbers/[Reset]
1867lrwxr--r-- 60 Thu 01-Jun-2023 00:00:00 .sh [LtBlue]example/files/numbers/[Reset][LtCyan]count.sh[Reset] -> [LtBlue]/etc/numbers/[Reset][LtGreen]count.sh[Reset]
1868lrw-r--r-- 999 Mon 01-May-2023 00:00:00 .gz [LtBlue]example/files/numbers/[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
1869lrw-r--r-- 0 Sat 01-Apr-2023 00:00:00 [LtBlue]example/files/numbers/[Reset][LtCyan]ordinals[Reset] -> [LtBlue]/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
1870drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/numbers/one two/[Reset]
1871-rw-r--r-- 70 Wed 01-Mar-2023 00:00:00 .txt [LtBlue]example/files/numbers/one two/[Reset]\"three\" 'four'.txt
1872---------------------------------------------
1873Total 1,279 9 files 5 directories
1874";
1875 let files = create_files("", "/root", "");
1876 let config = Config::default()
1877 .with_show_total(true)
1878 .with_abs_path(false);
1879 assert_eq!(expected, wrap_files(&config, false, &files));
1880 }
1881
1882 #[test]
1883 #[cfg(windows)]
1884 fn test_prints_pretty_fields_on_windows() {
1885 let expected = "\
1886drwxr-xr-x 0 B 1 day [LtBlue]example\\[Reset]
1887-rwxr-xr-x 10 B 2 month .sh [LtBlue]example\\[Reset][DkGreen]find.sh[Reset]
1888drwxr-xr-x 0 B 1 day [LtBlue]example\\files\\[Reset]
1889drwxr-xr-x 0 B 1 day [LtBlue]example\\files\\colours\\[Reset]
1890-rwxr--r-- 20 B 3 month .sh [LtBlue]example\\files\\colours\\[Reset][LtGreen]alpha.sh[Reset]
1891-rw-r--r-- 30 B 4 month .txt [LtBlue]example\\files\\colours\\[Reset]blue.txt
1892-rw-r--r-- 40 B 5 month .txt [LtBlue]example\\files\\colours\\[Reset]green.txt
1893-rw-r--r-- 50 B 6 month .txt [LtBlue]example\\files\\colours\\[Reset]red.txt
1894drwxr-xr-x 0 B 1 day [LtBlue]example\\files\\numbers\\[Reset]
1895lrwxr--r-- 60 B 7 month .sh [LtBlue]example\\files\\numbers\\[Reset][LtCyan]count.sh[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtGreen]count.sh[Reset]
1896lrw-r--r-- 999 B 8 month .gz [LtBlue]example\\files\\numbers\\[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtRed]googolplex.gz[Reset]
1897lrw-r--r-- 0 B 9 month [LtBlue]example\\files\\numbers\\[Reset][LtCyan]ordinals[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtBlue]ordinals\\[Reset]
1898drwxr-xr-x 0 B 1 day [LtBlue]example\\files\\numbers\\one two\\[Reset]
1899-rw-r--r-- 70 B 10 month .txt [LtBlue]example\\files\\numbers\\one two\\[Reset]\"three\" 'four'.txt
1900";
1901 let files = create_files("D:", "/root", "");
1902 let config = Config::default()
1903 .with_curr_time(2024, 1, 1, 0, 0, 0)
1904 .with_show_pretty(true)
1905 .with_abs_path(false);
1906 assert_eq!(expected, wrap_files(&config, false, &files));
1907 }
1908
1909 #[test]
1910 #[cfg(windows)]
1911 fn test_prints_pretty_fields_on_git_bash() {
1912 let expected = "\
1913drwxr-xr-x 0 B 1 day [LtBlue]example/[Reset]
1914-rwxr-xr-x 10 B 2 month .sh [LtBlue]example/[Reset][DkGreen]find.sh[Reset]
1915drwxr-xr-x 0 B 1 day [LtBlue]example/files/[Reset]
1916drwxr-xr-x 0 B 1 day [LtBlue]example/files/colours/[Reset]
1917-rwxr--r-- 20 B 3 month .sh [LtBlue]example/files/colours/[Reset][LtGreen]alpha.sh[Reset]
1918-rw-r--r-- 30 B 4 month .txt [LtBlue]example/files/colours/[Reset]blue.txt
1919-rw-r--r-- 40 B 5 month .txt [LtBlue]example/files/colours/[Reset]green.txt
1920-rw-r--r-- 50 B 6 month .txt [LtBlue]example/files/colours/[Reset]red.txt
1921drwxr-xr-x 0 B 1 day [LtBlue]example/files/numbers/[Reset]
1922lrwxr--r-- 60 B 7 month .sh [LtBlue]example/files/numbers/[Reset][LtCyan]count.sh[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtGreen]count.sh[Reset]
1923lrw-r--r-- 999 B 8 month .gz [LtBlue]example/files/numbers/[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
1924lrw-r--r-- 0 B 9 month [LtBlue]example/files/numbers/[Reset][LtCyan]ordinals[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
1925drwxr-xr-x 0 B 1 day [LtBlue]example/files/numbers/one two/[Reset]
1926-rw-r--r-- 70 B 10 month .txt [LtBlue]example/files/numbers/one two/[Reset]\"three\" 'four'.txt
1927";
1928 let files = create_files("D:", "/root", "");
1929 let config = Config::default()
1930 .with_curr_time(2024, 1, 1, 0, 0, 0)
1931 .with_show_pretty(true)
1932 .with_abs_path(false);
1933 assert_eq!(expected, wrap_files(&config, true, &files));
1934 }
1935
1936 #[test]
1937 #[cfg(not(windows))]
1938 fn test_prints_pretty_fields_on_linux() {
1939 let expected = "\
1940drwxr-xr-x 0 B 1 day [LtBlue]example/[Reset]
1941-rwxr-xr-x 10 B 2 month .sh [LtBlue]example/[Reset][DkGreen]find.sh[Reset]
1942drwxr-xr-x 0 B 1 day [LtBlue]example/files/[Reset]
1943drwxr-xr-x 0 B 1 day [LtBlue]example/files/colours/[Reset]
1944-rwxr--r-- 20 B 3 month .sh [LtBlue]example/files/colours/[Reset][LtGreen]alpha.sh[Reset]
1945-rw-r--r-- 30 B 4 month .txt [LtBlue]example/files/colours/[Reset]blue.txt
1946-rw-r--r-- 40 B 5 month .txt [LtBlue]example/files/colours/[Reset]green.txt
1947-rw-r--r-- 50 B 6 month .txt [LtBlue]example/files/colours/[Reset]red.txt
1948drwxr-xr-x 0 B 1 day [LtBlue]example/files/numbers/[Reset]
1949lrwxr--r-- 60 B 7 month .sh [LtBlue]example/files/numbers/[Reset][LtCyan]count.sh[Reset] -> [LtBlue]/etc/numbers/[Reset][LtGreen]count.sh[Reset]
1950lrw-r--r-- 999 B 8 month .gz [LtBlue]example/files/numbers/[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
1951lrw-r--r-- 0 B 9 month [LtBlue]example/files/numbers/[Reset][LtCyan]ordinals[Reset] -> [LtBlue]/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
1952drwxr-xr-x 0 B 1 day [LtBlue]example/files/numbers/one two/[Reset]
1953-rw-r--r-- 70 B 10 month .txt [LtBlue]example/files/numbers/one two/[Reset]\"three\" 'four'.txt
1954";
1955 let files = create_files("", "/root", "");
1956 let config = Config::default()
1957 .with_curr_time(2024, 1, 1, 0, 0, 0)
1958 .with_show_pretty(true)
1959 .with_abs_path(false);
1960 assert_eq!(expected, wrap_files(&config, false, &files));
1961 }
1962
1963 #[test]
1964 #[cfg(windows)]
1965 fn test_prints_pretty_fields_with_header_and_footer_on_windows() {
1966 let expected = "\
1967Start 1 year
1968----------------------------
1969drwxr-xr-x 0 B 1 day [LtBlue]example\\[Reset]
1970-rwxr-xr-x 10 B 2 month .sh [LtBlue]example\\[Reset][DkGreen]find.sh[Reset]
1971drwxr-xr-x 0 B 1 day [LtBlue]example\\files\\[Reset]
1972drwxr-xr-x 0 B 1 day [LtBlue]example\\files\\colours\\[Reset]
1973-rwxr--r-- 20 B 3 month .sh [LtBlue]example\\files\\colours\\[Reset][LtGreen]alpha.sh[Reset]
1974-rw-r--r-- 30 B 4 month .txt [LtBlue]example\\files\\colours\\[Reset]blue.txt
1975-rw-r--r-- 40 B 5 month .txt [LtBlue]example\\files\\colours\\[Reset]green.txt
1976-rw-r--r-- 50 B 6 month .txt [LtBlue]example\\files\\colours\\[Reset]red.txt
1977drwxr-xr-x 0 B 1 day [LtBlue]example\\files\\numbers\\[Reset]
1978lrwxr--r-- 60 B 7 month .sh [LtBlue]example\\files\\numbers\\[Reset][LtCyan]count.sh[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtGreen]count.sh[Reset]
1979lrw-r--r-- 999 B 8 month .gz [LtBlue]example\\files\\numbers\\[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtRed]googolplex.gz[Reset]
1980lrw-r--r-- 0 B 9 month [LtBlue]example\\files\\numbers\\[Reset][LtCyan]ordinals[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtBlue]ordinals\\[Reset]
1981drwxr-xr-x 0 B 1 day [LtBlue]example\\files\\numbers\\one two\\[Reset]
1982-rw-r--r-- 70 B 10 month .txt [LtBlue]example\\files\\numbers\\one two\\[Reset]\"three\" 'four'.txt
1983----------------------------
1984Total 1 KB 9 files 5 directories
1985";
1986 let files = create_files("D:", "/root", "");
1987 let config = Config::default()
1988 .with_curr_time(2024, 1, 1, 0, 0, 0)
1989 .with_show_pretty(true)
1990 .with_filter_recent(RecentKind::Year(1))
1991 .with_show_total(true)
1992 .with_abs_path(false);
1993 assert_eq!(expected, wrap_files(&config, false, &files));
1994 }
1995
1996 #[test]
1997 #[cfg(windows)]
1998 fn test_prints_pretty_fields_with_header_and_footer_on_git_bash() {
1999 let expected = "\
2000Start 1 year
2001----------------------------
2002drwxr-xr-x 0 B 1 day [LtBlue]example/[Reset]
2003-rwxr-xr-x 10 B 2 month .sh [LtBlue]example/[Reset][DkGreen]find.sh[Reset]
2004drwxr-xr-x 0 B 1 day [LtBlue]example/files/[Reset]
2005drwxr-xr-x 0 B 1 day [LtBlue]example/files/colours/[Reset]
2006-rwxr--r-- 20 B 3 month .sh [LtBlue]example/files/colours/[Reset][LtGreen]alpha.sh[Reset]
2007-rw-r--r-- 30 B 4 month .txt [LtBlue]example/files/colours/[Reset]blue.txt
2008-rw-r--r-- 40 B 5 month .txt [LtBlue]example/files/colours/[Reset]green.txt
2009-rw-r--r-- 50 B 6 month .txt [LtBlue]example/files/colours/[Reset]red.txt
2010drwxr-xr-x 0 B 1 day [LtBlue]example/files/numbers/[Reset]
2011lrwxr--r-- 60 B 7 month .sh [LtBlue]example/files/numbers/[Reset][LtCyan]count.sh[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtGreen]count.sh[Reset]
2012lrw-r--r-- 999 B 8 month .gz [LtBlue]example/files/numbers/[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
2013lrw-r--r-- 0 B 9 month [LtBlue]example/files/numbers/[Reset][LtCyan]ordinals[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
2014drwxr-xr-x 0 B 1 day [LtBlue]example/files/numbers/one two/[Reset]
2015-rw-r--r-- 70 B 10 month .txt [LtBlue]example/files/numbers/one two/[Reset]\"three\" 'four'.txt
2016----------------------------
2017Total 1 KB 9 files 5 directories
2018";
2019 let files = create_files("D:", "/root", "");
2020 let config = Config::default()
2021 .with_curr_time(2024, 1, 1, 0, 0, 0)
2022 .with_show_pretty(true)
2023 .with_filter_recent(RecentKind::Year(1))
2024 .with_show_total(true)
2025 .with_abs_path(false);
2026 assert_eq!(expected, wrap_files(&config, true, &files));
2027 }
2028
2029 #[test]
2030 #[cfg(not(windows))]
2031 fn test_prints_pretty_fields_with_header_and_footer_on_linux() {
2032 let expected = "\
2033Start 1 year
2034----------------------------
2035drwxr-xr-x 0 B 1 day [LtBlue]example/[Reset]
2036-rwxr-xr-x 10 B 2 month .sh [LtBlue]example/[Reset][DkGreen]find.sh[Reset]
2037drwxr-xr-x 0 B 1 day [LtBlue]example/files/[Reset]
2038drwxr-xr-x 0 B 1 day [LtBlue]example/files/colours/[Reset]
2039-rwxr--r-- 20 B 3 month .sh [LtBlue]example/files/colours/[Reset][LtGreen]alpha.sh[Reset]
2040-rw-r--r-- 30 B 4 month .txt [LtBlue]example/files/colours/[Reset]blue.txt
2041-rw-r--r-- 40 B 5 month .txt [LtBlue]example/files/colours/[Reset]green.txt
2042-rw-r--r-- 50 B 6 month .txt [LtBlue]example/files/colours/[Reset]red.txt
2043drwxr-xr-x 0 B 1 day [LtBlue]example/files/numbers/[Reset]
2044lrwxr--r-- 60 B 7 month .sh [LtBlue]example/files/numbers/[Reset][LtCyan]count.sh[Reset] -> [LtBlue]/etc/numbers/[Reset][LtGreen]count.sh[Reset]
2045lrw-r--r-- 999 B 8 month .gz [LtBlue]example/files/numbers/[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
2046lrw-r--r-- 0 B 9 month [LtBlue]example/files/numbers/[Reset][LtCyan]ordinals[Reset] -> [LtBlue]/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
2047drwxr-xr-x 0 B 1 day [LtBlue]example/files/numbers/one two/[Reset]
2048-rw-r--r-- 70 B 10 month .txt [LtBlue]example/files/numbers/one two/[Reset]\"three\" 'four'.txt
2049----------------------------
2050Total 1 KB 9 files 5 directories
2051";
2052 let files = create_files("", "/root", "");
2053 let config = Config::default()
2054 .with_curr_time(2024, 1, 1, 0, 0, 0)
2055 .with_show_pretty(true)
2056 .with_filter_recent(RecentKind::Year(1))
2057 .with_show_total(true)
2058 .with_abs_path(false);
2059 assert_eq!(expected, wrap_files(&config, false, &files));
2060 }
2061
2062 #[test]
2063 #[cfg(windows)]
2064 fn test_prints_git_flags_on_windows() {
2065 let expected = "\
2066drwxr-xr-x ----- 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example\\[Reset]
2067-rwxr-xr-x AMRUI 10 Wed 01-Nov-2023 00:00:00 .sh [LtBlue]example\\[Reset][DkGreen]find.sh[Reset]
2068drwxr-xr-x ----- 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example\\files\\[Reset]
2069drwxr-xr-x ----- 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example\\files\\colours\\[Reset]
2070-rwxr--r-- A---- 20 Sun 01-Oct-2023 00:00:00 .sh [LtBlue]example\\files\\colours\\[Reset][LtGreen]alpha.sh[Reset]
2071-rw-r--r-- -M--- 30 Fri 01-Sep-2023 00:00:00 .txt [LtBlue]example\\files\\colours\\[Reset]blue.txt
2072-rw-r--r-- --R-- 40 Tue 01-Aug-2023 00:00:00 .txt [LtBlue]example\\files\\colours\\[Reset]green.txt
2073-rw-r--r-- ---U- 50 Sat 01-Jul-2023 00:00:00 .txt [LtBlue]example\\files\\colours\\[Reset]red.txt
2074drwxr-xr-x ----- 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example\\files\\numbers\\[Reset]
2075lrwxr--r-- ----- 60 Thu 01-Jun-2023 00:00:00 .sh [LtBlue]example\\files\\numbers\\[Reset][LtCyan]count.sh[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtGreen]count.sh[Reset]
2076lrw-r--r-- ----- 999 Mon 01-May-2023 00:00:00 .gz [LtBlue]example\\files\\numbers\\[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtRed]googolplex.gz[Reset]
2077lrw-r--r-- ----- 0 Sat 01-Apr-2023 00:00:00 [LtBlue]example\\files\\numbers\\[Reset][LtCyan]ordinals[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtBlue]ordinals\\[Reset]
2078drwxr-xr-x ----- 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example\\files\\numbers\\one two\\[Reset]
2079-rw-r--r-- ----I 70 Wed 01-Mar-2023 00:00:00 .txt [LtBlue]example\\files\\numbers\\one two\\[Reset]\"three\" 'four'.txt
2080";
2081 let files = create_files("D:", "/root", "");
2082 let config = Config::default()
2083 .with_filter_git(GitFlags::new());
2084 assert_eq!(expected, wrap_files(&config, false, &files));
2085 }
2086
2087 #[test]
2088 #[cfg(windows)]
2089 fn test_prints_git_flags_on_git_bash() {
2090 let expected = "\
2091drwxr-xr-x ----- 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/[Reset]
2092-rwxr-xr-x AMRUI 10 Wed 01-Nov-2023 00:00:00 .sh [LtBlue]example/[Reset][DkGreen]find.sh[Reset]
2093drwxr-xr-x ----- 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/[Reset]
2094drwxr-xr-x ----- 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/colours/[Reset]
2095-rwxr--r-- A---- 20 Sun 01-Oct-2023 00:00:00 .sh [LtBlue]example/files/colours/[Reset][LtGreen]alpha.sh[Reset]
2096-rw-r--r-- -M--- 30 Fri 01-Sep-2023 00:00:00 .txt [LtBlue]example/files/colours/[Reset]blue.txt
2097-rw-r--r-- --R-- 40 Tue 01-Aug-2023 00:00:00 .txt [LtBlue]example/files/colours/[Reset]green.txt
2098-rw-r--r-- ---U- 50 Sat 01-Jul-2023 00:00:00 .txt [LtBlue]example/files/colours/[Reset]red.txt
2099drwxr-xr-x ----- 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/numbers/[Reset]
2100lrwxr--r-- ----- 60 Thu 01-Jun-2023 00:00:00 .sh [LtBlue]example/files/numbers/[Reset][LtCyan]count.sh[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtGreen]count.sh[Reset]
2101lrw-r--r-- ----- 999 Mon 01-May-2023 00:00:00 .gz [LtBlue]example/files/numbers/[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
2102lrw-r--r-- ----- 0 Sat 01-Apr-2023 00:00:00 [LtBlue]example/files/numbers/[Reset][LtCyan]ordinals[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
2103drwxr-xr-x ----- 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/numbers/one two/[Reset]
2104-rw-r--r-- ----I 70 Wed 01-Mar-2023 00:00:00 .txt [LtBlue]example/files/numbers/one two/[Reset]\"three\" 'four'.txt
2105";
2106 let files = create_files("D:", "/root", "");
2107 let config = Config::default()
2108 .with_filter_git(GitFlags::new());
2109 assert_eq!(expected, wrap_files(&config, true, &files));
2110 }
2111
2112 #[test]
2113 #[cfg(not(windows))]
2114 fn test_prints_git_flags_on_linux() {
2115 let expected = "\
2116drwxr-xr-x ----- 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/[Reset]
2117-rwxr-xr-x AMRUI 10 Wed 01-Nov-2023 00:00:00 .sh [LtBlue]example/[Reset][DkGreen]find.sh[Reset]
2118drwxr-xr-x ----- 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/[Reset]
2119drwxr-xr-x ----- 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/colours/[Reset]
2120-rwxr--r-- A---- 20 Sun 01-Oct-2023 00:00:00 .sh [LtBlue]example/files/colours/[Reset][LtGreen]alpha.sh[Reset]
2121-rw-r--r-- -M--- 30 Fri 01-Sep-2023 00:00:00 .txt [LtBlue]example/files/colours/[Reset]blue.txt
2122-rw-r--r-- --R-- 40 Tue 01-Aug-2023 00:00:00 .txt [LtBlue]example/files/colours/[Reset]green.txt
2123-rw-r--r-- ---U- 50 Sat 01-Jul-2023 00:00:00 .txt [LtBlue]example/files/colours/[Reset]red.txt
2124drwxr-xr-x ----- 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/numbers/[Reset]
2125lrwxr--r-- ----- 60 Thu 01-Jun-2023 00:00:00 .sh [LtBlue]example/files/numbers/[Reset][LtCyan]count.sh[Reset] -> [LtBlue]/etc/numbers/[Reset][LtGreen]count.sh[Reset]
2126lrw-r--r-- ----- 999 Mon 01-May-2023 00:00:00 .gz [LtBlue]example/files/numbers/[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
2127lrw-r--r-- ----- 0 Sat 01-Apr-2023 00:00:00 [LtBlue]example/files/numbers/[Reset][LtCyan]ordinals[Reset] -> [LtBlue]/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
2128drwxr-xr-x ----- 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/numbers/one two/[Reset]
2129-rw-r--r-- ----I 70 Wed 01-Mar-2023 00:00:00 .txt [LtBlue]example/files/numbers/one two/[Reset]\"three\" 'four'.txt
2130";
2131 let files = create_files("", "/root", "");
2132 let config = Config::default()
2133 .with_filter_git(GitFlags::new());
2134 assert_eq!(expected, wrap_files(&config, false, &files));
2135 }
2136
2137 #[test]
2138 #[cfg(windows)]
2139 fn test_prints_git_flags_with_header_and_footer_on_windows() {
2140 let expected = "\
2141Start Sun 01-Jan-2023 00:00:00
2142---------------------------------------------------
2143drwxr-xr-x ----- 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example\\[Reset]
2144-rwxr-xr-x AMRUI 10 Wed 01-Nov-2023 00:00:00 .sh [LtBlue]example\\[Reset][DkGreen]find.sh[Reset]
2145drwxr-xr-x ----- 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example\\files\\[Reset]
2146drwxr-xr-x ----- 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example\\files\\colours\\[Reset]
2147-rwxr--r-- A---- 20 Sun 01-Oct-2023 00:00:00 .sh [LtBlue]example\\files\\colours\\[Reset][LtGreen]alpha.sh[Reset]
2148-rw-r--r-- -M--- 30 Fri 01-Sep-2023 00:00:00 .txt [LtBlue]example\\files\\colours\\[Reset]blue.txt
2149-rw-r--r-- --R-- 40 Tue 01-Aug-2023 00:00:00 .txt [LtBlue]example\\files\\colours\\[Reset]green.txt
2150-rw-r--r-- ---U- 50 Sat 01-Jul-2023 00:00:00 .txt [LtBlue]example\\files\\colours\\[Reset]red.txt
2151drwxr-xr-x ----- 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example\\files\\numbers\\[Reset]
2152lrwxr--r-- ----- 60 Thu 01-Jun-2023 00:00:00 .sh [LtBlue]example\\files\\numbers\\[Reset][LtCyan]count.sh[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtGreen]count.sh[Reset]
2153lrw-r--r-- ----- 999 Mon 01-May-2023 00:00:00 .gz [LtBlue]example\\files\\numbers\\[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtRed]googolplex.gz[Reset]
2154lrw-r--r-- ----- 0 Sat 01-Apr-2023 00:00:00 [LtBlue]example\\files\\numbers\\[Reset][LtCyan]ordinals[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtBlue]ordinals\\[Reset]
2155drwxr-xr-x ----- 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example\\files\\numbers\\one two\\[Reset]
2156-rw-r--r-- ----I 70 Wed 01-Mar-2023 00:00:00 .txt [LtBlue]example\\files\\numbers\\one two\\[Reset]\"three\" 'four'.txt
2157---------------------------------------------------
2158Total 1,279 9 files 5 directories
2159";
2160 let files = create_files("D:", "/root", "");
2161 let config = Config::default()
2162 .with_filter_recent(RecentKind::Year(1))
2163 .with_show_total(true)
2164 .with_filter_git(GitFlags::new());
2165 assert_eq!(expected, wrap_files(&config, false, &files));
2166 }
2167
2168 #[test]
2169 #[cfg(windows)]
2170 fn test_prints_git_flags_with_header_and_footer_on_git_bash() {
2171 let expected = "\
2172Start Sun 01-Jan-2023 00:00:00
2173---------------------------------------------------
2174drwxr-xr-x ----- 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/[Reset]
2175-rwxr-xr-x AMRUI 10 Wed 01-Nov-2023 00:00:00 .sh [LtBlue]example/[Reset][DkGreen]find.sh[Reset]
2176drwxr-xr-x ----- 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/[Reset]
2177drwxr-xr-x ----- 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/colours/[Reset]
2178-rwxr--r-- A---- 20 Sun 01-Oct-2023 00:00:00 .sh [LtBlue]example/files/colours/[Reset][LtGreen]alpha.sh[Reset]
2179-rw-r--r-- -M--- 30 Fri 01-Sep-2023 00:00:00 .txt [LtBlue]example/files/colours/[Reset]blue.txt
2180-rw-r--r-- --R-- 40 Tue 01-Aug-2023 00:00:00 .txt [LtBlue]example/files/colours/[Reset]green.txt
2181-rw-r--r-- ---U- 50 Sat 01-Jul-2023 00:00:00 .txt [LtBlue]example/files/colours/[Reset]red.txt
2182drwxr-xr-x ----- 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/numbers/[Reset]
2183lrwxr--r-- ----- 60 Thu 01-Jun-2023 00:00:00 .sh [LtBlue]example/files/numbers/[Reset][LtCyan]count.sh[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtGreen]count.sh[Reset]
2184lrw-r--r-- ----- 999 Mon 01-May-2023 00:00:00 .gz [LtBlue]example/files/numbers/[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
2185lrw-r--r-- ----- 0 Sat 01-Apr-2023 00:00:00 [LtBlue]example/files/numbers/[Reset][LtCyan]ordinals[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
2186drwxr-xr-x ----- 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/numbers/one two/[Reset]
2187-rw-r--r-- ----I 70 Wed 01-Mar-2023 00:00:00 .txt [LtBlue]example/files/numbers/one two/[Reset]\"three\" 'four'.txt
2188---------------------------------------------------
2189Total 1,279 9 files 5 directories
2190";
2191 let files = create_files("D:", "/root", "");
2192 let config = Config::default()
2193 .with_filter_recent(RecentKind::Year(1))
2194 .with_show_total(true)
2195 .with_filter_git(GitFlags::new());
2196 assert_eq!(expected, wrap_files(&config, true, &files));
2197 }
2198
2199 #[test]
2200 #[cfg(not(windows))]
2201 fn test_prints_git_flags_with_header_and_footer_on_linux() {
2202 let expected = "\
2203Start Sun 01-Jan-2023 00:00:00
2204---------------------------------------------------
2205drwxr-xr-x ----- 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/[Reset]
2206-rwxr-xr-x AMRUI 10 Wed 01-Nov-2023 00:00:00 .sh [LtBlue]example/[Reset][DkGreen]find.sh[Reset]
2207drwxr-xr-x ----- 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/[Reset]
2208drwxr-xr-x ----- 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/colours/[Reset]
2209-rwxr--r-- A---- 20 Sun 01-Oct-2023 00:00:00 .sh [LtBlue]example/files/colours/[Reset][LtGreen]alpha.sh[Reset]
2210-rw-r--r-- -M--- 30 Fri 01-Sep-2023 00:00:00 .txt [LtBlue]example/files/colours/[Reset]blue.txt
2211-rw-r--r-- --R-- 40 Tue 01-Aug-2023 00:00:00 .txt [LtBlue]example/files/colours/[Reset]green.txt
2212-rw-r--r-- ---U- 50 Sat 01-Jul-2023 00:00:00 .txt [LtBlue]example/files/colours/[Reset]red.txt
2213drwxr-xr-x ----- 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/numbers/[Reset]
2214lrwxr--r-- ----- 60 Thu 01-Jun-2023 00:00:00 .sh [LtBlue]example/files/numbers/[Reset][LtCyan]count.sh[Reset] -> [LtBlue]/etc/numbers/[Reset][LtGreen]count.sh[Reset]
2215lrw-r--r-- ----- 999 Mon 01-May-2023 00:00:00 .gz [LtBlue]example/files/numbers/[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
2216lrw-r--r-- ----- 0 Sat 01-Apr-2023 00:00:00 [LtBlue]example/files/numbers/[Reset][LtCyan]ordinals[Reset] -> [LtBlue]/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
2217drwxr-xr-x ----- 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example/files/numbers/one two/[Reset]
2218-rw-r--r-- ----I 70 Wed 01-Mar-2023 00:00:00 .txt [LtBlue]example/files/numbers/one two/[Reset]\"three\" 'four'.txt
2219---------------------------------------------------
2220Total 1,279 9 files 5 directories
2221";
2222 let files = create_files("", "/root", "");
2223 let config = Config::default()
2224 .with_filter_recent(RecentKind::Year(1))
2225 .with_show_total(true)
2226 .with_filter_git(GitFlags::new());
2227 assert_eq!(expected, wrap_files(&config, false, &files));
2228 }
2229
2230 #[test]
2231 #[cfg(windows)]
2232 fn test_prints_file_signature_on_windows() {
2233 let expected = "\
2234drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 00000000 .... [LtBlue]example\\[Reset]
2235-rwxr-xr-x 10 Wed 01-Nov-2023 00:00:00 23212f75 #!/u .sh [LtBlue]example\\[Reset][DkGreen]find.sh[Reset]
2236drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 00000000 .... [LtBlue]example\\files\\[Reset]
2237drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 00000000 .... [LtBlue]example\\files\\colours\\[Reset]
2238-rwxr--r-- 20 Sun 01-Oct-2023 00:00:00 23212f75 #!/u .sh [LtBlue]example\\files\\colours\\[Reset][LtGreen]alpha.sh[Reset]
2239-rw-r--r-- 30 Fri 01-Sep-2023 00:00:00 424c5545 BLUE .txt [LtBlue]example\\files\\colours\\[Reset]blue.txt
2240-rw-r--r-- 40 Tue 01-Aug-2023 00:00:00 47524545 GREE .txt [LtBlue]example\\files\\colours\\[Reset]green.txt
2241-rw-r--r-- 50 Sat 01-Jul-2023 00:00:00 52454400 RED. .txt [LtBlue]example\\files\\colours\\[Reset]red.txt
2242drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 00000000 .... [LtBlue]example\\files\\numbers\\[Reset]
2243lrwxr--r-- 60 Thu 01-Jun-2023 00:00:00 23212f75 #!/u .sh [LtBlue]example\\files\\numbers\\[Reset][LtCyan]count.sh[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtGreen]count.sh[Reset]
2244lrw-r--r-- 999 Mon 01-May-2023 00:00:00 00000000 .... .gz [LtBlue]example\\files\\numbers\\[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtRed]googolplex.gz[Reset]
2245lrw-r--r-- 0 Sat 01-Apr-2023 00:00:00 00000000 .... [LtBlue]example\\files\\numbers\\[Reset][LtCyan]ordinals[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtBlue]ordinals\\[Reset]
2246drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 00000000 .... [LtBlue]example\\files\\numbers\\one two\\[Reset]
2247-rw-r--r-- 70 Wed 01-Mar-2023 00:00:00 fffe3334 ..34 .txt [LtBlue]example\\files\\numbers\\one two\\[Reset]\"three\" 'four'.txt
2248";
2249 let files = create_files("D:", "/root", "");
2250 let config = Config::default()
2251 .with_show_sig(true);
2252 assert_eq!(expected, wrap_files(&config, false, &files));
2253 }
2254
2255 #[test]
2256 #[cfg(windows)]
2257 fn test_prints_file_signature_on_git_bash() {
2258 let expected = "\
2259drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 00000000 .... [LtBlue]example/[Reset]
2260-rwxr-xr-x 10 Wed 01-Nov-2023 00:00:00 23212f75 #!/u .sh [LtBlue]example/[Reset][DkGreen]find.sh[Reset]
2261drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 00000000 .... [LtBlue]example/files/[Reset]
2262drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 00000000 .... [LtBlue]example/files/colours/[Reset]
2263-rwxr--r-- 20 Sun 01-Oct-2023 00:00:00 23212f75 #!/u .sh [LtBlue]example/files/colours/[Reset][LtGreen]alpha.sh[Reset]
2264-rw-r--r-- 30 Fri 01-Sep-2023 00:00:00 424c5545 BLUE .txt [LtBlue]example/files/colours/[Reset]blue.txt
2265-rw-r--r-- 40 Tue 01-Aug-2023 00:00:00 47524545 GREE .txt [LtBlue]example/files/colours/[Reset]green.txt
2266-rw-r--r-- 50 Sat 01-Jul-2023 00:00:00 52454400 RED. .txt [LtBlue]example/files/colours/[Reset]red.txt
2267drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 00000000 .... [LtBlue]example/files/numbers/[Reset]
2268lrwxr--r-- 60 Thu 01-Jun-2023 00:00:00 23212f75 #!/u .sh [LtBlue]example/files/numbers/[Reset][LtCyan]count.sh[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtGreen]count.sh[Reset]
2269lrw-r--r-- 999 Mon 01-May-2023 00:00:00 00000000 .... .gz [LtBlue]example/files/numbers/[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
2270lrw-r--r-- 0 Sat 01-Apr-2023 00:00:00 00000000 .... [LtBlue]example/files/numbers/[Reset][LtCyan]ordinals[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
2271drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 00000000 .... [LtBlue]example/files/numbers/one two/[Reset]
2272-rw-r--r-- 70 Wed 01-Mar-2023 00:00:00 fffe3334 ..34 .txt [LtBlue]example/files/numbers/one two/[Reset]\"three\" 'four'.txt
2273";
2274 let files = create_files("D:", "/root", "");
2275 let config = Config::default()
2276 .with_show_sig(true);
2277 assert_eq!(expected, wrap_files(&config, true, &files));
2278 }
2279
2280 #[test]
2281 #[cfg(not(windows))]
2282 fn test_prints_file_signature_on_linux() {
2283 let expected = "\
2284drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 00000000 .... [LtBlue]example/[Reset]
2285-rwxr-xr-x 10 Wed 01-Nov-2023 00:00:00 23212f75 #!/u .sh [LtBlue]example/[Reset][DkGreen]find.sh[Reset]
2286drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 00000000 .... [LtBlue]example/files/[Reset]
2287drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 00000000 .... [LtBlue]example/files/colours/[Reset]
2288-rwxr--r-- 20 Sun 01-Oct-2023 00:00:00 23212f75 #!/u .sh [LtBlue]example/files/colours/[Reset][LtGreen]alpha.sh[Reset]
2289-rw-r--r-- 30 Fri 01-Sep-2023 00:00:00 424c5545 BLUE .txt [LtBlue]example/files/colours/[Reset]blue.txt
2290-rw-r--r-- 40 Tue 01-Aug-2023 00:00:00 47524545 GREE .txt [LtBlue]example/files/colours/[Reset]green.txt
2291-rw-r--r-- 50 Sat 01-Jul-2023 00:00:00 52454400 RED. .txt [LtBlue]example/files/colours/[Reset]red.txt
2292drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 00000000 .... [LtBlue]example/files/numbers/[Reset]
2293lrwxr--r-- 60 Thu 01-Jun-2023 00:00:00 23212f75 #!/u .sh [LtBlue]example/files/numbers/[Reset][LtCyan]count.sh[Reset] -> [LtBlue]/etc/numbers/[Reset][LtGreen]count.sh[Reset]
2294lrw-r--r-- 999 Mon 01-May-2023 00:00:00 00000000 .... .gz [LtBlue]example/files/numbers/[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
2295lrw-r--r-- 0 Sat 01-Apr-2023 00:00:00 00000000 .... [LtBlue]example/files/numbers/[Reset][LtCyan]ordinals[Reset] -> [LtBlue]/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
2296drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 00000000 .... [LtBlue]example/files/numbers/one two/[Reset]
2297-rw-r--r-- 70 Wed 01-Mar-2023 00:00:00 fffe3334 ..34 .txt [LtBlue]example/files/numbers/one two/[Reset]\"three\" 'four'.txt
2298";
2299 let files = create_files("", "/root", "");
2300 let config = Config::default()
2301 .with_show_sig(true);
2302 assert_eq!(expected, wrap_files(&config, false, &files));
2303 }
2304
2305 #[test]
2306 #[cfg(windows)]
2307 fn test_prints_file_signature_with_header_and_footer_on_windows() {
2308 let expected = "\
2309Start Sun 01-Jan-2023 00:00:00
2310---------------------------------------------
2311drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 00000000 .... [LtBlue]example\\[Reset]
2312-rwxr-xr-x 10 Wed 01-Nov-2023 00:00:00 23212f75 #!/u .sh [LtBlue]example\\[Reset][DkGreen]find.sh[Reset]
2313drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 00000000 .... [LtBlue]example\\files\\[Reset]
2314drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 00000000 .... [LtBlue]example\\files\\colours\\[Reset]
2315-rwxr--r-- 20 Sun 01-Oct-2023 00:00:00 23212f75 #!/u .sh [LtBlue]example\\files\\colours\\[Reset][LtGreen]alpha.sh[Reset]
2316-rw-r--r-- 30 Fri 01-Sep-2023 00:00:00 424c5545 BLUE .txt [LtBlue]example\\files\\colours\\[Reset]blue.txt
2317-rw-r--r-- 40 Tue 01-Aug-2023 00:00:00 47524545 GREE .txt [LtBlue]example\\files\\colours\\[Reset]green.txt
2318-rw-r--r-- 50 Sat 01-Jul-2023 00:00:00 52454400 RED. .txt [LtBlue]example\\files\\colours\\[Reset]red.txt
2319drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 00000000 .... [LtBlue]example\\files\\numbers\\[Reset]
2320lrwxr--r-- 60 Thu 01-Jun-2023 00:00:00 23212f75 #!/u .sh [LtBlue]example\\files\\numbers\\[Reset][LtCyan]count.sh[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtGreen]count.sh[Reset]
2321lrw-r--r-- 999 Mon 01-May-2023 00:00:00 00000000 .... .gz [LtBlue]example\\files\\numbers\\[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtRed]googolplex.gz[Reset]
2322lrw-r--r-- 0 Sat 01-Apr-2023 00:00:00 00000000 .... [LtBlue]example\\files\\numbers\\[Reset][LtCyan]ordinals[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtBlue]ordinals\\[Reset]
2323drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 00000000 .... [LtBlue]example\\files\\numbers\\one two\\[Reset]
2324-rw-r--r-- 70 Wed 01-Mar-2023 00:00:00 fffe3334 ..34 .txt [LtBlue]example\\files\\numbers\\one two\\[Reset]\"three\" 'four'.txt
2325---------------------------------------------
2326Total 1,279 9 files 5 directories
2327";
2328 let files = create_files("D:", "/root", "");
2329 let config = Config::default()
2330 .with_filter_recent(RecentKind::Year(1))
2331 .with_show_total(true)
2332 .with_show_sig(true);
2333 assert_eq!(expected, wrap_files(&config, false, &files));
2334 }
2335
2336 #[test]
2337 #[cfg(windows)]
2338 fn test_prints_file_signature_with_header_and_footer_on_git_bash() {
2339 let expected = "\
2340Start Sun 01-Jan-2023 00:00:00
2341---------------------------------------------
2342drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 00000000 .... [LtBlue]example/[Reset]
2343-rwxr-xr-x 10 Wed 01-Nov-2023 00:00:00 23212f75 #!/u .sh [LtBlue]example/[Reset][DkGreen]find.sh[Reset]
2344drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 00000000 .... [LtBlue]example/files/[Reset]
2345drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 00000000 .... [LtBlue]example/files/colours/[Reset]
2346-rwxr--r-- 20 Sun 01-Oct-2023 00:00:00 23212f75 #!/u .sh [LtBlue]example/files/colours/[Reset][LtGreen]alpha.sh[Reset]
2347-rw-r--r-- 30 Fri 01-Sep-2023 00:00:00 424c5545 BLUE .txt [LtBlue]example/files/colours/[Reset]blue.txt
2348-rw-r--r-- 40 Tue 01-Aug-2023 00:00:00 47524545 GREE .txt [LtBlue]example/files/colours/[Reset]green.txt
2349-rw-r--r-- 50 Sat 01-Jul-2023 00:00:00 52454400 RED. .txt [LtBlue]example/files/colours/[Reset]red.txt
2350drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 00000000 .... [LtBlue]example/files/numbers/[Reset]
2351lrwxr--r-- 60 Thu 01-Jun-2023 00:00:00 23212f75 #!/u .sh [LtBlue]example/files/numbers/[Reset][LtCyan]count.sh[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtGreen]count.sh[Reset]
2352lrw-r--r-- 999 Mon 01-May-2023 00:00:00 00000000 .... .gz [LtBlue]example/files/numbers/[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
2353lrw-r--r-- 0 Sat 01-Apr-2023 00:00:00 00000000 .... [LtBlue]example/files/numbers/[Reset][LtCyan]ordinals[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
2354drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 00000000 .... [LtBlue]example/files/numbers/one two/[Reset]
2355-rw-r--r-- 70 Wed 01-Mar-2023 00:00:00 fffe3334 ..34 .txt [LtBlue]example/files/numbers/one two/[Reset]\"three\" 'four'.txt
2356---------------------------------------------
2357Total 1,279 9 files 5 directories
2358";
2359 let files = create_files("D:", "/root", "");
2360 let config = Config::default()
2361 .with_filter_recent(RecentKind::Year(1))
2362 .with_show_total(true)
2363 .with_show_sig(true);
2364 assert_eq!(expected, wrap_files(&config, true, &files));
2365 }
2366
2367 #[test]
2368 #[cfg(not(windows))]
2369 fn test_prints_file_signature_with_header_and_footer_on_linux() {
2370 let expected = "\
2371Start Sun 01-Jan-2023 00:00:00
2372---------------------------------------------
2373drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 00000000 .... [LtBlue]example/[Reset]
2374-rwxr-xr-x 10 Wed 01-Nov-2023 00:00:00 23212f75 #!/u .sh [LtBlue]example/[Reset][DkGreen]find.sh[Reset]
2375drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 00000000 .... [LtBlue]example/files/[Reset]
2376drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 00000000 .... [LtBlue]example/files/colours/[Reset]
2377-rwxr--r-- 20 Sun 01-Oct-2023 00:00:00 23212f75 #!/u .sh [LtBlue]example/files/colours/[Reset][LtGreen]alpha.sh[Reset]
2378-rw-r--r-- 30 Fri 01-Sep-2023 00:00:00 424c5545 BLUE .txt [LtBlue]example/files/colours/[Reset]blue.txt
2379-rw-r--r-- 40 Tue 01-Aug-2023 00:00:00 47524545 GREE .txt [LtBlue]example/files/colours/[Reset]green.txt
2380-rw-r--r-- 50 Sat 01-Jul-2023 00:00:00 52454400 RED. .txt [LtBlue]example/files/colours/[Reset]red.txt
2381drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 00000000 .... [LtBlue]example/files/numbers/[Reset]
2382lrwxr--r-- 60 Thu 01-Jun-2023 00:00:00 23212f75 #!/u .sh [LtBlue]example/files/numbers/[Reset][LtCyan]count.sh[Reset] -> [LtBlue]/etc/numbers/[Reset][LtGreen]count.sh[Reset]
2383lrw-r--r-- 999 Mon 01-May-2023 00:00:00 00000000 .... .gz [LtBlue]example/files/numbers/[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
2384lrw-r--r-- 0 Sat 01-Apr-2023 00:00:00 00000000 .... [LtBlue]example/files/numbers/[Reset][LtCyan]ordinals[Reset] -> [LtBlue]/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
2385drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 00000000 .... [LtBlue]example/files/numbers/one two/[Reset]
2386-rw-r--r-- 70 Wed 01-Mar-2023 00:00:00 fffe3334 ..34 .txt [LtBlue]example/files/numbers/one two/[Reset]\"three\" 'four'.txt
2387---------------------------------------------
2388Total 1,279 9 files 5 directories
2389";
2390 let files = create_files("", "/root", "");
2391 let config = Config::default()
2392 .with_filter_recent(RecentKind::Year(1))
2393 .with_show_total(true)
2394 .with_show_sig(true);
2395 assert_eq!(expected, wrap_files(&config, false, &files));
2396 }
2397
2398 #[test]
2399 #[cfg(not(windows))]
2400 #[cfg(unix)]
2401 fn test_prints_owner_information_on_linux() {
2402 let expected = "\
2403drwxr-xr-x alice public 0 B 1 day [LtBlue]example/[Reset]
2404-rwxr-xr-x root root 10 B 2 month .sh [LtBlue]example/[Reset][DkGreen]find.sh[Reset]
2405drwxr-xr-x alice public 0 B 1 day [LtBlue]example/files/[Reset]
2406drwxr-xr-x alice public 0 B 1 day [LtBlue]example/files/colours/[Reset]
2407-rwxr--r-- alice public 20 B 3 month .sh [LtBlue]example/files/colours/[Reset][LtGreen]alpha.sh[Reset]
2408-rw-r--r-- alice public 30 B 4 month .txt [LtBlue]example/files/colours/[Reset]blue.txt
2409-rw-r--r-- alice public 40 B 5 month .txt [LtBlue]example/files/colours/[Reset]green.txt
2410-rw-r--r-- alice public 50 B 6 month .txt [LtBlue]example/files/colours/[Reset]red.txt
2411drwxr-xr-x bob public 0 B 1 day [LtBlue]example/files/numbers/[Reset]
2412lrwxr--r-- bob public 60 B 7 month .sh [LtBlue]example/files/numbers/[Reset][LtCyan]count.sh[Reset] -> [LtBlue]/etc/numbers/[Reset][LtGreen]count.sh[Reset]
2413lrw-r--r-- bob public 999 B 8 month .gz [LtBlue]example/files/numbers/[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
2414lrw-r--r-- bob public 0 B 9 month [LtBlue]example/files/numbers/[Reset][LtCyan]ordinals[Reset] -> [LtBlue]/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
2415drwxr-xr-x - - 0 B 1 day [LtBlue]example/files/numbers/one two/[Reset]
2416-rw-r--r-- - - 70 B 10 month .txt [LtBlue]example/files/numbers/one two/[Reset]\"three\" 'four'.txt
2417";
2418 let files = create_files("", "/root", "");
2419 let config = Config::default()
2420 .with_curr_time(2024, 1, 1, 0, 0, 0)
2421 .with_show_pretty(true)
2422 .with_show_owner(true)
2423 .with_abs_path(false);
2424 assert_eq!(expected, wrap_files(&config, false, &files));
2425 }
2426
2427 #[test]
2428 #[cfg(not(windows))]
2429 #[cfg(unix)]
2430 fn test_prints_owner_information_with_header_and_footer_on_linux() {
2431 let expected = "\
2432Start 1 year
2433------------------------------------------
2434drwxr-xr-x alice public 0 B 1 day [LtBlue]example/[Reset]
2435-rwxr-xr-x root root 10 B 2 month .sh [LtBlue]example/[Reset][DkGreen]find.sh[Reset]
2436drwxr-xr-x alice public 0 B 1 day [LtBlue]example/files/[Reset]
2437drwxr-xr-x alice public 0 B 1 day [LtBlue]example/files/colours/[Reset]
2438-rwxr--r-- alice public 20 B 3 month .sh [LtBlue]example/files/colours/[Reset][LtGreen]alpha.sh[Reset]
2439-rw-r--r-- alice public 30 B 4 month .txt [LtBlue]example/files/colours/[Reset]blue.txt
2440-rw-r--r-- alice public 40 B 5 month .txt [LtBlue]example/files/colours/[Reset]green.txt
2441-rw-r--r-- alice public 50 B 6 month .txt [LtBlue]example/files/colours/[Reset]red.txt
2442drwxr-xr-x bob public 0 B 1 day [LtBlue]example/files/numbers/[Reset]
2443lrwxr--r-- bob public 60 B 7 month .sh [LtBlue]example/files/numbers/[Reset][LtCyan]count.sh[Reset] -> [LtBlue]/etc/numbers/[Reset][LtGreen]count.sh[Reset]
2444lrw-r--r-- bob public 999 B 8 month .gz [LtBlue]example/files/numbers/[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
2445lrw-r--r-- bob public 0 B 9 month [LtBlue]example/files/numbers/[Reset][LtCyan]ordinals[Reset] -> [LtBlue]/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
2446drwxr-xr-x - - 0 B 1 day [LtBlue]example/files/numbers/one two/[Reset]
2447-rw-r--r-- - - 70 B 10 month .txt [LtBlue]example/files/numbers/one two/[Reset]\"three\" 'four'.txt
2448------------------------------------------
2449Total 1 KB 9 files 5 directories
2450";
2451 let files = create_files("", "/root", "");
2452 let config = Config::default()
2453 .with_curr_time(2024, 1, 1, 0, 0, 0)
2454 .with_show_pretty(true)
2455 .with_show_owner(true)
2456 .with_filter_recent(RecentKind::Year(1))
2457 .with_show_total(true)
2458 .with_abs_path(false);
2459 assert_eq!(expected, wrap_files(&config, false, &files));
2460 }
2461
2462 #[test]
2463 #[cfg(windows)]
2464 fn test_prints_version_numbers_on_windows() {
2465 let expected = "\
2466-rwxr--r-- 999 Mon 01-Jan-2024 00:00:00 12.3.4.0 .exe [LtGreen]binary.exe[Reset]
2467-rwxr--r-- 999 Mon 01-Jan-2024 00:00:00 5.67.89.0 .dll library.dll
2468-rw-r--r-- 999 Mon 01-Jan-2024 00:00:00 .txt readme.txt
2469";
2470 let files = create_files_with_version();
2471 let config = Config::default()
2472 .with_win_ver(true);
2473 assert_eq!(expected, wrap_files(&config, false, &files));
2474 }
2475
2476 #[test]
2477 #[cfg(windows)]
2478 fn test_prints_version_numbers_on_git_bash() {
2479 let expected = "\
2480-rwxr--r-- 999 Mon 01-Jan-2024 00:00:00 12.3.4.0 .exe [LtGreen]binary.exe[Reset]
2481-rwxr--r-- 999 Mon 01-Jan-2024 00:00:00 5.67.89.0 .dll library.dll
2482-rw-r--r-- 999 Mon 01-Jan-2024 00:00:00 .txt readme.txt
2483";
2484 let files = create_files_with_version();
2485 let config = Config::default()
2486 .with_win_ver(true);
2487 assert_eq!(expected, wrap_files(&config, true, &files));
2488 }
2489
2490 #[test]
2491 #[cfg(windows)]
2492 fn test_prints_relative_paths_no_attributes_on_windows() {
2493 let expected = "\
2494[LtBlue]example\\[Reset]
2495[LtBlue]example\\[Reset][DkGreen]find.sh[Reset]
2496[LtBlue]example\\files\\[Reset]
2497[LtBlue]example\\files\\colours\\[Reset]
2498[LtBlue]example\\files\\colours\\[Reset][LtGreen]alpha.sh[Reset]
2499[LtBlue]example\\files\\colours\\[Reset]blue.txt
2500[LtBlue]example\\files\\colours\\[Reset]green.txt
2501[LtBlue]example\\files\\colours\\[Reset]red.txt
2502[LtBlue]example\\files\\numbers\\[Reset]
2503[LtBlue]example\\files\\numbers\\[Reset][LtCyan]count.sh[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtGreen]count.sh[Reset]
2504[LtBlue]example\\files\\numbers\\[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtRed]googolplex.gz[Reset]
2505[LtBlue]example\\files\\numbers\\[Reset][LtCyan]ordinals[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtBlue]ordinals\\[Reset]
2506[LtBlue]example\\files\\numbers\\one two\\[Reset]
2507[LtBlue]example\\files\\numbers\\one two\\[Reset]\"three\" 'four'.txt
2508";
2509 let files = create_files("D:", "/root", "");
2510 let config = Config::default()
2511 .with_only_path(true)
2512 .with_abs_path(false);
2513 assert_eq!(expected, wrap_files(&config, false, &files));
2514 }
2515
2516 #[test]
2517 #[cfg(windows)]
2518 fn test_prints_relative_paths_no_attributes_on_git_bash() {
2519 let expected = "\
2520[LtBlue]example/[Reset]
2521[LtBlue]example/[Reset][DkGreen]find.sh[Reset]
2522[LtBlue]example/files/[Reset]
2523[LtBlue]example/files/colours/[Reset]
2524[LtBlue]example/files/colours/[Reset][LtGreen]alpha.sh[Reset]
2525[LtBlue]example/files/colours/[Reset]blue.txt
2526[LtBlue]example/files/colours/[Reset]green.txt
2527[LtBlue]example/files/colours/[Reset]red.txt
2528[LtBlue]example/files/numbers/[Reset]
2529[LtBlue]example/files/numbers/[Reset][LtCyan]count.sh[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtGreen]count.sh[Reset]
2530[LtBlue]example/files/numbers/[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
2531[LtBlue]example/files/numbers/[Reset][LtCyan]ordinals[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
2532[LtBlue]example/files/numbers/one two/[Reset]
2533[LtBlue]example/files/numbers/one two/[Reset]\"three\" 'four'.txt
2534";
2535 let files = create_files("D:", "/root", "");
2536 let config = Config::default()
2537 .with_only_path(true)
2538 .with_abs_path(false);
2539 assert_eq!(expected, wrap_files(&config, true, &files));
2540 }
2541
2542 #[test]
2543 #[cfg(not(windows))]
2544 fn test_prints_relative_paths_no_attributes_on_linux() {
2545 let expected = "\
2546[LtBlue]example/[Reset]
2547[LtBlue]example/[Reset][DkGreen]find.sh[Reset]
2548[LtBlue]example/files/[Reset]
2549[LtBlue]example/files/colours/[Reset]
2550[LtBlue]example/files/colours/[Reset][LtGreen]alpha.sh[Reset]
2551[LtBlue]example/files/colours/[Reset]blue.txt
2552[LtBlue]example/files/colours/[Reset]green.txt
2553[LtBlue]example/files/colours/[Reset]red.txt
2554[LtBlue]example/files/numbers/[Reset]
2555[LtBlue]example/files/numbers/[Reset][LtCyan]count.sh[Reset] -> [LtBlue]/etc/numbers/[Reset][LtGreen]count.sh[Reset]
2556[LtBlue]example/files/numbers/[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
2557[LtBlue]example/files/numbers/[Reset][LtCyan]ordinals[Reset] -> [LtBlue]/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
2558[LtBlue]example/files/numbers/one two/[Reset]
2559[LtBlue]example/files/numbers/one two/[Reset]\"three\" 'four'.txt
2560";
2561 let files = create_files("", "/root", "");
2562 let config = Config::default()
2563 .with_only_path(true)
2564 .with_abs_path(false);
2565 assert_eq!(expected, wrap_files(&config, false, &files));
2566 }
2567
2568 #[test]
2569 #[cfg(windows)]
2570 fn test_prints_absolute_paths_no_attributes_on_windows() {
2571 let expected = "\
2572[LtBlue]D:\\root\\example\\[Reset]
2573[LtBlue]D:\\root\\example\\[Reset][DkGreen]find.sh[Reset]
2574[LtBlue]D:\\root\\example\\files\\[Reset]
2575[LtBlue]D:\\root\\example\\files\\colours\\[Reset]
2576[LtBlue]D:\\root\\example\\files\\colours\\[Reset][LtGreen]alpha.sh[Reset]
2577[LtBlue]D:\\root\\example\\files\\colours\\[Reset]blue.txt
2578[LtBlue]D:\\root\\example\\files\\colours\\[Reset]green.txt
2579[LtBlue]D:\\root\\example\\files\\colours\\[Reset]red.txt
2580[LtBlue]D:\\root\\example\\files\\numbers\\[Reset]
2581[LtBlue]D:\\root\\example\\files\\numbers\\[Reset][LtCyan]count.sh[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtGreen]count.sh[Reset]
2582[LtBlue]D:\\root\\example\\files\\numbers\\[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtRed]googolplex.gz[Reset]
2583[LtBlue]D:\\root\\example\\files\\numbers\\[Reset][LtCyan]ordinals[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtBlue]ordinals\\[Reset]
2584[LtBlue]D:\\root\\example\\files\\numbers\\one two\\[Reset]
2585[LtBlue]D:\\root\\example\\files\\numbers\\one two\\[Reset]\"three\" 'four'.txt
2586";
2587 let files = create_files("D:", "/root", "");
2588 let config = Config::default()
2589 .with_only_path(true)
2590 .with_abs_path(true);
2591 assert_eq!(expected, wrap_files(&config, false, &files));
2592 }
2593
2594 #[test]
2595 #[cfg(windows)]
2596 fn test_prints_absolute_paths_no_attributes_on_git_bash() {
2597 let expected = "\
2598[LtBlue]/d/root/example/[Reset]
2599[LtBlue]/d/root/example/[Reset][DkGreen]find.sh[Reset]
2600[LtBlue]/d/root/example/files/[Reset]
2601[LtBlue]/d/root/example/files/colours/[Reset]
2602[LtBlue]/d/root/example/files/colours/[Reset][LtGreen]alpha.sh[Reset]
2603[LtBlue]/d/root/example/files/colours/[Reset]blue.txt
2604[LtBlue]/d/root/example/files/colours/[Reset]green.txt
2605[LtBlue]/d/root/example/files/colours/[Reset]red.txt
2606[LtBlue]/d/root/example/files/numbers/[Reset]
2607[LtBlue]/d/root/example/files/numbers/[Reset][LtCyan]count.sh[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtGreen]count.sh[Reset]
2608[LtBlue]/d/root/example/files/numbers/[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
2609[LtBlue]/d/root/example/files/numbers/[Reset][LtCyan]ordinals[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
2610[LtBlue]/d/root/example/files/numbers/one two/[Reset]
2611[LtBlue]/d/root/example/files/numbers/one two/[Reset]\"three\" 'four'.txt
2612";
2613 let files = create_files("D:", "/root", "");
2614 let config = Config::default()
2615 .with_only_path(true)
2616 .with_abs_path(true);
2617 assert_eq!(expected, wrap_files(&config, true, &files));
2618 }
2619
2620 #[test]
2621 #[cfg(not(windows))]
2622 fn test_prints_absolute_paths_no_attributes_on_linux() {
2623 let expected = "\
2624[LtBlue]/root/example/[Reset]
2625[LtBlue]/root/example/[Reset][DkGreen]find.sh[Reset]
2626[LtBlue]/root/example/files/[Reset]
2627[LtBlue]/root/example/files/colours/[Reset]
2628[LtBlue]/root/example/files/colours/[Reset][LtGreen]alpha.sh[Reset]
2629[LtBlue]/root/example/files/colours/[Reset]blue.txt
2630[LtBlue]/root/example/files/colours/[Reset]green.txt
2631[LtBlue]/root/example/files/colours/[Reset]red.txt
2632[LtBlue]/root/example/files/numbers/[Reset]
2633[LtBlue]/root/example/files/numbers/[Reset][LtCyan]count.sh[Reset] -> [LtBlue]/etc/numbers/[Reset][LtGreen]count.sh[Reset]
2634[LtBlue]/root/example/files/numbers/[Reset][LtCyan]googolplex.gz[Reset] -> [LtBlue]/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
2635[LtBlue]/root/example/files/numbers/[Reset][LtCyan]ordinals[Reset] -> [LtBlue]/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
2636[LtBlue]/root/example/files/numbers/one two/[Reset]
2637[LtBlue]/root/example/files/numbers/one two/[Reset]\"three\" 'four'.txt
2638";
2639 let files = create_files("", "/root", "");
2640 let config = Config::default()
2641 .with_only_path(true)
2642 .with_abs_path(true);
2643 assert_eq!(expected, wrap_files(&config, false, &files));
2644 }
2645
2646 #[test]
2647 #[cfg(windows)]
2648 fn test_prints_relative_paths_with_escaping_on_windows() {
2649 let expected = "\
2650[LtBlue]example\\[Reset]
2651[LtBlue]example\\[Reset][DkGreen]find.sh[Reset]
2652[LtBlue]example\\files\\[Reset]
2653[LtBlue]example\\files\\colours\\[Reset]
2654[LtBlue]example\\files\\colours\\[Reset][LtGreen]alpha.sh[Reset]
2655[LtBlue]example\\files\\colours\\[Reset]blue.txt
2656[LtBlue]example\\files\\colours\\[Reset]green.txt
2657[LtBlue]example\\files\\colours\\[Reset]red.txt
2658[LtBlue]example\\files\\numbers\\[Reset]
2659[LtBlue]example\\files\\numbers\\[Reset][LtCyan]count.sh[Reset]
2660[LtBlue]example\\files\\numbers\\[Reset][LtCyan]googolplex.gz[Reset]
2661[LtBlue]example\\files\\numbers\\[Reset][LtCyan]ordinals[Reset]
2662[LtBlue]example\\files\\numbers\\one two\\[Reset]
2663[LtBlue]example\\files\\numbers\\one two\\[Reset]\"three\" 'four'.txt
2664";
2665 let files = create_files("D:", "/root", "");
2666 let config = Config::default()
2667 .with_only_path(true)
2668 .with_escape_path(true)
2669 .with_abs_path(false);
2670 assert_eq!(expected, wrap_files(&config, false, &files));
2671 }
2672
2673 #[test]
2674 #[cfg(windows)]
2675 fn test_prints_relative_paths_with_escaping_on_git_bash() {
2676 let expected = "\
2677[LtBlue]example/[Reset]
2678[LtBlue]example/[Reset][DkGreen]find.sh[Reset]
2679[LtBlue]example/files/[Reset]
2680[LtBlue]example/files/colours/[Reset]
2681[LtBlue]example/files/colours/[Reset][LtGreen]alpha.sh[Reset]
2682[LtBlue]example/files/colours/[Reset]blue.txt
2683[LtBlue]example/files/colours/[Reset]green.txt
2684[LtBlue]example/files/colours/[Reset]red.txt
2685[LtBlue]example/files/numbers/[Reset]
2686[LtBlue]example/files/numbers/[Reset][LtCyan]count.sh[Reset]
2687[LtBlue]example/files/numbers/[Reset][LtCyan]googolplex.gz[Reset]
2688[LtBlue]example/files/numbers/[Reset][LtCyan]ordinals[Reset]
2689[LtBlue]example/files/numbers/one\\ two/[Reset]
2690[LtBlue]example/files/numbers/one\\ two/[Reset]\\\"three\\\"\\ \\'four\\'.txt
2691";
2692 let files = create_files("D:", "/root", "");
2693 let config = Config::default()
2694 .with_only_path(true)
2695 .with_escape_path(true)
2696 .with_abs_path(false);
2697 assert_eq!(expected, wrap_files(&config, true, &files));
2698 }
2699
2700 #[test]
2701 #[cfg(not(windows))]
2702 fn test_prints_relative_paths_with_escaping_on_linux() {
2703 let expected = "\
2704[LtBlue]example/[Reset]
2705[LtBlue]example/[Reset][DkGreen]find.sh[Reset]
2706[LtBlue]example/files/[Reset]
2707[LtBlue]example/files/colours/[Reset]
2708[LtBlue]example/files/colours/[Reset][LtGreen]alpha.sh[Reset]
2709[LtBlue]example/files/colours/[Reset]blue.txt
2710[LtBlue]example/files/colours/[Reset]green.txt
2711[LtBlue]example/files/colours/[Reset]red.txt
2712[LtBlue]example/files/numbers/[Reset]
2713[LtBlue]example/files/numbers/[Reset][LtCyan]count.sh[Reset]
2714[LtBlue]example/files/numbers/[Reset][LtCyan]googolplex.gz[Reset]
2715[LtBlue]example/files/numbers/[Reset][LtCyan]ordinals[Reset]
2716[LtBlue]example/files/numbers/one\\ two/[Reset]
2717[LtBlue]example/files/numbers/one\\ two/[Reset]\\\"three\\\"\\ \\'four\\'.txt
2718";
2719 let files = create_files("", "/root", "");
2720 let config = Config::default()
2721 .with_only_path(true)
2722 .with_escape_path(true)
2723 .with_abs_path(false);
2724 assert_eq!(expected, wrap_files(&config, false, &files));
2725 }
2726
2727 #[test]
2728 #[cfg(windows)]
2729 fn test_prints_absolute_paths_with_escaping_on_windows() {
2730 let expected = "\
2731[LtBlue]D:\\root\\example\\[Reset]
2732[LtBlue]D:\\root\\example\\[Reset][DkGreen]find.sh[Reset]
2733[LtBlue]D:\\root\\example\\files\\[Reset]
2734[LtBlue]D:\\root\\example\\files\\colours\\[Reset]
2735[LtBlue]D:\\root\\example\\files\\colours\\[Reset][LtGreen]alpha.sh[Reset]
2736[LtBlue]D:\\root\\example\\files\\colours\\[Reset]blue.txt
2737[LtBlue]D:\\root\\example\\files\\colours\\[Reset]green.txt
2738[LtBlue]D:\\root\\example\\files\\colours\\[Reset]red.txt
2739[LtBlue]D:\\root\\example\\files\\numbers\\[Reset]
2740[LtBlue]D:\\root\\example\\files\\numbers\\[Reset][LtCyan]count.sh[Reset]
2741[LtBlue]D:\\root\\example\\files\\numbers\\[Reset][LtCyan]googolplex.gz[Reset]
2742[LtBlue]D:\\root\\example\\files\\numbers\\[Reset][LtCyan]ordinals[Reset]
2743[LtBlue]D:\\root\\example\\files\\numbers\\one two\\[Reset]
2744[LtBlue]D:\\root\\example\\files\\numbers\\one two\\[Reset]\"three\" 'four'.txt
2745";
2746 let files = create_files("D:", "/root", "");
2747 let config = Config::default()
2748 .with_only_path(true)
2749 .with_escape_path(true)
2750 .with_abs_path(true);
2751 assert_eq!(expected, wrap_files(&config, false, &files));
2752 }
2753
2754 #[test]
2755 #[cfg(windows)]
2756 fn test_prints_absolute_paths_with_escaping_on_git_bash() {
2757 let expected = "\
2758[LtBlue]/d/root/example/[Reset]
2759[LtBlue]/d/root/example/[Reset][DkGreen]find.sh[Reset]
2760[LtBlue]/d/root/example/files/[Reset]
2761[LtBlue]/d/root/example/files/colours/[Reset]
2762[LtBlue]/d/root/example/files/colours/[Reset][LtGreen]alpha.sh[Reset]
2763[LtBlue]/d/root/example/files/colours/[Reset]blue.txt
2764[LtBlue]/d/root/example/files/colours/[Reset]green.txt
2765[LtBlue]/d/root/example/files/colours/[Reset]red.txt
2766[LtBlue]/d/root/example/files/numbers/[Reset]
2767[LtBlue]/d/root/example/files/numbers/[Reset][LtCyan]count.sh[Reset]
2768[LtBlue]/d/root/example/files/numbers/[Reset][LtCyan]googolplex.gz[Reset]
2769[LtBlue]/d/root/example/files/numbers/[Reset][LtCyan]ordinals[Reset]
2770[LtBlue]/d/root/example/files/numbers/one\\ two/[Reset]
2771[LtBlue]/d/root/example/files/numbers/one\\ two/[Reset]\\\"three\\\"\\ \\'four\\'.txt
2772";
2773 let files = create_files("D:", "/root", "");
2774 let config = Config::default()
2775 .with_only_path(true)
2776 .with_escape_path(true)
2777 .with_abs_path(true);
2778 assert_eq!(expected, wrap_files(&config, true, &files));
2779 }
2780
2781 #[test]
2782 #[cfg(not(windows))]
2783 fn test_prints_absolute_paths_with_escaping_on_linux() {
2784 let expected = "\
2785[LtBlue]/root/example/[Reset]
2786[LtBlue]/root/example/[Reset][DkGreen]find.sh[Reset]
2787[LtBlue]/root/example/files/[Reset]
2788[LtBlue]/root/example/files/colours/[Reset]
2789[LtBlue]/root/example/files/colours/[Reset][LtGreen]alpha.sh[Reset]
2790[LtBlue]/root/example/files/colours/[Reset]blue.txt
2791[LtBlue]/root/example/files/colours/[Reset]green.txt
2792[LtBlue]/root/example/files/colours/[Reset]red.txt
2793[LtBlue]/root/example/files/numbers/[Reset]
2794[LtBlue]/root/example/files/numbers/[Reset][LtCyan]count.sh[Reset]
2795[LtBlue]/root/example/files/numbers/[Reset][LtCyan]googolplex.gz[Reset]
2796[LtBlue]/root/example/files/numbers/[Reset][LtCyan]ordinals[Reset]
2797[LtBlue]/root/example/files/numbers/one\\ two/[Reset]
2798[LtBlue]/root/example/files/numbers/one\\ two/[Reset]\\\"three\\\"\\ \\'four\\'.txt
2799";
2800 let files = create_files("", "/root", "");
2801 let config = Config::default()
2802 .with_only_path(true)
2803 .with_escape_path(true)
2804 .with_abs_path(true);
2805 assert_eq!(expected, wrap_files(&config, false, &files));
2806 }
2807
2808 #[test]
2809 #[cfg(windows)]
2810 fn test_prints_relative_paths_sorted_by_name_on_windows() {
2811 let expected = "\
2812[LtGreen]alpha.sh[Reset] ([LtBlue]example\\files\\colours\\[Reset])
2813blue.txt ([LtBlue]example\\files\\colours\\[Reset])
2814[LtCyan]count.sh[Reset] ([LtBlue]example\\files\\numbers\\[Reset]) -> [LtBlue]D:\\etc\\numbers\\[Reset][LtGreen]count.sh[Reset]
2815[DkGreen]find.sh[Reset] ([LtBlue]example\\[Reset])
2816[LtCyan]googolplex.gz[Reset] ([LtBlue]example\\files\\numbers\\[Reset]) -> [LtBlue]D:\\etc\\numbers\\[Reset][LtRed]googolplex.gz[Reset]
2817green.txt ([LtBlue]example\\files\\colours\\[Reset])
2818[LtCyan]ordinals[Reset] ([LtBlue]example\\files\\numbers\\[Reset]) -> [LtBlue]D:\\etc\\numbers\\[Reset][LtBlue]ordinals\\[Reset]
2819red.txt ([LtBlue]example\\files\\colours\\[Reset])
2820\"three\" 'four'.txt ([LtBlue]example\\files\\numbers\\one two\\[Reset])
2821";
2822 let files = create_files("D:", "/root", "");
2823 let files = modify_files_by_name(files);
2824 let config = Config::default()
2825 .with_order_name(true)
2826 .with_only_path(true)
2827 .with_abs_path(false);
2828 assert_eq!(expected, wrap_files(&config, false, &files));
2829 }
2830
2831 #[test]
2832 #[cfg(windows)]
2833 fn test_prints_relative_paths_sorted_by_name_on_git_bash() {
2834 let expected = "\
2835[LtGreen]alpha.sh[Reset] ([LtBlue]example/files/colours/[Reset])
2836blue.txt ([LtBlue]example/files/colours/[Reset])
2837[LtCyan]count.sh[Reset] ([LtBlue]example/files/numbers/[Reset]) -> [LtBlue]/d/etc/numbers/[Reset][LtGreen]count.sh[Reset]
2838[DkGreen]find.sh[Reset] ([LtBlue]example/[Reset])
2839[LtCyan]googolplex.gz[Reset] ([LtBlue]example/files/numbers/[Reset]) -> [LtBlue]/d/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
2840green.txt ([LtBlue]example/files/colours/[Reset])
2841[LtCyan]ordinals[Reset] ([LtBlue]example/files/numbers/[Reset]) -> [LtBlue]/d/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
2842red.txt ([LtBlue]example/files/colours/[Reset])
2843\"three\" 'four'.txt ([LtBlue]example/files/numbers/one two/[Reset])
2844";
2845 let files = create_files("D:", "/root", "");
2846 let files = modify_files_by_name(files);
2847 let config = Config::default()
2848 .with_order_name(true)
2849 .with_only_path(true)
2850 .with_abs_path(false);
2851 assert_eq!(expected, wrap_files(&config, true, &files));
2852 }
2853
2854 #[test]
2855 #[cfg(not(windows))]
2856 fn test_prints_relative_paths_sorted_by_name_on_linux() {
2857 let expected = "\
2858[LtGreen]alpha.sh[Reset] ([LtBlue]example/files/colours/[Reset])
2859blue.txt ([LtBlue]example/files/colours/[Reset])
2860[LtCyan]count.sh[Reset] ([LtBlue]example/files/numbers/[Reset]) -> [LtBlue]/etc/numbers/[Reset][LtGreen]count.sh[Reset]
2861[DkGreen]find.sh[Reset] ([LtBlue]example/[Reset])
2862[LtCyan]googolplex.gz[Reset] ([LtBlue]example/files/numbers/[Reset]) -> [LtBlue]/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
2863green.txt ([LtBlue]example/files/colours/[Reset])
2864[LtCyan]ordinals[Reset] ([LtBlue]example/files/numbers/[Reset]) -> [LtBlue]/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
2865red.txt ([LtBlue]example/files/colours/[Reset])
2866\"three\" 'four'.txt ([LtBlue]example/files/numbers/one two/[Reset])
2867";
2868 let files = create_files("", "/root", "");
2869 let files = modify_files_by_name(files);
2870 let config = Config::default()
2871 .with_order_name(true)
2872 .with_only_path(true)
2873 .with_abs_path(false);
2874 assert_eq!(expected, wrap_files(&config, false, &files));
2875 }
2876
2877 #[test]
2878 #[cfg(windows)]
2879 fn test_prints_absolute_paths_sorted_by_name_on_windows() {
2880 let expected = "\
2881[LtGreen]alpha.sh[Reset] ([LtBlue]D:\\root\\example\\files\\colours\\[Reset])
2882blue.txt ([LtBlue]D:\\root\\example\\files\\colours\\[Reset])
2883[LtCyan]count.sh[Reset] ([LtBlue]D:\\root\\example\\files\\numbers\\[Reset]) -> [LtBlue]D:\\etc\\numbers\\[Reset][LtGreen]count.sh[Reset]
2884[DkGreen]find.sh[Reset] ([LtBlue]D:\\root\\example\\[Reset])
2885[LtCyan]googolplex.gz[Reset] ([LtBlue]D:\\root\\example\\files\\numbers\\[Reset]) -> [LtBlue]D:\\etc\\numbers\\[Reset][LtRed]googolplex.gz[Reset]
2886green.txt ([LtBlue]D:\\root\\example\\files\\colours\\[Reset])
2887[LtCyan]ordinals[Reset] ([LtBlue]D:\\root\\example\\files\\numbers\\[Reset]) -> [LtBlue]D:\\etc\\numbers\\[Reset][LtBlue]ordinals\\[Reset]
2888red.txt ([LtBlue]D:\\root\\example\\files\\colours\\[Reset])
2889\"three\" 'four'.txt ([LtBlue]D:\\root\\example\\files\\numbers\\one two\\[Reset])
2890";
2891 let files = create_files("D:", "/root", "");
2892 let files = modify_files_by_name(files);
2893 let config = Config::default()
2894 .with_order_name(true)
2895 .with_only_path(true)
2896 .with_abs_path(true);
2897 assert_eq!(expected, wrap_files(&config, false, &files));
2898 }
2899
2900 #[test]
2901 #[cfg(windows)]
2902 fn test_prints_absolute_paths_sorted_by_name_on_git_bash() {
2903 let expected = "\
2904[LtGreen]alpha.sh[Reset] ([LtBlue]/d/root/example/files/colours/[Reset])
2905blue.txt ([LtBlue]/d/root/example/files/colours/[Reset])
2906[LtCyan]count.sh[Reset] ([LtBlue]/d/root/example/files/numbers/[Reset]) -> [LtBlue]/d/etc/numbers/[Reset][LtGreen]count.sh[Reset]
2907[DkGreen]find.sh[Reset] ([LtBlue]/d/root/example/[Reset])
2908[LtCyan]googolplex.gz[Reset] ([LtBlue]/d/root/example/files/numbers/[Reset]) -> [LtBlue]/d/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
2909green.txt ([LtBlue]/d/root/example/files/colours/[Reset])
2910[LtCyan]ordinals[Reset] ([LtBlue]/d/root/example/files/numbers/[Reset]) -> [LtBlue]/d/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
2911red.txt ([LtBlue]/d/root/example/files/colours/[Reset])
2912\"three\" 'four'.txt ([LtBlue]/d/root/example/files/numbers/one two/[Reset])
2913";
2914 let files = create_files("D:", "/root", "");
2915 let files = modify_files_by_name(files);
2916 let config = Config::default()
2917 .with_order_name(true)
2918 .with_only_path(true)
2919 .with_abs_path(true);
2920 assert_eq!(expected, wrap_files(&config, true, &files));
2921 }
2922
2923 #[test]
2924 #[cfg(not(windows))]
2925 fn test_prints_absolute_paths_sorted_by_name_on_linux() {
2926 let expected = "\
2927[LtGreen]alpha.sh[Reset] ([LtBlue]/root/example/files/colours/[Reset])
2928blue.txt ([LtBlue]/root/example/files/colours/[Reset])
2929[LtCyan]count.sh[Reset] ([LtBlue]/root/example/files/numbers/[Reset]) -> [LtBlue]/etc/numbers/[Reset][LtGreen]count.sh[Reset]
2930[DkGreen]find.sh[Reset] ([LtBlue]/root/example/[Reset])
2931[LtCyan]googolplex.gz[Reset] ([LtBlue]/root/example/files/numbers/[Reset]) -> [LtBlue]/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
2932green.txt ([LtBlue]/root/example/files/colours/[Reset])
2933[LtCyan]ordinals[Reset] ([LtBlue]/root/example/files/numbers/[Reset]) -> [LtBlue]/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
2934red.txt ([LtBlue]/root/example/files/colours/[Reset])
2935\"three\" 'four'.txt ([LtBlue]/root/example/files/numbers/one two/[Reset])
2936";
2937 let files = create_files("", "/root", "");
2938 let files = modify_files_by_name(files);
2939 let config = Config::default()
2940 .with_order_name(true)
2941 .with_only_path(true)
2942 .with_abs_path(true);
2943 assert_eq!(expected, wrap_files(&config, false, &files));
2944 }
2945
2946 #[test]
2947 #[cfg(windows)]
2948 fn test_prints_relative_paths_with_zip_sorted_by_name_on_windows() {
2949 let expected = "\
2950[LtGreen]alpha.sh[Reset] ([LtBlue]example\\[LtRed]files.zip[LtBlue]\\colours\\[Reset])
2951blue.txt ([LtBlue]example\\[LtRed]files.zip[LtBlue]\\colours\\[Reset])
2952[LtCyan]count.sh[Reset] ([LtBlue]example\\[LtRed]files.zip[LtBlue]\\numbers\\[Reset]) -> [LtBlue]D:\\etc\\numbers\\[Reset][LtGreen]count.sh[Reset]
2953[DkGreen]find.sh[Reset] ([LtBlue]example\\[Reset])
2954[LtCyan]googolplex.gz[Reset] ([LtBlue]example\\[LtRed]files.zip[LtBlue]\\numbers\\[Reset]) -> [LtBlue]D:\\etc\\numbers\\[Reset][LtRed]googolplex.gz[Reset]
2955green.txt ([LtBlue]example\\[LtRed]files.zip[LtBlue]\\colours\\[Reset])
2956[LtCyan]ordinals[Reset] ([LtBlue]example\\[LtRed]files.zip[LtBlue]\\numbers\\[Reset]) -> [LtBlue]D:\\etc\\numbers\\[Reset][LtBlue]ordinals\\[Reset]
2957red.txt ([LtBlue]example\\[LtRed]files.zip[LtBlue]\\colours\\[Reset])
2958\"three\" 'four'.txt ([LtBlue]example\\[LtRed]files.zip[LtBlue]\\numbers\\one two\\[Reset])
2959";
2960 let files = create_files("D:", "/root", "");
2961 let files = modify_files_by_name(files);
2962 let files = modify_files_for_zip(files);
2963 let config = Config::default()
2964 .with_zip_expand(true)
2965 .with_order_name(true)
2966 .with_only_path(true)
2967 .with_abs_path(false);
2968 assert_eq!(expected, wrap_files(&config, false, &files));
2969 }
2970
2971 #[test]
2972 #[cfg(windows)]
2973 fn test_prints_relative_paths_with_zip_sorted_by_name_on_git_bash() {
2974 let expected = "\
2975[LtGreen]alpha.sh[Reset] ([LtBlue]example/[LtRed]files.zip[LtBlue]/colours/[Reset])
2976blue.txt ([LtBlue]example/[LtRed]files.zip[LtBlue]/colours/[Reset])
2977[LtCyan]count.sh[Reset] ([LtBlue]example/[LtRed]files.zip[LtBlue]/numbers/[Reset]) -> [LtBlue]/d/etc/numbers/[Reset][LtGreen]count.sh[Reset]
2978[DkGreen]find.sh[Reset] ([LtBlue]example/[Reset])
2979[LtCyan]googolplex.gz[Reset] ([LtBlue]example/[LtRed]files.zip[LtBlue]/numbers/[Reset]) -> [LtBlue]/d/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
2980green.txt ([LtBlue]example/[LtRed]files.zip[LtBlue]/colours/[Reset])
2981[LtCyan]ordinals[Reset] ([LtBlue]example/[LtRed]files.zip[LtBlue]/numbers/[Reset]) -> [LtBlue]/d/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
2982red.txt ([LtBlue]example/[LtRed]files.zip[LtBlue]/colours/[Reset])
2983\"three\" 'four'.txt ([LtBlue]example/[LtRed]files.zip[LtBlue]/numbers/one two/[Reset])
2984";
2985 let files = create_files("D:", "/root", "");
2986 let files = modify_files_by_name(files);
2987 let files = modify_files_for_zip(files);
2988 let config = Config::default()
2989 .with_zip_expand(true)
2990 .with_order_name(true)
2991 .with_only_path(true)
2992 .with_abs_path(false);
2993 assert_eq!(expected, wrap_files(&config, true, &files));
2994 }
2995
2996 #[test]
2997 #[cfg(not(windows))]
2998 fn test_prints_relative_paths_with_zip_sorted_by_name_on_linux() {
2999 let expected = "\
3000[LtGreen]alpha.sh[Reset] ([LtBlue]example/[LtRed]files.zip[LtBlue]/colours/[Reset])
3001blue.txt ([LtBlue]example/[LtRed]files.zip[LtBlue]/colours/[Reset])
3002[LtCyan]count.sh[Reset] ([LtBlue]example/[LtRed]files.zip[LtBlue]/numbers/[Reset]) -> [LtBlue]/etc/numbers/[Reset][LtGreen]count.sh[Reset]
3003[DkGreen]find.sh[Reset] ([LtBlue]example/[Reset])
3004[LtCyan]googolplex.gz[Reset] ([LtBlue]example/[LtRed]files.zip[LtBlue]/numbers/[Reset]) -> [LtBlue]/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
3005green.txt ([LtBlue]example/[LtRed]files.zip[LtBlue]/colours/[Reset])
3006[LtCyan]ordinals[Reset] ([LtBlue]example/[LtRed]files.zip[LtBlue]/numbers/[Reset]) -> [LtBlue]/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
3007red.txt ([LtBlue]example/[LtRed]files.zip[LtBlue]/colours/[Reset])
3008\"three\" 'four'.txt ([LtBlue]example/[LtRed]files.zip[LtBlue]/numbers/one two/[Reset])
3009";
3010 let files = create_files("", "/root", "");
3011 let files = modify_files_by_name(files);
3012 let files = modify_files_for_zip(files);
3013 let config = Config::default()
3014 .with_zip_expand(true)
3015 .with_order_name(true)
3016 .with_only_path(true)
3017 .with_abs_path(false);
3018 assert_eq!(expected, wrap_files(&config, false, &files));
3019 }
3020
3021 #[test]
3022 #[cfg(windows)]
3023 fn test_prints_absolute_paths_with_zip_sorted_by_name_on_windows() {
3024 let expected = "\
3025[LtGreen]alpha.sh[Reset] ([LtBlue]D:\\root\\example\\[LtRed]files.zip[LtBlue]\\colours\\[Reset])
3026blue.txt ([LtBlue]D:\\root\\example\\[LtRed]files.zip[LtBlue]\\colours\\[Reset])
3027[LtCyan]count.sh[Reset] ([LtBlue]D:\\root\\example\\[LtRed]files.zip[LtBlue]\\numbers\\[Reset]) -> [LtBlue]D:\\etc\\numbers\\[Reset][LtGreen]count.sh[Reset]
3028[DkGreen]find.sh[Reset] ([LtBlue]D:\\root\\example\\[Reset])
3029[LtCyan]googolplex.gz[Reset] ([LtBlue]D:\\root\\example\\[LtRed]files.zip[LtBlue]\\numbers\\[Reset]) -> [LtBlue]D:\\etc\\numbers\\[Reset][LtRed]googolplex.gz[Reset]
3030green.txt ([LtBlue]D:\\root\\example\\[LtRed]files.zip[LtBlue]\\colours\\[Reset])
3031[LtCyan]ordinals[Reset] ([LtBlue]D:\\root\\example\\[LtRed]files.zip[LtBlue]\\numbers\\[Reset]) -> [LtBlue]D:\\etc\\numbers\\[Reset][LtBlue]ordinals\\[Reset]
3032red.txt ([LtBlue]D:\\root\\example\\[LtRed]files.zip[LtBlue]\\colours\\[Reset])
3033\"three\" 'four'.txt ([LtBlue]D:\\root\\example\\[LtRed]files.zip[LtBlue]\\numbers\\one two\\[Reset])
3034";
3035 let files = create_files("D:", "/root", "");
3036 let files = modify_files_by_name(files);
3037 let files = modify_files_for_zip(files);
3038 let config = Config::default()
3039 .with_zip_expand(true)
3040 .with_order_name(true)
3041 .with_only_path(true)
3042 .with_abs_path(true);
3043 assert_eq!(expected, wrap_files(&config, false, &files));
3044 }
3045
3046 #[test]
3047 #[cfg(windows)]
3048 fn test_prints_absolute_paths_with_zip_sorted_by_name_on_git_bash() {
3049 let expected = "\
3050[LtGreen]alpha.sh[Reset] ([LtBlue]/d/root/example/[LtRed]files.zip[LtBlue]/colours/[Reset])
3051blue.txt ([LtBlue]/d/root/example/[LtRed]files.zip[LtBlue]/colours/[Reset])
3052[LtCyan]count.sh[Reset] ([LtBlue]/d/root/example/[LtRed]files.zip[LtBlue]/numbers/[Reset]) -> [LtBlue]/d/etc/numbers/[Reset][LtGreen]count.sh[Reset]
3053[DkGreen]find.sh[Reset] ([LtBlue]/d/root/example/[Reset])
3054[LtCyan]googolplex.gz[Reset] ([LtBlue]/d/root/example/[LtRed]files.zip[LtBlue]/numbers/[Reset]) -> [LtBlue]/d/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
3055green.txt ([LtBlue]/d/root/example/[LtRed]files.zip[LtBlue]/colours/[Reset])
3056[LtCyan]ordinals[Reset] ([LtBlue]/d/root/example/[LtRed]files.zip[LtBlue]/numbers/[Reset]) -> [LtBlue]/d/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
3057red.txt ([LtBlue]/d/root/example/[LtRed]files.zip[LtBlue]/colours/[Reset])
3058\"three\" 'four'.txt ([LtBlue]/d/root/example/[LtRed]files.zip[LtBlue]/numbers/one two/[Reset])
3059";
3060 let files = create_files("D:", "/root", "");
3061 let files = modify_files_by_name(files);
3062 let files = modify_files_for_zip(files);
3063 let config = Config::default()
3064 .with_zip_expand(true)
3065 .with_order_name(true)
3066 .with_only_path(true)
3067 .with_abs_path(true);
3068 assert_eq!(expected, wrap_files(&config, true, &files));
3069 }
3070
3071 #[test]
3072 #[cfg(not(windows))]
3073 fn test_prints_absolute_paths_with_zip_sorted_by_name_on_linux() {
3074 let expected = "\
3075[LtGreen]alpha.sh[Reset] ([LtBlue]/root/example/[LtRed]files.zip[LtBlue]/colours/[Reset])
3076blue.txt ([LtBlue]/root/example/[LtRed]files.zip[LtBlue]/colours/[Reset])
3077[LtCyan]count.sh[Reset] ([LtBlue]/root/example/[LtRed]files.zip[LtBlue]/numbers/[Reset]) -> [LtBlue]/etc/numbers/[Reset][LtGreen]count.sh[Reset]
3078[DkGreen]find.sh[Reset] ([LtBlue]/root/example/[Reset])
3079[LtCyan]googolplex.gz[Reset] ([LtBlue]/root/example/[LtRed]files.zip[LtBlue]/numbers/[Reset]) -> [LtBlue]/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
3080green.txt ([LtBlue]/root/example/[LtRed]files.zip[LtBlue]/colours/[Reset])
3081[LtCyan]ordinals[Reset] ([LtBlue]/root/example/[LtRed]files.zip[LtBlue]/numbers/[Reset]) -> [LtBlue]/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
3082red.txt ([LtBlue]/root/example/[LtRed]files.zip[LtBlue]/colours/[Reset])
3083\"three\" 'four'.txt ([LtBlue]/root/example/[LtRed]files.zip[LtBlue]/numbers/one two/[Reset])
3084";
3085 let files = create_files("", "/root", "");
3086 let files = modify_files_by_name(files);
3087 let files = modify_files_for_zip(files);
3088 let config = Config::default()
3089 .with_zip_expand(true)
3090 .with_order_name(true)
3091 .with_only_path(true)
3092 .with_abs_path(true);
3093 assert_eq!(expected, wrap_files(&config, false, &files));
3094 }
3095
3096 #[test]
3097 #[cfg(windows)]
3098 fn test_prints_indented_paths_with_attributes_on_windows() {
3099 let expected = "\
3100drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example[Reset]
3101-rwxr-xr-x 10 Wed 01-Nov-2023 00:00:00 .sh [LtBlue]+-[Reset] [DkGreen]find.sh[Reset]
3102drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]\\-[Reset] [LtBlue]files[Reset]
3103drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]+-[Reset] [LtBlue]colours[Reset]
3104-rwxr--r-- 20 Sun 01-Oct-2023 00:00:00 .sh [LtBlue]|[Reset] [LtBlue]+-[Reset] [LtGreen]alpha.sh[Reset]
3105-rw-r--r-- 30 Fri 01-Sep-2023 00:00:00 .txt [LtBlue]|[Reset] [LtBlue]+-[Reset] blue.txt
3106-rw-r--r-- 40 Tue 01-Aug-2023 00:00:00 .txt [LtBlue]|[Reset] [LtBlue]+-[Reset] green.txt
3107-rw-r--r-- 50 Sat 01-Jul-2023 00:00:00 .txt [LtBlue]|[Reset] [LtBlue]\\-[Reset] red.txt
3108drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]\\-[Reset] [LtBlue]numbers[Reset]
3109lrwxr--r-- 60 Thu 01-Jun-2023 00:00:00 .sh [LtBlue]+-[Reset] [LtCyan]count.sh[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtGreen]count.sh[Reset]
3110lrw-r--r-- 999 Mon 01-May-2023 00:00:00 .gz [LtBlue]+-[Reset] [LtCyan]googolplex.gz[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtRed]googolplex.gz[Reset]
3111lrw-r--r-- 0 Sat 01-Apr-2023 00:00:00 [LtBlue]+-[Reset] [LtCyan]ordinals[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtBlue]ordinals\\[Reset]
3112drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]\\-[Reset] [LtBlue]one two[Reset]
3113-rw-r--r-- 70 Wed 01-Mar-2023 00:00:00 .txt [LtBlue]\\-[Reset] \"three\" 'four'.txt
3114";
3115 let files = create_files("D:", "/root", "../..");
3116 let config = Config::default()
3117 .with_show_indent(true)
3118 .with_only_path(false)
3119 .with_abs_path(true);
3120 assert_eq!(expected, wrap_files(&config, false, &files));
3121 }
3122
3123 #[test]
3124 #[cfg(windows)]
3125 fn test_prints_indented_paths_with_attributes_on_git_bash() {
3126 let expected = "\
3127drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example[Reset]
3128-rwxr-xr-x 10 Wed 01-Nov-2023 00:00:00 .sh [LtBlue]+-[Reset] [DkGreen]find.sh[Reset]
3129drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]\\-[Reset] [LtBlue]files[Reset]
3130drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]+-[Reset] [LtBlue]colours[Reset]
3131-rwxr--r-- 20 Sun 01-Oct-2023 00:00:00 .sh [LtBlue]|[Reset] [LtBlue]+-[Reset] [LtGreen]alpha.sh[Reset]
3132-rw-r--r-- 30 Fri 01-Sep-2023 00:00:00 .txt [LtBlue]|[Reset] [LtBlue]+-[Reset] blue.txt
3133-rw-r--r-- 40 Tue 01-Aug-2023 00:00:00 .txt [LtBlue]|[Reset] [LtBlue]+-[Reset] green.txt
3134-rw-r--r-- 50 Sat 01-Jul-2023 00:00:00 .txt [LtBlue]|[Reset] [LtBlue]\\-[Reset] red.txt
3135drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]\\-[Reset] [LtBlue]numbers[Reset]
3136lrwxr--r-- 60 Thu 01-Jun-2023 00:00:00 .sh [LtBlue]+-[Reset] [LtCyan]count.sh[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtGreen]count.sh[Reset]
3137lrw-r--r-- 999 Mon 01-May-2023 00:00:00 .gz [LtBlue]+-[Reset] [LtCyan]googolplex.gz[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
3138lrw-r--r-- 0 Sat 01-Apr-2023 00:00:00 [LtBlue]+-[Reset] [LtCyan]ordinals[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
3139drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]\\-[Reset] [LtBlue]one two[Reset]
3140-rw-r--r-- 70 Wed 01-Mar-2023 00:00:00 .txt [LtBlue]\\-[Reset] \"three\" 'four'.txt
3141";
3142 let files = create_files("D:", "/root", "../..");
3143 let config = Config::default()
3144 .with_show_indent(true)
3145 .with_only_path(false)
3146 .with_abs_path(true);
3147 assert_eq!(expected, wrap_files(&config, true, &files));
3148 }
3149
3150 #[test]
3151 #[cfg(not(windows))]
3152 fn test_prints_indented_paths_with_attributes_on_linux() {
3153 let expected = "\
3154drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example[Reset]
3155-rwxr-xr-x 10 Wed 01-Nov-2023 00:00:00 .sh [LtBlue]+-[Reset] [DkGreen]find.sh[Reset]
3156drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]\\-[Reset] [LtBlue]files[Reset]
3157drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]+-[Reset] [LtBlue]colours[Reset]
3158-rwxr--r-- 20 Sun 01-Oct-2023 00:00:00 .sh [LtBlue]|[Reset] [LtBlue]+-[Reset] [LtGreen]alpha.sh[Reset]
3159-rw-r--r-- 30 Fri 01-Sep-2023 00:00:00 .txt [LtBlue]|[Reset] [LtBlue]+-[Reset] blue.txt
3160-rw-r--r-- 40 Tue 01-Aug-2023 00:00:00 .txt [LtBlue]|[Reset] [LtBlue]+-[Reset] green.txt
3161-rw-r--r-- 50 Sat 01-Jul-2023 00:00:00 .txt [LtBlue]|[Reset] [LtBlue]\\-[Reset] red.txt
3162drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]\\-[Reset] [LtBlue]numbers[Reset]
3163lrwxr--r-- 60 Thu 01-Jun-2023 00:00:00 .sh [LtBlue]+-[Reset] [LtCyan]count.sh[Reset] -> [LtBlue]/etc/numbers/[Reset][LtGreen]count.sh[Reset]
3164lrw-r--r-- 999 Mon 01-May-2023 00:00:00 .gz [LtBlue]+-[Reset] [LtCyan]googolplex.gz[Reset] -> [LtBlue]/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
3165lrw-r--r-- 0 Sat 01-Apr-2023 00:00:00 [LtBlue]+-[Reset] [LtCyan]ordinals[Reset] -> [LtBlue]/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
3166drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]\\-[Reset] [LtBlue]one two[Reset]
3167-rw-r--r-- 70 Wed 01-Mar-2023 00:00:00 .txt [LtBlue]\\-[Reset] \"three\" 'four'.txt
3168";
3169 let files = create_files("", "/root", "../..");
3170 let config = Config::default()
3171 .with_show_indent(true)
3172 .with_only_path(false)
3173 .with_abs_path(true);
3174 assert_eq!(expected, wrap_files(&config, false, &files));
3175 }
3176
3177 #[test]
3178 #[cfg(windows)]
3179 fn test_prints_indented_paths_no_attributes_on_windows() {
3180 let expected = "\
3181[LtBlue]example[Reset]
3182 [LtBlue]+-[Reset] [DkGreen]find.sh[Reset]
3183 [LtBlue]\\-[Reset] [LtBlue]files[Reset]
3184 [LtBlue]+-[Reset] [LtBlue]colours[Reset]
3185 [LtBlue]|[Reset] [LtBlue]+-[Reset] [LtGreen]alpha.sh[Reset]
3186 [LtBlue]|[Reset] [LtBlue]+-[Reset] blue.txt
3187 [LtBlue]|[Reset] [LtBlue]+-[Reset] green.txt
3188 [LtBlue]|[Reset] [LtBlue]\\-[Reset] red.txt
3189 [LtBlue]\\-[Reset] [LtBlue]numbers[Reset]
3190 [LtBlue]+-[Reset] [LtCyan]count.sh[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtGreen]count.sh[Reset]
3191 [LtBlue]+-[Reset] [LtCyan]googolplex.gz[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtRed]googolplex.gz[Reset]
3192 [LtBlue]+-[Reset] [LtCyan]ordinals[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtBlue]ordinals\\[Reset]
3193 [LtBlue]\\-[Reset] [LtBlue]one two[Reset]
3194 [LtBlue]\\-[Reset] \"three\" 'four'.txt
3195";
3196 let files = create_files("D:", "/root", "../..");
3197 let config = Config::default()
3198 .with_show_indent(true)
3199 .with_only_path(true)
3200 .with_abs_path(true);
3201 assert_eq!(expected, wrap_files(&config, false, &files));
3202 }
3203
3204 #[test]
3205 #[cfg(windows)]
3206 fn test_prints_indented_paths_no_attributes_on_git_bash() {
3207 let expected = "\
3208[LtBlue]example[Reset]
3209 [LtBlue]+-[Reset] [DkGreen]find.sh[Reset]
3210 [LtBlue]\\-[Reset] [LtBlue]files[Reset]
3211 [LtBlue]+-[Reset] [LtBlue]colours[Reset]
3212 [LtBlue]|[Reset] [LtBlue]+-[Reset] [LtGreen]alpha.sh[Reset]
3213 [LtBlue]|[Reset] [LtBlue]+-[Reset] blue.txt
3214 [LtBlue]|[Reset] [LtBlue]+-[Reset] green.txt
3215 [LtBlue]|[Reset] [LtBlue]\\-[Reset] red.txt
3216 [LtBlue]\\-[Reset] [LtBlue]numbers[Reset]
3217 [LtBlue]+-[Reset] [LtCyan]count.sh[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtGreen]count.sh[Reset]
3218 [LtBlue]+-[Reset] [LtCyan]googolplex.gz[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
3219 [LtBlue]+-[Reset] [LtCyan]ordinals[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
3220 [LtBlue]\\-[Reset] [LtBlue]one two[Reset]
3221 [LtBlue]\\-[Reset] \"three\" 'four'.txt
3222";
3223 let files = create_files("D:", "/root", "../..");
3224 let config = Config::default()
3225 .with_show_indent(true)
3226 .with_only_path(true)
3227 .with_abs_path(true);
3228 assert_eq!(expected, wrap_files(&config, true, &files));
3229 }
3230
3231 #[test]
3232 #[cfg(not(windows))]
3233 fn test_prints_indented_paths_no_attributes_on_linux() {
3234 let expected = "\
3235[LtBlue]example[Reset]
3236 [LtBlue]+-[Reset] [DkGreen]find.sh[Reset]
3237 [LtBlue]\\-[Reset] [LtBlue]files[Reset]
3238 [LtBlue]+-[Reset] [LtBlue]colours[Reset]
3239 [LtBlue]|[Reset] [LtBlue]+-[Reset] [LtGreen]alpha.sh[Reset]
3240 [LtBlue]|[Reset] [LtBlue]+-[Reset] blue.txt
3241 [LtBlue]|[Reset] [LtBlue]+-[Reset] green.txt
3242 [LtBlue]|[Reset] [LtBlue]\\-[Reset] red.txt
3243 [LtBlue]\\-[Reset] [LtBlue]numbers[Reset]
3244 [LtBlue]+-[Reset] [LtCyan]count.sh[Reset] -> [LtBlue]/etc/numbers/[Reset][LtGreen]count.sh[Reset]
3245 [LtBlue]+-[Reset] [LtCyan]googolplex.gz[Reset] -> [LtBlue]/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
3246 [LtBlue]+-[Reset] [LtCyan]ordinals[Reset] -> [LtBlue]/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
3247 [LtBlue]\\-[Reset] [LtBlue]one two[Reset]
3248 [LtBlue]\\-[Reset] \"three\" 'four'.txt
3249";
3250 let files = create_files("", "/root", "../..");
3251 let config = Config::default()
3252 .with_show_indent(true)
3253 .with_only_path(true)
3254 .with_abs_path(true);
3255 assert_eq!(expected, wrap_files(&config, false, &files));
3256 }
3257
3258 #[test]
3259 #[cfg(windows)]
3260 fn test_prints_indented_paths_with_zip_with_attributes_on_windows() {
3261 let expected = "\
3262-drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example[Reset]
3263--rwxr-xr-x 10 Wed 01-Nov-2023 00:00:00 .sh [LtBlue]+-[Reset] [DkGreen]find.sh[Reset]
3264zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]\\-[Reset] [LtRed]files.zip[Reset]
3265zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]+-[Reset] [LtBlue]colours[Reset]
3266z-rwxr--r-- 20 Sun 01-Oct-2023 00:00:00 .sh [LtBlue]|[Reset] [LtBlue]+-[Reset] [LtGreen]alpha.sh[Reset]
3267z-rw-r--r-- 30 Fri 01-Sep-2023 00:00:00 .txt [LtBlue]|[Reset] [LtBlue]+-[Reset] blue.txt
3268z-rw-r--r-- 40 Tue 01-Aug-2023 00:00:00 .txt [LtBlue]|[Reset] [LtBlue]+-[Reset] green.txt
3269z-rw-r--r-- 50 Sat 01-Jul-2023 00:00:00 .txt [LtBlue]|[Reset] [LtBlue]\\-[Reset] red.txt
3270zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]\\-[Reset] [LtBlue]numbers[Reset]
3271zlrwxr--r-- 60 Thu 01-Jun-2023 00:00:00 .sh [LtBlue]+-[Reset] [LtCyan]count.sh[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtGreen]count.sh[Reset]
3272zlrw-r--r-- 999 Mon 01-May-2023 00:00:00 .gz [LtBlue]+-[Reset] [LtCyan]googolplex.gz[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtRed]googolplex.gz[Reset]
3273zlrw-r--r-- 0 Sat 01-Apr-2023 00:00:00 [LtBlue]+-[Reset] [LtCyan]ordinals[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtBlue]ordinals\\[Reset]
3274zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]\\-[Reset] [LtBlue]one two[Reset]
3275z-rw-r--r-- 70 Wed 01-Mar-2023 00:00:00 .txt [LtBlue]\\-[Reset] \"three\" 'four'.txt
3276";
3277 let files = create_files("D:", "/root", "../..");
3278 let files = modify_files_for_zip(files);
3279 let config = Config::default()
3280 .with_zip_expand(true)
3281 .with_show_indent(true)
3282 .with_only_path(false)
3283 .with_abs_path(true);
3284 assert_eq!(expected, wrap_files(&config, false, &files));
3285 }
3286
3287 #[test]
3288 #[cfg(windows)]
3289 fn test_prints_indented_paths_with_zip_with_attributes_on_git_bash() {
3290 let expected = "\
3291-drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example[Reset]
3292--rwxr-xr-x 10 Wed 01-Nov-2023 00:00:00 .sh [LtBlue]+-[Reset] [DkGreen]find.sh[Reset]
3293zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]\\-[Reset] [LtRed]files.zip[Reset]
3294zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]+-[Reset] [LtBlue]colours[Reset]
3295z-rwxr--r-- 20 Sun 01-Oct-2023 00:00:00 .sh [LtBlue]|[Reset] [LtBlue]+-[Reset] [LtGreen]alpha.sh[Reset]
3296z-rw-r--r-- 30 Fri 01-Sep-2023 00:00:00 .txt [LtBlue]|[Reset] [LtBlue]+-[Reset] blue.txt
3297z-rw-r--r-- 40 Tue 01-Aug-2023 00:00:00 .txt [LtBlue]|[Reset] [LtBlue]+-[Reset] green.txt
3298z-rw-r--r-- 50 Sat 01-Jul-2023 00:00:00 .txt [LtBlue]|[Reset] [LtBlue]\\-[Reset] red.txt
3299zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]\\-[Reset] [LtBlue]numbers[Reset]
3300zlrwxr--r-- 60 Thu 01-Jun-2023 00:00:00 .sh [LtBlue]+-[Reset] [LtCyan]count.sh[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtGreen]count.sh[Reset]
3301zlrw-r--r-- 999 Mon 01-May-2023 00:00:00 .gz [LtBlue]+-[Reset] [LtCyan]googolplex.gz[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
3302zlrw-r--r-- 0 Sat 01-Apr-2023 00:00:00 [LtBlue]+-[Reset] [LtCyan]ordinals[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
3303zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]\\-[Reset] [LtBlue]one two[Reset]
3304z-rw-r--r-- 70 Wed 01-Mar-2023 00:00:00 .txt [LtBlue]\\-[Reset] \"three\" 'four'.txt
3305";
3306 let files = create_files("D:", "/root", "../..");
3307 let files = modify_files_for_zip(files);
3308 let config = Config::default()
3309 .with_zip_expand(true)
3310 .with_show_indent(true)
3311 .with_only_path(false)
3312 .with_abs_path(true);
3313 assert_eq!(expected, wrap_files(&config, true, &files));
3314 }
3315
3316 #[test]
3317 #[cfg(not(windows))]
3318 fn test_prints_indented_paths_with_zip_with_attributes_on_linux() {
3319 let expected = "\
3320-drwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]example[Reset]
3321--rwxr-xr-x 10 Wed 01-Nov-2023 00:00:00 .sh [LtBlue]+-[Reset] [DkGreen]find.sh[Reset]
3322zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]\\-[Reset] [LtRed]files.zip[Reset]
3323zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]+-[Reset] [LtBlue]colours[Reset]
3324z-rwxr--r-- 20 Sun 01-Oct-2023 00:00:00 .sh [LtBlue]|[Reset] [LtBlue]+-[Reset] [LtGreen]alpha.sh[Reset]
3325z-rw-r--r-- 30 Fri 01-Sep-2023 00:00:00 .txt [LtBlue]|[Reset] [LtBlue]+-[Reset] blue.txt
3326z-rw-r--r-- 40 Tue 01-Aug-2023 00:00:00 .txt [LtBlue]|[Reset] [LtBlue]+-[Reset] green.txt
3327z-rw-r--r-- 50 Sat 01-Jul-2023 00:00:00 .txt [LtBlue]|[Reset] [LtBlue]\\-[Reset] red.txt
3328zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]\\-[Reset] [LtBlue]numbers[Reset]
3329zlrwxr--r-- 60 Thu 01-Jun-2023 00:00:00 .sh [LtBlue]+-[Reset] [LtCyan]count.sh[Reset] -> [LtBlue]/etc/numbers/[Reset][LtGreen]count.sh[Reset]
3330zlrw-r--r-- 999 Mon 01-May-2023 00:00:00 .gz [LtBlue]+-[Reset] [LtCyan]googolplex.gz[Reset] -> [LtBlue]/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
3331zlrw-r--r-- 0 Sat 01-Apr-2023 00:00:00 [LtBlue]+-[Reset] [LtCyan]ordinals[Reset] -> [LtBlue]/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
3332zdrwxr-xr-x 0 Sun 31-Dec-2023 00:00:00 [LtBlue]\\-[Reset] [LtBlue]one two[Reset]
3333z-rw-r--r-- 70 Wed 01-Mar-2023 00:00:00 .txt [LtBlue]\\-[Reset] \"three\" 'four'.txt
3334";
3335 let files = create_files("", "/root", "../..");
3336 let files = modify_files_for_zip(files);
3337 let config = Config::default()
3338 .with_zip_expand(true)
3339 .with_show_indent(true)
3340 .with_only_path(false)
3341 .with_abs_path(true);
3342 assert_eq!(expected, wrap_files(&config, false, &files));
3343 }
3344
3345 #[test]
3346 #[cfg(windows)]
3347 fn test_prints_indented_paths_with_zip_no_attributes_on_windows() {
3348 let expected = "\
3349[LtBlue]example[Reset]
3350 [LtBlue]+-[Reset] [DkGreen]find.sh[Reset]
3351 [LtBlue]\\-[Reset] [LtRed]files.zip[Reset]
3352 [LtBlue]+-[Reset] [LtBlue]colours[Reset]
3353 [LtBlue]|[Reset] [LtBlue]+-[Reset] [LtGreen]alpha.sh[Reset]
3354 [LtBlue]|[Reset] [LtBlue]+-[Reset] blue.txt
3355 [LtBlue]|[Reset] [LtBlue]+-[Reset] green.txt
3356 [LtBlue]|[Reset] [LtBlue]\\-[Reset] red.txt
3357 [LtBlue]\\-[Reset] [LtBlue]numbers[Reset]
3358 [LtBlue]+-[Reset] [LtCyan]count.sh[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtGreen]count.sh[Reset]
3359 [LtBlue]+-[Reset] [LtCyan]googolplex.gz[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtRed]googolplex.gz[Reset]
3360 [LtBlue]+-[Reset] [LtCyan]ordinals[Reset] -> [LtBlue]D:\\etc\\numbers\\[Reset][LtBlue]ordinals\\[Reset]
3361 [LtBlue]\\-[Reset] [LtBlue]one two[Reset]
3362 [LtBlue]\\-[Reset] \"three\" 'four'.txt
3363";
3364 let files = create_files("D:", "/root", "../..");
3365 let files = modify_files_for_zip(files);
3366 let config = Config::default()
3367 .with_zip_expand(true)
3368 .with_show_indent(true)
3369 .with_only_path(true)
3370 .with_abs_path(true);
3371 assert_eq!(expected, wrap_files(&config, false, &files));
3372 }
3373
3374 #[test]
3375 #[cfg(windows)]
3376 fn test_prints_indented_paths_with_zip_no_attributes_on_git_bash() {
3377 let expected = "\
3378[LtBlue]example[Reset]
3379 [LtBlue]+-[Reset] [DkGreen]find.sh[Reset]
3380 [LtBlue]\\-[Reset] [LtRed]files.zip[Reset]
3381 [LtBlue]+-[Reset] [LtBlue]colours[Reset]
3382 [LtBlue]|[Reset] [LtBlue]+-[Reset] [LtGreen]alpha.sh[Reset]
3383 [LtBlue]|[Reset] [LtBlue]+-[Reset] blue.txt
3384 [LtBlue]|[Reset] [LtBlue]+-[Reset] green.txt
3385 [LtBlue]|[Reset] [LtBlue]\\-[Reset] red.txt
3386 [LtBlue]\\-[Reset] [LtBlue]numbers[Reset]
3387 [LtBlue]+-[Reset] [LtCyan]count.sh[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtGreen]count.sh[Reset]
3388 [LtBlue]+-[Reset] [LtCyan]googolplex.gz[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
3389 [LtBlue]+-[Reset] [LtCyan]ordinals[Reset] -> [LtBlue]/d/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
3390 [LtBlue]\\-[Reset] [LtBlue]one two[Reset]
3391 [LtBlue]\\-[Reset] \"three\" 'four'.txt
3392";
3393 let files = create_files("D:", "/root", "../..");
3394 let files = modify_files_for_zip(files);
3395 let config = Config::default()
3396 .with_zip_expand(true)
3397 .with_show_indent(true)
3398 .with_only_path(true)
3399 .with_abs_path(true);
3400 assert_eq!(expected, wrap_files(&config, true, &files));
3401 }
3402
3403 #[test]
3404 #[cfg(not(windows))]
3405 fn test_prints_indented_paths_with_zip_no_attributes_on_linux() {
3406 let expected = "\
3407[LtBlue]example[Reset]
3408 [LtBlue]+-[Reset] [DkGreen]find.sh[Reset]
3409 [LtBlue]\\-[Reset] [LtRed]files.zip[Reset]
3410 [LtBlue]+-[Reset] [LtBlue]colours[Reset]
3411 [LtBlue]|[Reset] [LtBlue]+-[Reset] [LtGreen]alpha.sh[Reset]
3412 [LtBlue]|[Reset] [LtBlue]+-[Reset] blue.txt
3413 [LtBlue]|[Reset] [LtBlue]+-[Reset] green.txt
3414 [LtBlue]|[Reset] [LtBlue]\\-[Reset] red.txt
3415 [LtBlue]\\-[Reset] [LtBlue]numbers[Reset]
3416 [LtBlue]+-[Reset] [LtCyan]count.sh[Reset] -> [LtBlue]/etc/numbers/[Reset][LtGreen]count.sh[Reset]
3417 [LtBlue]+-[Reset] [LtCyan]googolplex.gz[Reset] -> [LtBlue]/etc/numbers/[Reset][LtRed]googolplex.gz[Reset]
3418 [LtBlue]+-[Reset] [LtCyan]ordinals[Reset] -> [LtBlue]/etc/numbers/[Reset][LtBlue]ordinals/[Reset]
3419 [LtBlue]\\-[Reset] [LtBlue]one two[Reset]
3420 [LtBlue]\\-[Reset] \"three\" 'four'.txt
3421";
3422 let files = create_files("", "/root", "../..");
3423 let files = modify_files_for_zip(files);
3424 let config = Config::default()
3425 .with_zip_expand(true)
3426 .with_show_indent(true)
3427 .with_only_path(true)
3428 .with_abs_path(true);
3429 assert_eq!(expected, wrap_files(&config, false, &files));
3430 }
3431
3432 fn wrap_mode(
3433 zip_expand: bool,
3434 zip_depth: Option<usize>,
3435 file_mode: u32,
3436 file_type: FileKind,
3437 ) -> String {
3438 let config = Config::default().with_zip_expand(zip_expand);
3439 wrap_function(&config, false, |p| p.print_mode(file_type, file_mode, zip_depth))
3440 }
3441
3442 fn wrap_size(config: &Config, file_size: u64, size_width: usize) -> String {
3443 wrap_function(config, false, |p| p.print_size(file_size, size_width))
3444 }
3445
3446 fn wrap_time(
3447 config: &Config,
3448 year: i32,
3449 month: u32,
3450 day: u32,
3451 hour: u32,
3452 minute: u32,
3453 second: u32,
3454 ) -> String {
3455 let time = Utc.with_ymd_and_hms(year, month, day, hour, minute, second).unwrap();
3456 wrap_function(config, false, |p| p.print_time(&time, &Utc, true))
3457 }
3458
3459 #[cfg(windows)]
3460 fn wrap_version(file_ver: Option<&str>, ver_width: usize) -> String {
3461 let config = Config::default();
3462 let file_ver = file_ver.map(str::to_string);
3463 wrap_function(&config, false, |p| p.print_version(&file_ver, ver_width))
3464 }
3465
3466 fn wrap_ext(file_ext: &str, ext_width: usize) -> String {
3467 let config = Config::default();
3468 wrap_function(&config, false, |p| p.print_ext(file_ext, ext_width))
3469 }
3470
3471 fn wrap_total(num_files: usize, num_dirs: usize) -> String {
3472 let config = Config::default();
3473 let mut total = Total::new(None);
3474 total.num_files = num_files;
3475 total.num_dirs = num_dirs;
3476 wrap_function(&config, false, |p| p.print_summary(&total))
3477 }
3478
3479 fn wrap_files(config: &Config, git_bash: bool, files: &Vec<File>) -> String {
3480 let total = create_total(config, files);
3481 wrap_function(config, git_bash, |p| p.print_files(files, &total, &Utc))
3482 }
3483
3484 fn wrap_function<F>(config: &Config, git_bash: bool, func: F) -> String where
3485 F: FnOnce(&mut Printer<BufferWrapper>) -> MyResult<()>,
3486 {
3487 let mut buffer = String::new();
3488 let writer = unsafe { BufferWrapper::new(buffer.as_mut_vec()) };
3489 let colors = Some(String::from("*.gz=01;31:*.zip=01;31:*.png=01;35"));
3490 let colors = ColorMap::new(colors);
3491 let chars = IndentChars {
3492 branching: '+',
3493 terminating: '\\',
3494 horizontal: '-',
3495 vertical: '|',
3496 };
3497 let mut printer = Printer::new(
3498 config,
3499 &Utc,
3500 writer,
3501 colors,
3502 chars,
3503 git_bash,
3504 );
3505 func(&mut printer).unwrap();
3506 buffer
3507 }
3508
3509 fn create_files(drive: &str, abs_prefix: &str, rel_prefix: &str) -> Vec<File> {
3510 let abs_prefix = drive.to_string() + abs_prefix;
3511 let link_exec = PathBuf::from(drive.to_string() + "/etc/numbers/count.sh").clean();
3512 let link_file = PathBuf::from(drive.to_string() + "/etc/numbers/googolplex.gz").clean();
3513 let link_dir = PathBuf::from(drive.to_string() + "/etc/numbers/ordinals").clean();
3514 vec![
3515 create_file(&abs_prefix, rel_prefix, "example", "", "")
3516 .with_type(FileKind::Dir)
3517 .with_mode(0o755)
3518 .with_owner_ref("alice", "public")
3519 .with_size(0)
3520 .with_date(2023, 12, 31),
3521 create_file(&abs_prefix, rel_prefix, "example", "find", ".sh")
3522 .with_type(FileKind::File(ExecKind::Other))
3523 .with_mode(0o755)
3524 .with_owner_ref("root", "root")
3525 .with_size(10)
3526 .with_date(2023, 11, 01)
3527 .with_git(Some(GitFlags::new()
3528 .with_added(true)
3529 .with_modified(true)
3530 .with_renamed(true)
3531 .with_untracked(true)
3532 .with_ignored(true)))
3533 .with_sig_str("#!/u"),
3534 create_file(&abs_prefix, rel_prefix, "example/files", "", "")
3535 .with_type(FileKind::Dir)
3536 .with_mode(0o755)
3537 .with_owner_ref("alice", "public")
3538 .with_size(0)
3539 .with_date(2023, 12, 31),
3540 create_file(&abs_prefix, rel_prefix, "example/files/colours", "", "")
3541 .with_type(FileKind::Dir)
3542 .with_mode(0o755)
3543 .with_owner_ref("alice", "public")
3544 .with_size(0)
3545 .with_date(2023, 12, 31),
3546 create_file(&abs_prefix, rel_prefix, "example/files/colours", "alpha", ".sh")
3547 .with_type(FileKind::File(ExecKind::User))
3548 .with_mode(0o744)
3549 .with_owner_ref("alice", "public")
3550 .with_size(20)
3551 .with_date(2023, 10, 01)
3552 .with_git(Some(GitFlags::new().with_added(true)))
3553 .with_sig_str("#!/u"),
3554 create_file(&abs_prefix, rel_prefix, "example/files/colours", "blue", ".txt")
3555 .with_type(FileKind::File(ExecKind::None))
3556 .with_mode(0o644)
3557 .with_owner_ref("alice", "public")
3558 .with_size(30)
3559 .with_date(2023, 09, 01)
3560 .with_git(Some(GitFlags::new().with_modified(true)))
3561 .with_sig_str("BLUE"),
3562 create_file(&abs_prefix, rel_prefix, "example/files/colours", "green", ".txt")
3563 .with_type(FileKind::File(ExecKind::None))
3564 .with_mode(0o644)
3565 .with_owner_ref("alice", "public")
3566 .with_size(40)
3567 .with_date(2023, 08, 01)
3568 .with_git(Some(GitFlags::new().with_renamed(true)))
3569 .with_sig_str("GREE"),
3570 create_file(&abs_prefix, rel_prefix, "example/files/colours", "red", ".txt")
3571 .with_type(FileKind::File(ExecKind::None))
3572 .with_mode(0o644)
3573 .with_owner_ref("alice", "public")
3574 .with_size(50)
3575 .with_date(2023, 07, 01)
3576 .with_git(Some(GitFlags::new().with_untracked(true)))
3577 .with_sig_str("RED"),
3578 create_file(&abs_prefix, rel_prefix, "example/files/numbers", "", "")
3579 .with_type(FileKind::Dir)
3580 .with_mode(0o755)
3581 .with_owner_ref("bob", "public")
3582 .with_size(0)
3583 .with_date(2023, 12, 31),
3584 create_file(&abs_prefix, rel_prefix, "example/files/numbers", "count", ".sh")
3585 .with_type(FileKind::Link(true))
3586 .with_mode(0o744)
3587 .with_owner_ref("bob", "public")
3588 .with_size(60)
3589 .with_date(2023, 06, 01)
3590 .with_sig_str("#!/u")
3591 .with_link(link_exec, FileKind::File(ExecKind::User)),
3592 create_file(&abs_prefix, rel_prefix, "example/files/numbers", "googolplex", ".gz")
3593 .with_type(FileKind::Link(true))
3594 .with_mode(0o644)
3595 .with_owner_ref("bob", "public")
3596 .with_size(999)
3597 .with_date(2023, 05, 01)
3598 .with_link(link_file, FileKind::File(ExecKind::None)),
3599 create_file(&abs_prefix, rel_prefix, "example/files/numbers", "ordinals", "")
3600 .with_type(FileKind::Link(true))
3601 .with_mode(0o644)
3602 .with_owner_ref("bob", "public")
3603 .with_size(0)
3604 .with_date(2023, 04, 01)
3605 .with_link(link_dir, FileKind::Dir),
3606 create_file(&abs_prefix, rel_prefix, "example/files/numbers/one two", "", "")
3607 .with_type(FileKind::Dir)
3608 .with_mode(0o755)
3609 .with_size(0)
3610 .with_date(2023, 12, 31),
3611 create_file(&abs_prefix, rel_prefix, "example/files/numbers/one two", "\"three\" 'four'", ".txt")
3612 .with_type(FileKind::File(ExecKind::None))
3613 .with_mode(0o644)
3614 .with_size(70)
3615 .with_date(2023, 03, 01)
3616 .with_git(Some(GitFlags::new().with_ignored(true)))
3617 .with_sig(Some([0xff, 0xfe, 0x33, 0x34])),
3618 ]
3619 }
3620
3621 fn modify_files_by_name(files: Vec<File>) -> Vec<File> {
3622 let mut files = files.into_iter()
3623 .filter(|file| file.file_type != FileKind::Dir)
3624 .collect::<Vec<File>>();
3625 files.sort_by(&compare_files_by_name);
3626 files
3627 }
3628
3629 fn compare_files_by_name(left: &File, right: &File) -> Ordering {
3630 let left = left.file_name.trim_start_matches("\"");
3631 let right = right.file_name.trim_start_matches("\"");
3632 left.cmp(&right)
3633 }
3634
3635 fn modify_files_for_zip(files: Vec<File>) -> Vec<File> {
3636 files.into_iter().map(modify_file_for_zip).collect()
3637 }
3638
3639 fn modify_file_for_zip(file: File) -> File {
3640 let (abs_dir, mut zip_depth) = modify_dir_for_zip(&file.abs_dir);
3641 let (rel_dir, _) = modify_dir_for_zip(&file.rel_dir);
3642 if file.file_type != FileKind::Dir {
3643 zip_depth = zip_depth.map(|depth| depth + 1);
3644 }
3645 file.with_dirs(abs_dir, rel_dir).with_zip_depth(zip_depth)
3646 }
3647
3648 fn modify_dir_for_zip(old_dir: &Path) -> (PathBuf, Option<usize>) {
3649 let mut new_dir = PathBuf::new();
3650 let mut zip_depth = None;
3651 for component in old_dir.components() {
3652 if let Component::Normal(dir) = component {
3653 if dir == "files" {
3654 new_dir.push("files.zip");
3655 zip_depth = Some(0);
3656 continue;
3657 }
3658 }
3659 new_dir.push(component);
3660 zip_depth = zip_depth.map(|depth| depth + 1);
3661 }
3662 (new_dir, zip_depth)
3663 }
3664
3665 #[cfg(windows)]
3666 fn create_files_with_version() -> Vec<File> {
3667 vec![
3668 create_file("", "", "", "binary", ".exe")
3669 .with_type(FileKind::File(ExecKind::User))
3670 .with_mode(0o744)
3671 .with_size(999)
3672 .with_date(2024, 01, 01)
3673 .with_version(String::from("12.3.4.0")),
3674 create_file("", "", "", "library", ".dll")
3675 .with_type(FileKind::File(ExecKind::None))
3676 .with_mode(0o744)
3677 .with_size(999)
3678 .with_date(2024, 01, 01)
3679 .with_version(String::from("5.67.89.0")),
3680 create_file("", "", "", "readme", ".txt")
3681 .with_type(FileKind::File(ExecKind::None))
3682 .with_mode(0o644)
3683 .with_size(999)
3684 .with_date(2024, 01, 01),
3685 ]
3686 }
3687
3688 fn create_file(
3689 abs_prefix: &str,
3690 rel_prefix: &str,
3691 file_dir: &str,
3692 file_name: &str,
3693 file_ext: &str,
3694 ) -> File {
3695 let abs_dir = PathBuf::from(abs_prefix).join(file_dir).clean();
3696 let rel_dir = PathBuf::from(rel_prefix).join(file_dir).clean();
3697 let file_depth = PathBuf::from(file_dir).join(file_name).components().count();
3698 let file_name = format!("{file_name}{file_ext}");
3699 let file_ext = String::from(file_ext);
3700 File::new(abs_dir, rel_dir, file_depth, None, file_name, file_ext, FileKind::Other)
3701 }
3702
3703 fn create_total(config: &Config, files: &Vec<File>) -> Total {
3704 let start_time = Utc.with_ymd_and_hms(2023, 1, 1, 0, 0, 0).unwrap();
3705 Total::from_files(Some(start_time), config, files)
3706 }
3707
3708 struct BufferWrapper<'a> {
3709 buffer: &'a mut Vec<u8>,
3710 }
3711
3712 impl<'a> BufferWrapper<'a> {
3713 fn new(buffer: &'a mut Vec<u8>) -> Self {
3714 Self { buffer }
3715 }
3716 }
3717
3718 impl<'a> Write for BufferWrapper<'a> {
3719 fn write(&mut self, buffer: &[u8]) -> io::Result<usize> {
3720 self.buffer.write(buffer)
3721 }
3722
3723 fn flush(&mut self) -> io::Result<()> {
3724 Ok(())
3725 }
3726 }
3727
3728 impl<'a> WriteColor for BufferWrapper<'a> {
3729 fn supports_color(&self) -> bool {
3730 false
3731 }
3732
3733 fn set_color(&mut self, color: &ColorSpec) -> io::Result<()> {
3734 let bold = if color.bold() { "Lt" } else { "Dk" };
3735 let fg = match color.fg() {
3736 Some(Color::Black) => "Black",
3737 Some(Color::Blue) => "Blue",
3738 Some(Color::Green) => "Green",
3739 Some(Color::Red) => "Red",
3740 Some(Color::Cyan) => "Cyan",
3741 Some(Color::Magenta) => "Magenta",
3742 Some(Color::Yellow) => "Yellow",
3743 Some(Color::White) => "White",
3744 Some(_) => "Other",
3745 None => "None",
3746 };
3747 write!(&mut self.buffer, "[{bold}{fg}]")?;
3748 Ok(())
3749 }
3750
3751 fn reset(&mut self) -> io::Result<()> {
3752 write!(&mut self.buffer, "[Reset]")?;
3753 Ok(())
3754 }
3755 }
3756}