diff --git a/pkg/analyze/sort_test.go b/pkg/analyze/sort_test.go index a7d208f0b..d5f739876 100644 --- a/pkg/analyze/sort_test.go +++ b/pkg/analyze/sort_test.go @@ -29,6 +29,29 @@ func TestSortByUsage(t *testing.T) { assert.Equal(t, int64(1), files[2].GetUsage()) } +func TestStableSortByUsage(t *testing.T) { + files := fs.Files{ + &File{ + Name: "aaa", + Usage: 1, + }, + &File{ + Name: "bbb", + Usage: 1, + }, + &File{ + Name: "ccc", + Usage: 3, + }, + } + + sort.Sort(files) + + assert.Equal(t, "ccc", files[0].GetName()) + assert.Equal(t, "bbb", files[1].GetName()) + assert.Equal(t, "aaa", files[2].GetName()) +} + func TestSortByUsageAsc(t *testing.T) { files := fs.Files{ &File{ diff --git a/pkg/fs/file.go b/pkg/fs/file.go index 71e85c2c2..4023ea60a 100644 --- a/pkg/fs/file.go +++ b/pkg/fs/file.go @@ -71,23 +71,41 @@ func (f Files) RemoveByName(name string) Files { return append(f[:index], f[index+1:]...) } -func (f Files) Len() int { return len(f) } -func (f Files) Swap(i, j int) { f[i], f[j] = f[j], f[i] } -func (f Files) Less(i, j int) bool { return f[i].GetUsage() > f[j].GetUsage() } +func (f Files) Len() int { return len(f) } +func (f Files) Swap(i, j int) { f[i], f[j] = f[j], f[i] } +func (f Files) Less(i, j int) bool { + if f[i].GetUsage() != f[j].GetUsage() { + return f[i].GetUsage() > f[j].GetUsage() + } + // if usage is the same, sort by name + return f[i].GetName() > f[j].GetName() +} // ByApparentSize sorts files by apparent size type ByApparentSize Files -func (f ByApparentSize) Len() int { return len(f) } -func (f ByApparentSize) Swap(i, j int) { f[i], f[j] = f[j], f[i] } -func (f ByApparentSize) Less(i, j int) bool { return f[i].GetSize() > f[j].GetSize() } +func (f ByApparentSize) Len() int { return len(f) } +func (f ByApparentSize) Swap(i, j int) { f[i], f[j] = f[j], f[i] } +func (f ByApparentSize) Less(i, j int) bool { + if f[i].GetSize() != f[j].GetSize() { + return f[i].GetSize() > f[j].GetSize() + } + // if size is the same, sort by name + return f[i].GetName() > f[j].GetName() +} // ByItemCount sorts files by item count type ByItemCount Files -func (f ByItemCount) Len() int { return len(f) } -func (f ByItemCount) Swap(i, j int) { f[i], f[j] = f[j], f[i] } -func (f ByItemCount) Less(i, j int) bool { return f[i].GetItemCount() > f[j].GetItemCount() } +func (f ByItemCount) Len() int { return len(f) } +func (f ByItemCount) Swap(i, j int) { f[i], f[j] = f[j], f[i] } +func (f ByItemCount) Less(i, j int) bool { + if f[i].GetItemCount() != f[j].GetItemCount() { + return f[i].GetItemCount() > f[j].GetItemCount() + } + // if item count is the same, sort by name + return f[i].GetName() > f[j].GetName() +} // ByName sorts files by name type ByName Files @@ -99,6 +117,12 @@ func (f ByName) Less(i, j int) bool { return f[i].GetName() > f[j].GetName() } // ByMtime sorts files by name type ByMtime Files -func (f ByMtime) Len() int { return len(f) } -func (f ByMtime) Swap(i, j int) { f[i], f[j] = f[j], f[i] } -func (f ByMtime) Less(i, j int) bool { return f[i].GetMtime().After(f[j].GetMtime()) } +func (f ByMtime) Len() int { return len(f) } +func (f ByMtime) Swap(i, j int) { f[i], f[j] = f[j], f[i] } +func (f ByMtime) Less(i, j int) bool { + if !f[i].GetMtime().Equal(f[j].GetMtime()) { + return f[i].GetMtime().After(f[j].GetMtime()) + } + // if item count is the same, sort by name + return f[i].GetName() > f[j].GetName() +} diff --git a/tui/actions_test.go b/tui/actions_test.go index c6acd1226..325c71f59 100644 --- a/tui/actions_test.go +++ b/tui/actions_test.go @@ -79,7 +79,7 @@ func TestDeviceSelected(t *testing.T) { assert.Equal(t, "test_dir", ui.currentDir.GetName()) assert.Equal(t, 4, ui.table.GetRowCount()) - assert.Contains(t, ui.table.GetCell(0, 0).Text, "aaa") + assert.Contains(t, ui.table.GetCell(0, 0).Text, "ccc") assert.Contains(t, ui.table.GetCell(1, 0).Text, "bbb") } @@ -87,14 +87,14 @@ func TestAnalyzePath(t *testing.T) { ui := getAnalyzedPathMockedApp(t, true, true, true) assert.Equal(t, 4, ui.table.GetRowCount()) - assert.Contains(t, ui.table.GetCell(0, 0).Text, "aaa") + assert.Contains(t, ui.table.GetCell(0, 0).Text, "ccc") } func TestAnalyzePathBW(t *testing.T) { ui := getAnalyzedPathMockedApp(t, false, true, true) assert.Equal(t, 4, ui.table.GetRowCount()) - assert.Contains(t, ui.table.GetCell(0, 0).Text, "aaa") + assert.Contains(t, ui.table.GetCell(0, 0).Text, "ccc") } func TestAnalyzePathWithParentDir(t *testing.T) { @@ -127,7 +127,7 @@ func TestAnalyzePathWithParentDir(t *testing.T) { assert.Equal(t, 5, ui.table.GetRowCount()) assert.Contains(t, ui.table.GetCell(0, 0).Text, "/..") - assert.Contains(t, ui.table.GetCell(1, 0).Text, "aaa") + assert.Contains(t, ui.table.GetCell(1, 0).Text, "ccc") } func TestReadAnalysis(t *testing.T) { diff --git a/tui/filter_test.go b/tui/filter_test.go index b9d86c8b9..17474380d 100644 --- a/tui/filter_test.go +++ b/tui/filter_test.go @@ -33,17 +33,17 @@ func TestFiltering(t *testing.T) { ui.filterValue = "" ui.showDir() - assert.Contains(t, ui.table.GetCell(0, 0).Text, "aaa") // nothing is filtered + assert.Contains(t, ui.table.GetCell(0, 0).Text, "ccc") // nothing is filtered - ui.filterValue = "cc" + ui.filterValue = "aa" ui.showDir() - assert.Contains(t, ui.table.GetCell(0, 0).Text, "ccc") // shows only cccc + assert.Contains(t, ui.table.GetCell(0, 0).Text, "aaa") // shows only cccc ui.hideFilterInput() ui.showDir() - assert.Contains(t, ui.table.GetCell(0, 0).Text, "aaa") // filtering reset + assert.Contains(t, ui.table.GetCell(0, 0).Text, "ccc") // filtering reset } func TestFilteringWithoutCurrentDir(t *testing.T) { diff --git a/tui/keys_test.go b/tui/keys_test.go index 4652a2476..0907d1588 100644 --- a/tui/keys_test.go +++ b/tui/keys_test.go @@ -670,7 +670,7 @@ func TestRescan(t *testing.T) { assert.Equal(t, 5, ui.table.GetRowCount()) assert.Contains(t, ui.table.GetCell(0, 0).Text, "/..") - assert.Contains(t, ui.table.GetCell(1, 0).Text, "aaa") + assert.Contains(t, ui.table.GetCell(1, 0).Text, "ccc") } func TestSorting(t *testing.T) { diff --git a/tui/sort_test.go b/tui/sort_test.go index 483eb442e..71b8d7419 100644 --- a/tui/sort_test.go +++ b/tui/sort_test.go @@ -13,9 +13,9 @@ func TestAnalyzeByApparentSize(t *testing.T) { ui := getAnalyzedPathWithSorting("size", "desc", true) assert.Equal(t, 4, ui.table.GetRowCount()) - assert.Contains(t, ui.table.GetCell(0, 0).Text, "aaa") + assert.Contains(t, ui.table.GetCell(0, 0).Text, "ccc") assert.Contains(t, ui.table.GetCell(1, 0).Text, "bbb") - assert.Contains(t, ui.table.GetCell(2, 0).Text, "ccc") + assert.Contains(t, ui.table.GetCell(2, 0).Text, "aaa") assert.Contains(t, ui.table.GetCell(3, 0).Text, "ddd") } @@ -33,9 +33,9 @@ func TestAnalyzeBySize(t *testing.T) { ui := getAnalyzedPathWithSorting("size", "desc", false) assert.Equal(t, 4, ui.table.GetRowCount()) - assert.Contains(t, ui.table.GetCell(0, 0).Text, "aaa") + assert.Contains(t, ui.table.GetCell(0, 0).Text, "ccc") assert.Contains(t, ui.table.GetCell(1, 0).Text, "bbb") - assert.Contains(t, ui.table.GetCell(2, 0).Text, "ccc") + assert.Contains(t, ui.table.GetCell(2, 0).Text, "aaa") assert.Contains(t, ui.table.GetCell(3, 0).Text, "ddd") } @@ -73,10 +73,10 @@ func TestAnalyzeByItemCount(t *testing.T) { ui := getAnalyzedPathWithSorting("itemCount", "desc", false) assert.Equal(t, 4, ui.table.GetRowCount()) - assert.Contains(t, ui.table.GetCell(0, 0).Text, "aaa") - assert.Contains(t, ui.table.GetCell(1, 0).Text, "bbb") - assert.Contains(t, ui.table.GetCell(2, 0).Text, "ccc") - assert.Contains(t, ui.table.GetCell(3, 0).Text, "ddd") + assert.Contains(t, ui.table.GetCell(0, 0).Text, "ddd") + assert.Contains(t, ui.table.GetCell(1, 0).Text, "ccc") + assert.Contains(t, ui.table.GetCell(2, 0).Text, "bbb") + assert.Contains(t, ui.table.GetCell(3, 0).Text, "aaa") } func TestAnalyzeByItemCountAsc(t *testing.T) { diff --git a/tui/tui_test.go b/tui/tui_test.go index c5bffda61..aab92f999 100644 --- a/tui/tui_test.go +++ b/tui/tui_test.go @@ -179,7 +179,7 @@ func TestRescanDir(t *testing.T) { assert.Equal(t, 5, ui.table.GetRowCount()) assert.Contains(t, ui.table.GetCell(0, 0).Text, "/..") - assert.Contains(t, ui.table.GetCell(1, 0).Text, "aaa") + assert.Contains(t, ui.table.GetCell(1, 0).Text, "ccc") } func TestDirSelected(t *testing.T) { @@ -202,7 +202,7 @@ func TestFileSelected(t *testing.T) { ui.fileItemSelected(3, 0) assert.Equal(t, 4, ui.table.GetRowCount()) - assert.Contains(t, ui.table.GetCell(0, 0).Text, "aaa") + assert.Contains(t, ui.table.GetCell(0, 0).Text, "ccc") } func TestSelectedWithoutCurrentDir(t *testing.T) {