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