Skip to content

Commit

Permalink
Removed sort data from FileListItem
Browse files Browse the repository at this point in the history
  • Loading branch information
viktor-podzigun committed Apr 5, 2024
1 parent ff3f1b9 commit 4e84e12
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 154 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@

## @farjs/filelist

Common FileList api/plugin/interfaces library.
Common plugin/api/ui library for FAR.js **File Browser** module.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"author": "viktor-podzigun",
"version": "0.0.0",
"license": "MIT",
"description": "Common FileList api/plugin/interfaces",
"description": "Common plugin/api/ui for FAR.js File Browser module",
"scripts": {
"lint": "quick-lint-js ./**/*.mjs ./**/*.ts",
"test": "tsc && bun test && node ./test/all.mjs",
Expand Down
6 changes: 0 additions & 6 deletions src/api/FileListItem.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,4 @@ export interface FileListItem {
* Format: `drwx---rwx`
*/
readonly permissions: string;

nameNormalized(): string;
ext(): string;
extNormalized(): string;

toString(): string;
}
38 changes: 0 additions & 38 deletions src/api/FileListItem.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,38 +8,6 @@
* @returns {FileListItem}
*/
function FileListItem(name, isDir) {
/** @type {string | null} */
let _nameNormalized = null;

function nameNormalized() {
if (_nameNormalized === null) {
_nameNormalized = name.toLowerCase();
}
return _nameNormalized;
}

/** @type {string | null} */
let _ext = null;

function ext() {
if (_ext === null) {
const dotIndex = name.lastIndexOf(".");
if (dotIndex < 0) _ext = name;
else _ext = name.slice(dotIndex + 1);
}
return _ext;
}

/** @type {string | null} */
let _extNormalized = null;

function extNormalized() {
if (_extNormalized === null) {
_extNormalized = ext().toLowerCase();
}
return _extNormalized;
}

return {
name,
isDir: !!isDir,
Expand All @@ -50,12 +18,6 @@ function FileListItem(name, isDir) {
ctimeMs: 0,
birthtimeMs: 0,
permissions: "",
nameNormalized,
ext,
extNormalized,
toString: () => {
return name;
},
};
}

Expand Down
84 changes: 62 additions & 22 deletions src/sort/FileListSort.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import SortMode from "./SortMode.mjs";
* @returns {FileListSort}
*/
function nextSort(sort, nextMode) {
/** @returns {boolean} */
/**
* @returns {boolean}
*/
function nextAsc() {
if (sort.mode === nextMode) {
return !sort.asc;
Expand All @@ -37,32 +39,46 @@ function nextSort(sort, nextMode) {
}

/**
* @param {string} s1
* @param {string} s2
* @typedef {{
* idx: number,
* name: string,
* nameNormalized: string,
* ext: string,
* extNormalized: string,
* size: number,
* atimeMs: number,
* mtimeMs: number,
* ctimeMs: number,
* }} SortableItem
*/

/**
* @param {string} a
* @param {string} b
* @returns {number}
*/
function strCompare(s1, s2) {
return s1 === s2 ? 0 : s1 < s2 ? -1 : 1;
function strCompare(a, b) {
return a === b ? 0 : a < b ? -1 : 1;
}

/**
* @param {FileListItem} i1
* @param {FileListItem} i2
* @param {SortableItem} a
* @param {SortableItem} b
* @returns {number}
*/
function sortByName(i1, i2) {
const res = strCompare(i1.nameNormalized(), i2.nameNormalized());
return res === 0 ? strCompare(i1.name, i2.name) : res;
function sortByName(a, b) {
const res = strCompare(a.nameNormalized, b.nameNormalized);
return res === 0 ? strCompare(a.name, b.name) : res;
}

/**
* @param {FileListItem} i1
* @param {FileListItem} i2
* @param {SortableItem} a
* @param {SortableItem} b
* @returns {number}
*/
function sortByExt(i1, i2) {
const res = strCompare(i1.extNormalized(), i2.extNormalized());
return res === 0 ? strCompare(i1.ext(), i2.ext()) : res;
function sortByExt(a, b) {
const res = strCompare(a.extNormalized, b.extNormalized);
return res === 0 ? strCompare(a.ext, b.ext) : res;
}

/**
Expand All @@ -71,34 +87,58 @@ function sortByExt(i1, i2) {
* @returns {FileListItem[]}
*/
function sortItems(items, mode) {
const newItems = [...items];
/**
* @param {(a: SortableItem, b: SortableItem) => number} compareFn
* @returns {FileListItem[]}
*/
function doSort(compareFn) {
const sortableItems = items.map((item, idx) => {
const extIndex = item.name.lastIndexOf(".");
const ext = item.name.substring(extIndex + 1);

return {
idx,
name: item.name,
nameNormalized: item.name.toLowerCase(),
ext,
extNormalized: ext.toLowerCase(),
size: item.size,
atimeMs: item.atimeMs,
mtimeMs: item.mtimeMs,
ctimeMs: item.ctimeMs,
};
});

return sortableItems.sort(compareFn).map((item) => items[item.idx]);
}

switch (mode) {
case SortMode.Name:
return newItems.sort(sortByName);
return doSort(sortByName);
case SortMode.Extension:
return newItems.sort((i1, i2) => {
return doSort((i1, i2) => {
const res = sortByExt(i1, i2);
return res === 0 ? sortByName(i1, i2) : res;
});
case SortMode.ModificationTime:
return newItems.sort((i1, i2) => {
return doSort((i1, i2) => {
const res = i1.mtimeMs - i2.mtimeMs;
return res === 0 ? sortByName(i1, i2) : res;
});
case SortMode.Size:
return newItems.sort((i1, i2) => {
return doSort((i1, i2) => {
const res = i1.size - i2.size;
return res === 0 ? sortByName(i1, i2) : res;
});
case SortMode.Unsorted:
return items;
case SortMode.CreationTime:
return newItems.sort((i1, i2) => {
return doSort((i1, i2) => {
const res = i1.ctimeMs - i2.ctimeMs;
return res === 0 ? sortByName(i1, i2) : res;
});
case SortMode.AccessTime:
return newItems.sort((i1, i2) => {
return doSort((i1, i2) => {
const res = i1.atimeMs - i2.atimeMs;
return res === 0 ? sortByName(i1, i2) : res;
});
Expand Down
86 changes: 5 additions & 81 deletions test/api/FileListItem.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ describe("FileListItem.test.mjs", () => {

//then
assert.deepEqual(result, {
...defaultItem(result),
...defaultItem(),
name: "test.file",
isDir: false,
});
Expand All @@ -32,7 +32,7 @@ describe("FileListItem.test.mjs", () => {

//then
assert.deepEqual(result, {
...defaultItem(result),
...defaultItem(),
name: "dir",
isDir: true,
});
Expand All @@ -44,7 +44,7 @@ describe("FileListItem.test.mjs", () => {

//then
assert.deepEqual(result, {
...defaultItem(result),
...defaultItem(),
name: "..",
isDir: true,
});
Expand All @@ -56,89 +56,17 @@ describe("FileListItem.test.mjs", () => {

//then
assert.deepEqual(result, {
...defaultItem(result),
...defaultItem(),
name: ".",
isDir: true,
});
});

it("should return normalized name when item.nameNormalized()", () => {
//given
const item = FileListItem("TEst");

//when
const result = item.nameNormalized();

//then
assert.deepEqual(result, "test");

//when & then
assert.deepEqual(item.nameNormalized() === result, true);
assert.deepEqual(FileListItem("").nameNormalized(), "");
assert.deepEqual(FileListItem("test").nameNormalized(), "test");
assert.deepEqual(FileListItem("A").nameNormalized(), "a");
assert.deepEqual(FileListItem("aB").nameNormalized(), "ab");
assert.deepEqual(FileListItem.up.nameNormalized(), "..");
assert.deepEqual(FileListItem.currDir.nameNormalized(), ".");
});

it("should return file extension when item.ext()", () => {
//given
const item = FileListItem("Test.txt");

//when
const result = item.ext();

//then
assert.deepEqual(result, "txt");

//when & then
assert.deepEqual(item.ext() === result, true);
assert.deepEqual(FileListItem("").ext(), "");
assert.deepEqual(FileListItem(".").ext(), "");
assert.deepEqual(FileListItem("test.").ext(), "");
assert.deepEqual(FileListItem("test").ext(), "test");
assert.deepEqual(FileListItem(".Test2").ext(), "Test2");
assert.deepEqual(FileListItem("A").ext(), "A");
assert.deepEqual(FileListItem("aB").ext(), "aB");
});

it("should return normalized extension when item.extNormalized()", () => {
//given
const item = FileListItem("Test.TXT");

//when
const result = item.extNormalized();

//then
assert.deepEqual(result, "txt");

//when & then
assert.deepEqual(item.extNormalized() === result, true);
assert.deepEqual(FileListItem("").extNormalized(), "");
assert.deepEqual(FileListItem(".").extNormalized(), "");
assert.deepEqual(FileListItem("Test.").extNormalized(), "");
assert.deepEqual(FileListItem("Test").extNormalized(), "test");
assert.deepEqual(FileListItem(".Test2").extNormalized(), "test2");
assert.deepEqual(FileListItem("A").extNormalized(), "a");
assert.deepEqual(FileListItem("aB").extNormalized(), "ab");
});

it("should return name when item.toString()", () => {
//given
const item = FileListItem("Test.file");

//when & then
assert.deepEqual(item.toString(), "Test.file");
assert.deepEqual(`${item}`, "Test.file");
});
});

/**
* @param {FileListItem} result
* @returns {FileListItem}
*/
function defaultItem(result) {
function defaultItem() {
return {
name: "",
isDir: false,
Expand All @@ -149,9 +77,5 @@ function defaultItem(result) {
ctimeMs: 0,
birthtimeMs: 0,
permissions: "",
nameNormalized: result.nameNormalized,
ext: result.ext,
extNormalized: result.extNormalized,
toString: result.toString,
};
}
5 changes: 0 additions & 5 deletions test/sort/FileListSort.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,6 @@ describe("FileListSort.test.mjs", () => {
const items = [item0, item1, item2, item3, item4];
const itemsR = [...items].reverse();

assert.deepEqual(item1.name , "Item.bin");
assert.deepEqual(item1.nameNormalized() , "item.bin");
assert.deepEqual(item2.ext() , "BIN");
assert.deepEqual(item2.extNormalized() , "bin");

/**
* @param {FileListItem[]} items
* @param {SortMode} mode
Expand Down

0 comments on commit 4e84e12

Please sign in to comment.