CC-Tweaked/projects/core/src/test/resources/test-rom/spec/apis/fs_spec.lua

308 lines
12 KiB
Lua

describe("The fs library", function()
local test_root = "/test-files/fs"
local function test_file(path) return fs.combine(test_root, path) end
before_each(function() fs.delete(test_root) end)
describe("fs.complete", function()
it("validates arguments", function()
fs.complete("", "")
fs.complete("", "", true)
fs.complete("", "", nil, true)
expect.error(fs.complete, nil):eq("bad argument #1 (expected string, got nil)")
expect.error(fs.complete, "", nil):eq("bad argument #2 (expected string, got nil)")
expect.error(fs.complete, "", "", 1):eq("bad argument #3 (expected boolean, got number)")
expect.error(fs.complete, "", "", true, 1):eq("bad argument #4 (expected boolean, got number)")
end)
describe("include_hidden", function()
local dir = "tmp/hidden"
local function setup_tree()
fs.delete(dir)
fs.makeDir(dir)
fs.open(dir .. "/file.txt", "w").close()
fs.open(dir .. "/.hidden.txt", "w").close()
end
it("hides hidden files", function()
setup_tree()
local opts = { include_files = true, include_dirs = false, include_hidden = false }
expect(fs.complete("", dir, opts)):same { "../", "file.txt" }
expect(fs.complete(dir .. "/", "", opts)):same { "file.txt" }
end)
it("shows hidden files when typing a dot", function()
setup_tree()
local opts = { include_files = true, include_dirs = false, include_hidden = false }
expect(fs.complete(".", dir, opts)):same { "./", "hidden.txt" }
expect(fs.complete(dir .. "/.", "", opts)):same { "hidden.txt" }
-- Also test
expect(fs.complete(dir .. "/file", "", opts)):same { ".txt" }
expect(fs.complete(dir .. "/file.", "", opts)):same { "txt" }
expect(fs.complete("file", dir, opts)):same { ".txt" }
expect(fs.complete("file.", dir, opts)):same { "txt" }
end)
it("shows hidden files when include_hidden is true", function()
setup_tree()
local opts = { include_files = true, include_dirs = false, include_hidden = true }
expect(fs.complete("", dir, opts)):same { "../", ".hidden.txt", "file.txt" }
expect(fs.complete(dir .. "/", "", opts)):same { ".hidden.txt", "file.txt" }
end)
end)
end)
describe("fs.isDriveRoot", function()
it("validates arguments", function()
fs.isDriveRoot("")
expect.error(fs.isDriveRoot, nil):eq("bad argument #1 (expected string, got nil)")
end)
it("correctly identifies drive roots", function()
expect(fs.isDriveRoot("/rom")):eq(true)
expect(fs.isDriveRoot("/")):eq(true)
expect(fs.isDriveRoot("/rom/startup.lua")):eq(false)
expect(fs.isDriveRoot("/rom/programs/delete.lua")):eq(false)
end)
end)
describe("fs.list", function()
it("fails on files", function()
expect.error(fs.list, "rom/startup.lua"):eq("/rom/startup.lua: Not a directory")
expect.error(fs.list, "startup.lua"):eq("/startup.lua: Not a directory")
end)
it("fails on non-existent nodes", function()
expect.error(fs.list, "rom/x"):eq("/rom/x: Not a directory")
expect.error(fs.list, "x"):eq("/x: Not a directory")
end)
end)
describe("fs.combine", function()
it("removes . and ..", function()
expect(fs.combine("./a/b")):eq("a/b")
expect(fs.combine("a/b", "../c")):eq("a/c")
expect(fs.combine("a", "../c")):eq("c")
expect(fs.combine("a", "../../c")):eq("../c")
end)
it("combines empty paths", function()
expect(fs.combine("a")):eq("a")
expect(fs.combine("a", "")):eq("a")
expect(fs.combine("", "a")):eq("a")
expect(fs.combine("a", "", "b", "c")):eq("a/b/c")
end)
end)
describe("fs.getSize", function()
it("fails on non-existent nodes", function()
expect.error(fs.getSize, "rom/x"):eq("/rom/x: No such file")
expect.error(fs.getSize, "x"):eq("/x: No such file")
end)
end)
describe("fs.open", function()
describe("reading", function()
it("fails on directories", function()
expect { fs.open("rom", "r") }:same { nil, "/rom: No such file" }
expect { fs.open("", "r") }:same { nil, "/: No such file" }
end)
it("fails on non-existent nodes", function()
expect { fs.open("rom/x", "r") }:same { nil, "/rom/x: No such file" }
expect { fs.open("x", "r") }:same { nil, "/x: No such file" }
end)
it("errors when closing twice", function()
local handle = fs.open("rom/startup.lua", "r")
handle.close()
expect.error(handle.close):eq("attempt to use a closed file")
end)
end)
describe("reading in binary mode", function()
it("errors when closing twice", function()
local handle = fs.open("rom/startup.lua", "rb")
handle.close()
expect.error(handle.close):eq("attempt to use a closed file")
end)
end)
describe("writing", function()
it("fails on directories", function()
expect { fs.open("", "w") }:same { nil, "/: Cannot write to directory" }
end)
it("fails on read-only mounts", function()
expect { fs.open("rom/x", "w") }:same { nil, "/rom/x: Access denied" }
end)
it("errors when closing twice", function()
local handle = fs.open(test_file "out.txt", "w")
handle.close()
expect.error(handle.close):eq("attempt to use a closed file")
end)
it("fails gracefully when opening 'CON' on Windows", function()
local ok, err = fs.open("test-files/con", "w")
if ok then fs.delete("test-files/con") return end
-- On my Windows/Java version the message appears to be "Incorrect function.". It may not be
-- consistent though, and honestly doesn't matter too much.
expect(err):str_match("^/test%-files/con: .*")
end)
end)
describe("writing in binary mode", function()
it("errors when closing twice", function()
local handle = fs.open("test-files/out.txt", "wb")
handle.close()
expect.error(handle.close):eq("attempt to use a closed file")
end)
end)
describe("appending", function()
it("fails on directories", function()
expect { fs.open("", "a") }:same { nil, "/: Cannot write to directory" }
end)
it("fails on read-only mounts", function()
expect { fs.open("rom/x", "a") }:same { nil, "/rom/x: Access denied" }
end)
end)
end)
describe("fs.makeDir", function()
it("fails on files", function()
expect.error(fs.makeDir, "startup.lua"):eq("/startup.lua: File exists")
end)
it("fails on read-only mounts", function()
expect.error(fs.makeDir, "rom/x"):eq("/rom/x: Access denied")
end)
end)
describe("fs.delete", function()
it("fails on read-only mounts", function()
expect.error(fs.delete, "rom/x"):eq("/rom/x: Access denied")
end)
end)
describe("fs.copy", function()
it("fails on read-only mounts", function()
expect.error(fs.copy, "rom", "rom/startup"):eq("/rom/startup: Access denied")
end)
it("fails to copy a folder inside itself", function()
fs.makeDir("some-folder")
expect.error(fs.copy, "some-folder", "some-folder/x"):eq("/some-folder: Can't copy a directory inside itself")
expect.error(fs.copy, "some-folder", "Some-Folder/x"):eq("/some-folder: Can't copy a directory inside itself")
end)
it("copies folders", function()
fs.delete("some-folder")
fs.delete("another-folder")
fs.makeDir("some-folder")
fs.copy("some-folder", "another-folder")
expect(fs.isDir("another-folder")):eq(true)
end)
end)
describe("fs.move", function()
it("fails on read-only mounts", function()
expect.error(fs.move, "rom", "rom/move"):eq("Access denied")
expect.error(fs.move, "test-files", "rom/move"):eq("Access denied")
expect.error(fs.move, "rom", "test-files"):eq("Access denied")
end)
it("fails if source does not exist", function()
expect.error(fs.move, test_file "src", test_file "dest"):eq("No such file")
end)
it("fails if destination exists", function()
fs.open(test_file "src", "w").close()
fs.open(test_file "dest", "w").close()
expect.error(fs.move, test_file "src", test_file "dest"):eq("File exists")
end)
it("fails to move a directory inside itself", function()
fs.open(test_file "file", "w").close()
expect.error(fs.move, test_root, test_file "child"):eq("Can't move a directory inside itself")
expect.error(fs.move, "", "child"):eq("Can't move a directory inside itself")
end)
it("files can be renamed", function()
fs.open(test_file "src", "w").close()
fs.move(test_file "src", test_file" dest")
expect(fs.exists(test_file "src")):eq(false)
expect(fs.exists(test_file "dest")):eq(true)
end)
it("directories can be renamed", function()
fs.open(test_file "src/some/file", "w").close()
fs.move(test_file "src", test_file" dest")
expect(fs.exists(test_file "src")):eq(false)
expect(fs.exists(test_file "dest")):eq(true)
expect(fs.exists(test_file "dest/some/file")):eq(true)
end)
it("creates directories before renaming", function()
fs.open(test_file "src", "w").close()
fs.move(test_file "src", test_file "dest/file")
expect(fs.exists(test_file "src")):eq(false)
expect(fs.exists(test_file "dest/file")):eq(true)
end)
end)
describe("fs.getCapacity", function()
it("returns nil on read-only mounts", function()
expect(fs.getCapacity("rom")):eq(nil)
end)
it("returns the capacity on the root mount", function()
expect(fs.getCapacity("")):eq(10000000)
end)
end)
describe("fs.attributes", function()
it("errors on non-existent files", function()
expect.error(fs.attributes, "xuxu_nao_existe"):eq("/xuxu_nao_existe: No such file")
end)
it("returns information about read-only mounts", function()
expect(fs.attributes("rom")):matches { isDir = true, size = 0, isReadOnly = true }
end)
it("returns information about files", function()
local now = os.epoch("utc")
local h = fs.open(test_file "basic-file", "w")
h.write("A reasonably sized string")
h.close()
local attributes = fs.attributes(test_file "basic-file")
expect(attributes):matches { isDir = false, size = 25, isReadOnly = false }
if attributes.created - now >= 1000 then
fail(("Expected created time (%d) to be within 1000ms of now (%d"):format(attributes.created, now))
end
if attributes.modified - now >= 1000 then
fail(("Expected modified time (%d) to be within 1000ms of now (%d"):format(attributes.modified, now))
end
expect(attributes.modification):eq(attributes.modified)
end)
end)
end)