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