From 8ea961ff93c1d5479656779f7085bb6eaffd20f7 Mon Sep 17 00:00:00 2001 From: The Magician Date: Sat, 18 Nov 2023 17:12:57 +0000 Subject: [PATCH] Add ls method to prevfile --- spec/prevfile_spec.lua | 74 +++++++++++++++++++++++++++++++++++++++--- src/prevfile.lua | 29 +++++++++++++++-- 2 files changed, 96 insertions(+), 7 deletions(-) diff --git a/spec/prevfile_spec.lua b/spec/prevfile_spec.lua index d1ffb67..eb19d4c 100644 --- a/spec/prevfile_spec.lua +++ b/spec/prevfile_spec.lua @@ -1,9 +1,75 @@ -describe("prevfile", function() +function get_directory_iterator_from_table(table) + return function(directory) + local index = 0 + local filenames = table + + return function() + index = index + 1 + return filenames[index] + end + end +end + +describe("ls", function() + local lfs = require "lfs" local prevfile = require "prevfile" - it("returns nil when target directory is empty", function() - previous = prevfile.prevfile("dummy/") + insulate("if directory does not exist", function() + lfs.dir = function(directory) error("No such file or directory") end - assert.are.equals(nil, previous) + it("should return nil", function() + local files = prevfile.ls("/testdir") + + assert.equals(nil, files) + end) + end) + + insulate("if directory is empty", function() + lfs.dir = get_directory_iterator_from_table({}) + + it("should return empty table", function() + local files = prevfile.ls("/testdir") + + assert.are.same({}, files) + end) + + it("should call lfs.dir with target directory", function() + spy.on(lfs, "dir") + local test_directory = "/testdir" + + prevfile.ls(test_directory) + + assert.stub(lfs.dir).was_called_with(test_directory) + end) + end) + + insulate("if directory contains files", function() + lfs.dir = get_directory_iterator_from_table({"a.txt", "b.txt", "z.txt", "c.txt"}) + + it("should return the files in lexographical order", function() + local files = prevfile.ls("/testdir") + + assert.are.same({"a.txt", "b.txt", "c.txt", "z.txt"}, files) + end) + end) + + insulate("if directory contains numerically-named files", function() + lfs.dir = get_directory_iterator_from_table({"/testdir/709.txt", "/testdir/71.txt", "/testdir/710.txt"}) + + it("should return the files in numerical order", function() + local files = prevfile.ls("/testdir") + + assert.are.same({"/testdir/71.txt", "/testdir/709.txt", "/testdir/710.txt"}, files) + end) + end) + + insulate("if directory contains hidden files", function() + lfs.dir = get_directory_iterator_from_table({"a.txt", ".b.txt.swp", "c.txt"}) + + it("should exclude them from the listing", function() + local files = prevfile.ls("/testdir") + + assert.are.same({"a.txt", "c.txt"}, files) + end) end) end) diff --git a/src/prevfile.lua b/src/prevfile.lua index 367c5f8..81ae92a 100644 --- a/src/prevfile.lua +++ b/src/prevfile.lua @@ -1,7 +1,30 @@ -local prevfile = {} +local lfs = require "lfs" -function prevfile.prevfile(target_directory) - return nil +local prevfile = {} + +local function padnum(d) + local dec, n = string.match(d, "(%.?)0*(.+)") + return #dec > 0 and ("%.12f"):format(d) or ("%s%03d%s"):format(dec, #n, n) +end + +local function humansort(a, b) + return tostring(a):gsub("%.?%d+", padnum) < tostring(b):gsub("%.?%d+", padnum) + end + +function prevfile.ls(directory) + if not pcall(lfs.dir, directory) then + return nil + end + + local files = {} + for file in lfs.dir(directory) do + if string.sub(file, 1, 1) ~= "." then + table.insert(files, file) + end + end + + table.sort(files, humansort) + return files end return prevfile