1local compl = require("awful.completion") 2local shell = function(...) 3 local command, pos, matches = compl.shell(...) 4 return {command, pos, matches} 5end 6local gfs = require("gears.filesystem") 7local Gio = require("lgi").Gio 8local GLib = require("lgi").GLib 9local lfs = require("lfs") 10 11local has_bash = GLib.find_program_in_path("bash") 12local has_zsh = GLib.find_program_in_path("zsh") 13 14if not has_bash and not has_zsh then 15 print('Skipping spec/awful/completion_spec.lua: bash and zsh are not installed.') 16 return 17end 18 19local orig_path_env = GLib.getenv("PATH") 20local required_commands = {"bash", "zsh", "sort"} 21 22-- Change PATH 23local function get_test_path_dir() 24 local test_path = Gio.File.new_tmp("awesome-tests-path-XXXXXX") 25 test_path:delete() 26 test_path:make_directory() 27 28 for _, cmd in ipairs(required_commands) do 29 local target = GLib.find_program_in_path(cmd) 30 if target then 31 test_path:get_child(cmd):make_symbolic_link(target) 32 end 33 end 34 35 test_path = test_path:get_path() 36 GLib.setenv("PATH", test_path, true) 37 return test_path 38end 39 40-- Reset PATH 41local function remove_test_path_dir(test_path) 42 GLib.setenv("PATH", orig_path_env, true) 43 for _, cmd in ipairs(required_commands) do 44 os.remove(test_path .. "/" .. cmd) 45 end 46 os.remove(test_path) 47end 48 49local test_dir 50local test_path 51 52--- Get and create a temporary test dir based on `pat`, where %d gets replaced by 53-- the current PID. 54local function get_test_dir() 55 local tfile = Gio.File.new_tmp("awesome-tests-XXXXXX") 56 local path = tfile:get_path() 57 tfile:delete() 58 gfs.make_directories(path) 59 return path 60end 61 62describe("awful.completion.shell in empty directory", function() 63 local orig_dir = lfs.currentdir() 64 65 setup(function() 66 test_dir = get_test_dir() 67 lfs.chdir(test_dir) 68 test_path = get_test_path_dir() 69 end) 70 71 teardown(function() 72 assert.True(os.remove(test_dir)) 73 remove_test_path_dir(test_path) 74 lfs.chdir(orig_dir) 75 end) 76 77 if has_bash then 78 it("handles completion of true (bash)", function() 79 assert.same(shell('true', 5, 1, 'bash'), {'true', 5, {'true'}}) 80 end) 81 end 82 if has_zsh then 83 it("handles completion of true (zsh)", function() 84 assert.same(shell('true', 5, 1, 'zsh'), {'true', 5, {'true'}}) 85 end) 86 end 87 it("handles completion of true (nil)", function() 88 assert.same(shell('true', 5, 1, nil), {'true', 5, {'true'}}) 89 end) 90end) 91 92describe("awful.completion.shell", function() 93 local orig_dir = lfs.currentdir() 94 95 setup(function() 96 test_dir = get_test_dir() 97 gfs.make_directories(test_dir .. '/true') 98 Gio.File.new_for_path(test_dir .. '/true/with_file'):create(Gio.FileCreateFlags.NONE); 99 gfs.make_directories(test_dir .. '/just_a_directory') 100 Gio.File.new_for_path(test_dir .. '/just_a_directory/with_file'):create(Gio.FileCreateFlags.NONE); 101 -- Chaotic order is intended! 102 gfs.make_directories(test_dir .. '/ambiguous_dir_a') 103 gfs.make_directories(test_dir .. '/ambiguous_dir_e') 104 Gio.File.new_for_path(test_dir .. '/ambiguous_dir_e/with_file'):create(Gio.FileCreateFlags.NONE); 105 gfs.make_directories(test_dir .. '/ambiguous_dir_c') 106 Gio.File.new_for_path(test_dir .. '/ambiguous_dir_c/with_file'):create(Gio.FileCreateFlags.NONE); 107 gfs.make_directories(test_dir .. '/ambiguous_dir_d') 108 gfs.make_directories(test_dir .. '/ambiguous_dir_b') 109 gfs.make_directories(test_dir .. '/ambiguous_dir_f') 110 os.execute(string.format( 111 'cd %s && touch localcommand && chmod +x localcommand', test_dir)) 112 lfs.chdir(test_dir) 113 test_path = get_test_path_dir() 114 end) 115 116 teardown(function() 117 assert.True(os.remove(test_dir .. '/ambiguous_dir_a')) 118 assert.True(os.remove(test_dir .. '/ambiguous_dir_b')) 119 assert.True(os.remove(test_dir .. '/ambiguous_dir_c/with_file')) 120 assert.True(os.remove(test_dir .. '/ambiguous_dir_c')) 121 assert.True(os.remove(test_dir .. '/ambiguous_dir_d')) 122 assert.True(os.remove(test_dir .. '/ambiguous_dir_e/with_file')) 123 assert.True(os.remove(test_dir .. '/ambiguous_dir_e')) 124 assert.True(os.remove(test_dir .. '/ambiguous_dir_f')) 125 assert.True(os.remove(test_dir .. '/just_a_directory/with_file')) 126 assert.True(os.remove(test_dir .. '/just_a_directory')) 127 assert.True(os.remove(test_dir .. '/localcommand')) 128 assert.True(os.remove(test_dir .. '/true/with_file')) 129 assert.True(os.remove(test_dir .. '/true')) 130 assert.True(os.remove(test_dir)) 131 remove_test_path_dir(test_path) 132 lfs.chdir(orig_dir) 133 end) 134 135 if has_bash then 136 it("handles empty input (bash)", function() 137 assert.same(shell('', 1, 1, 'bash'), {'', 1}) 138 end) 139 end 140 if has_zsh then 141 it("handles empty input (zsh)", function() 142 assert.same(shell('', 1, 1, 'zsh'), {'', 1}) 143 end) 144 end 145 it("handles empty input (nil)", function() 146 assert.same(shell('', 1, 1, nil), {'', 1}) 147 end) 148 149 if has_bash then 150 it("completes local command (bash)", function() 151 assert.same(shell('./localcomm', 12, 1, 'bash'), {'./localcommand', 15, {'./localcommand'}}) 152 end) 153 end 154 if has_zsh then 155 it("completes local command (zsh)", function() 156 assert.same(shell('./localcomm', 12, 1, 'zsh'), {'./localcommand', 15, {'./localcommand'}}) 157 end) 158 end 159 160 if has_bash then 161 it("completes local file (bash)", function() 162 assert.same(shell('ls l', 5, 1, 'bash'), {'ls localcommand', 16, {'localcommand'}}) 163 end) 164 end 165 if has_zsh then 166 it("completes local file (zsh)", function() 167 assert.same(shell('ls l', 5, 1, 'zsh'), {'ls localcommand', 16, {'localcommand'}}) 168 end) 169 end 170 171 if has_bash then 172 it("completes command regardless of local directory (bash)", function() 173 assert.same(shell('true', 5, 1, 'bash'), {'true', 5, {'true'}}) 174 end) 175 end 176 if has_zsh then 177 it("completes command regardless of local directory (zsh)", function() 178 assert.same(shell('true', 5, 1, 'zsh'), {'true', 5, {'true'}}) 179 end) 180 end 181 it("completes command regardless of local directory (nil)", function() 182 assert.same(shell('true', 5, 1, nil), {'true', 5, {'true'}}) 183 end) 184 185 if has_bash then 186 it("does not complete local directory not starting with ./ (bash)", function() 187 assert.same(shell('just_a', 7, 1, 'bash'), {'just_a', 7}) 188 end) 189 end 190 if has_zsh then 191 it("does not complete local directory not starting with ./ (zsh)", function() 192 assert.same(shell('just_a', 7, 1, 'zsh'), {'just_a', 7}) 193 end) 194 end 195 196 if has_bash then 197 it("completes local directories starting with ./ (bash)", function() 198 assert.same(shell('./just', 7, 1, 'bash'), {'./just_a_directory/', 20, {'./just_a_directory/'}}) 199 assert.same(shell('./t', 4, 1, 'bash'), {'./true/', 8, {'./true/'}}) 200 end) 201 end 202 if has_zsh then 203 it("completes local directories starting with ./ (zsh, non-empty)", function() 204 assert.same(shell('./just', 7, 1, 'zsh'), {'./just_a_directory/', 20, {'./just_a_directory/'}}) 205 assert.same(shell('./t', 4, 1, 'zsh'), {'./true/', 8, {'./true/'}}) 206 end) 207 end 208 --]] 209 210 if has_bash then 211 it("correctly sorts completed items (bash)", function() 212 assert.same(shell('./ambi', 7, 1, 'bash'), {'./ambiguous_dir_a/', 19, 213 {'./ambiguous_dir_a/', './ambiguous_dir_b/', './ambiguous_dir_c/', 214 './ambiguous_dir_d/', './ambiguous_dir_e/', './ambiguous_dir_f/'}}) 215 end) 216 end 217 if has_zsh then 218 it("correctly sorts completed items (zsh)", function() 219 assert.same(shell('./ambi', 7, 1, 'zsh'), {'./ambiguous_dir_c/', 19, 220 {'./ambiguous_dir_c/', './ambiguous_dir_e/'}}) 221 end) 222 end 223end) 224 225describe("awful.completion.shell handles $SHELL", function() 226 local orig_getenv = os.getenv 227 local gdebug = require("gears.debug") 228 local orig_print_warning 229 local print_warning_message 230 local os_getenv_shell 231 232 setup(function() 233 os.getenv = function(name) -- luacheck: ignore 234 if name == 'SHELL' then return os_getenv_shell end 235 return orig_getenv(name) 236 end 237 238 orig_print_warning = gdebug.print_warning 239 gdebug.print_warning = function(message) 240 print_warning_message = message 241 end 242 243 test_path = get_test_path_dir() 244 end) 245 246 teardown(function() 247 os.getenv = orig_getenv --luacheck: ignore 248 gdebug.print_warning = orig_print_warning 249 remove_test_path_dir(test_path) 250 end) 251 252 before_each(function() 253 compl.default_shell = nil 254 print_warning_message = nil 255 end) 256 257 it("falls back to bash if unset", function() 258 assert.same(shell('true', 5, 1, nil), {'true', 5, {'true'}}) 259 assert.same(print_warning_message, 260 'SHELL not set in environment, falling back to bash.') 261 assert.same(compl.default_shell, "bash") 262 end) 263 264 it("uses zsh from path", function() 265 os_getenv_shell = '/opt/bin/zsh' 266 assert.same(shell('true', 5, 1, nil), {'true', 5, {'true'}}) 267 assert.same(compl.default_shell, "zsh") 268 assert.is_nil(print_warning_message) 269 end) 270 271 it("uses bash for unknown", function() 272 os_getenv_shell = '/dev/null' 273 assert.same(shell('true', 5, 1, nil), {'true', 5, {'true'}}) 274 assert.same(compl.default_shell, "bash") 275 assert.is_nil(print_warning_message) 276 end) 277end) 278 279-- vim: ft=lua:et:sw=4:ts=8:sts=4:tw=80 280