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