uri_spec.lua (8409B)
1 local t = require('test.testutil') 2 local n = require('test.functional.testnvim')() 3 4 local clear = n.clear 5 local exec_lua = n.exec_lua 6 local eq = t.eq 7 local is_os = t.is_os 8 local skip = t.skip 9 local write_file = t.write_file 10 11 describe('URI methods', function() 12 before_each(function() 13 clear() 14 end) 15 16 describe('file path to uri', function() 17 describe('encode Unix file path', function() 18 it('file path includes only ascii characters', function() 19 exec_lua("filepath = '/Foo/Bar/Baz.txt'") 20 21 eq('file:///Foo/Bar/Baz.txt', exec_lua('return vim.uri_from_fname(filepath)')) 22 end) 23 24 it('file path including white space', function() 25 exec_lua("filepath = '/Foo /Bar/Baz.txt'") 26 27 eq('file:///Foo%20/Bar/Baz.txt', exec_lua('return vim.uri_from_fname(filepath)')) 28 end) 29 30 it('file path including Unicode characters', function() 31 exec_lua("filepath = '/xy/åäö/ɧ/汉语/↥/🤦/🦄/å/بِيَّ.txt'") 32 33 -- The URI encoding should be case-insensitive 34 eq( 35 'file:///xy/%c3%a5%c3%a4%c3%b6/%c9%a7/%e6%b1%89%e8%af%ad/%e2%86%a5/%f0%9f%a4%a6/%f0%9f%a6%84/a%cc%8a/%d8%a8%d9%90%d9%8a%d9%8e%d9%91.txt', 36 exec_lua('return vim.uri_from_fname(filepath)') 37 ) 38 end) 39 end) 40 41 describe('encode Windows filepath', function() 42 it('file path includes only ascii characters', function() 43 exec_lua([[filepath = 'C:\\Foo\\Bar\\Baz.txt']]) 44 45 eq('file:///C:/Foo/Bar/Baz.txt', exec_lua('return vim.uri_from_fname(filepath)')) 46 end) 47 48 it('file path including white space', function() 49 exec_lua([[filepath = 'C:\\Foo \\Bar\\Baz.txt']]) 50 51 eq('file:///C:/Foo%20/Bar/Baz.txt', exec_lua('return vim.uri_from_fname(filepath)')) 52 end) 53 54 it('file path including Unicode characters', function() 55 exec_lua([[filepath = 'C:\\xy\\åäö\\ɧ\\汉语\\↥\\🤦\\🦄\\å\\بِيَّ.txt']]) 56 57 eq( 58 'file:///C:/xy/%c3%a5%c3%a4%c3%b6/%c9%a7/%e6%b1%89%e8%af%ad/%e2%86%a5/%f0%9f%a4%a6/%f0%9f%a6%84/a%cc%8a/%d8%a8%d9%90%d9%8a%d9%8e%d9%91.txt', 59 exec_lua('return vim.uri_from_fname(filepath)') 60 ) 61 end) 62 end) 63 end) 64 65 describe('uri to filepath', function() 66 describe('decode Unix file path', function() 67 it('file path includes only ascii characters', function() 68 exec_lua("uri = 'file:///Foo/Bar/Baz.txt'") 69 70 eq('/Foo/Bar/Baz.txt', exec_lua('return vim.uri_to_fname(uri)')) 71 end) 72 73 it('local file path without hostname', function() 74 exec_lua("uri = 'file:/Foo/Bar/Baz.txt'") 75 76 eq('/Foo/Bar/Baz.txt', exec_lua('return vim.uri_to_fname(uri)')) 77 end) 78 79 it('file path including white space', function() 80 exec_lua("uri = 'file:///Foo%20/Bar/Baz.txt'") 81 82 eq('/Foo /Bar/Baz.txt', exec_lua('return vim.uri_to_fname(uri)')) 83 end) 84 85 it('file path including Unicode characters', function() 86 local test_case = [[ 87 local uri = 'file:///xy/%C3%A5%C3%A4%C3%B6/%C9%A7/%E6%B1%89%E8%AF%AD/%E2%86%A5/%F0%9F%A4%A6/%F0%9F%A6%84/a%CC%8A/%D8%A8%D9%90%D9%8A%D9%8E%D9%91.txt' 88 return vim.uri_to_fname(uri) 89 ]] 90 91 eq('/xy/åäö/ɧ/汉语/↥/🤦/🦄/å/بِيَّ.txt', exec_lua(test_case)) 92 end) 93 94 it('file path with uri fragment', function() 95 exec_lua("uri = 'file:///Foo/Bar/Baz.txt#fragment'") 96 97 eq('/Foo/Bar/Baz.txt', exec_lua('return vim.uri_to_fname(uri)')) 98 end) 99 end) 100 101 describe('decode Windows filepath', function() 102 it('file path includes only ascii characters', function() 103 local test_case = [[ 104 local uri = 'file:///C:/Foo/Bar/Baz.txt' 105 return vim.uri_to_fname(uri) 106 ]] 107 108 eq('C:\\Foo\\Bar\\Baz.txt', exec_lua(test_case)) 109 end) 110 111 it('local file path without hostname', function() 112 local test_case = [[ 113 local uri = 'file:/C:/Foo/Bar/Baz.txt' 114 return vim.uri_to_fname(uri) 115 ]] 116 117 eq('C:\\Foo\\Bar\\Baz.txt', exec_lua(test_case)) 118 end) 119 120 it('file path includes only ascii characters with encoded colon character', function() 121 local test_case = [[ 122 local uri = 'file:///C%3A/Foo/Bar/Baz.txt' 123 return vim.uri_to_fname(uri) 124 ]] 125 126 eq('C:\\Foo\\Bar\\Baz.txt', exec_lua(test_case)) 127 end) 128 129 it('file path including white space', function() 130 local test_case = [[ 131 local uri = 'file:///C:/Foo%20/Bar/Baz.txt' 132 return vim.uri_to_fname(uri) 133 ]] 134 135 eq('C:\\Foo \\Bar\\Baz.txt', exec_lua(test_case)) 136 end) 137 138 it('file path including Unicode characters', function() 139 local test_case = [[ 140 local uri = 'file:///C:/xy/%C3%A5%C3%A4%C3%B6/%C9%A7/%E6%B1%89%E8%AF%AD/%E2%86%A5/%F0%9F%A4%A6/%F0%9F%A6%84/a%CC%8A/%D8%A8%D9%90%D9%8A%D9%8E%D9%91.txt' 141 return vim.uri_to_fname(uri) 142 ]] 143 144 eq('C:\\xy\\åäö\\ɧ\\汉语\\↥\\🤦\\🦄\\å\\بِيَّ.txt', exec_lua(test_case)) 145 end) 146 end) 147 148 describe('decode non-file URI', function() 149 it('uri_to_fname returns non-file URI unchanged', function() 150 eq( 151 'jdt1.23+x-z://content/%5C/', 152 exec_lua [[ 153 return vim.uri_to_fname('jdt1.23+x-z://content/%5C/') 154 ]] 155 ) 156 end) 157 158 it('uri_to_fname returns non-file upper-case scheme URI unchanged', function() 159 eq( 160 'JDT://content/%5C/', 161 exec_lua [[ 162 return vim.uri_to_fname('JDT://content/%5C/') 163 ]] 164 ) 165 end) 166 167 it('uri_to_fname returns non-file scheme URI without authority unchanged', function() 168 eq( 169 'zipfile:///path/to/archive.zip%3A%3Afilename.txt', 170 exec_lua [[ 171 return vim.uri_to_fname('zipfile:///path/to/archive.zip%3A%3Afilename.txt') 172 ]] 173 ) 174 end) 175 end) 176 177 describe('decode URI without scheme', function() 178 it('fails because URI must have a scheme', function() 179 eq( 180 false, 181 exec_lua [[ 182 return pcall(vim.uri_to_fname, 'not_an_uri.txt') 183 ]] 184 ) 185 end) 186 187 it('uri_to_fname should not treat comma as a scheme character', function() 188 eq( 189 false, 190 exec_lua [[ 191 return pcall(vim.uri_to_fname, 'foo,://bar') 192 ]] 193 ) 194 end) 195 196 it('uri_to_fname returns non-file schema URI with fragment unchanged', function() 197 eq( 198 'scheme://path#fragment', 199 exec_lua [[ 200 return vim.uri_to_fname('scheme://path#fragment') 201 ]] 202 ) 203 end) 204 end) 205 end) 206 207 describe('uri from bufnr', function() 208 it('Windows paths should not be treated as uris', function() 209 skip(not is_os('win'), 'N/A on non-Windows') 210 211 local file = t.tmpname() 212 write_file(file, 'Test content') 213 local test_case = string.format( 214 [[ 215 local file = '%s' 216 return vim.uri_from_bufnr(vim.fn.bufadd(file)) 217 ]], 218 file 219 ) 220 local expected_uri = 'file:///' .. t.fix_slashes(file) 221 eq(expected_uri, exec_lua(test_case)) 222 os.remove(file) 223 end) 224 end) 225 226 describe('uri to bufnr', function() 227 it('uri_to_bufnr & uri_from_bufnr returns original uri for non-file uris', function() 228 local uri = 229 'jdt://contents/java.base/java.util/List.class?=sql/%5C/home%5C/user%5C/.jabba%5C/jdk%5C/openjdk%5C@1.14.0%5C/lib%5C/jrt-fs.jar%60java.base=/javadoc_location=/https:%5C/%5C/docs.oracle.com%5C/en%5C/java%5C/javase%5C/14%5C/docs%5C/api%5C/=/%3Cjava.util(List.class' 230 local test_case = string.format( 231 [[ 232 local uri = '%s' 233 return vim.uri_from_bufnr(vim.uri_to_bufnr(uri)) 234 ]], 235 uri 236 ) 237 eq(uri, exec_lua(test_case)) 238 end) 239 240 it( 241 'uri_to_bufnr & uri_from_bufnr returns original uri for non-file uris without authority', 242 function() 243 local uri = 'zipfile:///path/to/archive.zip%3A%3Afilename.txt' 244 local test_case = string.format( 245 [[ 246 local uri = '%s' 247 return vim.uri_from_bufnr(vim.uri_to_bufnr(uri)) 248 ]], 249 uri 250 ) 251 eq(uri, exec_lua(test_case)) 252 end 253 ) 254 end) 255 256 describe('encode to uri', function() 257 it('rfc2732 including brackets', function() 258 exec_lua("str = '[:]'") 259 exec_lua("rfc = 'rfc2732'") 260 eq('[%3a]', exec_lua('return vim.uri_encode(str, rfc)')) 261 end) 262 end) 263 end)