Merge branch 'sort-tests'

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

Fixes #113.
This commit is contained in:
Benjamin Sago 2017-06-29 15:07:07 +01:00
commit 22c6fb048f
17 changed files with 141 additions and 28 deletions

View File

@ -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**.

14
Vagrantfile vendored
View File

@ -139,22 +139,22 @@ Vagrant.configure(2) do |config|
# File name extension testcases.
# These are tested in grid view, so we dont need to bother setting
# owners or timestamps or anything.
# These arent 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"

View File

@ -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
;;

View File

@ -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

View File

@ -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]" \

View File

@ -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

View File

@ -40,8 +40,11 @@ pub type uid_t = u32;
/// This type is set entirely by the filesystem, rather than relying on a
/// files 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 {

View File

@ -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))
}
}

View File

@ -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
"##;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 arent 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 cant guarantee inode numbers, but we can at least check that theyre 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
xtests/sort-by-type Normal file
View File

@ -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
xtests/specials_sort Normal file
View File

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