ソースを参照

Merge branch 'sort-tests'

Adds some tests for sorting, and also adds --sort=type functionality.

Fixes #113.
Benjamin Sago 8 年 前
コミット
22c6fb048f

+ 1 - 1
README.md

@@ -53,7 +53,7 @@ These options are available when running with --long (`-l`):
 - **--git**: list each file's Git status, if tracked
 
 - Valid **--color** options are **always**, **automatic**, and **never**.
-- Valid sort fields are **accessed**, **created**, **extension**, **Extension**, **inode**, **modified**, **name**, **Name**, **size**, and **none**. Fields starting with a capital letter are case-sensitive.
+- Valid sort fields are **accessed**, **created**, **extension**, **Extension**, **inode**, **modified**, **name**, **Name**, **size**, **type**, and **none**. Fields starting with a capital letter are case-sensitive.
 - Valid time fields are **modified**, **accessed**, and **created**.
 
 

+ 7 - 7
Vagrantfile

@@ -139,22 +139,22 @@ Vagrant.configure(2) do |config|
 
 
     # File name extension testcases.
-    # These are tested in grid view, so we don’t need to bother setting
-    # owners or timestamps or anything.
+    # These aren’t tested in details view, but we set timestamps on them to
+    # test that various sort options work.
     config.vm.provision :shell, privileged: false, inline: <<-EOF
         set -xe
         mkdir "#{test_dir}/file-names-exts"
 
         touch "#{test_dir}/file-names-exts/Makefile"
 
-        touch "#{test_dir}/file-names-exts/image.png"
+        touch "#{test_dir}/file-names-exts/IMAGE.PNG"
         touch "#{test_dir}/file-names-exts/image.svg"
 
-        touch "#{test_dir}/file-names-exts/video.avi"
+        touch "#{test_dir}/file-names-exts/VIDEO.AVI"
         touch "#{test_dir}/file-names-exts/video.wmv"
 
         touch "#{test_dir}/file-names-exts/music.mp3"
-        touch "#{test_dir}/file-names-exts/music.ogg"
+        touch "#{test_dir}/file-names-exts/MUSIC.OGG"
 
         touch "#{test_dir}/file-names-exts/lossless.flac"
         touch "#{test_dir}/file-names-exts/lossless.wav"
@@ -163,9 +163,9 @@ Vagrant.configure(2) do |config|
         touch "#{test_dir}/file-names-exts/crypto.signature"
 
         touch "#{test_dir}/file-names-exts/document.pdf"
-        touch "#{test_dir}/file-names-exts/document.xlsx"
+        touch "#{test_dir}/file-names-exts/DOCUMENT.XLSX"
 
-        touch "#{test_dir}/file-names-exts/compressed.zip"
+        touch "#{test_dir}/file-names-exts/COMPRESSED.ZIP"
         touch "#{test_dir}/file-names-exts/compressed.tar.gz"
         touch "#{test_dir}/file-names-exts/compressed.tgz"
 

+ 1 - 1
contrib/completions.bash

@@ -14,7 +14,7 @@ _exa()
             ;;
 
         -s|--sort)
-            COMPREPLY=( $( compgen -W 'name filename Name Filename size filesize extension Extension modified accessed created none inode --' -- "$cur" ) )
+            COMPREPLY=( $( compgen -W 'name filename Name Filename size filesize extension Extension modified accessed created type inode none --' -- "$cur" ) )
             return
             ;;
 

+ 1 - 0
contrib/completions.fish

@@ -36,6 +36,7 @@ complete -c exa -s 's' -l 'sort'   -x -d "Which field to sort by" -a "
     Name\t'Sort by filename (case-insensitive)'
     none\t'Do not sort files at all'
     size\t'Sort by file size'
+    type\t'Sort by file type'
 "
 
 complete -c exa -s 'I' -l 'ignore-glob' -d "Ignore files that match these glob patterns" -r

+ 1 - 1
contrib/completions.zsh

@@ -18,7 +18,7 @@ __exa() {
         {-d,--list-dirs}"[List directories like regular files]" \
         {-L,--level}"+[Limit the depth of recursion]" \
         {-r,--reverse}"[Reverse the sort order]" \
-        {-s,--sort}"[Which field to sort by]:(sort field):(accessed created extension Extension filename Filename inode modified name Name none size)" \
+        {-s,--sort}"[Which field to sort by]:(sort field):(accessed created extension Extension filename Filename inode modified name Name none size type)" \
         {-I,--ignore-glob}"[Ignore files that match these glob patterns]" \
         {-b,--binary}"[List file sizes with binary prefixes]" \
         {-B,--bytes}"[List file sizes in bytes, without any prefixes]" \

+ 1 - 1
contrib/man/exa.1

@@ -76,7 +76,7 @@ reverse the sort order
 .TP
 .B \-s, \-\-sort=\f[I]SORT_FIELD\f[]
 which field to sort by.
-Valid fields are name, Name, extension, Extension, size, modified, accessed, created, inode, and none.
+Valid fields are name, Name, extension, Extension, size, modified, accessed, created, inode, type, and none.
 Fields starting with a capital letter are case-sensitive.
 .RS
 .RE

+ 4 - 1
src/fs/fields.rs

@@ -40,8 +40,11 @@ pub type uid_t = u32;
 /// This type is set entirely by the filesystem, rather than relying on a
 /// file’s contents. So “link” is a type, but “image” is just a type of
 /// regular file. (See the `filetype` module for those checks.)
+///
+/// Its ordering is used when sorting by type.
+#[derive(PartialEq, Eq, PartialOrd, Ord)]
 pub enum Type {
-    File, Directory, Pipe, Link, Socket, CharDevice, BlockDevice, Special,
+    Directory, File, Link, Pipe, Socket, CharDevice, BlockDevice, Special,
 }
 
 impl Type {

+ 14 - 2
src/options/filter.rs

@@ -135,6 +135,11 @@ impl FileFilter {
             SortField::AccessedDate  => a.metadata.atime().cmp(&b.metadata.atime()),
             SortField::CreatedDate   => a.metadata.ctime().cmp(&b.metadata.ctime()),
 
+            SortField::FileType => match a.type_char().cmp(&b.type_char()) { // todo: this recomputes
+                Ordering::Equal  => natord::compare(&*a.name, &*b.name),
+                order            => order,
+            },
+
             SortField::Extension(Sensitive) => match a.ext.cmp(&b.ext) {
                 Ordering::Equal  => natord::compare(&*a.name, &*b.name),
                 order            => order,
@@ -195,6 +200,12 @@ pub enum SortField {
     /// In original Unix, this was, however, meant as creation time.
     /// https://www.bell-labs.com/usr/dmr/www/cacm.html
     CreatedDate,
+
+    /// The type of the file: directories, links, pipes, regular, files, etc.
+    ///
+    /// Files are ordered according to the `PartialOrd` implementation of
+    /// `fs::fields::Type`, so changing that will change this.
+    FileType,
 }
 
 /// Whether a field should be sorted case-sensitively or case-insensitively.
@@ -226,7 +237,7 @@ impl SortField {
 
         const SORTS: &[&str] = &[ "name", "Name", "size", "extension",
                                   "Extension", "modified", "accessed",
-                                  "created", "inode", "none" ];
+                                  "created", "inode", "type", "none" ];
 
         if let Some(word) = matches.opt_str("sort") {
             match &*word {
@@ -238,8 +249,9 @@ impl SortField {
                 "mod"  | "modified"   => Ok(SortField::ModifiedDate),
                 "acc"  | "accessed"   => Ok(SortField::AccessedDate),
                 "cr"   | "created"    => Ok(SortField::CreatedDate),
-                "none"                => Ok(SortField::Unsorted),
                 "inode"               => Ok(SortField::FileInode),
+                "type"                => Ok(SortField::FileType),
+                "none"                => Ok(SortField::Unsorted),
                 field                 => Err(Misfire::bad_argument("sort", field, SORTS))
             }
         }

+ 1 - 1
src/options/help.rs

@@ -23,7 +23,7 @@ FILTERING AND SORTING OPTIONS
   -s, --sort SORT_FIELD      which field to sort by:
   --group-directories-first  list directories before other files
   -I, --ignore-glob GLOBS    glob patterns (pipe-separated) of files to ignore
-  Valid sort fields:         name, Name, extension, Extension, size,
+  Valid sort fields:         name, Name, extension, Extension, size, type,
                              modified, accessed, created, inode, none
 "##;
 

+ 6 - 6
xtests/file-names-exts

@@ -1,5 +1,4 @@
 #SAVEFILE#
-Makefile
 backup~
 compiled.class
 compiled.coffee
@@ -7,17 +6,18 @@ compiled.coffee
 compiled.o
 compressed.tar.gz
 compressed.tgz
-compressed.zip
+COMPRESSED.ZIP
 crypto.asc
 crypto.signature
 document.pdf
-document.xlsx
+DOCUMENT.XLSX
 file.tmp
-image.png
+IMAGE.PNG
 image.svg
 lossless.flac
 lossless.wav
+Makefile
 music.mp3
-music.ogg
-video.avi
+MUSIC.OGG
+VIDEO.AVI
 video.wmv

+ 23 - 0
xtests/file-names-exts-case

@@ -0,0 +1,23 @@
+#SAVEFILE#
+COMPRESSED.ZIP
+DOCUMENT.XLSX
+IMAGE.PNG
+MUSIC.OGG
+Makefile
+VIDEO.AVI
+backup~
+compiled.class
+compiled.coffee
+compiled.js
+compiled.o
+compressed.tar.gz
+compressed.tgz
+crypto.asc
+crypto.signature
+document.pdf
+file.tmp
+image.svg
+lossless.flac
+lossless.wav
+music.mp3
+video.wmv

+ 23 - 0
xtests/file-names-exts-ext

@@ -0,0 +1,23 @@
+#SAVEFILE#
+backup~
+Makefile
+crypto.asc
+VIDEO.AVI
+compiled.class
+compiled.coffee
+lossless.flac
+compressed.tar.gz
+compiled.js
+music.mp3
+compiled.o
+MUSIC.OGG
+document.pdf
+IMAGE.PNG
+crypto.signature
+image.svg
+compressed.tgz
+file.tmp
+lossless.wav
+video.wmv
+DOCUMENT.XLSX
+COMPRESSED.ZIP

+ 23 - 0
xtests/file-names-exts-ext-case

@@ -0,0 +1,23 @@
+#SAVEFILE#
+Makefile
+backup~
+crypto.asc
+VIDEO.AVI
+compiled.class
+compiled.coffee
+lossless.flac
+compressed.tar.gz
+compiled.js
+music.mp3
+compiled.o
+MUSIC.OGG
+document.pdf
+IMAGE.PNG
+crypto.signature
+image.svg
+compressed.tgz
+file.tmp
+lossless.wav
+video.wmv
+DOCUMENT.XLSX
+COMPRESSED.ZIP

+ 1 - 1
xtests/help

@@ -22,7 +22,7 @@ FILTERING AND SORTING OPTIONS
   -s, --sort SORT_FIELD      which field to sort by:
   --group-directories-first  list directories before other files
   -I, --ignore-glob GLOBS    glob patterns (pipe-separated) of files to ignore
-  Valid sort fields:         name, Name, extension, Extension, size,
+  Valid sort fields:         name, Name, extension, Extension, size, type,
                              modified, accessed, created, inode, none
 
 LONG VIEW OPTIONS

+ 21 - 6
xtests/run.sh

@@ -79,15 +79,30 @@ COLUMNS=80 $exa $testcases/file-names -R 2>&1 | diff -q - $results/file_names_R
 $exa $testcases/file-names/* 2>/dev/null
 
 
-# File types
-$exa $testcases/file-names-exts -1 2>&1 | diff -q - $results/file-names-exts  || exit 1
-$exa $testcases/specials        -l 2>&1 | diff -q - $results/specials         || exit 1
-$exa $testcases/specials     -F -l 2>&1 | diff -q - $results/specials_F       || exit 1
+# Sorting and extension file types
+$exa $testcases/file-names-exts -1 2>&1 --sort=Name | diff -q - $results/file-names-exts           || exit 1
+$exa $testcases/file-names-exts -1 2>&1 --sort=name | diff -q - $results/file-names-exts-case      || exit 1
+$exa $testcases/file-names-exts -1 2>&1 --sort=Ext  | diff -q - $results/file-names-exts-ext       || exit 1
+$exa $testcases/file-names-exts -1 2>&1 --sort=ext  | diff -q - $results/file-names-exts-ext-case  || exit 1
+
+# Pass multiple input arguments because there aren’t enough of different types
+# in one directory already
+$exa $testcases/links -1 --sort=type 2>&1 | diff -q - $results/sort-by-type  || exit 1
+
+# We can’t guarantee inode numbers, but we can at least check that they’re in
+# order. The inode column is the leftmost one, so sort works for this.
+$exa $testcases/file-names-exts --long --inode --sort=inode | sort --check  || exit 1
+
+
+# Other file types
+$exa $testcases/specials             -l 2>&1 | diff -q - $results/specials       || exit 1
+$exa $testcases/specials          -F -l 2>&1 | diff -q - $results/specials_F     || exit 1
+$exa $testcases/specials --sort=type -1 2>&1 | diff -q - $results/specials_sort  || exit 1
 
 
 # Ignores
-$exa $testcases/file-names-exts/music.* -I "*.ogg"       -1 2>&1 | diff -q - $results/ignores_ogg  || exit 1
-$exa $testcases/file-names-exts/music.* -I "*.ogg|*.mp3" -1 2>&1 | diff -q - $results/empty        || exit 1
+$exa $testcases/file-names-exts/music.* -I "*.OGG"       -1 2>&1 | diff -q - $results/ignores_ogg  || exit 1
+$exa $testcases/file-names-exts/music.* -I "*.OGG|*.mp3" -1 2>&1 | diff -q - $results/empty        || exit 1
 
 
 # Paths and directories

+ 10 - 0
xtests/sort-by-type

@@ -0,0 +1,10 @@
+some_file
+broken -> nowhere
+current_dir -> .
+forbidden -> /proc/1/root
+itself -> itself
+parent_dir -> ..
+root -> /
+some_file_absolute -> /testcases/links/some_file
+some_file_relative -> some_file
+usr -> /usr

+ 3 - 0
xtests/specials_sort

@@ -0,0 +1,3 @@
+named-pipe
+char-device
+block-device