neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

test_functions.vim (139170B)


      1 " Tests for various functions.
      2 
      3 source shared.vim
      4 source check.vim
      5 source term_util.vim
      6 source screendump.vim
      7 source vim9.vim
      8 
      9 " Must be done first, since the alternate buffer must be unset.
     10 func Test_00_bufexists()
     11  call assert_equal(0, bufexists('does_not_exist'))
     12  call assert_equal(1, bufexists(bufnr('%')))
     13  call assert_equal(0, bufexists(0))
     14  new Xfoo
     15  let bn = bufnr('%')
     16  call assert_equal(1, bufexists(bn))
     17  call assert_equal(1, bufexists('Xfoo'))
     18  call assert_equal(1, bufexists(getcwd() . '/Xfoo'))
     19  call assert_equal(1, bufexists(0))
     20  bw
     21  call assert_equal(0, bufexists(bn))
     22  call assert_equal(0, bufexists('Xfoo'))
     23 endfunc
     24 
     25 func Test_has()
     26  throw 'Skipped: Nvim has removed some features'
     27  call assert_equal(1, has('eval'))
     28  call assert_equal(1, has('eval', 1))
     29 
     30  if has('unix')
     31    call assert_equal(1, or(has('ttyin'), 1))
     32    call assert_equal(0, and(has('ttyout'), 0))
     33    call assert_equal(1, has('multi_byte_encoding'))
     34    call assert_equal(0, has(':tearoff'))
     35  endif
     36  call assert_equal(1, has('vcon', 1))
     37  call assert_equal(1, has('mouse_gpm_enabled', 1))
     38 
     39  call assert_equal(has('gui_win32') && has('menu'), has(':tearoff'))
     40 
     41  call assert_equal(0, has('nonexistent'))
     42  call assert_equal(0, has('nonexistent', 1))
     43 
     44  " Will we ever have patch 9999?
     45  let ver = 'patch-' .. v:version / 100 .. '.' .. v:version % 100 .. '.9999'
     46  call assert_equal(0, has(ver))
     47 
     48  " There actually isn't a patch 9.0.0, but this is more consistent.
     49  call assert_equal(1, has('patch-9.0.0'))
     50 endfunc
     51 
     52 func Test_empty()
     53  call assert_equal(1, empty(''))
     54  call assert_equal(0, empty('a'))
     55 
     56  call assert_equal(1, empty(0))
     57  call assert_equal(1, empty(-0))
     58  call assert_equal(0, empty(1))
     59  call assert_equal(0, empty(-1))
     60 
     61  if has('float')
     62    call assert_equal(1, empty(0.0))
     63    call assert_equal(1, empty(-0.0))
     64    call assert_equal(0, empty(1.0))
     65    call assert_equal(0, empty(-1.0))
     66    call assert_equal(0, empty(1.0/0.0))
     67    call assert_equal(0, empty(0.0/0.0))
     68  endif
     69 
     70  call assert_equal(1, empty([]))
     71  call assert_equal(0, empty(['a']))
     72 
     73  call assert_equal(1, empty({}))
     74  call assert_equal(0, empty({'a':1}))
     75 
     76  call assert_equal(1, empty(v:null))
     77  " call assert_equal(1, empty(v:none))
     78  call assert_equal(1, empty(v:false))
     79  call assert_equal(0, empty(v:true))
     80 
     81  if has('channel')
     82    call assert_equal(1, empty(test_null_channel()))
     83  endif
     84  if has('job')
     85    call assert_equal(1, empty(test_null_job()))
     86  endif
     87 
     88  call assert_equal(0, empty(function('Test_empty')))
     89  call assert_equal(0, empty(function('Test_empty', [0])))
     90 endfunc
     91 
     92 func Test_err_teapot()
     93  throw 'Skipped: Nvim does not have err_teapot()'
     94  call assert_fails('call err_teapot()', "E418: I'm a teapot")
     95  call assert_fails('call err_teapot(0)', "E418: I'm a teapot")
     96  call assert_fails('call err_teapot(v:false)', "E418: I'm a teapot")
     97 
     98  call assert_fails('call err_teapot("1")', "E503: Coffee is currently not available")
     99  call assert_fails('call err_teapot(v:true)', "E503: Coffee is currently not available")
    100  let expr = 1
    101  call assert_fails('call err_teapot(expr)', "E503: Coffee is currently not available")
    102 endfunc
    103 
    104 func Test_islocked()
    105  call assert_fails('call islocked(99)', 'E475:')
    106  call assert_fails('call islocked("s: x")', 'E488:')
    107 endfunc
    108 
    109 func Test_len()
    110  call assert_equal(1, len(0))
    111  call assert_equal(2, len(12))
    112 
    113  call assert_equal(0, len(''))
    114  call assert_equal(2, len('ab'))
    115 
    116  call assert_equal(0, len([]))
    117  call assert_equal(0, len(v:_null_list))
    118  call assert_equal(2, len([2, 1]))
    119 
    120  call assert_equal(0, len({}))
    121  call assert_equal(0, len(v:_null_dict))
    122  call assert_equal(2, len({'a': 1, 'b': 2}))
    123 
    124  " call assert_fails('call len(v:none)', 'E701:')
    125  call assert_fails('call len({-> 0})', 'E701:')
    126 endfunc
    127 
    128 func Test_max()
    129  call assert_equal(0, max([]))
    130  call assert_equal(2, max([2]))
    131  call assert_equal(2, max([1, 2]))
    132  call assert_equal(2, max([1, 2, v:null]))
    133 
    134  call assert_equal(0, max({}))
    135  call assert_equal(2, max({'a':1, 'b':2}))
    136 
    137  call assert_fails('call max(1)', 'E712:')
    138  " call assert_fails('call max(v:none)', 'E712:')
    139 
    140  " check we only get one error
    141  call assert_fails('call max([#{}, [1]])', ['E728:', 'E728:'])
    142  call assert_fails('call max(#{a: {}, b: [1]})', ['E728:', 'E728:'])
    143 endfunc
    144 
    145 func Test_min()
    146  call assert_equal(0, min([]))
    147  call assert_equal(2, min([2]))
    148  call assert_equal(1, min([1, 2]))
    149  call assert_equal(0, min([1, 2, v:null]))
    150 
    151  call assert_equal(0, min({}))
    152  call assert_equal(1, min({'a':1, 'b':2}))
    153 
    154  call assert_fails('call min(1)', 'E712:')
    155  " call assert_fails('call min(v:none)', 'E712:')
    156  call assert_fails('call min([1, {}])', 'E728:')
    157 
    158  " check we only get one error
    159  call assert_fails('call min([[1], #{}])', ['E745:', 'E745:'])
    160  call assert_fails('call min(#{a: [1], b: #{}})', ['E745:', 'E745:'])
    161 endfunc
    162 
    163 func Test_strwidth()
    164  for aw in ['single', 'double']
    165    exe 'set ambiwidth=' . aw
    166    call assert_equal(0, strwidth(''))
    167    call assert_equal(1, strwidth("\t"))
    168    call assert_equal(3, strwidth('Vim'))
    169    call assert_equal(4, strwidth(1234))
    170    call assert_equal(5, strwidth(-1234))
    171 
    172    call assert_equal(2, strwidth('😉'))
    173    call assert_equal(17, strwidth('Eĥoŝanĝo ĉiuĵaŭde'))
    174    call assert_equal((aw == 'single') ? 6 : 7, strwidth('Straße'))
    175 
    176    call assert_fails('call strwidth({->0})', 'E729:')
    177    call assert_fails('call strwidth([])', 'E730:')
    178    call assert_fails('call strwidth({})', 'E731:')
    179  endfor
    180 
    181  if has('float')
    182    call assert_equal(3, strwidth(1.2))
    183    call CheckDefExecAndScriptFailure(['echo strwidth(1.2)'], 'E806:')
    184  endif
    185 
    186  set ambiwidth&
    187 endfunc
    188 
    189 func Test_str2nr()
    190  call assert_equal(0, str2nr(''))
    191  call assert_equal(1, str2nr('1'))
    192  call assert_equal(1, str2nr(' 1 '))
    193 
    194  call assert_equal(1, str2nr('+1'))
    195  call assert_equal(1, str2nr('+ 1'))
    196  call assert_equal(1, str2nr(' + 1 '))
    197 
    198  call assert_equal(-1, str2nr('-1'))
    199  call assert_equal(-1, str2nr('- 1'))
    200  call assert_equal(-1, str2nr(' - 1 '))
    201 
    202  call assert_equal(123456789, str2nr('123456789'))
    203  call assert_equal(-123456789, str2nr('-123456789'))
    204 
    205  call assert_equal(5, str2nr('101', 2))
    206  call assert_equal(5, '0b101'->str2nr(2))
    207  call assert_equal(5, str2nr('0B101', 2))
    208  call assert_equal(-5, str2nr('-101', 2))
    209  call assert_equal(-5, str2nr('-0b101', 2))
    210  call assert_equal(-5, str2nr('-0B101', 2))
    211 
    212  call assert_equal(65, str2nr('101', 8))
    213  call assert_equal(65, str2nr('0101', 8))
    214  call assert_equal(-65, str2nr('-101', 8))
    215  call assert_equal(-65, str2nr('-0101', 8))
    216  call assert_equal(65, str2nr('0o101', 8))
    217  call assert_equal(65, str2nr('0O0101', 8))
    218  call assert_equal(-65, str2nr('-0O101', 8))
    219  call assert_equal(-65, str2nr('-0o0101', 8))
    220 
    221  call assert_equal(11259375, str2nr('abcdef', 16))
    222  call assert_equal(11259375, str2nr('ABCDEF', 16))
    223  call assert_equal(-11259375, str2nr('-ABCDEF', 16))
    224  call assert_equal(11259375, str2nr('0xabcdef', 16))
    225  call assert_equal(11259375, str2nr('0Xabcdef', 16))
    226  call assert_equal(11259375, str2nr('0XABCDEF', 16))
    227  call assert_equal(-11259375, str2nr('-0xABCDEF', 16))
    228 
    229  call assert_equal(1, str2nr("1'000'000", 10, 0))
    230  call assert_equal(256, str2nr("1'0000'0000", 2, 1))
    231  call assert_equal(262144, str2nr("1'000'000", 8, 1))
    232  call assert_equal(1000000, str2nr("1'000'000", 10, 1))
    233  call assert_equal(1000, str2nr("1'000''000", 10, 1))
    234  call assert_equal(65536, str2nr("1'00'00", 16, 1))
    235 
    236  call assert_equal(0, str2nr('0x10'))
    237  call assert_equal(0, str2nr('0b10'))
    238  call assert_equal(0, str2nr('0o10'))
    239  call assert_equal(1, str2nr('12', 2))
    240  call assert_equal(1, str2nr('18', 8))
    241  call assert_equal(1, str2nr('1g', 16))
    242 
    243  call assert_equal(0, str2nr(v:null))
    244  " call assert_equal(0, str2nr(v:none))
    245 
    246  call assert_fails('call str2nr([])', 'E730:')
    247  call assert_fails('call str2nr({->2})', 'E729:')
    248  if has('float')
    249    call assert_equal(1, str2nr(1.2))
    250    call CheckDefExecFailure(['echo str2nr(1.2)'], 'E1013:')
    251    call CheckScriptFailure(['vim9script', 'echo str2nr(1.2)'], 'E806:')
    252  endif
    253  call assert_fails('call str2nr(10, [])', 'E745:')
    254 endfunc
    255 
    256 func Test_strftime()
    257  CheckFunction strftime
    258 
    259  " Format of strftime() depends on system. We assume
    260  " that basic formats tested here are available and
    261  " identical on all systems which support strftime().
    262  "
    263  " The 2nd parameter of strftime() is a local time, so the output day
    264  " of strftime() can be 17 or 18, depending on timezone.
    265  call assert_match('^2017-01-1[78]$', strftime('%Y-%m-%d', 1484695512))
    266  "
    267  call assert_match('^\d\d\d\d-\(0\d\|1[012]\)-\([012]\d\|3[01]\) \([01]\d\|2[0-3]\):[0-5]\d:\([0-5]\d\|60\)$', '%Y-%m-%d %H:%M:%S'->strftime())
    268 
    269  call assert_fails('call strftime([])', 'E730:')
    270  call assert_fails('call strftime("%Y", [])', 'E745:')
    271 
    272  " Check that the time changes after we change the timezone
    273  " Save previous timezone value, if any
    274  if exists('$TZ')
    275    let tz = $TZ
    276  endif
    277 
    278  " Force different time zones, save the current hour (24-hour clock) for each
    279  let $TZ = 'GMT+1' | let one = strftime('%H')
    280  let $TZ = 'GMT+2' | let two = strftime('%H')
    281 
    282  " Those hours should be two bytes long, and should not be the same; if they
    283  " are, a tzset(3) call may have failed somewhere
    284  call assert_equal(strlen(one), 2)
    285  call assert_equal(strlen(two), 2)
    286  " TODO: this fails on MS-Windows
    287  if has('unix')
    288    call assert_notequal(one, two)
    289  endif
    290 
    291  " If we cached a timezone value, put it back, otherwise clear it
    292  if exists('tz')
    293    let $TZ = tz
    294  else
    295    unlet $TZ
    296  endif
    297 endfunc
    298 
    299 func Test_strptime()
    300  CheckFunction strptime
    301  CheckNotBSD
    302  CheckNotMSWindows
    303 
    304  if exists('$TZ')
    305    let tz = $TZ
    306  endif
    307  let $TZ = 'UTC'
    308 
    309  call assert_equal(1484653763, strptime('%Y-%m-%d %T', '2017-01-17 11:49:23'))
    310 
    311  " Force DST and check that it's considered
    312  let $TZ = 'WINTER0SUMMER,J1,J365'
    313  call assert_equal(1484653763 - 3600, strptime('%Y-%m-%d %T', '2017-01-17 11:49:23'))
    314 
    315  call assert_fails('call strptime()', 'E119:')
    316  call assert_fails('call strptime("xxx")', 'E119:')
    317  " This fails on BSD 14 and returns
    318  " -2209078800 instead of 0
    319  call assert_equal(0, strptime("%Y", ''))
    320  call assert_equal(0, strptime("%Y", "xxx"))
    321 
    322  if exists('tz')
    323    let $TZ = tz
    324  else
    325    unlet $TZ
    326  endif
    327 endfunc
    328 
    329 func Test_resolve_unix()
    330  if !has('unix')
    331    return
    332  endif
    333 
    334  " Xlink1 -> Xlink2
    335  " Xlink2 -> Xlink3
    336  silent !ln -s -f Xlink2 Xlink1
    337  silent !ln -s -f Xlink3 Xlink2
    338  call assert_equal('Xlink3', resolve('Xlink1'))
    339  call assert_equal('./Xlink3', resolve('./Xlink1'))
    340  call assert_equal('Xlink3/', resolve('Xlink2/'))
    341  " FIXME: these tests result in things like "Xlink2/" instead of "Xlink3/"?!
    342  "call assert_equal('Xlink3/', resolve('Xlink1/'))
    343  "call assert_equal('./Xlink3/', resolve('./Xlink1/'))
    344  "call assert_equal(getcwd() . '/Xlink3/', resolve(getcwd() . '/Xlink1/'))
    345  call assert_equal(getcwd() . '/Xlink3', resolve(getcwd() . '/Xlink1'))
    346 
    347  " Test resolve() with a symlink cycle.
    348  " Xlink1 -> Xlink2
    349  " Xlink2 -> Xlink3
    350  " Xlink3 -> Xlink1
    351  silent !ln -s -f Xlink1 Xlink3
    352  call assert_fails('call resolve("Xlink1")',   'E655:')
    353  call assert_fails('call resolve("./Xlink1")', 'E655:')
    354  call assert_fails('call resolve("Xlink2")',   'E655:')
    355  call assert_fails('call resolve("Xlink3")',   'E655:')
    356  call delete('Xlink1')
    357  call delete('Xlink2')
    358  call delete('Xlink3')
    359 
    360  silent !ln -s -f Xdir//Xfile Xlink
    361  call assert_equal('Xdir/Xfile', resolve('Xlink'))
    362  call delete('Xlink')
    363 
    364  silent !ln -s -f Xlink2/ Xlink1
    365  call assert_equal('Xlink2', 'Xlink1'->resolve())
    366  call assert_equal('Xlink2/', resolve('Xlink1/'))
    367  call delete('Xlink1')
    368 
    369  silent !ln -s -f ./Xlink2 Xlink1
    370  call assert_equal('Xlink2', resolve('Xlink1'))
    371  call assert_equal('./Xlink2', resolve('./Xlink1'))
    372  call delete('Xlink1')
    373 
    374  call assert_equal('/', resolve('/'))
    375 endfunc
    376 
    377 func s:normalize_fname(fname)
    378  let ret = substitute(a:fname, '\', '/', 'g')
    379  let ret = substitute(ret, '//', '/', 'g')
    380  return ret->tolower()
    381 endfunc
    382 
    383 func Test_simplify()
    384  call assert_equal('',            simplify(''))
    385  call assert_equal('/',           simplify('/'))
    386  call assert_equal('/',           simplify('/.'))
    387  call assert_equal('/',           simplify('/..'))
    388  call assert_equal('/...',        simplify('/...'))
    389  call assert_equal('//path',      simplify('//path'))
    390  if has('unix')
    391    call assert_equal('/path',       simplify('///path'))
    392    call assert_equal('/path',       simplify('////path'))
    393  endif
    394 
    395  call assert_equal('./dir/file',  './dir/file'->simplify())
    396  call assert_equal('./dir/file',  simplify('.///dir//file'))
    397  call assert_equal('./dir/file',  simplify('./dir/./file'))
    398  call assert_equal('./file',      simplify('./dir/../file'))
    399  call assert_equal('../dir/file', simplify('dir/../../dir/file'))
    400  call assert_equal('./file',      simplify('dir/.././file'))
    401  call assert_equal('../dir',      simplify('./../dir'))
    402  call assert_equal('..',          simplify('../testdir/..'))
    403  call mkdir('Xdir')
    404  call assert_equal('.',           simplify('Xdir/../.'))
    405  call delete('Xdir', 'd')
    406 
    407  call assert_fails('call simplify({->0})', 'E729:')
    408  call assert_fails('call simplify([])', 'E730:')
    409  call assert_fails('call simplify({})', 'E731:')
    410  if has('float')
    411    call assert_equal('1.2', simplify(1.2))
    412    call CheckDefExecAndScriptFailure(['echo simplify(1.2)'], 'E806:')
    413  endif
    414 endfunc
    415 
    416 func Test_pathshorten()
    417  call assert_equal('', pathshorten(''))
    418  call assert_equal('foo', pathshorten('foo'))
    419  call assert_equal('/foo', '/foo'->pathshorten())
    420  call assert_equal('f/', pathshorten('foo/'))
    421  call assert_equal('f/bar', pathshorten('foo/bar'))
    422  call assert_equal('f/b/foobar', 'foo/bar/foobar'->pathshorten())
    423  call assert_equal('/f/b/foobar', pathshorten('/foo/bar/foobar'))
    424  call assert_equal('.f/bar', pathshorten('.foo/bar'))
    425  call assert_equal('~f/bar', pathshorten('~foo/bar'))
    426  call assert_equal('~.f/bar', pathshorten('~.foo/bar'))
    427  call assert_equal('.~f/bar', pathshorten('.~foo/bar'))
    428  call assert_equal('~/f/bar', pathshorten('~/foo/bar'))
    429  call assert_fails('call pathshorten([])', 'E730:')
    430 
    431  " test pathshorten with optional variable to set preferred size of shortening
    432  call assert_equal('', pathshorten('', 2))
    433  call assert_equal('foo', pathshorten('foo', 2))
    434  call assert_equal('/foo', pathshorten('/foo', 2))
    435  call assert_equal('fo/', pathshorten('foo/', 2))
    436  call assert_equal('fo/bar', pathshorten('foo/bar', 2))
    437  call assert_equal('fo/ba/foobar', pathshorten('foo/bar/foobar', 2))
    438  call assert_equal('/fo/ba/foobar', pathshorten('/foo/bar/foobar', 2))
    439  call assert_equal('.fo/bar', pathshorten('.foo/bar', 2))
    440  call assert_equal('~fo/bar', pathshorten('~foo/bar', 2))
    441  call assert_equal('~.fo/bar', pathshorten('~.foo/bar', 2))
    442  call assert_equal('.~fo/bar', pathshorten('.~foo/bar', 2))
    443  call assert_equal('~/fo/bar', pathshorten('~/foo/bar', 2))
    444  call assert_fails('call pathshorten([],2)', 'E730:')
    445  call assert_notequal('~/fo/bar', pathshorten('~/foo/bar', 3))
    446  call assert_equal('~/foo/bar', pathshorten('~/foo/bar', 3))
    447  call assert_equal('~/f/bar', pathshorten('~/foo/bar', 0))
    448 endfunc
    449 
    450 func Test_strpart()
    451  call assert_equal('de', strpart('abcdefg', 3, 2))
    452  call assert_equal('ab', strpart('abcdefg', -2, 4))
    453  call assert_equal('abcdefg', 'abcdefg'->strpart(-2))
    454  call assert_equal('fg', strpart('abcdefg', 5, 4))
    455  call assert_equal('defg', strpart('abcdefg', 3))
    456  call assert_equal('', strpart('abcdefg', 10))
    457  call assert_fails("let s=strpart('abcdef', [])", 'E745:')
    458 
    459  call assert_equal('lép', strpart('éléphant', 2, 4))
    460  call assert_equal('léphant', strpart('éléphant', 2))
    461 
    462  call assert_equal('é', strpart('éléphant', 0, 1, 1))
    463  call assert_equal('ép', strpart('éléphant', 3, 2, v:true))
    464  call assert_equal('ó', strpart('cómposed', 1, 1, 1))
    465 endfunc
    466 
    467 func Test_tolower()
    468  call assert_equal("", tolower(""))
    469 
    470  " Test with all printable ASCII characters.
    471  call assert_equal(' !"#$%&''()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~',
    472          \ tolower(' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~'))
    473 
    474  " Test with a few uppercase diacritics.
    475  call assert_equal("aàáâãäåāăąǎǟǡả", tolower("AÀÁÂÃÄÅĀĂĄǍǞǠẢ"))
    476  call assert_equal("bḃḇ", tolower("BḂḆ"))
    477  call assert_equal("cçćĉċč", tolower("CÇĆĈĊČ"))
    478  call assert_equal("dďđḋḏḑ", tolower("DĎĐḊḎḐ"))
    479  call assert_equal("eèéêëēĕėęěẻẽ", tolower("EÈÉÊËĒĔĖĘĚẺẼ"))
    480  call assert_equal("fḟ ", tolower("FḞ "))
    481  call assert_equal("gĝğġģǥǧǵḡ", tolower("GĜĞĠĢǤǦǴḠ"))
    482  call assert_equal("hĥħḣḧḩ", tolower("HĤĦḢḦḨ"))
    483  call assert_equal("iìíîïĩīĭįiǐỉ", tolower("IÌÍÎÏĨĪĬĮİǏỈ"))
    484  call assert_equal("jĵ", tolower("JĴ"))
    485  call assert_equal("kķǩḱḵ", tolower("KĶǨḰḴ"))
    486  call assert_equal("lĺļľŀłḻ", tolower("LĹĻĽĿŁḺ"))
    487  call assert_equal("mḿṁ", tolower("MḾṀ"))
    488  call assert_equal("nñńņňṅṉ", tolower("NÑŃŅŇṄṈ"))
    489  call assert_equal("oòóôõöøōŏőơǒǫǭỏ", tolower("OÒÓÔÕÖØŌŎŐƠǑǪǬỎ"))
    490  call assert_equal("pṕṗ", tolower("PṔṖ"))
    491  call assert_equal("q", tolower("Q"))
    492  call assert_equal("rŕŗřṙṟ", tolower("RŔŖŘṘṞ"))
    493  call assert_equal("sśŝşšṡ", tolower("SŚŜŞŠṠ"))
    494  call assert_equal("tţťŧṫṯ", tolower("TŢŤŦṪṮ"))
    495  call assert_equal("uùúûüũūŭůűųưǔủ", tolower("UÙÚÛÜŨŪŬŮŰŲƯǓỦ"))
    496  call assert_equal("vṽ", tolower("VṼ"))
    497  call assert_equal("wŵẁẃẅẇ", tolower("WŴẀẂẄẆ"))
    498  call assert_equal("xẋẍ", tolower("XẊẌ"))
    499  call assert_equal("yýŷÿẏỳỷỹ", tolower("YÝŶŸẎỲỶỸ"))
    500  call assert_equal("zźżžƶẑẕ", tolower("ZŹŻŽƵẐẔ"))
    501 
    502  " Test with a few lowercase diacritics, which should remain unchanged.
    503  call assert_equal("aàáâãäåāăąǎǟǡả", tolower("aàáâãäåāăąǎǟǡả"))
    504  call assert_equal("bḃḇ", tolower("bḃḇ"))
    505  call assert_equal("cçćĉċč", tolower("cçćĉċč"))
    506  call assert_equal("dďđḋḏḑ", tolower("dďđḋḏḑ"))
    507  call assert_equal("eèéêëēĕėęěẻẽ", tolower("eèéêëēĕėęěẻẽ"))
    508  call assert_equal("fḟ", tolower("fḟ"))
    509  call assert_equal("gĝğġģǥǧǵḡ", tolower("gĝğġģǥǧǵḡ"))
    510  call assert_equal("hĥħḣḧḩẖ", tolower("hĥħḣḧḩẖ"))
    511  call assert_equal("iìíîïĩīĭįǐỉ", tolower("iìíîïĩīĭįǐỉ"))
    512  call assert_equal("jĵǰ", tolower("jĵǰ"))
    513  call assert_equal("kķǩḱḵ", tolower("kķǩḱḵ"))
    514  call assert_equal("lĺļľŀłḻ", tolower("lĺļľŀłḻ"))
    515  call assert_equal("mḿṁ ", tolower("mḿṁ "))
    516  call assert_equal("nñńņňʼnṅṉ", tolower("nñńņňʼnṅṉ"))
    517  call assert_equal("oòóôõöøōŏőơǒǫǭỏ", tolower("oòóôõöøōŏőơǒǫǭỏ"))
    518  call assert_equal("pṕṗ", tolower("pṕṗ"))
    519  call assert_equal("q", tolower("q"))
    520  call assert_equal("rŕŗřṙṟ", tolower("rŕŗřṙṟ"))
    521  call assert_equal("sśŝşšṡ", tolower("sśŝşšṡ"))
    522  call assert_equal("tţťŧṫṯẗ", tolower("tţťŧṫṯẗ"))
    523  call assert_equal("uùúûüũūŭůűųưǔủ", tolower("uùúûüũūŭůűųưǔủ"))
    524  call assert_equal("vṽ", tolower("vṽ"))
    525  call assert_equal("wŵẁẃẅẇẘ", tolower("wŵẁẃẅẇẘ"))
    526  call assert_equal("ẋẍ", tolower("ẋẍ"))
    527  call assert_equal("yýÿŷẏẙỳỷỹ", tolower("yýÿŷẏẙỳỷỹ"))
    528  call assert_equal("zźżžƶẑẕ", tolower("zźżžƶẑẕ"))
    529 
    530  " According to https://twitter.com/jifa/status/625776454479970304
    531  " Ⱥ (U+023A) and Ⱦ (U+023E) are the *only* code points to increase
    532  " in length (2 to 3 bytes) when lowercased. So let's test them.
    533  call assert_equal("ⱥ ⱦ", tolower("Ⱥ Ⱦ"))
    534 
    535  " This call to tolower with invalid utf8 sequence used to cause access to
    536  " invalid memory.
    537  call tolower("\xC0\x80\xC0")
    538  call tolower("123\xC0\x80\xC0")
    539 
    540  " Test in latin1 encoding
    541  let save_enc = &encoding
    542  " set encoding=latin1
    543  call assert_equal("abc", tolower("ABC"))
    544  let &encoding = save_enc
    545 endfunc
    546 
    547 func Test_toupper()
    548  call assert_equal("", toupper(""))
    549 
    550  " Test with all printable ASCII characters.
    551  call assert_equal(' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~',
    552          \ toupper(' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~'))
    553 
    554  " Test with a few lowercase diacritics.
    555  call assert_equal("AÀÁÂÃÄÅĀĂĄǍǞǠẢ", "aàáâãäåāăąǎǟǡả"->toupper())
    556  call assert_equal("BḂḆ", toupper("bḃḇ"))
    557  call assert_equal("CÇĆĈĊČ", toupper("cçćĉċč"))
    558  call assert_equal("DĎĐḊḎḐ", toupper("dďđḋḏḑ"))
    559  call assert_equal("EÈÉÊËĒĔĖĘĚẺẼ", toupper("eèéêëēĕėęěẻẽ"))
    560  call assert_equal("FḞ", toupper("fḟ"))
    561  call assert_equal("GĜĞĠĢǤǦǴḠ", toupper("gĝğġģǥǧǵḡ"))
    562  call assert_equal("HĤĦḢḦḨẖ", toupper("hĥħḣḧḩẖ"))
    563  call assert_equal("IÌÍÎÏĨĪĬĮǏỈ", toupper("iìíîïĩīĭįǐỉ"))
    564  call assert_equal("JĴǰ", toupper("jĵǰ"))
    565  call assert_equal("KĶǨḰḴ", toupper("kķǩḱḵ"))
    566  call assert_equal("LĹĻĽĿŁḺ", toupper("lĺļľŀłḻ"))
    567  call assert_equal("MḾṀ ", toupper("mḿṁ "))
    568  call assert_equal("NÑŃŅŇʼnṄṈ", toupper("nñńņňʼnṅṉ"))
    569  call assert_equal("OÒÓÔÕÖØŌŎŐƠǑǪǬỎ", toupper("oòóôõöøōŏőơǒǫǭỏ"))
    570  call assert_equal("PṔṖ", toupper("pṕṗ"))
    571  call assert_equal("Q", toupper("q"))
    572  call assert_equal("RŔŖŘṘṞ", toupper("rŕŗřṙṟ"))
    573  call assert_equal("SŚŜŞŠṠ", toupper("sśŝşšṡ"))
    574  call assert_equal("TŢŤŦṪṮẗ", toupper("tţťŧṫṯẗ"))
    575  call assert_equal("UÙÚÛÜŨŪŬŮŰŲƯǓỦ", toupper("uùúûüũūŭůűųưǔủ"))
    576  call assert_equal("VṼ", toupper("vṽ"))
    577  call assert_equal("WŴẀẂẄẆẘ", toupper("wŵẁẃẅẇẘ"))
    578  call assert_equal("ẊẌ", toupper("ẋẍ"))
    579  call assert_equal("YÝŸŶẎẙỲỶỸ", toupper("yýÿŷẏẙỳỷỹ"))
    580  call assert_equal("ZŹŻŽƵẐẔ", toupper("zźżžƶẑẕ"))
    581 
    582  " Test that uppercase diacritics, which should remain unchanged.
    583  call assert_equal("AÀÁÂÃÄÅĀĂĄǍǞǠẢ", toupper("AÀÁÂÃÄÅĀĂĄǍǞǠẢ"))
    584  call assert_equal("BḂḆ", toupper("BḂḆ"))
    585  call assert_equal("CÇĆĈĊČ", toupper("CÇĆĈĊČ"))
    586  call assert_equal("DĎĐḊḎḐ", toupper("DĎĐḊḎḐ"))
    587  call assert_equal("EÈÉÊËĒĔĖĘĚẺẼ", toupper("EÈÉÊËĒĔĖĘĚẺẼ"))
    588  call assert_equal("FḞ ", toupper("FḞ "))
    589  call assert_equal("GĜĞĠĢǤǦǴḠ", toupper("GĜĞĠĢǤǦǴḠ"))
    590  call assert_equal("HĤĦḢḦḨ", toupper("HĤĦḢḦḨ"))
    591  call assert_equal("IÌÍÎÏĨĪĬĮİǏỈ", toupper("IÌÍÎÏĨĪĬĮİǏỈ"))
    592  call assert_equal("JĴ", toupper("JĴ"))
    593  call assert_equal("KĶǨḰḴ", toupper("KĶǨḰḴ"))
    594  call assert_equal("LĹĻĽĿŁḺ", toupper("LĹĻĽĿŁḺ"))
    595  call assert_equal("MḾṀ", toupper("MḾṀ"))
    596  call assert_equal("NÑŃŅŇṄṈ", toupper("NÑŃŅŇṄṈ"))
    597  call assert_equal("OÒÓÔÕÖØŌŎŐƠǑǪǬỎ", toupper("OÒÓÔÕÖØŌŎŐƠǑǪǬỎ"))
    598  call assert_equal("PṔṖ", toupper("PṔṖ"))
    599  call assert_equal("Q", toupper("Q"))
    600  call assert_equal("RŔŖŘṘṞ", toupper("RŔŖŘṘṞ"))
    601  call assert_equal("SŚŜŞŠṠ", toupper("SŚŜŞŠṠ"))
    602  call assert_equal("TŢŤŦṪṮ", toupper("TŢŤŦṪṮ"))
    603  call assert_equal("UÙÚÛÜŨŪŬŮŰŲƯǓỦ", toupper("UÙÚÛÜŨŪŬŮŰŲƯǓỦ"))
    604  call assert_equal("VṼ", toupper("VṼ"))
    605  call assert_equal("WŴẀẂẄẆ", toupper("WŴẀẂẄẆ"))
    606  call assert_equal("XẊẌ", toupper("XẊẌ"))
    607  call assert_equal("YÝŶŸẎỲỶỸ", toupper("YÝŶŸẎỲỶỸ"))
    608  call assert_equal("ZŹŻŽƵẐẔ", toupper("ZŹŻŽƵẐẔ"))
    609 
    610  call assert_equal("Ⱥ Ⱦ", toupper("ⱥ ⱦ"))
    611 
    612  " This call to toupper with invalid utf8 sequence used to cause access to
    613  " invalid memory.
    614  call toupper("\xC0\x80\xC0")
    615  call toupper("123\xC0\x80\xC0")
    616 
    617  " Test in latin1 encoding
    618  let save_enc = &encoding
    619  " set encoding=latin1
    620  call assert_equal("ABC", toupper("abc"))
    621  let &encoding = save_enc
    622 endfunc
    623 
    624 func Test_tr()
    625  call assert_equal('foo', tr('bar', 'bar', 'foo'))
    626  call assert_equal('zxy', 'cab'->tr('abc', 'xyz'))
    627  call assert_fails("let s=tr([], 'abc', 'def')", 'E730:')
    628  call assert_fails("let s=tr('abc', [], 'def')", 'E730:')
    629  call assert_fails("let s=tr('abc', 'abc', [])", 'E730:')
    630  call assert_fails("let s=tr('abcd', 'abcd', 'def')", 'E475:')
    631  " set encoding=latin1
    632  call assert_fails("let s=tr('abcd', 'abcd', 'def')", 'E475:')
    633  call assert_equal('hEllO', tr('hello', 'eo', 'EO'))
    634  call assert_equal('hello', tr('hello', 'xy', 'ab'))
    635  call assert_fails('call tr("abc", "123", "₁₂")', 'E475:')
    636  set encoding=utf8
    637 endfunc
    638 
    639 " Tests for the mode() function
    640 let current_modes = ''
    641 func Save_mode()
    642  let g:current_modes = mode(0) . '-' . mode(1)
    643  return ''
    644 endfunc
    645 
    646 " Test for the mode() function
    647 func Test_mode()
    648  new
    649  call append(0, ["Blue Ball Black", "Brown Band Bowl", ""])
    650 
    651  " Only complete from the current buffer.
    652  set complete=.
    653 
    654  noremap! <F2> <C-R>=Save_mode()<CR>
    655  xnoremap <F2> <Cmd>call Save_mode()<CR>
    656 
    657  normal! 3G
    658  exe "normal i\<F2>\<Esc>"
    659  call assert_equal('i-i', g:current_modes)
    660  " i_CTRL-P: Multiple matches
    661  exe "normal i\<C-G>uBa\<C-P>\<F2>\<Esc>u"
    662  call assert_equal('i-ic', g:current_modes)
    663  " i_CTRL-P: Single match
    664  exe "normal iBro\<C-P>\<F2>\<Esc>u"
    665  call assert_equal('i-ic', g:current_modes)
    666  " i_CTRL-X
    667  exe "normal iBa\<C-X>\<F2>\<Esc>u"
    668  call assert_equal('i-ix', g:current_modes)
    669  " i_CTRL-X CTRL-P: Multiple matches
    670  exe "normal iBa\<C-X>\<C-P>\<F2>\<Esc>u"
    671  call assert_equal('i-ic', g:current_modes)
    672  " i_CTRL-X CTRL-P: Single match
    673  exe "normal iBro\<C-X>\<C-P>\<F2>\<Esc>u"
    674  call assert_equal('i-ic', g:current_modes)
    675  " i_CTRL-X CTRL-P + CTRL-P: Single match
    676  exe "normal iBro\<C-X>\<C-P>\<C-P>\<F2>\<Esc>u"
    677  call assert_equal('i-ic', g:current_modes)
    678  " i_CTRL-X CTRL-L: Multiple matches
    679  exe "normal i\<C-X>\<C-L>\<F2>\<Esc>u"
    680  call assert_equal('i-ic', g:current_modes)
    681  " i_CTRL-X CTRL-L: Single match
    682  exe "normal iBlu\<C-X>\<C-L>\<F2>\<Esc>u"
    683  call assert_equal('i-ic', g:current_modes)
    684  " i_CTRL-P: No match
    685  exe "normal iCom\<C-P>\<F2>\<Esc>u"
    686  call assert_equal('i-ic', g:current_modes)
    687  " i_CTRL-X CTRL-P: No match
    688  exe "normal iCom\<C-X>\<C-P>\<F2>\<Esc>u"
    689  call assert_equal('i-ic', g:current_modes)
    690  " i_CTRL-X CTRL-L: No match
    691  exe "normal iabc\<C-X>\<C-L>\<F2>\<Esc>u"
    692  call assert_equal('i-ic', g:current_modes)
    693 
    694  exe "normal R\<F2>\<Esc>"
    695  call assert_equal('R-R', g:current_modes)
    696  " R_CTRL-P: Multiple matches
    697  exe "normal RBa\<C-P>\<F2>\<Esc>u"
    698  call assert_equal('R-Rc', g:current_modes)
    699  " R_CTRL-P: Single match
    700  exe "normal RBro\<C-P>\<F2>\<Esc>u"
    701  call assert_equal('R-Rc', g:current_modes)
    702  " R_CTRL-X
    703  exe "normal RBa\<C-X>\<F2>\<Esc>u"
    704  call assert_equal('R-Rx', g:current_modes)
    705  " R_CTRL-X CTRL-P: Multiple matches
    706  exe "normal RBa\<C-X>\<C-P>\<F2>\<Esc>u"
    707  call assert_equal('R-Rc', g:current_modes)
    708  " R_CTRL-X CTRL-P: Single match
    709  exe "normal RBro\<C-X>\<C-P>\<F2>\<Esc>u"
    710  call assert_equal('R-Rc', g:current_modes)
    711  " R_CTRL-X CTRL-P + CTRL-P: Single match
    712  exe "normal RBro\<C-X>\<C-P>\<C-P>\<F2>\<Esc>u"
    713  call assert_equal('R-Rc', g:current_modes)
    714  " R_CTRL-X CTRL-L: Multiple matches
    715  exe "normal R\<C-X>\<C-L>\<F2>\<Esc>u"
    716  call assert_equal('R-Rc', g:current_modes)
    717  " R_CTRL-X CTRL-L: Single match
    718  exe "normal RBlu\<C-X>\<C-L>\<F2>\<Esc>u"
    719  call assert_equal('R-Rc', g:current_modes)
    720  " R_CTRL-P: No match
    721  exe "normal RCom\<C-P>\<F2>\<Esc>u"
    722  call assert_equal('R-Rc', g:current_modes)
    723  " R_CTRL-X CTRL-P: No match
    724  exe "normal RCom\<C-X>\<C-P>\<F2>\<Esc>u"
    725  call assert_equal('R-Rc', g:current_modes)
    726  " R_CTRL-X CTRL-L: No match
    727  exe "normal Rabc\<C-X>\<C-L>\<F2>\<Esc>u"
    728  call assert_equal('R-Rc', g:current_modes)
    729 
    730  exe "normal gR\<F2>\<Esc>"
    731  call assert_equal('R-Rv', g:current_modes)
    732  " gR_CTRL-P: Multiple matches
    733  exe "normal gRBa\<C-P>\<F2>\<Esc>u"
    734  call assert_equal('R-Rvc', g:current_modes)
    735  " gR_CTRL-P: Single match
    736  exe "normal gRBro\<C-P>\<F2>\<Esc>u"
    737  call assert_equal('R-Rvc', g:current_modes)
    738  " gR_CTRL-X
    739  exe "normal gRBa\<C-X>\<F2>\<Esc>u"
    740  call assert_equal('R-Rvx', g:current_modes)
    741  " gR_CTRL-X CTRL-P: Multiple matches
    742  exe "normal gRBa\<C-X>\<C-P>\<F2>\<Esc>u"
    743  call assert_equal('R-Rvc', g:current_modes)
    744  " gR_CTRL-X CTRL-P: Single match
    745  exe "normal gRBro\<C-X>\<C-P>\<F2>\<Esc>u"
    746  call assert_equal('R-Rvc', g:current_modes)
    747  " gR_CTRL-X CTRL-P + CTRL-P: Single match
    748  exe "normal gRBro\<C-X>\<C-P>\<C-P>\<F2>\<Esc>u"
    749  call assert_equal('R-Rvc', g:current_modes)
    750  " gR_CTRL-X CTRL-L: Multiple matches
    751  exe "normal gR\<C-X>\<C-L>\<F2>\<Esc>u"
    752  call assert_equal('R-Rvc', g:current_modes)
    753  " gR_CTRL-X CTRL-L: Single match
    754  exe "normal gRBlu\<C-X>\<C-L>\<F2>\<Esc>u"
    755  call assert_equal('R-Rvc', g:current_modes)
    756  " gR_CTRL-P: No match
    757  exe "normal gRCom\<C-P>\<F2>\<Esc>u"
    758  call assert_equal('R-Rvc', g:current_modes)
    759  " gR_CTRL-X CTRL-P: No match
    760  exe "normal gRCom\<C-X>\<C-P>\<F2>\<Esc>u"
    761  call assert_equal('R-Rvc', g:current_modes)
    762  " gR_CTRL-X CTRL-L: No match
    763  exe "normal gRabc\<C-X>\<C-L>\<F2>\<Esc>u"
    764  call assert_equal('R-Rvc', g:current_modes)
    765 
    766  call assert_equal('n', 0->mode())
    767  call assert_equal('n', 1->mode())
    768 
    769  " i_CTRL-O
    770  exe "normal i\<C-O>:call Save_mode()\<Cr>\<Esc>"
    771  call assert_equal("n-niI", g:current_modes)
    772 
    773  " R_CTRL-O
    774  exe "normal R\<C-O>:call Save_mode()\<Cr>\<Esc>"
    775  call assert_equal("n-niR", g:current_modes)
    776 
    777  " gR_CTRL-O
    778  exe "normal gR\<C-O>:call Save_mode()\<Cr>\<Esc>"
    779  call assert_equal("n-niV", g:current_modes)
    780 
    781  " How to test operator-pending mode?
    782 
    783  call feedkeys("v", 'xt')
    784  call assert_equal('v', mode())
    785  call assert_equal('v', mode(1))
    786  call feedkeys("\<Esc>V", 'xt')
    787  call assert_equal('V', mode())
    788  call assert_equal('V', mode(1))
    789  call feedkeys("\<Esc>\<C-V>", 'xt')
    790  call assert_equal("\<C-V>", mode())
    791  call assert_equal("\<C-V>", mode(1))
    792  call feedkeys("\<Esc>", 'xt')
    793 
    794  call feedkeys("gh", 'xt')
    795  call assert_equal('s', mode())
    796  call assert_equal('s', mode(1))
    797  call feedkeys("\<Esc>gH", 'xt')
    798  call assert_equal('S', mode())
    799  call assert_equal('S', mode(1))
    800  call feedkeys("\<Esc>g\<C-H>", 'xt')
    801  call assert_equal("\<C-S>", mode())
    802  call assert_equal("\<C-S>", mode(1))
    803  call feedkeys("\<Esc>", 'xt')
    804 
    805  " v_CTRL-O
    806  exe "normal gh\<C-O>\<F2>\<Esc>"
    807  call assert_equal("v-vs", g:current_modes)
    808  exe "normal gH\<C-O>\<F2>\<Esc>"
    809  call assert_equal("V-Vs", g:current_modes)
    810  exe "normal g\<C-H>\<C-O>\<F2>\<Esc>"
    811  call assert_equal("\<C-V>-\<C-V>s", g:current_modes)
    812 
    813  call feedkeys(":\<F2>\<CR>", 'xt')
    814  call assert_equal('c-c', g:current_modes)
    815  call feedkeys(":\<Insert>\<F2>\<CR>", 'xt')
    816  call assert_equal("c-cr", g:current_modes)
    817  call feedkeys("gQ\<F2>vi\<CR>", 'xt')
    818  call assert_equal('c-cv', g:current_modes)
    819  call feedkeys("gQ\<Insert>\<F2>vi\<CR>", 'xt')
    820  call assert_equal("c-cvr", g:current_modes)
    821 
    822  " Commandline mode in Visual mode should return "c-c", never "v-v".
    823  call feedkeys("v\<Cmd>call input('')\<CR>\<F2>\<CR>\<Esc>", 'xt')
    824  call assert_equal("c-c", g:current_modes)
    825 
    826  " Executing commands in Vim Ex mode should return "cv", never "cvr",
    827  " as Cmdline editing has already ended.
    828  call feedkeys("gQcall Save_mode()\<CR>vi\<CR>", 'xt')
    829  call assert_equal('c-cv', g:current_modes)
    830  call feedkeys("gQ\<Insert>call Save_mode()\<CR>vi\<CR>", 'xt')
    831  call assert_equal('c-cv', g:current_modes)
    832 
    833  " call feedkeys("Qcall Save_mode()\<CR>vi\<CR>", 'xt')
    834  " call assert_equal('c-ce', g:current_modes)
    835 
    836  " Test mode in operatorfunc (it used to be Operator-pending).
    837  set operatorfunc=OperatorFunc
    838  function OperatorFunc(_)
    839    call Save_mode()
    840  endfunction
    841  execute "normal! g@l\<Esc>"
    842  call assert_equal('n-n', g:current_modes)
    843  execute "normal! i\<C-o>g@l\<Esc>"
    844  call assert_equal('n-niI', g:current_modes)
    845  execute "normal! R\<C-o>g@l\<Esc>"
    846  call assert_equal('n-niR', g:current_modes)
    847  execute "normal! gR\<C-o>g@l\<Esc>"
    848  call assert_equal('n-niV', g:current_modes)
    849 
    850 
    851  if has('terminal')
    852    term
    853    call feedkeys("\<C-W>N", 'xt')
    854    call assert_equal('n', mode())
    855    call assert_equal('nt', mode(1))
    856    call feedkeys("aexit\<CR>", 'xt')
    857  endif
    858 
    859  bwipe!
    860  unmap! <F2>
    861  xunmap <F2>
    862  set complete&
    863  set operatorfunc&
    864  delfunction OperatorFunc
    865 endfunc
    866 
    867 " Test for the mode() function using Screendump feature
    868 func Test_mode_screendump()
    869  CheckScreendump
    870 
    871  " Test statusline updates for overstrike mode
    872  let buf = RunVimInTerminal('', {'rows': 12})
    873  call term_sendkeys(buf, ":set laststatus=2 statusline=%!mode(1)\<CR>")
    874  call term_sendkeys(buf, ":")
    875  call TermWait(buf)
    876  call VerifyScreenDump(buf, 'Test_mode_1', {})
    877  call term_sendkeys(buf, "\<Insert>")
    878  call TermWait(buf)
    879  call VerifyScreenDump(buf, 'Test_mode_2', {})
    880  call StopVimInTerminal(buf)
    881 endfunc
    882 
    883 " Test for append()
    884 func Test_append()
    885  enew!
    886  split
    887  call assert_equal(0, append(1, []))
    888  call assert_equal(0, append(1, v:_null_list))
    889  call assert_equal(0, append(0, ["foo"]))
    890  call assert_equal(0, append(1, []))
    891  call assert_equal(0, append(1, v:_null_list))
    892  call assert_equal(0, append(8, []))
    893  call assert_equal(0, append(9, v:_null_list))
    894  call assert_equal(['foo', ''], getline(1, '$'))
    895  split
    896  only
    897  undo
    898  undo
    899 
    900  " Using $ instead of '$' must give an error
    901  call assert_fails("call append($, 'foobar')", 'E116:')
    902 
    903  call assert_fails("call append({}, '')", ['E728:', 'E728:'])
    904 endfunc
    905 
    906 " Test for setline()
    907 func Test_setline()
    908  new
    909  call setline(0, ["foo"])
    910  call setline(0, [])
    911  call setline(0, v:_null_list)
    912  call setline(1, ["bar"])
    913  call setline(1, [])
    914  call setline(1, v:_null_list)
    915  call setline(2, [])
    916  call setline(2, v:_null_list)
    917  call setline(3, [])
    918  call setline(3, v:_null_list)
    919  call setline(2, ["baz"])
    920  call assert_equal(['bar', 'baz'], getline(1, '$'))
    921  bw!
    922 endfunc
    923 
    924 func Test_getbufvar()
    925  let bnr = bufnr('%')
    926  let b:var_num = '1234'
    927  let def_num = '5678'
    928  call assert_equal('1234', getbufvar(bnr, 'var_num'))
    929  call assert_equal('1234', getbufvar(bnr, 'var_num', def_num))
    930 
    931  let bd = getbufvar(bnr, '')
    932  call assert_equal('1234', bd['var_num'])
    933  call assert_true(exists("bd['changedtick']"))
    934  call assert_equal(2, len(bd))
    935 
    936  let bd2 = getbufvar(bnr, '', def_num)
    937  call assert_equal(bd, bd2)
    938 
    939  unlet b:var_num
    940  call assert_equal(def_num, getbufvar(bnr, 'var_num', def_num))
    941  call assert_equal('', getbufvar(bnr, 'var_num'))
    942 
    943  let bd = getbufvar(bnr, '')
    944  call assert_equal(1, len(bd))
    945  let bd = getbufvar(bnr, '',def_num)
    946  call assert_equal(1, len(bd))
    947 
    948  call assert_equal('', getbufvar(9999, ''))
    949  call assert_equal(def_num, getbufvar(9999, '', def_num))
    950  unlet def_num
    951 
    952  call assert_equal(0, getbufvar(bnr, '&autoindent'))
    953  call assert_equal(0, getbufvar(bnr, '&autoindent', 1))
    954 
    955  " Set and get a buffer-local variable
    956  call setbufvar(bnr, 'bufvar_test', ['one', 'two'])
    957  call assert_equal(['one', 'two'], getbufvar(bnr, 'bufvar_test'))
    958 
    959  " Open new window with forced option values
    960  set fileformats=unix,dos
    961  new ++ff=dos ++bin ++enc=iso-8859-2
    962  call assert_equal('dos', getbufvar(bufnr('%'), '&fileformat'))
    963  call assert_equal(1, getbufvar(bufnr('%'), '&bin'))
    964  call assert_equal('iso-8859-2', getbufvar(bufnr('%'), '&fenc'))
    965  close
    966 
    967  " Get the b: dict.
    968  let b:testvar = 'one'
    969  new
    970  let b:testvar = 'two'
    971  let thebuf = bufnr()
    972  wincmd w
    973  call assert_equal('two', getbufvar(thebuf, 'testvar'))
    974  call assert_equal('two', getbufvar(thebuf, '').testvar)
    975  bwipe!
    976 
    977  set fileformats&
    978 endfunc
    979 
    980 func Test_last_buffer_nr()
    981  call assert_equal(bufnr('$'), last_buffer_nr())
    982 endfunc
    983 
    984 func Test_stridx()
    985  call assert_equal(-1, stridx('', 'l'))
    986  call assert_equal(0,  stridx('', ''))
    987  call assert_equal(0,  'hello'->stridx(''))
    988  call assert_equal(-1, stridx('hello', 'L'))
    989  call assert_equal(2,  stridx('hello', 'l', -1))
    990  call assert_equal(2,  stridx('hello', 'l', 0))
    991  call assert_equal(2,  'hello'->stridx('l', 1))
    992  call assert_equal(3,  stridx('hello', 'l', 3))
    993  call assert_equal(-1, stridx('hello', 'l', 4))
    994  call assert_equal(-1, stridx('hello', 'l', 10))
    995  call assert_equal(2,  stridx('hello', 'll'))
    996  call assert_equal(-1, stridx('hello', 'hello world'))
    997  call assert_fails("let n=stridx('hello', [])", 'E730:')
    998  call assert_fails("let n=stridx([], 'l')", 'E730:')
    999 endfunc
   1000 
   1001 func Test_strridx()
   1002  call assert_equal(-1, strridx('', 'l'))
   1003  call assert_equal(0,  strridx('', ''))
   1004  call assert_equal(5,  strridx('hello', ''))
   1005  call assert_equal(-1, strridx('hello', 'L'))
   1006  call assert_equal(3,  'hello'->strridx('l'))
   1007  call assert_equal(3,  strridx('hello', 'l', 10))
   1008  call assert_equal(3,  strridx('hello', 'l', 3))
   1009  call assert_equal(2,  strridx('hello', 'l', 2))
   1010  call assert_equal(-1, strridx('hello', 'l', 1))
   1011  call assert_equal(-1, strridx('hello', 'l', 0))
   1012  call assert_equal(-1, strridx('hello', 'l', -1))
   1013  call assert_equal(2,  strridx('hello', 'll'))
   1014  call assert_equal(-1, strridx('hello', 'hello world'))
   1015  call assert_fails("let n=strridx('hello', [])", 'E730:')
   1016  call assert_fails("let n=strridx([], 'l')", 'E730:')
   1017 endfunc
   1018 
   1019 func Test_match_func()
   1020  call assert_equal(4,  match('testing', 'ing'))
   1021  call assert_equal(4,  'testing'->match('ing', 2))
   1022  call assert_equal(-1, match('testing', 'ing', 5))
   1023  call assert_equal(-1, match('testing', 'ing', 8))
   1024  call assert_equal(1, match(['vim', 'testing', 'execute'], 'ing'))
   1025  call assert_equal(-1, match(['vim', 'testing', 'execute'], 'img'))
   1026  call assert_fails("let x=match('vim', [])", 'E730:')
   1027  call assert_equal(3, match(['a', 'b', 'c', 'a'], 'a', 1))
   1028  call assert_equal(-1, match(['a', 'b', 'c', 'a'], 'a', 5))
   1029  call assert_equal(4,  match('testing', 'ing', -1))
   1030  call assert_fails("let x=match('testing', 'ing', 0, [])", 'E745:')
   1031  call assert_equal(-1, match(v:_null_list, 2))
   1032  call assert_equal(-1, match('abc', '\\%('))
   1033 endfunc
   1034 
   1035 func Test_matchend()
   1036  call assert_equal(7,  matchend('testing', 'ing'))
   1037  call assert_equal(7,  'testing'->matchend('ing', 2))
   1038  call assert_equal(-1, matchend('testing', 'ing', 5))
   1039  call assert_equal(-1, matchend('testing', 'ing', 8))
   1040  call assert_equal(match(['vim', 'testing', 'execute'], 'ing'), matchend(['vim', 'testing', 'execute'], 'ing'))
   1041  call assert_equal(match(['vim', 'testing', 'execute'], 'img'), matchend(['vim', 'testing', 'execute'], 'img'))
   1042 endfunc
   1043 
   1044 func Test_matchlist()
   1045  call assert_equal(['acd', 'a', '', 'c', 'd', '', '', '', '', ''],  matchlist('acd', '\(a\)\?\(b\)\?\(c\)\?\(.*\)'))
   1046  call assert_equal(['d', '', '', '', 'd', '', '', '', '', ''],  'acd'->matchlist('\(a\)\?\(b\)\?\(c\)\?\(.*\)', 2))
   1047  call assert_equal([],  matchlist('acd', '\(a\)\?\(b\)\?\(c\)\?\(.*\)', 4))
   1048 endfunc
   1049 
   1050 func Test_matchstr()
   1051  call assert_equal('ing',  matchstr('testing', 'ing'))
   1052  call assert_equal('ing',  'testing'->matchstr('ing', 2))
   1053  call assert_equal('', matchstr('testing', 'ing', 5))
   1054  call assert_equal('', matchstr('testing', 'ing', 8))
   1055  call assert_equal('testing', matchstr(['vim', 'testing', 'execute'], 'ing'))
   1056  call assert_equal('', matchstr(['vim', 'testing', 'execute'], 'img'))
   1057 endfunc
   1058 
   1059 func Test_matchstrpos()
   1060  call assert_equal(['ing', 4, 7], matchstrpos('testing', 'ing'))
   1061  call assert_equal(['ing', 4, 7], 'testing'->matchstrpos('ing', 2))
   1062  call assert_equal(['', -1, -1], matchstrpos('testing', 'ing', 5))
   1063  call assert_equal(['', -1, -1], matchstrpos('testing', 'ing', 8))
   1064  call assert_equal(['ing', 1, 4, 7], matchstrpos(['vim', 'testing', 'execute'], 'ing'))
   1065  call assert_equal(['', -1, -1, -1], matchstrpos(['vim', 'testing', 'execute'], 'img'))
   1066  call assert_equal(['', -1, -1], matchstrpos(v:_null_list, '\a'))
   1067 endfunc
   1068 
   1069 " Test for matchstrlist()
   1070 func Test_matchstrlist()
   1071  let lines =<< trim END
   1072    #" Basic match
   1073    call assert_equal([{'idx': 0, 'byteidx': 1, 'text': 'bout'},
   1074          \ {'idx': 1, 'byteidx': 1, 'text': 'bove'}],
   1075          \ matchstrlist(['about', 'above'], 'bo.*'))
   1076    #" no match
   1077    call assert_equal([], matchstrlist(['about', 'above'], 'xy.*'))
   1078    #" empty string
   1079    call assert_equal([], matchstrlist([''], '.'))
   1080    #" empty pattern
   1081    call assert_equal([{'idx': 0, 'byteidx': 0, 'text': ''}], matchstrlist(['abc'], ''))
   1082    #" method call
   1083    call assert_equal([{'idx': 0, 'byteidx': 2, 'text': 'it'}], ['editor']->matchstrlist('ed\zsit\zeor'))
   1084    #" single character matches
   1085    call assert_equal([{'idx': 0, 'byteidx': 5, 'text': 'r'}],
   1086          \ ['editor']->matchstrlist('r'))
   1087    call assert_equal([{'idx': 0, 'byteidx': 0, 'text': 'a'}], ['a']->matchstrlist('a'))
   1088    call assert_equal([{'idx': 0, 'byteidx': 0, 'text': ''}],
   1089          \ matchstrlist(['foobar'], '\zs'))
   1090    #" string with tabs
   1091    call assert_equal([{'idx': 0, 'byteidx': 1, 'text': 'foo'}],
   1092          \ matchstrlist(["\tfoobar"], 'foo'))
   1093    #" string with multibyte characters
   1094    call assert_equal([{'idx': 0, 'byteidx': 2, 'text': '😊😊'}],
   1095          \ matchstrlist(["\t\t😊😊"], '\k\+'))
   1096 
   1097    #" null string
   1098    call assert_equal([], matchstrlist(v:_null_list, 'abc'))
   1099    call assert_equal([], matchstrlist([v:_null_string], 'abc'))
   1100    call assert_equal([{'idx': 0, 'byteidx': 0, 'text': ''}],
   1101          \ matchstrlist(['abc'], v:_null_string))
   1102 
   1103    #" sub matches
   1104    call assert_equal([{'idx': 0, 'byteidx': 0, 'text': 'acd', 'submatches': ['a', '', 'c', 'd', '', '', '', '', '']}], matchstrlist(['acd'], '\(a\)\?\(b\)\?\(c\)\?\(.*\)', {'submatches': v:true}))
   1105 
   1106    #" null dict argument
   1107    call assert_equal([{'idx': 0, 'byteidx': 0, 'text': 'vim'}],
   1108          \ matchstrlist(['vim'], '\w\+', v:_null_dict))
   1109 
   1110    #" Error cases
   1111    call assert_fails("echo matchstrlist('abc', 'a')", 'E1211: List required for argument 1')
   1112    call assert_fails("echo matchstrlist(['abc'], {})", 'E1174: String required for argument 2')
   1113    call assert_fails("echo matchstrlist(['abc'], '.', [])", 'E1206: Dictionary required for argument 3')
   1114    call assert_fails("echo matchstrlist(['abc'], 'a', {'submatches': []})", 'E475: Invalid value for argument submatches')
   1115    call assert_fails("echo matchstrlist(['abc'], '\\@=')", 'E866: (NFA regexp) Misplaced @')
   1116  END
   1117  call CheckLegacyAndVim9Success(lines)
   1118 
   1119  let lines =<< trim END
   1120    vim9script
   1121    # non string items
   1122    matchstrlist([0z10, {'a': 'x'}], 'x')
   1123  END
   1124  call CheckSourceSuccess(lines)
   1125 
   1126  let lines =<< trim END
   1127    vim9script
   1128    def Foo()
   1129      # non string items
   1130      assert_equal([], matchstrlist([0z10, {'a': 'x'}], 'x'))
   1131    enddef
   1132    Foo()
   1133  END
   1134  call CheckSourceFailure(lines, 'E1013: Argument 1: type mismatch, expected list<string> but got list<any>', 2)
   1135 endfunc
   1136 
   1137 " Test for matchbufline()
   1138 func Test_matchbufline()
   1139  let lines =<< trim END
   1140    #" Basic match
   1141    new
   1142    call setline(1, ['about', 'above', 'below'])
   1143    VAR bnr = bufnr()
   1144    wincmd w
   1145    call assert_equal([{'lnum': 1, 'byteidx': 1, 'text': 'bout'},
   1146          \ {'lnum': 2, 'byteidx': 1, 'text': 'bove'}],
   1147          \ matchbufline(bnr, 'bo.*', 1, '$'))
   1148    #" multiple matches in a line
   1149    call setbufline(bnr, 1, ['about about', 'above above', 'below'])
   1150    call assert_equal([{'lnum': 1, 'byteidx': 1, 'text': 'bout'},
   1151          \ {'lnum': 1, 'byteidx': 7, 'text': 'bout'},
   1152          \ {'lnum': 2, 'byteidx': 1, 'text': 'bove'},
   1153          \ {'lnum': 2, 'byteidx': 7, 'text': 'bove'}],
   1154          \ matchbufline(bnr, 'bo\k\+', 1, '$'))
   1155    #" no match
   1156    call assert_equal([], matchbufline(bnr, 'xy.*', 1, '$'))
   1157    #" match on a particular line
   1158    call assert_equal([{'lnum': 2, 'byteidx': 7, 'text': 'bove'}],
   1159          \ matchbufline(bnr, 'bo\k\+$', 2, 2))
   1160    #" match on a particular line
   1161    call assert_equal([], matchbufline(bnr, 'bo.*', 3, 3))
   1162    #" empty string
   1163    call deletebufline(bnr, 1, '$')
   1164    call assert_equal([], matchbufline(bnr, '.', 1, '$'))
   1165    #" empty pattern
   1166    call setbufline(bnr, 1, 'abc')
   1167    call assert_equal([{'lnum': 1, 'byteidx': 0, 'text': ''}],
   1168          \ matchbufline(bnr, '', 1, '$'))
   1169    #" method call
   1170    call setbufline(bnr, 1, 'editor')
   1171    call assert_equal([{'lnum': 1, 'byteidx': 2, 'text': 'it'}],
   1172          \ bnr->matchbufline('ed\zsit\zeor', 1, 1))
   1173    #" single character matches
   1174    call assert_equal([{'lnum': 1, 'byteidx': 5, 'text': 'r'}],
   1175          \ matchbufline(bnr, 'r', 1, '$'))
   1176    call setbufline(bnr, 1, 'a')
   1177    call assert_equal([{'lnum': 1, 'byteidx': 0, 'text': 'a'}],
   1178          \ matchbufline(bnr, 'a', 1, '$'))
   1179    #" zero-width match
   1180    call assert_equal([{'lnum': 1, 'byteidx': 0, 'text': ''}],
   1181          \ matchbufline(bnr, '\zs', 1, '$'))
   1182    #" string with tabs
   1183    call setbufline(bnr, 1, "\tfoobar")
   1184    call assert_equal([{'lnum': 1, 'byteidx': 1, 'text': 'foo'}],
   1185          \ matchbufline(bnr, 'foo', 1, '$'))
   1186    #" string with multibyte characters
   1187    call setbufline(bnr, 1, "\t\t😊😊")
   1188    call assert_equal([{'lnum': 1, 'byteidx': 2, 'text': '😊😊'}],
   1189          \ matchbufline(bnr, '\k\+', 1, '$'))
   1190    #" empty buffer
   1191    call deletebufline(bnr, 1, '$')
   1192    call assert_equal([], matchbufline(bnr, 'abc', 1, '$'))
   1193 
   1194    #" Non existing buffer
   1195    call setbufline(bnr, 1, 'abc')
   1196    call assert_fails("echo matchbufline(5000, 'abc', 1, 1)", 'E158: Invalid buffer name: 5000')
   1197    #" null string
   1198    call assert_equal([{'lnum': 1, 'byteidx': 0, 'text': ''}],
   1199          \ matchbufline(bnr, v:_null_string, 1, 1))
   1200    #" invalid starting line number
   1201    call assert_equal([], matchbufline(bnr, 'abc', 100, 100))
   1202    #" ending line number greater than the last line
   1203    call assert_equal([{'lnum': 1, 'byteidx': 0, 'text': 'abc'}],
   1204          \ matchbufline(bnr, 'abc', 1, 100))
   1205    #" ending line number greater than the starting line number
   1206    call setbufline(bnr, 1, ['one', 'two'])
   1207    call assert_fails($"echo matchbufline({bnr}, 'abc', 2, 1)", 'E475: Invalid value for argument end_lnum')
   1208 
   1209    #" sub matches
   1210    call deletebufline(bnr, 1, '$')
   1211    call setbufline(bnr, 1, 'acd')
   1212    call assert_equal([{'lnum': 1, 'byteidx': 0, 'text': 'acd', 'submatches': ['a', '', 'c', 'd', '', '', '', '', '']}],
   1213          \ matchbufline(bnr, '\(a\)\?\(b\)\?\(c\)\?\(.*\)', 1, '$', {'submatches': v:true}))
   1214 
   1215    #" null dict argument
   1216    call assert_equal([{'lnum': 1, 'byteidx': 0, 'text': 'acd'}],
   1217          \ matchbufline(bnr, '\w\+', '$', '$', v:_null_dict))
   1218 
   1219    #" Error cases
   1220    call assert_fails("echo matchbufline([1], 'abc', 1, 1)", 'E1220: String or Number required for argument 1')
   1221    call assert_fails("echo matchbufline(1, {}, 1, 1)", 'E1174: String required for argument 2')
   1222    call assert_fails("echo matchbufline(1, 'abc', {}, 1)", 'E1220: String or Number required for argument 3')
   1223    call assert_fails("echo matchbufline(1, 'abc', 1, {})", 'E1220: String or Number required for argument 4')
   1224    call assert_fails($"echo matchbufline({bnr}, 'abc', -1, '$')", 'E475: Invalid value for argument lnum')
   1225    call assert_fails($"echo matchbufline({bnr}, 'abc', 1, -1)", 'E475: Invalid value for argument end_lnum')
   1226    call assert_fails($"echo matchbufline({bnr}, '\\@=', 1, 1)", 'E866: (NFA regexp) Misplaced @')
   1227    call assert_fails($"echo matchbufline({bnr}, 'abc', 1, 1, {{'submatches': []}})", 'E475: Invalid value for argument submatches')
   1228    :%bdelete!
   1229    call assert_fails($"echo matchbufline({bnr}, 'abc', 1, '$'))", 'E681: Buffer is not loaded')
   1230  END
   1231  call CheckLegacyAndVim9Success(lines)
   1232 
   1233  call assert_fails($"echo matchbufline('', 'abc', 'abc', 1)", 'E475: Invalid value for argument lnum')
   1234  call assert_fails($"echo matchbufline('', 'abc', 1, 'abc')", 'E475: Invalid value for argument end_lnum')
   1235 
   1236  let lines =<< trim END
   1237    vim9script
   1238    def Foo()
   1239      echo matchbufline('', 'abc', 'abc', 1)
   1240    enddef
   1241    Foo()
   1242  END
   1243  call CheckSourceFailure(lines, 'E1030: Using a String as a Number: "abc"', 1)
   1244 
   1245  let lines =<< trim END
   1246    vim9script
   1247    def Foo()
   1248      echo matchbufline('', 'abc', 1, 'abc')
   1249    enddef
   1250    Foo()
   1251  END
   1252  call CheckSourceFailure(lines, 'E1030: Using a String as a Number: "abc"', 1)
   1253 endfunc
   1254 
   1255 func Test_nextnonblank_prevnonblank()
   1256  new
   1257 insert
   1258 This
   1259 
   1260 
   1261 is
   1262 
   1263 a
   1264 Test
   1265 .
   1266  call assert_equal(0, nextnonblank(-1))
   1267  call assert_equal(0, nextnonblank(0))
   1268  call assert_equal(1, nextnonblank(1))
   1269  call assert_equal(4, 2->nextnonblank())
   1270  call assert_equal(4, nextnonblank(3))
   1271  call assert_equal(4, nextnonblank(4))
   1272  call assert_equal(6, nextnonblank(5))
   1273  call assert_equal(6, nextnonblank(6))
   1274  call assert_equal(7, nextnonblank(7))
   1275  call assert_equal(0, 8->nextnonblank())
   1276 
   1277  call assert_equal(0, prevnonblank(-1))
   1278  call assert_equal(0, prevnonblank(0))
   1279  call assert_equal(1, 1->prevnonblank())
   1280  call assert_equal(1, prevnonblank(2))
   1281  call assert_equal(1, prevnonblank(3))
   1282  call assert_equal(4, prevnonblank(4))
   1283  call assert_equal(4, 5->prevnonblank())
   1284  call assert_equal(6, prevnonblank(6))
   1285  call assert_equal(7, prevnonblank(7))
   1286  call assert_equal(0, prevnonblank(8))
   1287  bw!
   1288 endfunc
   1289 
   1290 func Test_byte2line_line2byte()
   1291  new
   1292  set endofline
   1293  call setline(1, ['a', 'bc', 'd'])
   1294 
   1295  set fileformat=unix
   1296  call assert_equal([-1, -1, 1, 1, 2, 2, 2, 3, 3, -1],
   1297  \                 map(range(-1, 8), 'byte2line(v:val)'))
   1298  call assert_equal([-1, -1, 1, 3, 6, 8, -1],
   1299  \                 map(range(-1, 5), 'line2byte(v:val)'))
   1300 
   1301  set fileformat=mac
   1302  call assert_equal([-1, -1, 1, 1, 2, 2, 2, 3, 3, -1],
   1303  \                 map(range(-1, 8), 'v:val->byte2line()'))
   1304  call assert_equal([-1, -1, 1, 3, 6, 8, -1],
   1305  \                 map(range(-1, 5), 'v:val->line2byte()'))
   1306 
   1307  set fileformat=dos
   1308  call assert_equal([-1, -1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, -1],
   1309  \                 map(range(-1, 11), 'byte2line(v:val)'))
   1310  call assert_equal([-1, -1, 1, 4, 8, 11, -1],
   1311  \                 map(range(-1, 5), 'line2byte(v:val)'))
   1312 
   1313  bw!
   1314  set noendofline nofixendofline
   1315  normal a-
   1316  for ff in ["unix", "mac", "dos"]
   1317    let &fileformat = ff
   1318    call assert_equal(1, line2byte(1))
   1319    call assert_equal(2, line2byte(2))  " line2byte(line("$") + 1) is the buffer size plus one (as per :help line2byte).
   1320  endfor
   1321 
   1322  set endofline& fixendofline& fileformat&
   1323  bw!
   1324 endfunc
   1325 
   1326 " Test for byteidx() using a character index
   1327 func Test_byteidx()
   1328  let a = '.é.' " one char of two bytes
   1329  call assert_equal(0, byteidx(a, 0))
   1330  call assert_equal(1, byteidx(a, 1))
   1331  call assert_equal(3, byteidx(a, 2))
   1332  call assert_equal(4, byteidx(a, 3))
   1333  call assert_equal(-1, byteidx(a, 4))
   1334 
   1335  let b = '.é.' " normal e with composing char
   1336  call assert_equal(0, b->byteidx(0))
   1337  call assert_equal(1, b->byteidx(1))
   1338  call assert_equal(4, b->byteidx(2))
   1339  call assert_equal(5, b->byteidx(3))
   1340  call assert_equal(-1, b->byteidx(4))
   1341 
   1342  " string with multiple composing characters
   1343  let str = '-ą́-ą́'
   1344  call assert_equal(0, byteidx(str, 0))
   1345  call assert_equal(1, byteidx(str, 1))
   1346  call assert_equal(6, byteidx(str, 2))
   1347  call assert_equal(7, byteidx(str, 3))
   1348  call assert_equal(12, byteidx(str, 4))
   1349  call assert_equal(-1, byteidx(str, 5))
   1350 
   1351  " empty string
   1352  call assert_equal(0, byteidx('', 0))
   1353  call assert_equal(-1, byteidx('', 1))
   1354 
   1355  " error cases
   1356  call assert_fails("call byteidx([], 0)", 'E730:')
   1357  call assert_fails("call byteidx('abc', [])", 'E745:')
   1358  call assert_fails("call byteidx('abc', 0, {})", ['E728:', 'E728:'])
   1359  call assert_fails("call byteidx('abc', 0, -1)", ['E1023:', 'E1023:'])
   1360 endfunc
   1361 
   1362 " Test for byteidxcomp() using a character index
   1363 func Test_byteidxcomp()
   1364  let a = '.é.' " one char of two bytes
   1365  call assert_equal(0, byteidxcomp(a, 0))
   1366  call assert_equal(1, byteidxcomp(a, 1))
   1367  call assert_equal(3, byteidxcomp(a, 2))
   1368  call assert_equal(4, byteidxcomp(a, 3))
   1369  call assert_equal(-1, byteidxcomp(a, 4))
   1370 
   1371  let b = '.é.' " normal e with composing char
   1372  call assert_equal(0, b->byteidxcomp(0))
   1373  call assert_equal(1, b->byteidxcomp(1))
   1374  call assert_equal(2, b->byteidxcomp(2))
   1375  call assert_equal(4, b->byteidxcomp(3))
   1376  call assert_equal(5, b->byteidxcomp(4))
   1377  call assert_equal(-1, b->byteidxcomp(5))
   1378 
   1379  " string with multiple composing characters
   1380  let str = '-ą́-ą́'
   1381  call assert_equal(0, byteidxcomp(str, 0))
   1382  call assert_equal(1, byteidxcomp(str, 1))
   1383  call assert_equal(2, byteidxcomp(str, 2))
   1384  call assert_equal(4, byteidxcomp(str, 3))
   1385  call assert_equal(6, byteidxcomp(str, 4))
   1386  call assert_equal(7, byteidxcomp(str, 5))
   1387  call assert_equal(8, byteidxcomp(str, 6))
   1388  call assert_equal(10, byteidxcomp(str, 7))
   1389  call assert_equal(12, byteidxcomp(str, 8))
   1390  call assert_equal(-1, byteidxcomp(str, 9))
   1391 
   1392  " empty string
   1393  call assert_equal(0, byteidxcomp('', 0))
   1394  call assert_equal(-1, byteidxcomp('', 1))
   1395 
   1396  " error cases
   1397  call assert_fails("call byteidxcomp([], 0)", 'E730:')
   1398  call assert_fails("call byteidxcomp('abc', [])", 'E745:')
   1399  call assert_fails("call byteidxcomp('abc', 0, {})", ['E728:', 'E728:'])
   1400  call assert_fails("call byteidxcomp('abc', 0, -1)", ['E1023:', 'E1023:'])
   1401 endfunc
   1402 
   1403 " Test for byteidx() using a UTF-16 index
   1404 func Test_byteidx_from_utf16_index()
   1405  " string with single byte characters
   1406  let str = "abc"
   1407  for i in range(3)
   1408    call assert_equal(i, byteidx(str, i, v:true))
   1409  endfor
   1410  call assert_equal(3, byteidx(str, 3, v:true))
   1411  call assert_equal(-1, byteidx(str, 4, v:true))
   1412 
   1413  " string with two byte characters
   1414  let str = "a©©b"
   1415  call assert_equal(0, byteidx(str, 0, v:true))
   1416  call assert_equal(1, byteidx(str, 1, v:true))
   1417  call assert_equal(3, byteidx(str, 2, v:true))
   1418  call assert_equal(5, byteidx(str, 3, v:true))
   1419  call assert_equal(6, byteidx(str, 4, v:true))
   1420  call assert_equal(-1, byteidx(str, 5, v:true))
   1421 
   1422  " string with two byte characters
   1423  let str = "a😊😊b"
   1424  call assert_equal(0, byteidx(str, 0, v:true))
   1425  call assert_equal(1, byteidx(str, 1, v:true))
   1426  call assert_equal(1, byteidx(str, 2, v:true))
   1427  call assert_equal(5, byteidx(str, 3, v:true))
   1428  call assert_equal(5, byteidx(str, 4, v:true))
   1429  call assert_equal(9, byteidx(str, 5, v:true))
   1430  call assert_equal(10, byteidx(str, 6, v:true))
   1431  call assert_equal(-1, byteidx(str, 7, v:true))
   1432 
   1433  " string with composing characters
   1434  let str = '-á-b́'
   1435  call assert_equal(0, byteidx(str, 0, v:true))
   1436  call assert_equal(1, byteidx(str, 1, v:true))
   1437  call assert_equal(4, byteidx(str, 2, v:true))
   1438  call assert_equal(5, byteidx(str, 3, v:true))
   1439  call assert_equal(8, byteidx(str, 4, v:true))
   1440  call assert_equal(-1, byteidx(str, 5, v:true))
   1441 
   1442  " string with multiple composing characters
   1443  let str = '-ą́-ą́'
   1444  call assert_equal(0, byteidx(str, 0, v:true))
   1445  call assert_equal(1, byteidx(str, 1, v:true))
   1446  call assert_equal(6, byteidx(str, 2, v:true))
   1447  call assert_equal(7, byteidx(str, 3, v:true))
   1448  call assert_equal(12, byteidx(str, 4, v:true))
   1449  call assert_equal(-1, byteidx(str, 5, v:true))
   1450 
   1451  " empty string
   1452  call assert_equal(0, byteidx('', 0, v:true))
   1453  call assert_equal(-1, byteidx('', 1, v:true))
   1454 
   1455  " error cases
   1456  call assert_fails('call byteidx(str, 0, [])', 'E745:')
   1457 endfunc
   1458 
   1459 " Test for byteidxcomp() using a UTF-16 index
   1460 func Test_byteidxcomp_from_utf16_index()
   1461  " string with single byte characters
   1462  let str = "abc"
   1463  for i in range(3)
   1464    call assert_equal(i, byteidxcomp(str, i, v:true))
   1465  endfor
   1466  call assert_equal(3, byteidxcomp(str, 3, v:true))
   1467  call assert_equal(-1, byteidxcomp(str, 4, v:true))
   1468 
   1469  " string with two byte characters
   1470  let str = "a©©b"
   1471  call assert_equal(0, byteidxcomp(str, 0, v:true))
   1472  call assert_equal(1, byteidxcomp(str, 1, v:true))
   1473  call assert_equal(3, byteidxcomp(str, 2, v:true))
   1474  call assert_equal(5, byteidxcomp(str, 3, v:true))
   1475  call assert_equal(6, byteidxcomp(str, 4, v:true))
   1476  call assert_equal(-1, byteidxcomp(str, 5, v:true))
   1477 
   1478  " string with two byte characters
   1479  let str = "a😊😊b"
   1480  call assert_equal(0, byteidxcomp(str, 0, v:true))
   1481  call assert_equal(1, byteidxcomp(str, 1, v:true))
   1482  call assert_equal(1, byteidxcomp(str, 2, v:true))
   1483  call assert_equal(5, byteidxcomp(str, 3, v:true))
   1484  call assert_equal(5, byteidxcomp(str, 4, v:true))
   1485  call assert_equal(9, byteidxcomp(str, 5, v:true))
   1486  call assert_equal(10, byteidxcomp(str, 6, v:true))
   1487  call assert_equal(-1, byteidxcomp(str, 7, v:true))
   1488 
   1489  " string with composing characters
   1490  let str = '-á-b́'
   1491  call assert_equal(0, byteidxcomp(str, 0, v:true))
   1492  call assert_equal(1, byteidxcomp(str, 1, v:true))
   1493  call assert_equal(2, byteidxcomp(str, 2, v:true))
   1494  call assert_equal(4, byteidxcomp(str, 3, v:true))
   1495  call assert_equal(5, byteidxcomp(str, 4, v:true))
   1496  call assert_equal(6, byteidxcomp(str, 5, v:true))
   1497  call assert_equal(8, byteidxcomp(str, 6, v:true))
   1498  call assert_equal(-1, byteidxcomp(str, 7, v:true))
   1499  call assert_fails('call byteidxcomp(str, 0, [])', 'E745:')
   1500 
   1501  " string with multiple composing characters
   1502  let str = '-ą́-ą́'
   1503  call assert_equal(0, byteidxcomp(str, 0, v:true))
   1504  call assert_equal(1, byteidxcomp(str, 1, v:true))
   1505  call assert_equal(2, byteidxcomp(str, 2, v:true))
   1506  call assert_equal(4, byteidxcomp(str, 3, v:true))
   1507  call assert_equal(6, byteidxcomp(str, 4, v:true))
   1508  call assert_equal(7, byteidxcomp(str, 5, v:true))
   1509  call assert_equal(8, byteidxcomp(str, 6, v:true))
   1510  call assert_equal(10, byteidxcomp(str, 7, v:true))
   1511  call assert_equal(12, byteidxcomp(str, 8, v:true))
   1512  call assert_equal(-1, byteidxcomp(str, 9, v:true))
   1513 
   1514  " empty string
   1515  call assert_equal(0, byteidxcomp('', 0, v:true))
   1516  call assert_equal(-1, byteidxcomp('', 1, v:true))
   1517 
   1518  " error cases
   1519  call assert_fails('call byteidxcomp(str, 0, [])', 'E745:')
   1520 endfunc
   1521 
   1522 " Test for charidx() using a byte index
   1523 func Test_charidx()
   1524  let a = 'xáb́y'
   1525  call assert_equal(0, charidx(a, 0))
   1526  call assert_equal(1, charidx(a, 3))
   1527  call assert_equal(2, charidx(a, 4))
   1528  call assert_equal(3, charidx(a, 7))
   1529  call assert_equal(4, charidx(a, 8))
   1530  call assert_equal(-1, charidx(a, 9))
   1531  call assert_equal(-1, charidx(a, -1))
   1532 
   1533  " count composing characters
   1534  call assert_equal(0, a->charidx(0, 1))
   1535  call assert_equal(2, a->charidx(2, 1))
   1536  call assert_equal(3, a->charidx(4, 1))
   1537  call assert_equal(5, a->charidx(7, 1))
   1538  call assert_equal(6, a->charidx(8, 1))
   1539  call assert_equal(-1, a->charidx(9, 1))
   1540 
   1541  " empty string
   1542  call assert_equal(0, charidx('', 0))
   1543  call assert_equal(-1, charidx('', 1))
   1544  call assert_equal(0, charidx('', 0, 1))
   1545  call assert_equal(-1, charidx('', 1, 1))
   1546 
   1547  " error cases
   1548  call assert_equal(0, charidx(v:_null_string, 0))
   1549  call assert_equal(-1, charidx(v:_null_string, 1))
   1550  call assert_fails('let x = charidx([], 1)', 'E1174:')
   1551  call assert_fails('let x = charidx("abc", [])', 'E1210:')
   1552  call assert_fails('let x = charidx("abc", 1, [])', 'E1212:')
   1553  call assert_fails('let x = charidx("abc", 1, -1)', 'E1212:')
   1554  call assert_fails('let x = charidx("abc", 1, 2)', 'E1212:')
   1555 endfunc
   1556 
   1557 " Test for charidx() using a UTF-16 index
   1558 func Test_charidx_from_utf16_index()
   1559  " string with single byte characters
   1560  let str = "abc"
   1561  for i in range(4)
   1562    call assert_equal(i, charidx(str, i, v:false, v:true))
   1563  endfor
   1564  call assert_equal(-1, charidx(str, 4, v:false, v:true))
   1565 
   1566  " string with two byte characters
   1567  let str = "a©©b"
   1568  call assert_equal(0, charidx(str, 0, v:false, v:true))
   1569  call assert_equal(1, charidx(str, 1, v:false, v:true))
   1570  call assert_equal(2, charidx(str, 2, v:false, v:true))
   1571  call assert_equal(3, charidx(str, 3, v:false, v:true))
   1572  call assert_equal(4, charidx(str, 4, v:false, v:true))
   1573  call assert_equal(-1, charidx(str, 5, v:false, v:true))
   1574 
   1575  " string with four byte characters
   1576  let str = "a😊😊b"
   1577  call assert_equal(0, charidx(str, 0, v:false, v:true))
   1578  call assert_equal(1, charidx(str, 1, v:false, v:true))
   1579  call assert_equal(1, charidx(str, 2, v:false, v:true))
   1580  call assert_equal(2, charidx(str, 3, v:false, v:true))
   1581  call assert_equal(2, charidx(str, 4, v:false, v:true))
   1582  call assert_equal(3, charidx(str, 5, v:false, v:true))
   1583  call assert_equal(4, charidx(str, 6, v:false, v:true))
   1584  call assert_equal(-1, charidx(str, 7, v:false, v:true))
   1585 
   1586  " string with composing characters
   1587  let str = '-á-b́'
   1588  for i in str->strcharlen()->range()
   1589    call assert_equal(i, charidx(str, i, v:false, v:true))
   1590  endfor
   1591  call assert_equal(4, charidx(str, 4, v:false, v:true))
   1592  call assert_equal(-1, charidx(str, 5, v:false, v:true))
   1593  for i in str->strchars()->range()
   1594    call assert_equal(i, charidx(str, i, v:true, v:true))
   1595  endfor
   1596  call assert_equal(6, charidx(str, 6, v:true, v:true))
   1597  call assert_equal(-1, charidx(str, 7, v:true, v:true))
   1598 
   1599  " string with multiple composing characters
   1600  let str = '-ą́-ą́'
   1601  for i in str->strcharlen()->range()
   1602    call assert_equal(i, charidx(str, i, v:false, v:true))
   1603  endfor
   1604  call assert_equal(4, charidx(str, 4, v:false, v:true))
   1605  call assert_equal(-1, charidx(str, 5, v:false, v:true))
   1606  for i in str->strchars()->range()
   1607    call assert_equal(i, charidx(str, i, v:true, v:true))
   1608  endfor
   1609  call assert_equal(8, charidx(str, 8, v:true, v:true))
   1610  call assert_equal(-1, charidx(str, 9, v:true, v:true))
   1611 
   1612  " empty string
   1613  call assert_equal(0, charidx('', 0, v:false, v:true))
   1614  call assert_equal(-1, charidx('', 1, v:false, v:true))
   1615  call assert_equal(0, charidx('', 0, v:true, v:true))
   1616  call assert_equal(-1, charidx('', 1, v:true, v:true))
   1617 
   1618  " error cases
   1619  call assert_equal(0, charidx('', 0, v:false, v:true))
   1620  call assert_equal(-1, charidx('', 1, v:false, v:true))
   1621  call assert_equal(0, charidx('', 0, v:true, v:true))
   1622  call assert_equal(-1, charidx('', 1, v:true, v:true))
   1623  call assert_equal(0, charidx(v:_null_string, 0, v:false, v:true))
   1624  call assert_equal(-1, charidx(v:_null_string, 1, v:false, v:true))
   1625  call assert_fails('let x = charidx("abc", 1, v:false, [])', 'E1212:')
   1626  call assert_fails('let x = charidx("abc", 1, v:true, [])', 'E1212:')
   1627 endfunc
   1628 
   1629 " Test for utf16idx() using a byte index
   1630 func Test_utf16idx_from_byteidx()
   1631  " UTF-16 index of a string with single byte characters
   1632  let str = "abc"
   1633  for i in range(4)
   1634    call assert_equal(i, utf16idx(str, i))
   1635  endfor
   1636  call assert_equal(-1, utf16idx(str, 4))
   1637 
   1638  " UTF-16 index of a string with two byte characters
   1639  let str = 'a©©b'
   1640  call assert_equal(0, str->utf16idx(0))
   1641  call assert_equal(1, str->utf16idx(1))
   1642  call assert_equal(1, str->utf16idx(2))
   1643  call assert_equal(2, str->utf16idx(3))
   1644  call assert_equal(2, str->utf16idx(4))
   1645  call assert_equal(3, str->utf16idx(5))
   1646  call assert_equal(4, str->utf16idx(6))
   1647  call assert_equal(-1, str->utf16idx(7))
   1648 
   1649  " UTF-16 index of a string with four byte characters
   1650  let str = 'a😊😊b'
   1651  call assert_equal(0, utf16idx(str, 0))
   1652  call assert_equal(1, utf16idx(str, 1))
   1653  call assert_equal(1, utf16idx(str, 2))
   1654  call assert_equal(1, utf16idx(str, 3))
   1655  call assert_equal(1, utf16idx(str, 4))
   1656  call assert_equal(3, utf16idx(str, 5))
   1657  call assert_equal(3, utf16idx(str, 6))
   1658  call assert_equal(3, utf16idx(str, 7))
   1659  call assert_equal(3, utf16idx(str, 8))
   1660  call assert_equal(5, utf16idx(str, 9))
   1661  call assert_equal(6, utf16idx(str, 10))
   1662  call assert_equal(-1, utf16idx(str, 11))
   1663 
   1664  " UTF-16 index of a string with composing characters
   1665  let str = '-á-b́'
   1666  call assert_equal(0, utf16idx(str, 0))
   1667  call assert_equal(1, utf16idx(str, 1))
   1668  call assert_equal(1, utf16idx(str, 2))
   1669  call assert_equal(1, utf16idx(str, 3))
   1670  call assert_equal(2, utf16idx(str, 4))
   1671  call assert_equal(3, utf16idx(str, 5))
   1672  call assert_equal(3, utf16idx(str, 6))
   1673  call assert_equal(3, utf16idx(str, 7))
   1674  call assert_equal(4, utf16idx(str, 8))
   1675  call assert_equal(-1, utf16idx(str, 9))
   1676  call assert_equal(0, utf16idx(str, 0, v:true))
   1677  call assert_equal(1, utf16idx(str, 1, v:true))
   1678  call assert_equal(2, utf16idx(str, 2, v:true))
   1679  call assert_equal(2, utf16idx(str, 3, v:true))
   1680  call assert_equal(3, utf16idx(str, 4, v:true))
   1681  call assert_equal(4, utf16idx(str, 5, v:true))
   1682  call assert_equal(5, utf16idx(str, 6, v:true))
   1683  call assert_equal(5, utf16idx(str, 7, v:true))
   1684  call assert_equal(6, utf16idx(str, 8, v:true))
   1685  call assert_equal(-1, utf16idx(str, 9, v:true))
   1686 
   1687  " string with multiple composing characters
   1688  let str = '-ą́-ą́'
   1689  call assert_equal(0, utf16idx(str, 0))
   1690  call assert_equal(1, utf16idx(str, 1))
   1691  call assert_equal(1, utf16idx(str, 2))
   1692  call assert_equal(1, utf16idx(str, 3))
   1693  call assert_equal(1, utf16idx(str, 4))
   1694  call assert_equal(1, utf16idx(str, 5))
   1695  call assert_equal(2, utf16idx(str, 6))
   1696  call assert_equal(3, utf16idx(str, 7))
   1697  call assert_equal(3, utf16idx(str, 8))
   1698  call assert_equal(3, utf16idx(str, 9))
   1699  call assert_equal(3, utf16idx(str, 10))
   1700  call assert_equal(3, utf16idx(str, 11))
   1701  call assert_equal(4, utf16idx(str, 12))
   1702  call assert_equal(-1, utf16idx(str, 13))
   1703  call assert_equal(0, utf16idx(str, 0, v:true))
   1704  call assert_equal(1, utf16idx(str, 1, v:true))
   1705  call assert_equal(2, utf16idx(str, 2, v:true))
   1706  call assert_equal(2, utf16idx(str, 3, v:true))
   1707  call assert_equal(3, utf16idx(str, 4, v:true))
   1708  call assert_equal(3, utf16idx(str, 5, v:true))
   1709  call assert_equal(4, utf16idx(str, 6, v:true))
   1710  call assert_equal(5, utf16idx(str, 7, v:true))
   1711  call assert_equal(6, utf16idx(str, 8, v:true))
   1712  call assert_equal(6, utf16idx(str, 9, v:true))
   1713  call assert_equal(7, utf16idx(str, 10, v:true))
   1714  call assert_equal(7, utf16idx(str, 11, v:true))
   1715  call assert_equal(8, utf16idx(str, 12, v:true))
   1716  call assert_equal(-1, utf16idx(str, 13, v:true))
   1717 
   1718  " empty string
   1719  call assert_equal(0, utf16idx('', 0))
   1720  call assert_equal(-1, utf16idx('', 1))
   1721  call assert_equal(0, utf16idx('', 0, v:true))
   1722  call assert_equal(-1, utf16idx('', 1, v:true))
   1723 
   1724  " error cases
   1725  call assert_equal(0, utf16idx("", 0))
   1726  call assert_equal(-1, utf16idx("", 1))
   1727  call assert_equal(-1, utf16idx("abc", -1))
   1728  call assert_equal(0, utf16idx(v:_null_string, 0))
   1729  call assert_equal(-1, utf16idx(v:_null_string, 1))
   1730  call assert_fails('let l = utf16idx([], 0)', 'E1174:')
   1731  call assert_fails('let l = utf16idx("ab", [])', 'E1210:')
   1732  call assert_fails('let l = utf16idx("ab", 0, [])', 'E1212:')
   1733 endfunc
   1734 
   1735 " Test for utf16idx() using a character index
   1736 func Test_utf16idx_from_charidx()
   1737  let str = "abc"
   1738  for i in str->strcharlen()->range()
   1739    call assert_equal(i, utf16idx(str, i, v:false, v:true))
   1740  endfor
   1741  call assert_equal(3, utf16idx(str, 3, v:false, v:true))
   1742  call assert_equal(-1, utf16idx(str, 4, v:false, v:true))
   1743 
   1744  " UTF-16 index of a string with two byte characters
   1745  let str = "a©©b"
   1746  for i in str->strcharlen()->range()
   1747    call assert_equal(i, utf16idx(str, i, v:false, v:true))
   1748  endfor
   1749  call assert_equal(4, utf16idx(str, 4, v:false, v:true))
   1750  call assert_equal(-1, utf16idx(str, 5, v:false, v:true))
   1751 
   1752  " UTF-16 index of a string with four byte characters
   1753  let str = "a😊😊b"
   1754  call assert_equal(0, utf16idx(str, 0, v:false, v:true))
   1755  call assert_equal(1, utf16idx(str, 1, v:false, v:true))
   1756  call assert_equal(3, utf16idx(str, 2, v:false, v:true))
   1757  call assert_equal(5, utf16idx(str, 3, v:false, v:true))
   1758  call assert_equal(6, utf16idx(str, 4, v:false, v:true))
   1759  call assert_equal(-1, utf16idx(str, 5, v:false, v:true))
   1760 
   1761  " UTF-16 index of a string with composing characters
   1762  let str = '-á-b́'
   1763  for i in str->strcharlen()->range()
   1764    call assert_equal(i, utf16idx(str, i, v:false, v:true))
   1765  endfor
   1766  call assert_equal(4, utf16idx(str, 4, v:false, v:true))
   1767  call assert_equal(-1, utf16idx(str, 5, v:false, v:true))
   1768  for i in str->strchars()->range()
   1769    call assert_equal(i, utf16idx(str, i, v:true, v:true))
   1770  endfor
   1771  call assert_equal(6, utf16idx(str, 6, v:true, v:true))
   1772  call assert_equal(-1, utf16idx(str, 7, v:true, v:true))
   1773 
   1774  " string with multiple composing characters
   1775  let str = '-ą́-ą́'
   1776  for i in str->strcharlen()->range()
   1777    call assert_equal(i, utf16idx(str, i, v:false, v:true))
   1778  endfor
   1779  call assert_equal(4, utf16idx(str, 4, v:false, v:true))
   1780  call assert_equal(-1, utf16idx(str, 5, v:false, v:true))
   1781  for i in str->strchars()->range()
   1782    call assert_equal(i, utf16idx(str, i, v:true, v:true))
   1783  endfor
   1784  call assert_equal(8, utf16idx(str, 8, v:true, v:true))
   1785  call assert_equal(-1, utf16idx(str, 9, v:true, v:true))
   1786 
   1787  " empty string
   1788  call assert_equal(0, utf16idx('', 0, v:false, v:true))
   1789  call assert_equal(-1, utf16idx('', 1, v:false, v:true))
   1790  call assert_equal(0, utf16idx('', 0, v:true, v:true))
   1791  call assert_equal(-1, utf16idx('', 1, v:true, v:true))
   1792 
   1793  " error cases
   1794  call assert_equal(0, utf16idx(v:_null_string, 0, v:true, v:true))
   1795  call assert_equal(-1, utf16idx(v:_null_string, 1, v:true, v:true))
   1796  call assert_fails('let l = utf16idx("ab", 0, v:false, [])', 'E1212:')
   1797 endfunc
   1798 
   1799 " Test for strutf16len()
   1800 func Test_strutf16len()
   1801  call assert_equal(3, strutf16len('abc'))
   1802  call assert_equal(3, 'abc'->strutf16len(v:true))
   1803  call assert_equal(4, strutf16len('a©©b'))
   1804  call assert_equal(4, strutf16len('a©©b', v:true))
   1805  call assert_equal(6, strutf16len('a😊😊b'))
   1806  call assert_equal(6, strutf16len('a😊😊b', v:true))
   1807  call assert_equal(4, strutf16len('-á-b́'))
   1808  call assert_equal(6, strutf16len('-á-b́', v:true))
   1809  call assert_equal(4, strutf16len('-ą́-ą́'))
   1810  call assert_equal(8, strutf16len('-ą́-ą́', v:true))
   1811  call assert_equal(0, strutf16len(''))
   1812 
   1813  " error cases
   1814  call assert_fails('let l = strutf16len([])', 'E1174:')
   1815  call assert_fails('let l = strutf16len("a", [])', 'E1212:')
   1816  call assert_equal(0, strutf16len(v:_null_string))
   1817 endfunc
   1818 
   1819 func Test_count()
   1820  let l = ['a', 'a', 'A', 'b']
   1821  call assert_equal(2, count(l, 'a'))
   1822  call assert_equal(1, count(l, 'A'))
   1823  call assert_equal(1, count(l, 'b'))
   1824  call assert_equal(0, count(l, 'B'))
   1825 
   1826  call assert_equal(2, count(l, 'a', 0))
   1827  call assert_equal(1, count(l, 'A', 0))
   1828  call assert_equal(1, count(l, 'b', 0))
   1829  call assert_equal(0, count(l, 'B', 0))
   1830 
   1831  call assert_equal(3, count(l, 'a', 1))
   1832  call assert_equal(3, count(l, 'A', 1))
   1833  call assert_equal(1, count(l, 'b', 1))
   1834  call assert_equal(1, count(l, 'B', 1))
   1835  call assert_equal(0, count(l, 'c', 1))
   1836 
   1837  call assert_equal(1, count(l, 'a', 0, 1))
   1838  call assert_equal(2, count(l, 'a', 1, 1))
   1839  call assert_fails('call count(l, "a", 0, 10)', 'E684:')
   1840  call assert_fails('call count(l, "a", [])', 'E745:')
   1841 
   1842  let d = {1: 'a', 2: 'a', 3: 'A', 4: 'b'}
   1843  call assert_equal(2, count(d, 'a'))
   1844  call assert_equal(1, count(d, 'A'))
   1845  call assert_equal(1, count(d, 'b'))
   1846  call assert_equal(0, count(d, 'B'))
   1847 
   1848  call assert_equal(2, count(d, 'a', 0))
   1849  call assert_equal(1, count(d, 'A', 0))
   1850  call assert_equal(1, count(d, 'b', 0))
   1851  call assert_equal(0, count(d, 'B', 0))
   1852 
   1853  call assert_equal(3, count(d, 'a', 1))
   1854  call assert_equal(3, count(d, 'A', 1))
   1855  call assert_equal(1, count(d, 'b', 1))
   1856  call assert_equal(1, count(d, 'B', 1))
   1857  call assert_equal(0, count(d, 'c', 1))
   1858 
   1859  call assert_fails('call count(d, "a", 0, 1)', 'E474:')
   1860 
   1861  call assert_equal(0, count("foo", "bar"))
   1862  call assert_equal(1, count("foo", "oo"))
   1863  call assert_equal(2, count("foo", "o"))
   1864  call assert_equal(0, count("foo", "O"))
   1865  call assert_equal(2, count("foo", "O", 1))
   1866  call assert_equal(2, count("fooooo", "oo"))
   1867  call assert_equal(0, count("foo", ""))
   1868 
   1869  call assert_fails('call count(0, 0)', 'E706:')
   1870  call assert_fails('call count("", "", {})', ['E728:', 'E728:'])
   1871 endfunc
   1872 
   1873 func Test_changenr()
   1874  new Xchangenr
   1875  call assert_equal(0, changenr())
   1876  norm ifoo
   1877  call assert_equal(1, changenr())
   1878  set undolevels=10
   1879  norm Sbar
   1880  call assert_equal(2, changenr())
   1881  undo
   1882  call assert_equal(1, changenr())
   1883  redo
   1884  call assert_equal(2, changenr())
   1885  bw!
   1886  set undolevels&
   1887 endfunc
   1888 
   1889 func Test_filewritable()
   1890  new Xfilewritable
   1891  write!
   1892  call assert_equal(1, filewritable('Xfilewritable'))
   1893 
   1894  call assert_notequal(0, setfperm('Xfilewritable', 'r--r-----'))
   1895  call assert_equal(0, filewritable('Xfilewritable'))
   1896 
   1897  call assert_notequal(0, setfperm('Xfilewritable', 'rw-r-----'))
   1898  call assert_equal(1, 'Xfilewritable'->filewritable())
   1899 
   1900  call assert_equal(0, filewritable('doesnotexist'))
   1901 
   1902  call mkdir('Xdir')
   1903  call assert_equal(2, filewritable('Xdir'))
   1904  call delete('Xdir', 'd')
   1905 
   1906  call delete('Xfilewritable')
   1907  bw!
   1908 endfunc
   1909 
   1910 func Test_Executable()
   1911  if has('win32')
   1912    call assert_equal(1, executable('notepad'))
   1913    call assert_equal(1, 'notepad.exe'->executable())
   1914    call assert_equal(0, executable('notepad.exe.exe'))
   1915    call assert_equal(0, executable('shell32.dll'))
   1916    call assert_equal(0, executable('win.ini'))
   1917  elseif has('unix')
   1918    call assert_equal(1, 'cat'->executable())
   1919    call assert_equal(0, executable('nodogshere'))
   1920 
   1921    " get "cat" path and remove the leading /
   1922    let catcmd = exepath('cat')[1:]
   1923    new
   1924    " check that the relative path works in /
   1925    lcd /
   1926    call assert_equal(1, executable(catcmd))
   1927    let result = catcmd->exepath()
   1928    " when using chroot looking for sbin/cat can return bin/cat, that is OK
   1929    if catcmd =~ '\<sbin\>' && result =~ '\<bin\>'
   1930      call assert_equal('/' .. substitute(catcmd, '\<sbin\>', 'bin', ''), result)
   1931    else
   1932      " /bin/cat and /usr/bin/cat may be hard linked, we could get either
   1933      let result = substitute(result, '/usr/bin/cat', '/bin/cat', '')
   1934      let catcmd = substitute(catcmd, 'usr/bin/cat', 'bin/cat', '')
   1935      call assert_equal('/' .. catcmd, result)
   1936    endif
   1937    bwipe
   1938  else
   1939    throw 'Skipped: does not work on this platform'
   1940  endif
   1941 endfunc
   1942 
   1943 func Test_executable_longname()
   1944  if !has('win32')
   1945    return
   1946  endif
   1947 
   1948  let fname = 'X' . repeat('あ', 200) . '.bat'
   1949  call writefile([], fname)
   1950  call assert_equal(1, executable(fname))
   1951  call delete(fname)
   1952 endfunc
   1953 
   1954 func Test_hostname()
   1955  let hostname_vim = hostname()
   1956  if has('unix')
   1957    let hostname_system = systemlist('uname -n')[0]
   1958    call assert_equal(hostname_vim, hostname_system)
   1959  endif
   1960 endfunc
   1961 
   1962 func Test_getpid()
   1963  " getpid() always returns the same value within a vim instance.
   1964  call assert_equal(getpid(), getpid())
   1965  if has('unix')
   1966    call assert_equal(systemlist('echo $PPID')[0], string(getpid()))
   1967  endif
   1968 endfunc
   1969 
   1970 func Test_hlexists()
   1971  call assert_equal(0, hlexists('does_not_exist'))
   1972  " call assert_equal(0, 'Number'->hlexists())
   1973  call assert_equal(0, highlight_exists('does_not_exist'))
   1974  " call assert_equal(0, highlight_exists('Number'))
   1975  syntax on
   1976  call assert_equal(0, hlexists('does_not_exist'))
   1977  " call assert_equal(1, hlexists('Number'))
   1978  call assert_equal(0, highlight_exists('does_not_exist'))
   1979  " call assert_equal(1, highlight_exists('Number'))
   1980  syntax off
   1981 endfunc
   1982 
   1983 " Test for the col() function
   1984 func Test_col()
   1985  new
   1986  call setline(1, 'abcdef')
   1987  norm gg4|mx6|mY2|
   1988  call assert_equal(2, col('.'))
   1989  call assert_equal(7, col('$'))
   1990  call assert_equal(2, col('v'))
   1991  call assert_equal(4, col("'x"))
   1992  call assert_equal(6, col("'Y"))
   1993  call assert_equal(2, [1, 2]->col())
   1994  call assert_equal(7, col([1, '$']))
   1995 
   1996  call assert_equal(0, col(''))
   1997  call assert_equal(0, col('x'))
   1998  call assert_equal(0, col([2, '$']))
   1999  call assert_equal(0, col([1, 100]))
   2000  call assert_equal(0, col([1]))
   2001  call assert_equal(0, col(v:_null_list))
   2002  call assert_fails('let c = col({})', 'E1222:')
   2003  call assert_fails('let c = col(".", [])', 'E1210:')
   2004 
   2005  " test for getting the visual start column
   2006  func T()
   2007    let g:Vcol = col('v')
   2008    return ''
   2009  endfunc
   2010  let g:Vcol = 0
   2011  xmap <expr> <F2> T()
   2012  exe "normal gg3|ve\<F2>"
   2013  call assert_equal(3, g:Vcol)
   2014  xunmap <F2>
   2015  delfunc T
   2016 
   2017  " Test for the visual line start and end marks '< and '>
   2018  call setline(1, ['one', 'one two', 'one two three'])
   2019  "normal! ggVG
   2020  call feedkeys("ggVG\<Esc>", 'xt')
   2021  call assert_equal(1, col("'<"))
   2022  call assert_equal(14, col("'>"))
   2023  " Delete the last line of the visually selected region
   2024  $d
   2025  call assert_notequal(14, col("'>"))
   2026 
   2027  " Test with 'virtualedit'
   2028  set virtualedit=all
   2029  call cursor(1, 10)
   2030  call assert_equal(4, col('.'))
   2031  set virtualedit&
   2032 
   2033  " Test for getting the column number in another window
   2034  let winid = win_getid()
   2035  new
   2036  call win_execute(winid, 'normal 1G$')
   2037  call assert_equal(3, col('.', winid))
   2038  call win_execute(winid, 'normal 2G')
   2039  call assert_equal(8, col('$', winid))
   2040  call assert_equal(0, col('.', 5001))
   2041 
   2042  bw!
   2043 endfunc
   2044 
   2045 " Test for input()
   2046 func Test_input_func()
   2047  " Test for prompt with multiple lines
   2048  redir => v
   2049  call feedkeys(":let c = input(\"A\\nB\\nC\\n? \")\<CR>B\<CR>", 'xt')
   2050  redir END
   2051  call assert_equal("B", c)
   2052  call assert_equal(['A', 'B', 'C'], split(v, "\n"))
   2053 
   2054  " Test for default value
   2055  call feedkeys(":let c = input('color? ', 'red')\<CR>\<CR>", 'xt')
   2056  call assert_equal('red', c)
   2057 
   2058  " Test for completion at the input prompt
   2059  func! Tcomplete(arglead, cmdline, pos)
   2060    return "item1\nitem2\nitem3"
   2061  endfunc
   2062  call feedkeys(":let c = input('Q? ', '', 'custom,Tcomplete')\<CR>"
   2063        \ .. "\<C-A>\<CR>", 'xt')
   2064  delfunc Tcomplete
   2065  call assert_equal('item1 item2 item3', c)
   2066 
   2067  " Test for using special characters as default input
   2068  call feedkeys(":let c = input('name? ', \"x\\<BS>y\")\<CR>\<CR>", 'xt')
   2069  call assert_equal('y', c)
   2070 
   2071  " Test for using text with composing characters as default input
   2072  call feedkeys(":let c = input('name? ', \"ã̳\")\<CR>\<CR>", 'xt')
   2073  call assert_equal('ã̳', c)
   2074 
   2075  " Test for using <CR> as default input
   2076  call feedkeys(":let c = input('name? ', \"\\<CR>\")\<CR>x\<CR>", 'xt')
   2077  call assert_equal(' x', c)
   2078 
   2079  call assert_fails("call input('F:', '', 'invalid')", 'E180:')
   2080  call assert_fails("call input('F:', '', [])", 'E730:')
   2081 
   2082  " Test for using "command" as the completion function
   2083  call feedkeys(":let c = input('Command? ', '', 'command')\<CR>"
   2084        \ .. "echo bufnam\<C-A>\<CR>", 'xt')
   2085  call assert_equal('echo bufname(', c)
   2086 
   2087  " Test for using "shellcmdline" as the completion function
   2088  call feedkeys(":let c = input('Shell? ', '', 'shellcmdline')\<CR>"
   2089        \ .. "vim test_functions.\<C-A>\<CR>", 'xt')
   2090  call assert_equal('vim test_functions.vim', c)
   2091  if executable('whoami')
   2092    call feedkeys(":let c = input('Shell? ', '', 'shellcmdline')\<CR>"
   2093          \ .. "whoam\<C-A>\<CR>", 'xt')
   2094    call assert_match('\<whoami\>', c)
   2095  endif
   2096 endfunc
   2097 
   2098 " Test for the inputdialog() function
   2099 func Test_inputdialog()
   2100  set timeout timeoutlen=10
   2101  if has('gui_running')
   2102    call assert_fails('let v=inputdialog([], "xx")', 'E730:')
   2103    call assert_fails('let v=inputdialog("Q", [])', 'E730:')
   2104  else
   2105    call feedkeys(":let v=inputdialog('Q:', 'xx', 'yy')\<CR>\<CR>", 'xt')
   2106    call assert_equal('xx', v)
   2107    call feedkeys(":let v=inputdialog('Q:', 'xx', 'yy')\<CR>\<Esc>", 'xt')
   2108    call assert_equal('yy', v)
   2109  endif
   2110  set timeout& timeoutlen&
   2111 endfunc
   2112 
   2113 " Test for inputlist()
   2114 func Test_inputlist()
   2115  call feedkeys(":let c = inputlist(['Select color:', '1. red', '2. green', '3. blue'])\<cr>1\<cr>", 'tx')
   2116  call assert_equal(1, c)
   2117  call feedkeys(":let c = ['Select color:', '1. red', '2. green', '3. blue']->inputlist()\<cr>2\<cr>", 'tx')
   2118  call assert_equal(2, c)
   2119  call feedkeys(":let c = inputlist(['Select color:', '1. red', '2. green', '3. blue'])\<cr>3\<cr>", 'tx')
   2120  call assert_equal(3, c)
   2121 
   2122  " CR to cancel
   2123  call feedkeys(":let c = inputlist(['Select color:', '1. red', '2. green', '3. blue'])\<cr>\<cr>", 'tx')
   2124  call assert_equal(0, c)
   2125 
   2126  " Esc to cancel
   2127  call feedkeys(":let c = inputlist(['Select color:', '1. red', '2. green', '3. blue'])\<cr>\<Esc>", 'tx')
   2128  call assert_equal(0, c)
   2129 
   2130  " q to cancel
   2131  call feedkeys(":let c = inputlist(['Select color:', '1. red', '2. green', '3. blue'])\<cr>q", 'tx')
   2132  call assert_equal(0, c)
   2133 
   2134  " Cancel after inputting a number
   2135  call feedkeys(":let c = inputlist(['Select color:', '1. red', '2. green', '3. blue'])\<cr>5q", 'tx')
   2136  call assert_equal(0, c)
   2137 
   2138  " Use backspace to delete characters in the prompt
   2139  call feedkeys(":let c = inputlist(['Select color:', '1. red', '2. green', '3. blue'])\<cr>1\<BS>3\<BS>2\<cr>", 'tx')
   2140  call assert_equal(2, c)
   2141 
   2142  " Use mouse to make a selection
   2143  call Ntest_setmouse(&lines - 3, 2)
   2144  call feedkeys(":let c = inputlist(['Select color:', '1. red', '2. green', '3. blue'])\<cr>\<LeftMouse>", 'tx')
   2145  call assert_equal(1, c)
   2146  " Mouse click outside of the list
   2147  call Ntest_setmouse(&lines - 6, 2)
   2148  call feedkeys(":let c = inputlist(['Select color:', '1. red', '2. green', '3. blue'])\<cr>\<LeftMouse>", 'tx')
   2149  call assert_equal(-2, c)
   2150 
   2151  call assert_fails('call inputlist("")', 'E686:')
   2152  " Nvim accepts null list as empty list
   2153  " call assert_fails('call inputlist(v:_null_list)', 'E686:')
   2154 endfunc
   2155 
   2156 func Test_range_inputlist()
   2157  " flush out any garbage left in the buffer
   2158  while getchar(0)
   2159  endwhile
   2160 
   2161  call feedkeys(":let result = inputlist(range(10))\<CR>1\<CR>", 'x')
   2162  call assert_equal(1, result)
   2163  call feedkeys(":let result = inputlist(range(3, 10))\<CR>1\<CR>", 'x')
   2164  call assert_equal(1, result)
   2165 
   2166  unlet result
   2167 endfunc
   2168 
   2169 func Test_balloon_show()
   2170  CheckFeature balloon_eval
   2171 
   2172  " This won't do anything but must not crash either.
   2173  call balloon_show('hi!')
   2174  if !has('gui_running')
   2175    call balloon_show(range(3))
   2176    call balloon_show([])
   2177  endif
   2178 endfunc
   2179 
   2180 func Test_setbufvar_options()
   2181  " This tests that aucmd_prepbuf() and aucmd_restbuf() properly restore the
   2182  " window layout and cursor position.
   2183  call assert_equal(1, winnr('$'))
   2184  split dummy_preview
   2185  resize 2
   2186  set winfixheight winfixwidth
   2187  let prev_id = win_getid()
   2188 
   2189  wincmd j
   2190  let wh = winheight(0)
   2191  let dummy_buf = bufnr('dummy_buf1', v:true)
   2192  call setbufvar(dummy_buf, '&buftype', 'nofile')
   2193  execute 'belowright vertical split #' . dummy_buf
   2194  call assert_equal(wh, winheight(0))
   2195  let dum1_id = win_getid()
   2196  call setline(1, 'foo')
   2197  normal! V$
   2198  call assert_equal(4, col('.'))
   2199  call setbufvar('dummy_preview', '&buftype', 'nofile')
   2200  call assert_equal(4, col('.'))
   2201 
   2202  wincmd h
   2203  let wh = winheight(0)
   2204  call setline(1, 'foo')
   2205  normal! V$
   2206  call assert_equal(4, col('.'))
   2207  let dummy_buf = bufnr('dummy_buf2', v:true)
   2208  eval 'nofile'->setbufvar(dummy_buf, '&buftype')
   2209  call assert_equal(4, col('.'))
   2210  execute 'belowright vertical split #' . dummy_buf
   2211  call assert_equal(wh, winheight(0))
   2212 
   2213  bwipe!
   2214  call win_gotoid(prev_id)
   2215  bwipe!
   2216  call win_gotoid(dum1_id)
   2217  bwipe!
   2218 endfunc
   2219 
   2220 func Test_setbufvar_keep_window_title()
   2221  CheckRunVimInTerminal
   2222  if !has('title') || empty(&t_ts)
   2223    throw "Skipped: can't get/set title"
   2224  endif
   2225 
   2226  let lines =<< trim END
   2227      set title
   2228      edit Xa.txt
   2229      let g:buf = bufadd('Xb.txt')
   2230      inoremap <F2> <C-R>=setbufvar(g:buf, '&autoindent', 1) ?? ''<CR>
   2231  END
   2232  call writefile(lines, 'Xsetbufvar')
   2233  let buf = RunVimInTerminal('-S Xsetbufvar', {})
   2234  call WaitForAssert({-> assert_match('Xa.txt', term_gettitle(buf))}, 1000)
   2235 
   2236  call term_sendkeys(buf, "i\<F2>")
   2237  call TermWait(buf)
   2238  call term_sendkeys(buf, "\<Esc>")
   2239  call TermWait(buf)
   2240  call assert_match('Xa.txt', term_gettitle(buf))
   2241 
   2242  call StopVimInTerminal(buf)
   2243  call delete('Xsetbufvar')
   2244 endfunc
   2245 
   2246 func Test_redo_in_nested_functions()
   2247  nnoremap g. :set opfunc=Operator<CR>g@
   2248  function Operator( type, ... )
   2249     let @x = 'XXX'
   2250     execute 'normal! g`[' . (a:type ==# 'line' ? 'V' : 'v') . 'g`]' . '"xp'
   2251  endfunction
   2252 
   2253  function! Apply()
   2254      5,6normal! .
   2255  endfunction
   2256 
   2257  new
   2258  call setline(1, repeat(['some "quoted" text', 'more "quoted" text'], 3))
   2259  1normal g.i"
   2260  call assert_equal('some "XXX" text', getline(1))
   2261  3,4normal .
   2262  call assert_equal('some "XXX" text', getline(3))
   2263  call assert_equal('more "XXX" text', getline(4))
   2264  call Apply()
   2265  call assert_equal('some "XXX" text', getline(5))
   2266  call assert_equal('more "XXX" text', getline(6))
   2267  bwipe!
   2268 
   2269  nunmap g.
   2270  delfunc Operator
   2271  delfunc Apply
   2272 endfunc
   2273 
   2274 func Test_trim()
   2275  call assert_equal("Testing", trim("  \t\r\r\x0BTesting  \t\n\r\n\t\x0B\x0B"))
   2276  call assert_equal("Testing", "  \t  \r\r\n\n\x0BTesting  \t\n\r\n\t\x0B\x0B"->trim())
   2277  call assert_equal("RESERVE", trim("xyz \twwRESERVEzyww \t\t", " wxyz\t"))
   2278  call assert_equal("wRE    \tSERVEzyww", trim("wRE    \tSERVEzyww"))
   2279  call assert_equal("abcd\t     xxxx   tail", trim(" \tabcd\t     xxxx   tail"))
   2280  call assert_equal("\tabcd\t     xxxx   tail", trim(" \tabcd\t     xxxx   tail", " "))
   2281  call assert_equal(" \tabcd\t     xxxx   tail", trim(" \tabcd\t     xxxx   tail", "abx"))
   2282  call assert_equal("RESERVE", trim("你RESERVE好", "你好"))
   2283  call assert_equal("您R E SER V E早", trim("你好您R E SER V E早好你你", "你好"))
   2284  call assert_equal("你好您R E SER V E早好你你", trim(" \n\r\r   你好您R E SER V E早好你你    \t  \x0B", ))
   2285  call assert_equal("您R E SER V E早好你你    \t  \x0B", trim("    你好您R E SER V E早好你你    \t  \x0B", " 你好"))
   2286  call assert_equal("您R E SER V E早好你你    \t  \x0B", trim("    tteesstttt你好您R E SER V E早好你你    \t  \x0B ttestt", " 你好tes"))
   2287  call assert_equal("您R E SER V E早好你你    \t  \x0B", trim("    tteesstttt你好您R E SER V E早好你你    \t  \x0B ttestt", "   你你你好好好tttsses"))
   2288  call assert_equal("留下", trim("这些些不要这些留下这些", "这些不要"))
   2289  call assert_equal("", trim("", ""))
   2290  call assert_equal("a", trim("a", ""))
   2291  call assert_equal("", trim("", "a"))
   2292  call assert_equal("vim", trim("  vim  ", " ", 0))
   2293  call assert_equal("vim  ", trim("  vim  ", " ", 1))
   2294  call assert_equal("  vim", trim("  vim  ", " ", 2))
   2295  call assert_fails('eval trim("  vim  ", " ", [])', 'E745:')
   2296  call assert_fails('eval trim("  vim  ", " ", -1)', 'E475:')
   2297  call assert_fails('eval trim("  vim  ", " ", 3)', 'E475:')
   2298  call assert_fails('eval trim("  vim  ", 0)', 'E1174:')
   2299 
   2300  let chars = join(map(range(1, 0x20) + [0xa0], {n -> n->nr2char()}), '')
   2301  call assert_equal("x", trim(chars . "x" . chars))
   2302 
   2303  call assert_equal("x", trim(chars . "x" . chars, '', 0))
   2304  call assert_equal("x" . chars, trim(chars . "x" . chars, '', 1))
   2305  call assert_equal(chars . "x", trim(chars . "x" . chars, '', 2))
   2306 
   2307  call assert_fails('let c=trim([])', 'E730:')
   2308 endfunc
   2309 
   2310 " Test for reg_recording() and reg_executing()
   2311 func Test_reg_executing_and_recording()
   2312  let s:reg_stat = ''
   2313  func s:save_reg_stat()
   2314    let s:reg_stat = reg_recording() . ':' . reg_executing()
   2315    return ''
   2316  endfunc
   2317 
   2318  new
   2319  call s:save_reg_stat()
   2320  call assert_equal(':', s:reg_stat)
   2321  call feedkeys("qa\"=s:save_reg_stat()\<CR>pq", 'xt')
   2322  call assert_equal('a:', s:reg_stat)
   2323  call feedkeys("@a", 'xt')
   2324  call assert_equal(':a', s:reg_stat)
   2325  call feedkeys("qb@aq", 'xt')
   2326  call assert_equal('b:a', s:reg_stat)
   2327  call feedkeys("q\"\"=s:save_reg_stat()\<CR>pq", 'xt')
   2328  call assert_equal('":', s:reg_stat)
   2329 
   2330  " :normal command saves and restores reg_executing
   2331  let s:reg_stat = ''
   2332  let @q = ":call TestFunc()\<CR>:call s:save_reg_stat()\<CR>"
   2333  func TestFunc() abort
   2334    normal! ia
   2335  endfunc
   2336  call feedkeys("@q", 'xt')
   2337  call assert_equal(':q', s:reg_stat)
   2338  delfunc TestFunc
   2339 
   2340  " getchar() command saves and restores reg_executing
   2341  map W :call TestFunc()<CR>
   2342  let @q = "W"
   2343  let g:typed = ''
   2344  let g:regs = []
   2345  func TestFunc() abort
   2346    let g:regs += [reg_executing()]
   2347    let g:typed = getchar(0)
   2348    let g:regs += [reg_executing()]
   2349  endfunc
   2350  call feedkeys("@qy", 'xt')
   2351  call assert_equal(char2nr("y"), g:typed)
   2352  call assert_equal(['q', 'q'], g:regs)
   2353  delfunc TestFunc
   2354  unmap W
   2355  unlet g:typed
   2356  unlet g:regs
   2357 
   2358  " input() command saves and restores reg_executing
   2359  map W :call TestFunc()<CR>
   2360  let @q = "W"
   2361  let g:typed = ''
   2362  let g:regs = []
   2363  func TestFunc() abort
   2364    let g:regs += [reg_executing()]
   2365    let g:typed = '?'->input()
   2366    let g:regs += [reg_executing()]
   2367  endfunc
   2368  call feedkeys("@qy\<CR>", 'xt')
   2369  call assert_equal("y", g:typed)
   2370  call assert_equal(['q', 'q'], g:regs)
   2371  delfunc TestFunc
   2372  unmap W
   2373  unlet g:typed
   2374  unlet g:regs
   2375 
   2376  bwipe!
   2377  delfunc s:save_reg_stat
   2378  unlet s:reg_stat
   2379 endfunc
   2380 
   2381 func Test_inputsecret()
   2382  map W :call TestFunc()<CR>
   2383  let @q = "W"
   2384  let g:typed1 = ''
   2385  let g:typed2 = ''
   2386  let g:regs = []
   2387  func TestFunc() abort
   2388    let g:typed1 = '?'->inputsecret()
   2389    let g:typed2 = inputsecret('password: ')
   2390  endfunc
   2391  call feedkeys("@qsomething\<CR>else\<CR>", 'xt')
   2392  call assert_equal("something", g:typed1)
   2393  call assert_equal("else", g:typed2)
   2394  delfunc TestFunc
   2395  unmap W
   2396  unlet g:typed1
   2397  unlet g:typed2
   2398 endfunc
   2399 
   2400 func Test_getchar()
   2401  call feedkeys('a', '')
   2402  call assert_equal(char2nr('a'), getchar())
   2403  call assert_equal(0, getchar(0))
   2404  call assert_equal(0, getchar(1))
   2405 
   2406  call feedkeys('a', '')
   2407  call assert_equal('a', getcharstr())
   2408  call assert_equal('', getcharstr(0))
   2409  call assert_equal('', getcharstr(1))
   2410 
   2411  call feedkeys("\<M-F2>", '')
   2412  call assert_equal("\<M-F2>", getchar(0))
   2413  call assert_equal(0, getchar(0))
   2414 
   2415  call feedkeys("\<Tab>", '')
   2416  call assert_equal(char2nr("\<Tab>"), getchar())
   2417  call feedkeys("\<Tab>", '')
   2418  call assert_equal(char2nr("\<Tab>"), getchar(-1))
   2419  call feedkeys("\<Tab>", '')
   2420  call assert_equal(char2nr("\<Tab>"), getchar(-1, {}))
   2421  call feedkeys("\<Tab>", '')
   2422  call assert_equal(char2nr("\<Tab>"), getchar(-1, #{number: v:true}))
   2423  call assert_equal(0, getchar(0))
   2424  call assert_equal(0, getchar(1))
   2425  call assert_equal(0, getchar(0, #{number: v:true}))
   2426  call assert_equal(0, getchar(1, #{number: v:true}))
   2427 
   2428  call feedkeys("\<Tab>", '')
   2429  call assert_equal("\<Tab>", getcharstr())
   2430  call feedkeys("\<Tab>", '')
   2431  call assert_equal("\<Tab>", getcharstr(-1))
   2432  call feedkeys("\<Tab>", '')
   2433  call assert_equal("\<Tab>", getcharstr(-1, {}))
   2434  call feedkeys("\<Tab>", '')
   2435  call assert_equal("\<Tab>", getchar(-1, #{number: v:false}))
   2436  call assert_equal('', getcharstr(0))
   2437  call assert_equal('', getcharstr(1))
   2438  call assert_equal('', getchar(0, #{number: v:false}))
   2439  call assert_equal('', getchar(1, #{number: v:false}))
   2440 
   2441  " Nvim: <M-x> is never simplified
   2442  " for key in ["C-I", "C-X", "M-x"]
   2443  for key in ["C-I", "C-X"]
   2444    let lines =<< eval trim END
   2445      call feedkeys("\<*{key}>", '')
   2446      call assert_equal(char2nr("\<{key}>"), getchar())
   2447      call feedkeys("\<*{key}>", '')
   2448      call assert_equal(char2nr("\<{key}>"), getchar(-1))
   2449      call feedkeys("\<*{key}>", '')
   2450      call assert_equal(char2nr("\<{key}>"), getchar(-1, {{}}))
   2451      call feedkeys("\<*{key}>", '')
   2452      call assert_equal(char2nr("\<{key}>"), getchar(-1, {{'number': 1}}))
   2453      call feedkeys("\<*{key}>", '')
   2454      call assert_equal(char2nr("\<{key}>"), getchar(-1, {{'simplify': 1}}))
   2455      call feedkeys("\<*{key}>", '')
   2456      call assert_equal("\<*{key}>", getchar(-1, {{'simplify': v:false}}))
   2457      call assert_equal(0, getchar(0))
   2458      call assert_equal(0, getchar(1))
   2459    END
   2460    call CheckLegacyAndVim9Success(lines)
   2461 
   2462    let lines =<< eval trim END
   2463      call feedkeys("\<*{key}>", '')
   2464      call assert_equal("\<{key}>", getcharstr())
   2465      call feedkeys("\<*{key}>", '')
   2466      call assert_equal("\<{key}>", getcharstr(-1))
   2467      call feedkeys("\<*{key}>", '')
   2468      call assert_equal("\<{key}>", getcharstr(-1, {{}}))
   2469      call feedkeys("\<*{key}>", '')
   2470      call assert_equal("\<{key}>", getchar(-1, {{'number': 0}}))
   2471      call feedkeys("\<*{key}>", '')
   2472      call assert_equal("\<{key}>", getcharstr(-1, {{'simplify': 1}}))
   2473      call feedkeys("\<*{key}>", '')
   2474      call assert_equal("\<*{key}>", getcharstr(-1, {{'simplify': v:false}}))
   2475      call assert_equal('', getcharstr(0))
   2476      call assert_equal('', getcharstr(1))
   2477    END
   2478    call CheckLegacyAndVim9Success(lines)
   2479  endfor
   2480 
   2481  call assert_fails('call getchar(1, 1)', 'E1206:')
   2482  call assert_fails('call getcharstr(1, 1)', 'E1206:')
   2483  call assert_fails('call getchar(1, #{cursor: "foo"})', 'E475:')
   2484  call assert_fails('call getcharstr(1, #{cursor: "foo"})', 'E475:')
   2485  call assert_fails('call getchar(1, #{cursor: 0z})', 'E976:')
   2486  call assert_fails('call getcharstr(1, #{cursor: 0z})', 'E976:')
   2487  call assert_fails('call getchar(1, #{simplify: 0z})', 'E974:')
   2488  call assert_fails('call getcharstr(1, #{simplify: 0z})', 'E974:')
   2489  call assert_fails('call getchar(1, #{number: []})', 'E745:')
   2490  call assert_fails('call getchar(1, #{number: {}})', 'E728:')
   2491  call assert_fails('call getcharstr(1, #{number: v:true})', 'E475:')
   2492  call assert_fails('call getcharstr(1, #{number: v:false})', 'E475:')
   2493 
   2494  call setline(1, 'xxxx')
   2495  call Ntest_setmouse(1, 3)
   2496  let v:mouse_win = 9
   2497  let v:mouse_winid = 9
   2498  let v:mouse_lnum = 9
   2499  let v:mouse_col = 9
   2500  call feedkeys("\<S-LeftMouse>", '')
   2501  call assert_equal("\<S-LeftMouse>", getchar())
   2502  call assert_equal(1, v:mouse_win)
   2503  call assert_equal(win_getid(1), v:mouse_winid)
   2504  call assert_equal(1, v:mouse_lnum)
   2505  call assert_equal(3, v:mouse_col)
   2506  enew!
   2507 endfunc
   2508 
   2509 func Test_getchar_cursor_position()
   2510  CheckRunVimInTerminal
   2511 
   2512  let lines =<< trim END
   2513    call setline(1, ['foobar', 'foobar', 'foobar'])
   2514    call cursor(3, 6)
   2515    nnoremap <F1> <Cmd>echo 1234<Bar>call getchar()<CR>
   2516    nnoremap <F2> <Cmd>call getchar()<CR>
   2517    nnoremap <F3> <Cmd>call getchar(-1, {})<CR>
   2518    nnoremap <F4> <Cmd>call getchar(-1, #{cursor: 'msg'})<CR>
   2519    nnoremap <F5> <Cmd>call getchar(-1, #{cursor: 'keep'})<CR>
   2520    nnoremap <F6> <Cmd>call getchar(-1, #{cursor: 'hide'})<CR>
   2521  END
   2522  call writefile(lines, 'XgetcharCursorPos', 'D')
   2523  let buf = RunVimInTerminal('-S XgetcharCursorPos', {'rows': 6})
   2524  call WaitForAssert({-> assert_equal([3, 6], term_getcursor(buf)[0:1])})
   2525 
   2526  call term_sendkeys(buf, "\<F1>")
   2527  call WaitForAssert({-> assert_equal([6, 5], term_getcursor(buf)[0:1])})
   2528  call assert_true(term_getcursor(buf)[2].visible)
   2529  call term_sendkeys(buf, 'a')
   2530  call WaitForAssert({-> assert_equal([3, 6], term_getcursor(buf)[0:1])})
   2531  call assert_true(term_getcursor(buf)[2].visible)
   2532 
   2533  for key in ["\<F2>", "\<F3>", "\<F4>"]
   2534    call term_sendkeys(buf, key)
   2535    call WaitForAssert({-> assert_equal([6, 1], term_getcursor(buf)[0:1])})
   2536    call assert_true(term_getcursor(buf)[2].visible)
   2537    call term_sendkeys(buf, 'a')
   2538    call WaitForAssert({-> assert_equal([3, 6], term_getcursor(buf)[0:1])})
   2539    call assert_true(term_getcursor(buf)[2].visible)
   2540  endfor
   2541 
   2542  call term_sendkeys(buf, "\<F5>")
   2543  call TermWait(buf, 50)
   2544  call assert_equal([3, 6], term_getcursor(buf)[0:1])
   2545  call assert_true(term_getcursor(buf)[2].visible)
   2546  call term_sendkeys(buf, 'a')
   2547  call TermWait(buf, 50)
   2548  call assert_equal([3, 6], term_getcursor(buf)[0:1])
   2549  call assert_true(term_getcursor(buf)[2].visible)
   2550 
   2551  call term_sendkeys(buf, "\<F6>")
   2552  call WaitForAssert({-> assert_false(term_getcursor(buf)[2].visible)})
   2553  call term_sendkeys(buf, 'a')
   2554  call WaitForAssert({-> assert_true(term_getcursor(buf)[2].visible)})
   2555  call assert_equal([3, 6], term_getcursor(buf)[0:1])
   2556 
   2557  call StopVimInTerminal(buf)
   2558 endfunc
   2559 
   2560 func Test_libcall_libcallnr()
   2561  CheckFeature libcall
   2562 
   2563  if has('win32')
   2564    let libc = 'msvcrt.dll'
   2565  elseif has('mac')
   2566    let libc = 'libSystem.B.dylib'
   2567  elseif executable('ldd')
   2568    let libc = matchstr(split(system('ldd ' . GetVimProg())), '/libc\.so\>')
   2569  endif
   2570  if get(l:, 'libc', '') ==# ''
   2571    " On Unix, libc.so can be in various places.
   2572    if has('linux')
   2573      " There is not documented but regarding the 1st argument of glibc's
   2574      " dlopen an empty string and nullptr are equivalent, so using an empty
   2575      " string for the 1st argument of libcall allows to call functions.
   2576      let libc = ''
   2577    elseif has('sun')
   2578      " Set the path to libc.so according to the architecture.
   2579      let test_bits = system('file ' . GetVimProg())
   2580      let test_arch = system('uname -p')
   2581      if test_bits =~ '64-bit' && test_arch =~ 'sparc'
   2582        let libc = '/usr/lib/sparcv9/libc.so'
   2583      elseif test_bits =~ '64-bit' && test_arch =~ 'i386'
   2584        let libc = '/usr/lib/amd64/libc.so'
   2585      else
   2586        let libc = '/usr/lib/libc.so'
   2587      endif
   2588    else
   2589      " Unfortunately skip this test until a good way is found.
   2590      return
   2591    endif
   2592  endif
   2593 
   2594  if has('win32')
   2595    call assert_equal($USERPROFILE, 'USERPROFILE'->libcall(libc, 'getenv'))
   2596  else
   2597    call assert_equal($HOME, 'HOME'->libcall(libc, 'getenv'))
   2598  endif
   2599 
   2600  " If function returns NULL, libcall() should return an empty string.
   2601  call assert_equal('', libcall(libc, 'getenv', 'X_ENV_DOES_NOT_EXIT'))
   2602 
   2603  " Test libcallnr() with string and integer argument.
   2604  call assert_equal(4, 'abcd'->libcallnr(libc, 'strlen'))
   2605  call assert_equal(char2nr('A'), char2nr('a')->libcallnr(libc, 'toupper'))
   2606 
   2607  call assert_fails("call libcall(libc, 'Xdoesnotexist_', '')", ['', 'E364:'])
   2608  call assert_fails("call libcallnr(libc, 'Xdoesnotexist_', '')", ['', 'E364:'])
   2609 
   2610  call assert_fails("call libcall('Xdoesnotexist_', 'getenv', 'HOME')", ['', 'E364:'])
   2611  call assert_fails("call libcallnr('Xdoesnotexist_', 'strlen', 'abcd')", ['', 'E364:'])
   2612 endfunc
   2613 
   2614 sandbox function Fsandbox()
   2615  normal ix
   2616 endfunc
   2617 
   2618 func Test_func_sandbox()
   2619  sandbox let F = {-> 'hello'}
   2620  call assert_equal('hello', F())
   2621 
   2622  sandbox let F = {-> "normal ix\<Esc>"->execute()}
   2623  call assert_fails('call F()', 'E48:')
   2624  unlet F
   2625 
   2626  call assert_fails('call Fsandbox()', 'E48:')
   2627  delfunc Fsandbox
   2628 
   2629  " From a sandbox try to set a predefined variable (which cannot be modified
   2630  " from a sandbox)
   2631  call assert_fails('sandbox let v:lnum = 10', 'E794:')
   2632 endfunc
   2633 
   2634 func EditAnotherFile()
   2635  let word = expand('<cword>')
   2636  edit Xfuncrange2
   2637 endfunc
   2638 
   2639 func Test_func_range_with_edit()
   2640  " Define a function that edits another buffer, then call it with a range that
   2641  " is invalid in that buffer.
   2642  call writefile(['just one line'], 'Xfuncrange2')
   2643  new
   2644  eval 10->range()->setline(1)
   2645  write Xfuncrange1
   2646  call assert_fails('5,8call EditAnotherFile()', 'E16:')
   2647 
   2648  call delete('Xfuncrange1')
   2649  call delete('Xfuncrange2')
   2650  bwipe!
   2651 endfunc
   2652 
   2653 func Test_func_exists_on_reload()
   2654  call writefile(['func ExistingFunction()', 'echo "yes"', 'endfunc'], 'Xfuncexists')
   2655  call assert_equal(0, exists('*ExistingFunction'))
   2656  source Xfuncexists
   2657  call assert_equal(1, '*ExistingFunction'->exists())
   2658  " Redefining a function when reloading a script is OK.
   2659  source Xfuncexists
   2660  call assert_equal(1, exists('*ExistingFunction'))
   2661 
   2662  " But redefining in another script is not OK.
   2663  call writefile(['func ExistingFunction()', 'echo "yes"', 'endfunc'], 'Xfuncexists2')
   2664  call assert_fails('source Xfuncexists2', 'E122:')
   2665 
   2666  delfunc ExistingFunction
   2667  call assert_equal(0, exists('*ExistingFunction'))
   2668  call writefile([
   2669 \ 'func ExistingFunction()', 'echo "yes"', 'endfunc',
   2670 \ 'func ExistingFunction()', 'echo "no"', 'endfunc',
   2671 \ ], 'Xfuncexists')
   2672  call assert_fails('source Xfuncexists', 'E122:')
   2673  call assert_equal(1, exists('*ExistingFunction'))
   2674 
   2675  call delete('Xfuncexists2')
   2676  call delete('Xfuncexists')
   2677  delfunc ExistingFunction
   2678 endfunc
   2679 
   2680 " Test confirm({msg} [, {choices} [, {default} [, {type}]]])
   2681 func Test_confirm()
   2682  CheckUnix
   2683  CheckNotGui
   2684 
   2685  call feedkeys('o', 'L')
   2686  let a = confirm('Press O to proceed')
   2687  call assert_equal(1, a)
   2688 
   2689  call feedkeys('y', 'L')
   2690  let a = 'Are you sure?'->confirm("&Yes\n&No")
   2691  call assert_equal(1, a)
   2692 
   2693  call feedkeys('n', 'L')
   2694  let a = confirm('Are you sure?', "&Yes\n&No")
   2695  call assert_equal(2, a)
   2696 
   2697  " confirm() should return 0 when pressing CTRL-C.
   2698  call feedkeys("\<C-C>", 'L')
   2699  let a = confirm('Are you sure?', "&Yes\n&No")
   2700  call assert_equal(0, a)
   2701 
   2702  " <Esc> requires another character to avoid it being seen as the start of an
   2703  " escape sequence.  Zero should be harmless.
   2704  eval "\<Esc>0"->feedkeys('L')
   2705  let a = confirm('Are you sure?', "&Yes\n&No")
   2706  call assert_equal(0, a)
   2707 
   2708  " Default choice is returned when pressing <CR>.
   2709  call feedkeys("\<CR>", 'L')
   2710  let a = confirm('Are you sure?', "&Yes\n&No")
   2711  call assert_equal(1, a)
   2712 
   2713  call feedkeys("\<CR>", 'L')
   2714  let a = confirm('Are you sure?', "&Yes\n&No", 2)
   2715  call assert_equal(2, a)
   2716 
   2717  call feedkeys("\<CR>", 'L')
   2718  let a = confirm('Are you sure?', "&Yes\n&No", 0)
   2719  call assert_equal(0, a)
   2720 
   2721  " Test with the {type} 4th argument
   2722  for type in ['Error', 'Question', 'Info', 'Warning', 'Generic']
   2723    call feedkeys('y', 'L')
   2724    let a = confirm('Are you sure?', "&Yes\n&No\n", 1, type)
   2725    call assert_equal(1, a)
   2726  endfor
   2727 
   2728  call assert_fails('call confirm([])', 'E730:')
   2729  call assert_fails('call confirm("Are you sure?", [])', 'E730:')
   2730  call assert_fails('call confirm("Are you sure?", "&Yes\n&No\n", [])', 'E745:')
   2731  call assert_fails('call confirm("Are you sure?", "&Yes\n&No\n", 0, [])', 'E730:')
   2732 endfunc
   2733 
   2734 func Test_platform_name()
   2735  " The system matches at most only one name.
   2736  let names = ['amiga', 'bsd', 'hpux', 'linux', 'mac', 'qnx', 'sun', 'vms', 'win32', 'win32unix']
   2737  call assert_inrange(0, 1, len(filter(copy(names), 'has(v:val)')))
   2738 
   2739  " Is Unix?
   2740  call assert_equal(has('bsd'), has('bsd') && has('unix'))
   2741  call assert_equal(has('hpux'), has('hpux') && has('unix'))
   2742  call assert_equal(has('hurd'), has('hurd') && has('unix'))
   2743  call assert_equal(has('linux'), has('linux') && has('unix'))
   2744  call assert_equal(has('mac'), has('mac') && has('unix'))
   2745  call assert_equal(has('qnx'), has('qnx') && has('unix'))
   2746  call assert_equal(has('sun'), has('sun') && has('unix'))
   2747  call assert_equal(has('win32'), has('win32') && !has('unix'))
   2748  call assert_equal(has('win32unix'), has('win32unix') && has('unix'))
   2749 
   2750  if has('unix') && executable('uname')
   2751    let uname = system('uname')
   2752    " GNU userland on BSD kernels (e.g., GNU/kFreeBSD) don't have BSD defined
   2753    call assert_equal(uname =~? '\%(GNU/k\w\+\)\@<!BSD\|DragonFly', has('bsd'))
   2754    call assert_equal(uname =~? 'HP-UX', has('hpux'))
   2755    call assert_equal(uname =~? 'Linux', has('linux'))
   2756    call assert_equal(uname =~? 'Darwin', has('mac'))
   2757    call assert_equal(uname =~? 'QNX', has('qnx'))
   2758    call assert_equal(uname =~? 'SunOS', has('sun'))
   2759    call assert_equal(uname =~? 'CYGWIN\|MSYS', has('win32unix'))
   2760    call assert_equal(uname =~? 'GNU', has('hurd'))
   2761  endif
   2762 endfunc
   2763 
   2764 func Test_readdir()
   2765  call mkdir('Xdir')
   2766  call writefile([], 'Xdir/foo.txt')
   2767  call writefile([], 'Xdir/bar.txt')
   2768  call mkdir('Xdir/dir')
   2769 
   2770  " All results
   2771  let files = readdir('Xdir')
   2772  call assert_equal(['bar.txt', 'dir', 'foo.txt'], sort(files))
   2773 
   2774  " Only results containing "f"
   2775  let files = 'Xdir'->readdir({ x -> stridx(x, 'f') !=- 1 })
   2776  call assert_equal(['foo.txt'], sort(files))
   2777 
   2778  " Only .txt files
   2779  let files = readdir('Xdir', { x -> x =~ '.txt$' })
   2780  call assert_equal(['bar.txt', 'foo.txt'], sort(files))
   2781 
   2782  " Only .txt files with string
   2783  let files = readdir('Xdir', 'v:val =~ ".txt$"')
   2784  call assert_equal(['bar.txt', 'foo.txt'], sort(files))
   2785 
   2786  " Limit to 1 result.
   2787  let l = []
   2788  let files = readdir('Xdir', {x -> len(add(l, x)) == 2 ? -1 : 1})
   2789  call assert_equal(1, len(files))
   2790 
   2791  " Nested readdir() must not crash
   2792  let files = readdir('Xdir', 'readdir("Xdir", "1") != []')
   2793  call sort(files)->assert_equal(['bar.txt', 'dir', 'foo.txt'])
   2794 
   2795  eval 'Xdir'->delete('rf')
   2796 endfunc
   2797 
   2798 func Test_delete_rf()
   2799  call mkdir('Xdir')
   2800  call writefile([], 'Xdir/foo.txt')
   2801  call writefile([], 'Xdir/bar.txt')
   2802  call mkdir('Xdir/[a-1]')  " issue #696
   2803  call writefile([], 'Xdir/[a-1]/foo.txt')
   2804  call writefile([], 'Xdir/[a-1]/bar.txt')
   2805  call assert_true(filereadable('Xdir/foo.txt'))
   2806  call assert_true('Xdir/[a-1]/foo.txt'->filereadable())
   2807 
   2808  call assert_equal(0, delete('Xdir', 'rf'))
   2809  call assert_false(filereadable('Xdir/foo.txt'))
   2810  call assert_false(filereadable('Xdir/[a-1]/foo.txt'))
   2811 
   2812  if has('unix')
   2813    call mkdir('Xdir/Xdir2', 'p')
   2814    silent !chmod 555 Xdir
   2815    call assert_equal(-1, delete('Xdir/Xdir2', 'rf'))
   2816    call assert_equal(-1, delete('Xdir', 'rf'))
   2817    silent !chmod 755 Xdir
   2818    call assert_equal(0, delete('Xdir', 'rf'))
   2819  endif
   2820 endfunc
   2821 
   2822 func Test_call()
   2823  call assert_equal(3, call('len', [123]))
   2824  call assert_equal(3, 'len'->call([123]))
   2825  call assert_equal(4, call({ x -> len(x) }, ['xxxx']))
   2826  call assert_equal(2, call(function('len'), ['xx']))
   2827  call assert_fails("call call('len', 123)", 'E1211:')
   2828  call assert_equal(0, call('', []))
   2829  call assert_equal(0, call('len', v:_null_list))
   2830 
   2831  function Mylen() dict
   2832     return len(self.data)
   2833  endfunction
   2834  let mydict = {'data': [0, 1, 2, 3], 'len': function("Mylen")}
   2835  eval mydict.len->call([], mydict)->assert_equal(4)
   2836  call assert_fails("call call('Mylen', [], 0)", 'E1206:')
   2837  call assert_fails('call foo', 'E107:')
   2838 
   2839  " These once caused a crash.
   2840  " Nvim doesn't have null functions
   2841  " call call(test_null_function(), [])
   2842  " Nvim doesn't have null partials
   2843  " call call(test_null_partial(), [])
   2844  " Nvim doesn't have null functions
   2845  " call assert_fails('call test_null_function()()', 'E1192:')
   2846  " Nvim doesn't have null partials
   2847  " call assert_fails('call test_null_partial()()', 'E117:')
   2848 
   2849  let lines =<< trim END
   2850      let Time = 'localtime'
   2851      call Time()
   2852  END
   2853  call CheckScriptFailure(lines, 'E1085:')
   2854 endfunc
   2855 
   2856 func Test_char2nr()
   2857  call assert_equal(12354, char2nr('あ', 1))
   2858  call assert_equal(120, 'x'->char2nr())
   2859  " set encoding=latin1
   2860  call assert_equal(120, 'x'->char2nr())
   2861  set encoding=utf-8
   2862 endfunc
   2863 
   2864 func Test_charclass()
   2865  call assert_equal(0, charclass(' '))
   2866  call assert_equal(1, charclass('.'))
   2867  call assert_equal(2, charclass('x'))
   2868  call assert_equal(3, charclass("\u203c"))
   2869  " this used to crash vim
   2870  call assert_equal(0, "xxx"[-1]->charclass())
   2871 endfunc
   2872 
   2873 func Test_eventhandler()
   2874  call assert_equal(0, eventhandler())
   2875 endfunc
   2876 
   2877 func Test_bufadd_bufload()
   2878  call assert_equal(0, bufexists('someName'))
   2879  let buf = bufadd('someName')
   2880  call assert_notequal(0, buf)
   2881  call assert_equal(1, bufexists('someName'))
   2882  call assert_equal(0, getbufvar(buf, '&buflisted'))
   2883  call assert_equal(0, bufloaded(buf))
   2884  call bufload(buf)
   2885  call assert_equal(1, bufloaded(buf))
   2886  call assert_equal([''], getbufline(buf, 1, '$'))
   2887 
   2888  let curbuf = bufnr('')
   2889  eval ['some', 'text']->writefile('XotherName')
   2890  let buf = 'XotherName'->bufadd()
   2891  call assert_notequal(0, buf)
   2892  eval 'XotherName'->bufexists()->assert_equal(1)
   2893  call assert_equal(0, getbufvar(buf, '&buflisted'))
   2894  call assert_equal(0, bufloaded(buf))
   2895  eval buf->bufload()
   2896  call assert_equal(1, bufloaded(buf))
   2897  call assert_equal(['some', 'text'], getbufline(buf, 1, '$'))
   2898  call assert_equal(curbuf, bufnr(''))
   2899 
   2900  let buf1 = bufadd('')
   2901  let buf2 = bufadd('')
   2902  call assert_notequal(0, buf1)
   2903  call assert_notequal(0, buf2)
   2904  call assert_notequal(buf1, buf2)
   2905  call assert_equal(1, bufexists(buf1))
   2906  call assert_equal(1, bufexists(buf2))
   2907  call assert_equal(0, bufloaded(buf1))
   2908  exe 'bwipe ' .. buf1
   2909  call assert_equal(0, bufexists(buf1))
   2910  call assert_equal(1, bufexists(buf2))
   2911  exe 'bwipe ' .. buf2
   2912  call assert_equal(0, bufexists(buf2))
   2913 
   2914  " When 'buftype' is "nofile" then bufload() does not read the file.
   2915  " Other values too.
   2916  for val in [['nofile', 0],
   2917            \ ['nowrite', 1],
   2918            \ ['acwrite', 1],
   2919            \ ['quickfix', 0],
   2920            \ ['help', 1],
   2921            "\ ['terminal', 0],
   2922            \ ['prompt', 0],
   2923            "\ ['popup', 0],
   2924            \ ]
   2925    bwipe! XotherName
   2926    let buf = bufadd('XotherName')
   2927    call setbufvar(buf, '&bt', val[0])
   2928    call bufload(buf)
   2929    call assert_equal(val[1] ? ['some', 'text'] : [''], getbufline(buf, 1, '$'), val[0])
   2930  endfor
   2931 
   2932  bwipe someName
   2933  bwipe XotherName
   2934  call assert_equal(0, bufexists('someName'))
   2935  call delete('XotherName')
   2936 endfunc
   2937 
   2938 func Test_state()
   2939  CheckRunVimInTerminal
   2940 
   2941  let getstate = ":echo 'state: ' .. g:state .. '; mode: ' .. g:mode\<CR>"
   2942 
   2943  let lines =<< trim END
   2944 call setline(1, ['one', 'two', 'three'])
   2945 map ;; gg
   2946 set complete=.
   2947 func RunTimer()
   2948   call timer_start(10, {id -> execute('let g:state = state()') .. execute('let g:mode = mode()')})
   2949 endfunc
   2950 au Filetype foobar let g:state = state()|let g:mode = mode()
   2951  END
   2952  call writefile(lines, 'XState')
   2953  let buf = RunVimInTerminal('-S XState', #{rows: 6})
   2954 
   2955  " Using a ":" command Vim is busy, thus "S" is returned
   2956  call term_sendkeys(buf, ":echo 'state: ' .. state() .. '; mode: ' .. mode()\<CR>")
   2957  call WaitForAssert({-> assert_match('state: S; mode: n', term_getline(buf, 6))}, 1000)
   2958  call term_sendkeys(buf, ":\<CR>")
   2959 
   2960  " Using a timer callback
   2961  call term_sendkeys(buf, ":call RunTimer()\<CR>")
   2962  call TermWait(buf, 25)
   2963  call term_sendkeys(buf, getstate)
   2964  call WaitForAssert({-> assert_match('state: c; mode: n', term_getline(buf, 6))}, 1000)
   2965 
   2966  " Halfway a mapping
   2967  call term_sendkeys(buf, ":call RunTimer()\<CR>;")
   2968  call TermWait(buf, 25)
   2969  call term_sendkeys(buf, ";")
   2970  call term_sendkeys(buf, getstate)
   2971  call WaitForAssert({-> assert_match('state: mSc; mode: n', term_getline(buf, 6))}, 1000)
   2972 
   2973  " An operator is pending
   2974  call term_sendkeys(buf, ":call RunTimer()\<CR>y")
   2975  call TermWait(buf, 25)
   2976  call term_sendkeys(buf, "y")
   2977  call term_sendkeys(buf, getstate)
   2978  call WaitForAssert({-> assert_match('state: oSc; mode: n', term_getline(buf, 6))}, 1000)
   2979 
   2980  " A register was specified
   2981  call term_sendkeys(buf, ":call RunTimer()\<CR>\"r")
   2982  call TermWait(buf, 25)
   2983  call term_sendkeys(buf, "yy")
   2984  call term_sendkeys(buf, getstate)
   2985  call WaitForAssert({-> assert_match('state: oSc; mode: n', term_getline(buf, 6))}, 1000)
   2986 
   2987  " Insert mode completion (bit slower on Mac)
   2988  call term_sendkeys(buf, ":call RunTimer()\<CR>Got\<C-N>")
   2989  call TermWait(buf, 25)
   2990  call term_sendkeys(buf, "\<Esc>")
   2991  call term_sendkeys(buf, getstate)
   2992  call WaitForAssert({-> assert_match('state: aSc; mode: i', term_getline(buf, 6))}, 1000)
   2993 
   2994  " Autocommand executing
   2995  call term_sendkeys(buf, ":set filetype=foobar\<CR>")
   2996  call TermWait(buf, 25)
   2997  call term_sendkeys(buf, getstate)
   2998  call WaitForAssert({-> assert_match('state: xS; mode: n', term_getline(buf, 6))}, 1000)
   2999 
   3000  " Todo: "w" - waiting for ch_evalexpr()
   3001 
   3002  " messages scrolled
   3003  call term_sendkeys(buf, ":call RunTimer()\<CR>:echo \"one\\ntwo\\nthree\"\<CR>")
   3004  call TermWait(buf, 25)
   3005  call term_sendkeys(buf, "\<CR>")
   3006  call term_sendkeys(buf, getstate)
   3007  call WaitForAssert({-> assert_match('state: Scs; mode: r', term_getline(buf, 6))}, 1000)
   3008 
   3009  call StopVimInTerminal(buf)
   3010  call delete('XState')
   3011 endfunc
   3012 
   3013 func Test_range()
   3014  " destructuring
   3015  let [x, y] = range(2)
   3016  call assert_equal([0, 1], [x, y])
   3017 
   3018  " index
   3019  call assert_equal(4, range(1, 10)[3])
   3020 
   3021  " add()
   3022  call assert_equal([0, 1, 2, 3], add(range(3), 3))
   3023  call assert_equal([0, 1, 2, [0, 1, 2]], add([0, 1, 2], range(3)))
   3024  call assert_equal([0, 1, 2, [0, 1, 2]], add(range(3), range(3)))
   3025 
   3026  " append()
   3027  new
   3028  call append('.', range(5))
   3029  call assert_equal(['', '0', '1', '2', '3', '4'], getline(1, '$'))
   3030  bwipe!
   3031 
   3032  " appendbufline()
   3033  new
   3034  call appendbufline(bufnr(''), '.', range(5))
   3035  call assert_equal(['0', '1', '2', '3', '4', ''], getline(1, '$'))
   3036  bwipe!
   3037 
   3038  " call()
   3039  func TwoArgs(a, b)
   3040    return [a:a, a:b]
   3041  endfunc
   3042  call assert_equal([0, 1], call('TwoArgs', range(2)))
   3043 
   3044  " col()
   3045  new
   3046  call setline(1, ['foo', 'bar'])
   3047  call assert_equal(2, col(range(1, 2)))
   3048  bwipe!
   3049 
   3050  " complete()
   3051  execute "normal! a\<C-r>=[complete(col('.'), range(10)), ''][1]\<CR>"
   3052  " complete_info()
   3053  execute "normal! a\<C-r>=[complete(col('.'), range(10)), ''][1]\<CR>\<C-r>=[complete_info(range(5)), ''][1]\<CR>"
   3054 
   3055  " copy()
   3056  call assert_equal([1, 2, 3], copy(range(1, 3)))
   3057 
   3058  " count()
   3059  call assert_equal(0, count(range(0), 3))
   3060  call assert_equal(0, count(range(2), 3))
   3061  call assert_equal(1, count(range(5), 3))
   3062 
   3063  " cursor()
   3064  new
   3065  call setline(1, ['aaa', 'bbb', 'ccc'])
   3066  call cursor(range(1, 2))
   3067  call assert_equal([2, 1], [col('.'), line('.')])
   3068  bwipe!
   3069 
   3070  " deepcopy()
   3071  call assert_equal([1, 2, 3], deepcopy(range(1, 3)))
   3072 
   3073  " empty()
   3074  call assert_true(empty(range(0)))
   3075  call assert_false(empty(range(2)))
   3076 
   3077  " execute()
   3078  new
   3079  call setline(1, ['aaa', 'bbb', 'ccc'])
   3080  call execute(range(3))
   3081  call assert_equal(2, line('.'))
   3082  bwipe!
   3083 
   3084  " extend()
   3085  call assert_equal([1, 2, 3, 4], extend([1], range(2, 4)))
   3086  call assert_equal([1, 2, 3, 4], extend(range(1, 1), range(2, 4)))
   3087  call assert_equal([1, 2, 3, 4], extend(range(1, 1), [2, 3, 4]))
   3088 
   3089  " filter()
   3090  call assert_equal([1, 3], filter(range(5), 'v:val % 2'))
   3091 
   3092  " funcref()
   3093  call assert_equal([0, 1], funcref('TwoArgs', range(2))())
   3094 
   3095  " function()
   3096  call assert_equal([0, 1], function('TwoArgs', range(2))())
   3097 
   3098  " garbagecollect()
   3099  let thelist = [1, range(2), 3]
   3100  let otherlist = range(3)
   3101  call test_garbagecollect_now()
   3102 
   3103  " get()
   3104  call assert_equal(4, get(range(1, 10), 3))
   3105  call assert_equal(-1, get(range(1, 10), 42, -1))
   3106 
   3107  " index()
   3108  call assert_equal(1, index(range(1, 5), 2))
   3109  call assert_fails("echo index([1, 2], 1, [])", 'E745:')
   3110 
   3111  " insert()
   3112  call assert_equal([42, 1, 2, 3, 4, 5], insert(range(1, 5), 42))
   3113  call assert_equal([42, 1, 2, 3, 4, 5], insert(range(1, 5), 42, 0))
   3114  call assert_equal([1, 42, 2, 3, 4, 5], insert(range(1, 5), 42, 1))
   3115  call assert_equal([1, 2, 3, 4, 42, 5], insert(range(1, 5), 42, 4))
   3116  call assert_equal([1, 2, 3, 4, 42, 5], insert(range(1, 5), 42, -1))
   3117  call assert_equal([1, 2, 3, 4, 5, 42], insert(range(1, 5), 42, 5))
   3118 
   3119  " join()
   3120  call assert_equal('0 1 2 3 4', join(range(5)))
   3121 
   3122  " json_encode()
   3123  " call assert_equal('[0,1,2,3]', json_encode(range(4)))
   3124  call assert_equal('[0, 1, 2, 3]', json_encode(range(4)))
   3125 
   3126  " len()
   3127  call assert_equal(0, len(range(0)))
   3128  call assert_equal(2, len(range(2)))
   3129  call assert_equal(5, len(range(0, 12, 3)))
   3130  call assert_equal(4, len(range(3, 0, -1)))
   3131 
   3132  " list2str()
   3133  call assert_equal('ABC', list2str(range(65, 67)))
   3134  call assert_fails('let s = list2str(5)', 'E474:')
   3135 
   3136  " lock()
   3137  let thelist = range(5)
   3138  lockvar thelist
   3139 
   3140  " map()
   3141  call assert_equal([0, 2, 4, 6, 8], map(range(5), 'v:val * 2'))
   3142 
   3143  " match()
   3144  call assert_equal(3, match(range(5), 3))
   3145 
   3146  " matchaddpos()
   3147  highlight MyGreenGroup ctermbg=green guibg=green
   3148  call matchaddpos('MyGreenGroup', range(line('.'), line('.')))
   3149 
   3150  " matchend()
   3151  call assert_equal(4, matchend(range(5), '4'))
   3152  call assert_equal(3, matchend(range(1, 5), '4'))
   3153  call assert_equal(-1, matchend(range(1, 5), '42'))
   3154 
   3155  " matchstrpos()
   3156  call assert_equal(['4', 4, 0, 1], matchstrpos(range(5), '4'))
   3157  call assert_equal(['4', 3, 0, 1], matchstrpos(range(1, 5), '4'))
   3158  call assert_equal(['', -1, -1, -1], matchstrpos(range(1, 5), '42'))
   3159 
   3160  " max() reverse()
   3161  call assert_equal(0, max(range(0)))
   3162  call assert_equal(0, max(range(10, 9)))
   3163  call assert_equal(9, max(range(10)))
   3164  call assert_equal(18, max(range(0, 20, 3)))
   3165  call assert_equal(20, max(range(20, 0, -3)))
   3166  call assert_equal(99999, max(range(100000)))
   3167  call assert_equal(99999, max(range(99999, 0, -1)))
   3168  call assert_equal(99999, max(reverse(range(100000))))
   3169  call assert_equal(99999, max(reverse(range(99999, 0, -1))))
   3170 
   3171  " min() reverse()
   3172  call assert_equal(0, min(range(0)))
   3173  call assert_equal(0, min(range(10, 9)))
   3174  call assert_equal(5, min(range(5, 10)))
   3175  call assert_equal(5, min(range(5, 10, 3)))
   3176  call assert_equal(2, min(range(20, 0, -3)))
   3177  call assert_equal(0, min(range(100000)))
   3178  call assert_equal(0, min(range(99999, 0, -1)))
   3179  call assert_equal(0, min(reverse(range(100000))))
   3180  call assert_equal(0, min(reverse(range(99999, 0, -1))))
   3181 
   3182  " remove()
   3183  call assert_equal(1, remove(range(1, 10), 0))
   3184  call assert_equal(2, remove(range(1, 10), 1))
   3185  call assert_equal(9, remove(range(1, 10), 8))
   3186  call assert_equal(10, remove(range(1, 10), 9))
   3187  call assert_equal(10, remove(range(1, 10), -1))
   3188  call assert_equal([3, 4, 5], remove(range(1, 10), 2, 4))
   3189 
   3190  " repeat()
   3191  call assert_equal([0, 1, 2, 0, 1, 2], repeat(range(3), 2))
   3192  call assert_equal([0, 1, 2], repeat(range(3), 1))
   3193  call assert_equal([], repeat(range(3), 0))
   3194  call assert_equal([], repeat(range(5, 4), 2))
   3195  call assert_equal([], repeat(range(5, 4), 0))
   3196 
   3197  " reverse()
   3198  call assert_equal([2, 1, 0], reverse(range(3)))
   3199  call assert_equal([0, 1, 2, 3], reverse(range(3, 0, -1)))
   3200  call assert_equal([9, 8, 7, 6, 5, 4, 3, 2, 1, 0], reverse(range(10)))
   3201  call assert_equal([20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10], reverse(range(10, 20)))
   3202  call assert_equal([16, 13, 10], reverse(range(10, 18, 3)))
   3203  call assert_equal([19, 16, 13, 10], reverse(range(10, 19, 3)))
   3204  call assert_equal([19, 16, 13, 10], reverse(range(10, 20, 3)))
   3205  call assert_equal([11, 14, 17, 20], reverse(range(20, 10, -3)))
   3206  call assert_equal([], reverse(range(0)))
   3207 
   3208  " TODO: setpos()
   3209  " new
   3210  " call setline(1, repeat([''], bufnr('')))
   3211  " call setline(bufnr('') + 1, repeat('x', bufnr('') * 2 + 6))
   3212  " call setpos('x', range(bufnr(''), bufnr('') + 3))
   3213  " bwipe!
   3214 
   3215  " setreg()
   3216  call setreg('a', range(3))
   3217  call assert_equal("0\n1\n2\n", getreg('a'))
   3218 
   3219  " settagstack()
   3220  call settagstack(1, #{items : range(4)})
   3221 
   3222  " sign_define()
   3223  call assert_fails("call sign_define(range(5))", "E715:")
   3224  call assert_fails("call sign_placelist(range(5))", "E715:")
   3225 
   3226  " sign_undefine()
   3227  " call assert_fails("call sign_undefine(range(5))", "E908:")
   3228  call assert_fails("call sign_undefine(range(5))", "E155:")
   3229 
   3230  " sign_unplacelist()
   3231  call assert_fails("call sign_unplacelist(range(5))", "E715:")
   3232 
   3233  " sort()
   3234  call assert_equal([0, 1, 2, 3, 4, 5], sort(range(5, 0, -1)))
   3235 
   3236  " string()
   3237  call assert_equal('[0, 1, 2, 3, 4]', string(range(5)))
   3238 
   3239  " taglist() with 'tagfunc'
   3240  func TagFunc(pattern, flags, info)
   3241    return range(10)
   3242  endfunc
   3243  set tagfunc=TagFunc
   3244  call assert_fails("call taglist('asdf')", 'E987:')
   3245  set tagfunc=
   3246 
   3247  " term_start()
   3248  if has('terminal') && has('termguicolors')
   3249    call assert_fails('call term_start(range(3, 4))', 'E474:')
   3250    let g:terminal_ansi_colors = range(16)
   3251    if has('win32')
   3252      let cmd = "cmd /D /c dir"
   3253    else
   3254      let cmd = "ls"
   3255    endif
   3256    call assert_fails('call term_start("' .. cmd .. '", #{term_finish: "close"})', 'E475:')
   3257    unlet g:terminal_ansi_colors
   3258  endif
   3259 
   3260  " type()
   3261  call assert_equal(v:t_list, type(range(5)))
   3262 
   3263  " uniq()
   3264  call assert_equal([0, 1, 2, 3, 4], uniq(range(5)))
   3265 
   3266  " errors
   3267  call assert_fails('let x=range(2, 8, 0)', 'E726:')
   3268  call assert_fails('let x=range(3, 1)', 'E727:')
   3269  call assert_fails('let x=range(1, 3, -2)', 'E727:')
   3270  call assert_fails('let x=range([])', 'E745:')
   3271  call assert_fails('let x=range(1, [])', 'E745:')
   3272  call assert_fails('let x=range(1, 4, [])', 'E745:')
   3273 endfunc
   3274 
   3275 func Test_garbagecollect_now_fails()
   3276  let v:testing = 0
   3277  call assert_fails('call test_garbagecollect_now()', 'E1142:')
   3278  let v:testing = 1
   3279 endfunc
   3280 
   3281 " Test for echo highlighting
   3282 func Test_echohl()
   3283  echohl Search
   3284  echo 'Vim'
   3285  call assert_equal('Vim', Screenline(&lines))
   3286  " TODO: How to check the highlight group used by echohl?
   3287  " ScreenAttrs() returns all zeros.
   3288  echohl None
   3289 endfunc
   3290 
   3291 " Test for the eval() function
   3292 func Test_eval()
   3293  call assert_fails("call eval('5 a')", 'E488:')
   3294 endfunc
   3295 
   3296 " Test for the keytrans() function
   3297 func Test_keytrans()
   3298  call assert_equal('<Space>', keytrans(' '))
   3299  call assert_equal('<lt>', keytrans('<'))
   3300  call assert_equal('<lt>Tab>', keytrans('<Tab>'))
   3301  call assert_equal('<Tab>', keytrans("\<Tab>"))
   3302  call assert_equal('<C-V>', keytrans("\<C-V>"))
   3303  call assert_equal('<BS>', keytrans("\<BS>"))
   3304  call assert_equal('<Home>', keytrans("\<Home>"))
   3305  call assert_equal('<C-Home>', keytrans("\<C-Home>"))
   3306  call assert_equal('<M-Home>', keytrans("\<M-Home>"))
   3307  call assert_equal('<C-Space>', keytrans("\<C-Space>"))
   3308  call assert_equal('<M-Space>', keytrans("\<*M-Space>"))
   3309  call assert_equal('<M-x>', "\<*M-x>"->keytrans())
   3310  call assert_equal('<C-I>', "\<*C-I>"->keytrans())
   3311  call assert_equal('<S-3>', "\<*S-3>"->keytrans())
   3312  call assert_equal('π', 'π'->keytrans())
   3313  call assert_equal('<M-π>', "\<M-π>"->keytrans())
   3314  call assert_equal('ě', 'ě'->keytrans())
   3315  call assert_equal('<M-ě>', "\<M-ě>"->keytrans())
   3316  call assert_equal('', ''->keytrans())
   3317  call assert_equal('', v:_null_string->keytrans())
   3318  call assert_fails('call keytrans(1)', 'E1174:')
   3319  call assert_fails('call keytrans()', 'E119:')
   3320 endfunc
   3321 
   3322 " Test for the nr2char() function
   3323 func Test_nr2char()
   3324  " set encoding=latin1
   3325  call assert_equal('@', nr2char(64))
   3326  set encoding=utf8
   3327  call assert_equal('a', nr2char(97, 1))
   3328  call assert_equal('a', nr2char(97, 0))
   3329 
   3330  call assert_equal("\x80\xfc\b" .. nr2char(0x100000), eval('"\<M-' .. nr2char(0x100000) .. '>"'))
   3331  call assert_equal("\x80\xfc\b" .. nr2char(0x40000000), eval('"\<M-' .. nr2char(0x40000000) .. '>"'))
   3332 endfunc
   3333 
   3334 " Test for screenattr(), screenchar() and screenchars() functions
   3335 func Test_screen_functions()
   3336  call assert_equal(-1, screenattr(-1, -1))
   3337  call assert_equal(-1, screenchar(-1, -1))
   3338  call assert_equal([], screenchars(-1, -1))
   3339 
   3340  " Run this in a separate Vim instance to avoid messing up.
   3341  let after =<< trim [CODE]
   3342    scriptencoding utf-8
   3343    call setline(1, '口')
   3344    redraw
   3345    call assert_equal(0, screenattr(1, 1))
   3346    call assert_equal(char2nr('口'), screenchar(1, 1))
   3347    call assert_equal([char2nr('口')], screenchars(1, 1))
   3348    call assert_equal('口', screenstring(1, 1))
   3349    call writefile(v:errors, 'Xresult')
   3350    qall!
   3351  [CODE]
   3352 
   3353  let encodings = ['utf-8', 'cp932', 'cp936', 'cp949', 'cp950']
   3354  if !has('win32')
   3355    let encodings += ['euc-jp']
   3356  endif
   3357  if has('nvim')
   3358    let encodings = ['utf-8']
   3359  endif
   3360  for enc in encodings
   3361    let msg = 'enc=' .. enc
   3362    if RunVim([], after, $'--clean --cmd "set encoding={enc}"')
   3363      call assert_equal([], readfile('Xresult'), msg)
   3364    endif
   3365    call delete('Xresult')
   3366  endfor
   3367 endfunc
   3368 
   3369 " Test for getcurpos() and setpos()
   3370 func Test_getcurpos_setpos()
   3371  new
   3372  call setline(1, ['012345678', '012345678'])
   3373  normal gg6l
   3374  let sp = getcurpos()
   3375  normal 0
   3376  call setpos('.', sp)
   3377  normal jyl
   3378  call assert_equal('6', @")
   3379  call assert_equal(-1, setpos('.', v:_null_list))
   3380  call assert_equal(-1, setpos('.', {}))
   3381 
   3382  let winid = win_getid()
   3383  normal G$
   3384  let pos = getcurpos()
   3385  wincmd w
   3386  call assert_equal(pos, getcurpos(winid))
   3387 
   3388  wincmd w
   3389  close!
   3390 
   3391  call assert_equal(getcurpos(), getcurpos(0))
   3392  call assert_equal([0, 0, 0, 0, 0], getcurpos(-1))
   3393  call assert_equal([0, 0, 0, 0, 0], getcurpos(1999))
   3394 endfunc
   3395 
   3396 func Test_getmousepos()
   3397  enew!
   3398  call setline(1, "\t\t\t1234")
   3399  call Ntest_setmouse(1, 1)
   3400  call assert_equal(#{
   3401        \ screenrow: 1,
   3402        \ screencol: 1,
   3403        \ winid: win_getid(),
   3404        \ winrow: 1,
   3405        \ wincol: 1,
   3406        \ line: 1,
   3407        \ column: 1,
   3408        \ coladd: 0,
   3409        \ }, getmousepos())
   3410  call Ntest_setmouse(1, 2)
   3411  call assert_equal(#{
   3412        \ screenrow: 1,
   3413        \ screencol: 2,
   3414        \ winid: win_getid(),
   3415        \ winrow: 1,
   3416        \ wincol: 2,
   3417        \ line: 1,
   3418        \ column: 1,
   3419        \ coladd: 1,
   3420        \ }, getmousepos())
   3421  call Ntest_setmouse(1, 8)
   3422  call assert_equal(#{
   3423        \ screenrow: 1,
   3424        \ screencol: 8,
   3425        \ winid: win_getid(),
   3426        \ winrow: 1,
   3427        \ wincol: 8,
   3428        \ line: 1,
   3429        \ column: 1,
   3430        \ coladd: 7,
   3431        \ }, getmousepos())
   3432  call Ntest_setmouse(1, 9)
   3433  call assert_equal(#{
   3434        \ screenrow: 1,
   3435        \ screencol: 9,
   3436        \ winid: win_getid(),
   3437        \ winrow: 1,
   3438        \ wincol: 9,
   3439        \ line: 1,
   3440        \ column: 2,
   3441        \ coladd: 0,
   3442        \ }, getmousepos())
   3443  call Ntest_setmouse(1, 12)
   3444  call assert_equal(#{
   3445        \ screenrow: 1,
   3446        \ screencol: 12,
   3447        \ winid: win_getid(),
   3448        \ winrow: 1,
   3449        \ wincol: 12,
   3450        \ line: 1,
   3451        \ column: 2,
   3452        \ coladd: 3,
   3453        \ }, getmousepos())
   3454  call Ntest_setmouse(1, 25)
   3455  call assert_equal(#{
   3456        \ screenrow: 1,
   3457        \ screencol: 25,
   3458        \ winid: win_getid(),
   3459        \ winrow: 1,
   3460        \ wincol: 25,
   3461        \ line: 1,
   3462        \ column: 4,
   3463        \ coladd: 0,
   3464        \ }, getmousepos())
   3465  call Ntest_setmouse(1, 28)
   3466  call assert_equal(#{
   3467        \ screenrow: 1,
   3468        \ screencol: 28,
   3469        \ winid: win_getid(),
   3470        \ winrow: 1,
   3471        \ wincol: 28,
   3472        \ line: 1,
   3473        \ column: 7,
   3474        \ coladd: 0,
   3475        \ }, getmousepos())
   3476  call Ntest_setmouse(1, 29)
   3477  call assert_equal(#{
   3478        \ screenrow: 1,
   3479        \ screencol: 29,
   3480        \ winid: win_getid(),
   3481        \ winrow: 1,
   3482        \ wincol: 29,
   3483        \ line: 1,
   3484        \ column: 8,
   3485        \ coladd: 0,
   3486        \ }, getmousepos())
   3487  call Ntest_setmouse(1, 50)
   3488  call assert_equal(#{
   3489        \ screenrow: 1,
   3490        \ screencol: 50,
   3491        \ winid: win_getid(),
   3492        \ winrow: 1,
   3493        \ wincol: 50,
   3494        \ line: 1,
   3495        \ column: 8,
   3496        \ coladd: 21,
   3497        \ }, getmousepos())
   3498 
   3499  " If the mouse is positioned past the last buffer line, "line" and "column"
   3500  " should act like it's positioned on the last buffer line.
   3501  call Ntest_setmouse(2, 25)
   3502  call assert_equal(#{
   3503        \ screenrow: 2,
   3504        \ screencol: 25,
   3505        \ winid: win_getid(),
   3506        \ winrow: 2,
   3507        \ wincol: 25,
   3508        \ line: 1,
   3509        \ column: 4,
   3510        \ coladd: 0,
   3511        \ }, getmousepos())
   3512  call Ntest_setmouse(2, 50)
   3513  call assert_equal(#{
   3514        \ screenrow: 2,
   3515        \ screencol: 50,
   3516        \ winid: win_getid(),
   3517        \ winrow: 2,
   3518        \ wincol: 50,
   3519        \ line: 1,
   3520        \ column: 8,
   3521        \ coladd: 21,
   3522        \ }, getmousepos())
   3523 
   3524  30vnew
   3525  setlocal smoothscroll number
   3526  call setline(1, join(range(100)))
   3527  exe "normal! \<C-E>"
   3528  call Ntest_setmouse(1, 5)
   3529  call assert_equal(#{
   3530        \ screenrow: 1,
   3531        \ screencol: 5,
   3532        \ winid: win_getid(),
   3533        \ winrow: 1,
   3534        \ wincol: 5,
   3535        \ line: 1,
   3536        \ column: 27,
   3537        \ coladd: 0,
   3538        \ }, getmousepos())
   3539  call Ntest_setmouse(2, 5)
   3540  call assert_equal(#{
   3541        \ screenrow: 2,
   3542        \ screencol: 5,
   3543        \ winid: win_getid(),
   3544        \ winrow: 2,
   3545        \ wincol: 5,
   3546        \ line: 1,
   3547        \ column: 53,
   3548        \ coladd: 0,
   3549        \ }, getmousepos())
   3550 
   3551  exe "normal! \<C-E>"
   3552  call Ntest_setmouse(1, 5)
   3553  call assert_equal(#{
   3554        \ screenrow: 1,
   3555        \ screencol: 5,
   3556        \ winid: win_getid(),
   3557        \ winrow: 1,
   3558        \ wincol: 5,
   3559        \ line: 1,
   3560        \ column: 53,
   3561        \ coladd: 0,
   3562        \ }, getmousepos())
   3563  call Ntest_setmouse(2, 5)
   3564  call assert_equal(#{
   3565        \ screenrow: 2,
   3566        \ screencol: 5,
   3567        \ winid: win_getid(),
   3568        \ winrow: 2,
   3569        \ wincol: 5,
   3570        \ line: 1,
   3571        \ column: 79,
   3572        \ coladd: 0,
   3573        \ }, getmousepos())
   3574 
   3575  vert resize 4
   3576  call Ntest_setmouse(2, 2)
   3577  " This used to crash Vim
   3578  call assert_equal(#{
   3579        \ screenrow: 2,
   3580        \ screencol: 2,
   3581        \ winid: win_getid(),
   3582        \ winrow: 2,
   3583        \ wincol: 2,
   3584        \ line: 1,
   3585        \ column: 53,
   3586        \ coladd: 0,
   3587        \ }, getmousepos())
   3588 
   3589  bwipe!
   3590  bwipe!
   3591 endfunc
   3592 
   3593 " Test for glob()
   3594 func Test_glob()
   3595  call assert_equal('', glob(v:_null_string))
   3596  call assert_equal('', globpath(v:_null_string, v:_null_string))
   3597  call assert_fails("let x = globpath(&rtp, 'syntax/c.vim', [])", 'E745:')
   3598 
   3599  call writefile([], 'Xglob1')
   3600  call writefile([], 'XGLOB2')
   3601  set wildignorecase
   3602  " Sort output of glob() otherwise we end up with different
   3603  " ordering depending on whether file system is case-sensitive.
   3604  call assert_equal(['XGLOB2', 'Xglob1'], sort(glob('Xglob[12]', 0, 1)))
   3605  " wildignorecase shall be applied even when the pattern contains no wildcards.
   3606  call assert_equal('XGLOB2', glob('xglob2'))
   3607  set wildignorecase&
   3608 
   3609  call delete('Xglob1')
   3610  call delete('XGLOB2')
   3611 
   3612  call assert_fails("call glob('*', 0, {})", 'E728:')
   3613 endfunc
   3614 
   3615 func Test_glob2()
   3616  call mkdir('[XglobDir]', 'R')
   3617  call mkdir('abc[glob]def', 'R')
   3618 
   3619  call writefile(['glob'], '[XglobDir]/Xglob')
   3620  call writefile(['glob'], 'abc[glob]def/Xglob')
   3621  if has("unix")
   3622    call assert_equal([], (glob('[XglobDir]/*', 0, 1)))
   3623    call assert_equal([], (glob('abc[glob]def/*', 0, 1)))
   3624    call assert_equal(['[XglobDir]/Xglob'], (glob('\[XglobDir]/*', 0, 1)))
   3625    call assert_equal(['abc[glob]def/Xglob'], (glob('abc\[glob]def/*', 0, 1)))
   3626  elseif has("win32")
   3627    let _sl=&shellslash
   3628    call assert_equal([], (glob('[XglobDir]\*', 0, 1)))
   3629    call assert_equal([], (glob('abc[glob]def\*', 0, 1)))
   3630    call assert_equal([], (glob('\[XglobDir]\*', 0, 1)))
   3631    call assert_equal([], (glob('abc\[glob]def\*', 0, 1)))
   3632    set noshellslash
   3633    call assert_equal(['[XglobDir]\Xglob'], (glob('[[]XglobDir]/*', 0, 1)))
   3634    call assert_equal(['abc[glob]def\Xglob'], (glob('abc[[]glob]def/*', 0, 1)))
   3635    set shellslash
   3636    call assert_equal(['[XglobDir]/Xglob'], (glob('[[]XglobDir]/*', 0, 1)))
   3637    call assert_equal(['abc[glob]def/Xglob'], (glob('abc[[]glob]def/*', 0, 1)))
   3638    let &shellslash=_sl
   3639  endif
   3640 endfunc
   3641 
   3642 func Test_glob_symlinks()
   3643  call writefile([], 'Xglob1')
   3644 
   3645  if has("win32")
   3646    silent !mklink XglobBad DoesNotExist
   3647    if v:shell_error
   3648      throw 'Skipped: cannot create symlinks'
   3649    endif
   3650    silent !mklink XglobOk Xglob1
   3651  else
   3652    silent !ln -s DoesNotExist XglobBad
   3653    silent !ln -s Xglob1 XglobOk
   3654  endif
   3655 
   3656  " The broken symlink is excluded when alllinks is false.
   3657  call assert_equal(['Xglob1', 'XglobBad', 'XglobOk'], sort(glob('Xglob*', 0, 1, 1)))
   3658  call assert_equal(['Xglob1', 'XglobOk'], sort(glob('Xglob*', 0, 1, 0)))
   3659 
   3660  call delete('Xglob1')
   3661  call delete('XglobBad')
   3662  call delete('XglobOk')
   3663 endfunc
   3664 
   3665 " Test for browse()
   3666 func Test_browse()
   3667  CheckFeature browse
   3668  call assert_fails('call browse([], "open", "x", "a.c")', 'E745:')
   3669 endfunc
   3670 
   3671 " Test for browsedir()
   3672 func Test_browsedir()
   3673  CheckFeature browse
   3674  call assert_fails('call browsedir("open", [])', 'E730:')
   3675 endfunc
   3676 
   3677 func HasDefault(msg = 'msg')
   3678  return a:msg
   3679 endfunc
   3680 
   3681 func Test_default_arg_value()
   3682  call assert_equal('msg', HasDefault())
   3683 endfunc
   3684 
   3685 " Test for gettext()
   3686 func Test_gettext()
   3687  call assert_fails('call gettext(1)', 'E1174:')
   3688 endfunc
   3689 
   3690 func Test_builtin_check()
   3691  call assert_fails('let g:["trim"] = {x -> " " .. x}', 'E704:')
   3692  call assert_fails('let g:.trim = {x -> " " .. x}', 'E704:')
   3693  call assert_fails('let l:["trim"] = {x -> " " .. x}', 'E704:')
   3694  call assert_fails('let l:.trim = {x -> " " .. x}', 'E704:')
   3695  let lines =<< trim END
   3696    vim9script
   3697    var trim = (x) => " " .. x
   3698  END
   3699  call CheckScriptFailure(lines, 'E704:')
   3700 
   3701  call assert_fails('call extend(g:, #{foo: { -> "foo" }})', 'E704:')
   3702  let g:bar = 123
   3703  call extend(g:, #{bar: { -> "foo" }}, "keep")
   3704  call assert_fails('call extend(g:, #{bar: { -> "foo" }}, "force")', 'E704:')
   3705  unlet g:bar
   3706 
   3707  call assert_fails('call extend(l:, #{foo: { -> "foo" }})', 'E704:')
   3708  let bar = 123
   3709  call extend(l:, #{bar: { -> "foo" }}, "keep")
   3710  call assert_fails('call extend(l:, #{bar: { -> "foo" }}, "force")', 'E704:')
   3711  unlet bar
   3712 
   3713  call assert_fails('call extend(g:, #{foo: function("extend")})', 'E704:')
   3714  let g:bar = 123
   3715  call extend(g:, #{bar: function("extend")}, "keep")
   3716  call assert_fails('call extend(g:, #{bar: function("extend")}, "force")', 'E704:')
   3717  unlet g:bar
   3718 
   3719  call assert_fails('call extend(l:, #{foo: function("extend")})', 'E704:')
   3720  let bar = 123
   3721  call extend(l:, #{bar: function("extend")}, "keep")
   3722  call assert_fails('call extend(l:, #{bar: function("extend")}, "force")', 'E704:')
   3723  unlet bar
   3724 endfunc
   3725 
   3726 func Test_funcref_to_string()
   3727  let Fn = funcref('g:Test_funcref_to_string')
   3728  call assert_equal("function('g:Test_funcref_to_string')", string(Fn))
   3729 endfunc
   3730 
   3731 " Test for isabsolutepath()
   3732 func Test_isabsolutepath()
   3733  call assert_false(isabsolutepath(''))
   3734  call assert_false(isabsolutepath('.'))
   3735  call assert_false(isabsolutepath('../Foo'))
   3736  call assert_false(isabsolutepath('Foo/'))
   3737  if has('win32')
   3738    call assert_true(isabsolutepath('A:\'))
   3739    call assert_true(isabsolutepath('A:\Foo'))
   3740    call assert_true(isabsolutepath('A:/Foo'))
   3741    call assert_false(isabsolutepath('A:Foo'))
   3742    call assert_true(isabsolutepath('\Windows'))
   3743    call assert_true(isabsolutepath('/Windows'))
   3744    call assert_true(isabsolutepath('\\Server2\Share\Test\Foo.txt'))
   3745  else
   3746    call assert_true(isabsolutepath('/'))
   3747    call assert_true(isabsolutepath('/usr/share/'))
   3748  endif
   3749 endfunc
   3750 
   3751 " Test for exepath()
   3752 func Test_exepath()
   3753  if has('win32')
   3754    call assert_notequal(exepath('cmd'), '')
   3755 
   3756    let oldNoDefaultCurrentDirectoryInExePath = $NoDefaultCurrentDirectoryInExePath
   3757    call writefile(['@echo off', 'echo Evil'], 'vim-test-evil.bat')
   3758    let $NoDefaultCurrentDirectoryInExePath = ''
   3759    call assert_notequal(exepath("vim-test-evil.bat"), '')
   3760    let $NoDefaultCurrentDirectoryInExePath = '1'
   3761    call assert_equal(exepath("vim-test-evil.bat"), '')
   3762    let $NoDefaultCurrentDirectoryInExePath = oldNoDefaultCurrentDirectoryInExePath
   3763    call delete('vim-test-evil.bat')
   3764  else
   3765    call assert_notequal(exepath('sh'), '')
   3766  endif
   3767 endfunc
   3768 
   3769 " Test for virtcol()
   3770 func Test_virtcol()
   3771  new
   3772  call setline(1, "the\tquick\tbrown\tfox")
   3773  norm! 4|
   3774  call assert_equal(8, virtcol('.'))
   3775  call assert_equal(8, virtcol('.', v:false))
   3776  call assert_equal([4, 8], virtcol('.', v:true))
   3777 
   3778  let w = winwidth(0)
   3779  call setline(2, repeat('a', w + 2))
   3780  let win_nosbr = win_getid()
   3781  split
   3782  setlocal showbreak=!!
   3783  let win_sbr = win_getid()
   3784  call assert_equal([w, w], virtcol([2, w], v:true, win_nosbr))
   3785  call assert_equal([w + 1, w + 1], virtcol([2, w + 1], v:true, win_nosbr))
   3786  call assert_equal([w + 2, w + 2], virtcol([2, w + 2], v:true, win_nosbr))
   3787  call assert_equal([w, w], virtcol([2, w], v:true, win_sbr))
   3788  call assert_equal([w + 3, w + 3], virtcol([2, w + 1], v:true, win_sbr))
   3789  call assert_equal([w + 4, w + 4], virtcol([2, w + 2], v:true, win_sbr))
   3790  close
   3791 
   3792  call assert_equal(0, virtcol(''))
   3793  call assert_equal([0, 0], virtcol('', v:true))
   3794  call assert_equal(0, virtcol('.', v:false, 5001))
   3795  call assert_equal([0, 0], virtcol('.', v:true, 5001))
   3796 
   3797  bwipe!
   3798 endfunc
   3799 
   3800 func Test_delfunc_while_listing()
   3801  CheckRunVimInTerminal
   3802 
   3803  let lines =<< trim END
   3804      set nocompatible
   3805      for i in range(1, 999)
   3806        exe 'func ' .. 'MyFunc' .. i .. '()'
   3807        endfunc
   3808      endfor
   3809      au CmdlineLeave : call timer_start(0, {-> execute('delfunc MyFunc622')})
   3810  END
   3811  call writefile(lines, 'Xfunctionclear', 'D')
   3812  let buf = RunVimInTerminal('-S Xfunctionclear', {'rows': 12})
   3813 
   3814  " This was using freed memory.  The height of the terminal must be so that
   3815  " the next function to be listed with "j" is the one that is deleted in the
   3816  " timer callback, tricky!
   3817  call term_sendkeys(buf, ":func /MyFunc\<CR>")
   3818  call TermWait(buf, 50)
   3819  call term_sendkeys(buf, "j")
   3820  call TermWait(buf, 50)
   3821  call term_sendkeys(buf, "\<CR>")
   3822 
   3823  call StopVimInTerminal(buf)
   3824 endfunc
   3825 
   3826 " Test for the reverse() function with a string
   3827 func Test_string_reverse()
   3828  let lines =<< trim END
   3829    call assert_equal('', reverse(v:_null_string))
   3830    for [s1, s2] in [['', ''], ['a', 'a'], ['ab', 'ba'], ['abc', 'cba'],
   3831                   \ ['abcd', 'dcba'], ['«-«-»-»', '»-»-«-«'],
   3832                   \ ['🇦', '🇦'], ['🇦🇧', '🇦🇧'], ['🇦🇧🇨', '🇨🇦🇧'],
   3833                   \ ['🇦«🇧-🇨»🇩', '🇩»🇨-🇧«🇦']]
   3834      call assert_equal(s2, reverse(s1))
   3835    endfor
   3836  END
   3837  call CheckLegacyAndVim9Success(lines)
   3838 
   3839  " test in latin1 encoding
   3840  let save_enc = &encoding
   3841  " set encoding=latin1
   3842  call assert_equal('dcba', reverse('abcd'))
   3843  let &encoding = save_enc
   3844 endfunc
   3845 
   3846 func Test_fullcommand()
   3847  " this used to crash vim
   3848  call assert_equal('', fullcommand(10))
   3849 endfunc
   3850 
   3851 " Test for glob() with shell special patterns
   3852 func Test_glob_extended_bash()
   3853  CheckExecutable bash
   3854  CheckNotMSWindows
   3855  CheckNotMac   " The default version of bash is old on macOS.
   3856 
   3857  let _shell = &shell
   3858  set shell=bash
   3859 
   3860  call mkdir('Xtestglob/foo/bar/src', 'p')
   3861  call writefile([], 'Xtestglob/foo/bar/src/foo.sh')
   3862  call writefile([], 'Xtestglob/foo/bar/src/foo.h')
   3863  call writefile([], 'Xtestglob/foo/bar/src/foo.cpp')
   3864 
   3865  " Sort output of glob() otherwise we end up with different
   3866  " ordering depending on whether file system is case-sensitive.
   3867  let expected = ['Xtestglob/foo/bar/src/foo.cpp', 'Xtestglob/foo/bar/src/foo.h']
   3868  call assert_equal(expected, sort(glob('Xtestglob/**/foo.{h,cpp}', 0, 1)))
   3869  call delete('Xtestglob', 'rf')
   3870  let &shell=_shell
   3871 endfunc
   3872 
   3873 " Test for glob() with extended patterns (MS-Windows)
   3874 " Vim doesn't use 'shell' to expand wildcards on MS-Windows.
   3875 " Unlike bash, it doesn't support {,} expansion.
   3876 func Test_glob_extended_mswin()
   3877  CheckMSWindows
   3878 
   3879  call mkdir('Xtestglob/foo/bar/src', 'p')
   3880  call writefile([], 'Xtestglob/foo/bar/src/foo.sh')
   3881  call writefile([], 'Xtestglob/foo/bar/src/foo.h')
   3882  call writefile([], 'Xtestglob/foo/bar/src/foo.cpp')
   3883 
   3884  " Sort output of glob() otherwise we end up with different
   3885  " ordering depending on whether file system is case-sensitive.
   3886  let expected = ['Xtestglob/foo/bar/src/foo.cpp', 'Xtestglob/foo/bar/src/foo.h', 'Xtestglob/foo/bar/src/foo.sh']
   3887  call assert_equal(expected, sort(glob('Xtestglob/**/foo.*', 0, 1)))
   3888  call delete('Xtestglob', 'rf')
   3889 endfunc
   3890 
   3891 " Tests for the slice() function.
   3892 func Test_slice()
   3893  let lines =<< trim END
   3894    call assert_equal([1, 2, 3, 4, 5], slice(range(6), 1))
   3895    call assert_equal([2, 3, 4, 5], slice(range(6), 2))
   3896    call assert_equal([2, 3], slice(range(6), 2, 4))
   3897    call assert_equal([0, 1, 2, 3], slice(range(6), 0, 4))
   3898    call assert_equal([1, 2, 3], slice(range(6), 1, 4))
   3899    call assert_equal([1, 2, 3, 4], slice(range(6), 1, -1))
   3900    call assert_equal([1, 2], slice(range(6), 1, -3))
   3901    call assert_equal([1], slice(range(6), 1, -4))
   3902    call assert_equal([], slice(range(6), 1, -5))
   3903    call assert_equal([], slice(range(6), 1, -6))
   3904 
   3905    call assert_equal(0z1122334455, slice(0z001122334455, 1))
   3906    call assert_equal(0z22334455, slice(0z001122334455, 2))
   3907    call assert_equal(0z2233, slice(0z001122334455, 2, 4))
   3908    call assert_equal(0z00112233, slice(0z001122334455, 0, 4))
   3909    call assert_equal(0z112233, slice(0z001122334455, 1, 4))
   3910    call assert_equal(0z11223344, slice(0z001122334455, 1, -1))
   3911    call assert_equal(0z1122, slice(0z001122334455, 1, -3))
   3912    call assert_equal(0z11, slice(0z001122334455, 1, -4))
   3913    call assert_equal(0z, slice(0z001122334455, 1, -5))
   3914    call assert_equal(0z, slice(0z001122334455, 1, -6))
   3915 
   3916    call assert_equal('12345', slice('012345', 1))
   3917    call assert_equal('2345', slice('012345', 2))
   3918    call assert_equal('23', slice('012345', 2, 4))
   3919    call assert_equal('0123', slice('012345', 0, 4))
   3920    call assert_equal('123', slice('012345', 1, 4))
   3921    call assert_equal('1234', slice('012345', 1, -1))
   3922    call assert_equal('12', slice('012345', 1, -3))
   3923    call assert_equal('1', slice('012345', 1, -4))
   3924    call assert_equal('', slice('012345', 1, -5))
   3925    call assert_equal('', slice('012345', 1, -6))
   3926 
   3927    #" Composing chars are treated as a part of the preceding base char.
   3928    call assert_equal('β̳́γ̳̂δ̳̃ε̳̄ζ̳̅', 'ὰ̳β̳́γ̳̂δ̳̃ε̳̄ζ̳̅'->slice(1))
   3929    call assert_equal('γ̳̂δ̳̃ε̳̄ζ̳̅', 'ὰ̳β̳́γ̳̂δ̳̃ε̳̄ζ̳̅'->slice(2))
   3930    call assert_equal('γ̳̂δ̳̃', 'ὰ̳β̳́γ̳̂δ̳̃ε̳̄ζ̳̅'->slice(2, 4))
   3931    call assert_equal('ὰ̳β̳́γ̳̂δ̳̃', 'ὰ̳β̳́γ̳̂δ̳̃ε̳̄ζ̳̅'->slice(0, 4))
   3932    call assert_equal('β̳́γ̳̂δ̳̃', 'ὰ̳β̳́γ̳̂δ̳̃ε̳̄ζ̳̅'->slice(1, 4))
   3933    call assert_equal('β̳́γ̳̂δ̳̃ε̳̄', 'ὰ̳β̳́γ̳̂δ̳̃ε̳̄ζ̳̅'->slice(1, -1))
   3934    call assert_equal('β̳́γ̳̂', 'ὰ̳β̳́γ̳̂δ̳̃ε̳̄ζ̳̅'->slice(1, -3))
   3935    call assert_equal('β̳́', 'ὰ̳β̳́γ̳̂δ̳̃ε̳̄ζ̳̅'->slice(1, -4))
   3936    call assert_equal('', 'ὰ̳β̳́γ̳̂δ̳̃ε̳̄ζ̳̅'->slice(1, -5))
   3937    call assert_equal('', 'ὰ̳β̳́γ̳̂δ̳̃ε̳̄ζ̳̅'->slice(1, -6))
   3938  END
   3939  call CheckLegacyAndVim9Success(lines)
   3940 
   3941  call assert_equal(0, slice(v:true, 1))
   3942 endfunc
   3943 
   3944 " vim: shiftwidth=2 sts=2 expandtab