forked from stevearc/oil.nvim
-
Notifications
You must be signed in to change notification settings - Fork 0
/
tmpdir.lua
168 lines (153 loc) · 4.09 KB
/
tmpdir.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
local fs = require("oil.fs")
local test_util = require("tests.test_util")
local await = test_util.await
---@param path string
---@param cb fun(err: nil|string)
local function touch(path, cb)
vim.loop.fs_open(path, "w", 420, function(err, fd) -- 0644
if err then
cb(err)
else
local shortpath = path:gsub("^[^" .. fs.sep .. "]*" .. fs.sep, "")
vim.loop.fs_write(fd, shortpath, nil, function(err2)
if err2 then
cb(err2)
else
vim.loop.fs_close(fd, cb)
end
end)
end
end)
end
---@param filepath string
---@return boolean
local function exists(filepath)
local stat = vim.loop.fs_stat(filepath)
return stat ~= nil and stat.type ~= nil
end
local TmpDir = {}
TmpDir.new = function()
local path = await(vim.loop.fs_mkdtemp, 2, "oil_test_XXXXXXXXX")
a.util.scheduler()
return setmetatable({ path = path }, {
__index = TmpDir,
})
end
---@param paths string[]
function TmpDir:create(paths)
for _, path in ipairs(paths) do
local pieces = vim.split(path, fs.sep)
local partial_path = self.path
for i, piece in ipairs(pieces) do
partial_path = fs.join(partial_path, piece)
if i == #pieces and not vim.endswith(partial_path, fs.sep) then
await(touch, 2, partial_path)
elseif not exists(partial_path) then
vim.loop.fs_mkdir(partial_path, 493)
end
end
end
a.util.scheduler()
end
---@param filepath string
---@return string?
local read_file = function(filepath)
local fd = vim.loop.fs_open(filepath, "r", 420)
if not fd then
return nil
end
local stat = vim.loop.fs_fstat(fd)
local content = vim.loop.fs_read(fd, stat.size)
vim.loop.fs_close(fd)
a.util.scheduler()
return content
end
---@param dir string
---@param cb fun(err: nil|string, entry: {type: oil.EntryType, name: string, root: string}
local function walk(dir)
local ret = {}
for name, type in vim.fs.dir(dir) do
table.insert(ret, {
name = name,
type = type,
root = dir,
})
if type == "directory" then
vim.list_extend(ret, walk(fs.join(dir, name)))
end
end
return ret
end
---@param paths table<string, string>
local assert_fs = function(root, paths)
local unlisted_dirs = {}
for k in pairs(paths) do
local pieces = vim.split(k, "/")
local partial_path = ""
for i, piece in ipairs(pieces) do
partial_path = partial_path .. piece .. "/"
if i ~= #pieces then
unlisted_dirs[partial_path] = true
end
end
end
for k in pairs(unlisted_dirs) do
paths[k] = true
end
local entries = walk(root)
for _, entry in ipairs(entries) do
local fullpath = fs.join(entry.root, entry.name)
local shortpath = fullpath:sub(root:len() + 2)
if entry.type == "directory" then
shortpath = shortpath .. "/"
end
local expected_content = paths[shortpath]
paths[shortpath] = nil
assert.truthy(expected_content, string.format("Unexpected entry '%s'", shortpath))
if entry.type == "file" then
local data = read_file(fullpath)
assert.equals(
expected_content,
data,
string.format(
"File '%s' expected content '%s' received '%s'",
shortpath,
expected_content,
data
)
)
end
end
for k, v in pairs(paths) do
assert.falsy(
k,
string.format(
"Expected %s '%s', but it was not found",
v == true and "directory" or "file",
k
)
)
end
end
---@param paths table<string, string>
function TmpDir:assert_fs(paths)
a.util.scheduler()
assert_fs(self.path, paths)
end
function TmpDir:assert_exists(path)
a.util.scheduler()
path = fs.join(self.path, path)
local stat = vim.loop.fs_stat(path)
assert.truthy(stat, string.format("Expected path '%s' to exist", path))
end
function TmpDir:assert_not_exists(path)
a.util.scheduler()
path = fs.join(self.path, path)
local stat = vim.loop.fs_stat(path)
assert.falsy(stat, string.format("Expected path '%s' to not exist", path))
end
function TmpDir:dispose()
await(fs.recursive_delete, 3, "directory", self.path)
a.util.scheduler()
end
return TmpDir