neovim

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

test_filter_map.vim (16645B)


      1 " Test filter() and map()
      2 
      3 source vim9.vim
      4 
      5 " list with expression string
      6 func Test_filter_map_list_expr_string()
      7  " filter()
      8  call assert_equal([2, 3, 4], filter([1, 2, 3, 4], 'v:val > 1'))
      9  call assert_equal([3, 4], filter([1, 2, 3, 4], 'v:key > 1'))
     10  call assert_equal([], filter([1, 2, 3, 4], 0))
     11 
     12  " map()
     13  call assert_equal([2, 4, 6, 8], map([1, 2, 3, 4], 'v:val * 2'))
     14  call assert_equal([0, 2, 4, 6], map([1, 2, 3, 4], 'v:key * 2'))
     15  call assert_equal([9, 9, 9, 9], map([1, 2, 3, 4], 9))
     16  call assert_equal([7, 7, 7], map([1, 2, 3], ' 7 '))
     17 
     18  " foreach()
     19  let list01 = [1, 2, 3, 4]
     20  let list02 = []
     21  call assert_equal([1, 2, 3, 4], foreach(list01, 'call add(list02, v:val * 2)'))
     22  call assert_equal([2, 4, 6, 8], list02)
     23  let list02 = []
     24  call assert_equal([1, 2, 3, 4], foreach(list01, 'call add(list02, v:key * 2)'))
     25  call assert_equal([0, 2, 4, 6], list02)
     26  let list02 = []
     27  call assert_equal([1, 2, 3, 4], foreach(list01, 'call add(list02, 9)'))
     28  call assert_equal([9, 9, 9, 9], list02)
     29 endfunc
     30 
     31 " dict with expression string
     32 func Test_filter_map_dict_expr_string()
     33  let dict = {"foo": 1, "bar": 2, "baz": 3}
     34 
     35  " filter()
     36  call assert_equal({"bar": 2, "baz": 3}, filter(copy(dict), 'v:val > 1'))
     37  call assert_equal({"foo": 1, "baz": 3}, filter(copy(dict), 'v:key > "bar"'))
     38  call assert_equal({}, filter(copy(dict), 0))
     39 
     40  " map()
     41  call assert_equal({"foo": 2, "bar": 4, "baz": 6}, map(copy(dict), 'v:val * 2'))
     42  call assert_equal({"foo": "f", "bar": "b", "baz": "b"}, map(copy(dict), 'v:key[0]'))
     43  call assert_equal({"foo": 9, "bar": 9, "baz": 9}, map(copy(dict), 9))
     44 
     45  " foreach()
     46  let dict01 = {}
     47  call assert_equal(dict, foreach(copy(dict), 'let dict01[v:key] = v:val * 2'))
     48  call assert_equal({"foo": 2, "bar": 4, "baz": 6}, dict01)
     49  let dict01 = {}
     50  call assert_equal(dict, foreach(copy(dict), 'let dict01[v:key] = v:key[0]'))
     51  call assert_equal({"foo": "f", "bar": "b", "baz": "b"}, dict01)
     52 endfunc
     53 
     54 " list with funcref
     55 func Test_filter_map_list_expr_funcref()
     56  " filter()
     57  func! s:filter1(index, val) abort
     58    return a:val > 1
     59  endfunc
     60  call assert_equal([2, 3, 4], filter([1, 2, 3, 4], function('s:filter1')))
     61 
     62  func! s:filter2(index, val) abort
     63    return a:index > 1
     64  endfunc
     65  call assert_equal([3, 4], filter([1, 2, 3, 4], function('s:filter2')))
     66 
     67  " map()
     68  func! s:filter3(index, val) abort
     69    return a:val * 2
     70  endfunc
     71  call assert_equal([2, 4, 6, 8], map([1, 2, 3, 4], function('s:filter3')))
     72 
     73  func! s:filter4(index, val) abort
     74    return a:index * 2
     75  endfunc
     76  call assert_equal([0, 2, 4, 6], map([1, 2, 3, 4], function('s:filter4')))
     77 
     78  " foreach()
     79  func! s:foreach1(index, val) abort
     80    call add(g:test_variable, a:val + 1)
     81    return [ 11, 12, 13, 14 ]
     82  endfunc
     83  let g:test_variable = []
     84  call assert_equal([0, 1, 2, 3, 4], foreach(range(5), function('s:foreach1')))
     85  call assert_equal([1, 2, 3, 4, 5], g:test_variable)
     86  call remove(g:, 'test_variable')
     87 endfunc
     88 
     89 func Test_filter_map_nested()
     90  let x = {"x":10}
     91  let r = map(range(2), 'filter(copy(x), "1")')
     92  call assert_equal([x, x], r)
     93 
     94  let r = map(copy(x), 'filter(copy(x), "1")')
     95  call assert_equal({"x": x}, r)
     96 endfunc
     97 
     98 " dict with funcref
     99 func Test_filter_map_dict_expr_funcref()
    100  let dict = {"foo": 1, "bar": 2, "baz": 3}
    101 
    102  " filter()
    103  func! s:filter1(key, val) abort
    104    return a:val > 1
    105  endfunc
    106  call assert_equal({"bar": 2, "baz": 3}, filter(copy(dict), function('s:filter1')))
    107 
    108  func! s:filter2(key, val) abort
    109    return a:key > "bar"
    110  endfunc
    111  call assert_equal({"foo": 1, "baz": 3}, filter(copy(dict), function('s:filter2')))
    112 
    113  " map()
    114  func! s:filter3(key, val) abort
    115    return a:val * 2
    116  endfunc
    117  call assert_equal({"foo": 2, "bar": 4, "baz": 6}, map(copy(dict), function('s:filter3')))
    118 
    119  func! s:filter4(key, val) abort
    120    return a:key[0]
    121  endfunc
    122  call assert_equal({"foo": "f", "bar": "b", "baz": "b"}, map(copy(dict), function('s:filter4')))
    123 
    124  " foreach()
    125  func! s:foreach1(key, val) abort
    126    call extend(g:test_variable, {a:key: a:val * 2})
    127    return [ 11, 12, 13, 14 ]
    128  endfunc
    129  let g:test_variable = {}
    130  call assert_equal(dict, foreach(copy(dict), function('s:foreach1')))
    131  call assert_equal({"foo": 2, "bar": 4, "baz": 6}, g:test_variable)
    132  call remove(g:, 'test_variable')
    133 endfunc
    134 
    135 func Test_map_filter_locked()
    136  let list01 = [1, 2, 3, 4]
    137  lockvar 1 list01
    138  call assert_fails('call filter(list01, "v:val > 1")', 'E741:')
    139  call assert_equal([2, 4, 6, 8], map(list01, 'v:val * 2'))
    140  call assert_equal([1, 2, 3, 4], map(list01, 'v:val / 2'))
    141  call assert_equal([2, 4, 6, 8], mapnew(list01, 'v:val * 2'))
    142  let g:test_variable = []
    143  call assert_equal([1, 2, 3, 4], foreach(list01, 'call add(g:test_variable, v:val * 2)'))
    144  call remove(g:, 'test_variable')
    145  call assert_fails('call filter(list01, "v:val > 1")', 'E741:')
    146  unlockvar 1 list01
    147  lockvar! list01
    148  call assert_fails('call filter(list01, "v:val > 1")', 'E741:')
    149  call assert_fails('call map(list01, "v:val * 2")', 'E741:')
    150  call assert_equal([2, 4, 6, 8], mapnew(list01, 'v:val * 2'))
    151  let g:test_variable = []
    152  call assert_equal([1, 2, 3, 4], foreach(list01, 'call add(g:test_variable, v:val * 2)'))
    153  call assert_fails('call foreach(list01, "let list01[0] = -1")', 'E741:')
    154  call assert_fails('call filter(list01, "v:val > 1")', 'E741:')
    155  call remove(g:, 'test_variable')
    156  unlockvar! list01
    157 endfunc
    158 
    159 func Test_map_filter_fails()
    160  call assert_fails('call map([1], "42 +")', 'E15:')
    161  call assert_fails('call filter([1], "42 +")', 'E15:')
    162  call assert_fails('call foreach([1], "let a = }")', 'E15:')
    163  call assert_fails("let l = filter([1, 2, 3], '{}')", 'E728:')
    164  call assert_fails("let l = filter({'k' : 10}, '{}')", 'E728:')
    165  call assert_fails("let l = filter([1, 2], {})", 'E731:')
    166  call assert_equal(v:_null_list, filter(v:_null_list, 0))
    167  call assert_equal(v:_null_dict, filter(v:_null_dict, 0))
    168  call assert_equal(v:_null_list, map(v:_null_list, '"> " .. v:val'))
    169  call assert_equal(v:_null_dict, map(v:_null_dict, '"> " .. v:val'))
    170  " Nvim doesn't have null functions
    171  " call assert_equal([1, 2, 3], filter([1, 2, 3], test_null_function()))
    172  call assert_fails("let l = filter([1, 2], function('min'))", 'E118:')
    173  " Nvim doesn't have null partials
    174  " call assert_equal([1, 2, 3], filter([1, 2, 3], test_null_partial()))
    175  call assert_fails("let l = filter([1, 2], {a, b, c -> 1})", 'E119:')
    176  call assert_fails('call foreach([1], "xyzzy")', 'E492:')
    177  call assert_fails('call foreach([1], "let a = foo")', 'E121:')
    178 endfunc
    179 
    180 func Test_map_and_modify()
    181  let l = ["abc"]
    182  " cannot change the list halfway a map()
    183  call assert_fails('call map(l, "remove(l, 0)[0]")', 'E741:')
    184 
    185  let d = #{a: 1, b: 2, c: 3}
    186  call assert_fails('call map(d, "remove(d, v:key)[0]")', 'E741:')
    187  call assert_fails('echo map(d, {k,v -> remove(d, k)})', 'E741:')
    188 
    189  let b = 0z1234
    190  call assert_fails('call filter(b, "remove(b, 0)")', 'E741:')
    191 endfunc
    192 
    193 func Test_filter_and_modify()
    194  let l = [0]
    195  " cannot change the list halfway thru filter()
    196  call assert_fails('call filter(l, "remove(l, 0)")', 'E741:')
    197 
    198  let d = #{a: 0, b: 0, c: 0}
    199  call assert_fails('call filter(d, "remove(d, v:key)")', 'E741:')
    200 
    201  let b = 0z1234
    202  call assert_fails('call filter(b, "remove(b, 0)")', 'E741:')
    203 endfunc
    204 
    205 func Test_foreach_and_modify()
    206  let l = [0]
    207  " cannot change the list halfway thru foreach()
    208  call assert_fails('call foreach(l, "let a = remove(l, 0)")', 'E741:')
    209 
    210  let d = #{a: 0, b: 0, c: 0}
    211  call assert_fails('call foreach(d, "let a = remove(d, v:key)")', 'E741:')
    212 
    213  let b = 0z1234
    214  call assert_fails('call foreach(b, "let a = remove(b, 0)")', 'E741:')
    215 endfunc
    216 
    217 func Test_mapnew_dict()
    218  let din = #{one: 1, two: 2}
    219  let dout = mapnew(din, {k, v -> string(v)})
    220  call assert_equal(#{one: 1, two: 2}, din)
    221  call assert_equal(#{one: '1', two: '2'}, dout)
    222 
    223  const dconst = #{one: 1, two: 2, three: 3}
    224  call assert_equal(#{one: 2, two: 3, three: 4}, mapnew(dconst, {_, v -> v + 1}))
    225 
    226  " return value of mapnew() can be modified
    227  let dout = mapnew(dconst, {k, v -> $'{k}={v}'})
    228  let dout.one ..= '!'
    229  call assert_equal(#{one: 'one=1!', two: 'two=2', three: 'three=3'}, dout)
    230  unlet dout.three
    231  call assert_equal(#{one: 'one=1!', two: 'two=2'}, dout)
    232  " original Dict is still locked
    233  call assert_fails('unlet dconst.three', 'E741:')
    234  call assert_fails('let dconst.one += 1', 'E741:')
    235 endfunc
    236 
    237 func Test_mapnew_list()
    238  let lin = [1, 2, 3]
    239  let lout = mapnew(lin, {k, v -> string(v)})
    240  call assert_equal([1, 2, 3], lin)
    241  call assert_equal(['1', '2', '3'], lout)
    242 
    243  const lconst = [1, 2, 3]
    244  call assert_equal([2, 3, 4], mapnew(lconst, {_, v -> v + 1}))
    245 
    246  " return value of mapnew() can be modified
    247  let lout = mapnew(lconst, {k, v -> $'{k}={v}'})
    248  let lout[0] ..= '!'
    249  call assert_equal(['0=1!', '1=2', '2=3'], lout)
    250  unlet lout[2]
    251  call assert_equal(['0=1!', '1=2'], lout)
    252  " original List is still locked
    253  call assert_fails('unlet lconst[2]', 'E741:')
    254  call assert_fails('let lconst[0] += 1', 'E741:')
    255 endfunc
    256 
    257 func Test_mapnew_blob()
    258  let bin = 0z123456
    259  let bout = mapnew(bin, {k, v -> k == 1 ? 0x99 : v})
    260  call assert_equal(0z123456, bin)
    261  call assert_equal(0z129956, bout)
    262 endfunc
    263 
    264 func Test_foreach_blob()
    265  let lines =<< trim END
    266    LET g:test_variable = []
    267    call assert_equal(0z0001020304, foreach(0z0001020304, 'call add(g:test_variable, v:val)'))
    268    call assert_equal([0, 1, 2, 3, 4], g:test_variable)
    269  END
    270  call CheckLegacyAndVim9Success(lines)
    271 
    272  func! s:foreach1(index, val) abort
    273    call add(g:test_variable, a:val)
    274    return [ 11, 12, 13, 14 ]
    275  endfunc
    276  let g:test_variable = []
    277  call assert_equal(0z0001020304, foreach(0z0001020304, function('s:foreach1')))
    278  call assert_equal([0, 1, 2, 3, 4], g:test_variable)
    279 
    280  let lines =<< trim END
    281    def Foreach1(_, val: any): list<number>
    282      add(g:test_variable, val)
    283      return [ 11, 12, 13, 14 ]
    284    enddef
    285    g:test_variable = []
    286    assert_equal(0z0001020304, foreach(0z0001020304, Foreach1))
    287    assert_equal([0, 1, 2, 3, 4], g:test_variable)
    288  END
    289  call CheckDefSuccess(lines)
    290 
    291  call remove(g:, 'test_variable')
    292 endfunc
    293 
    294 " Test for using map(), filter() and mapnew() with a string
    295 func Test_filter_map_string()
    296  " filter()
    297  let lines =<< trim END
    298    VAR s = "abc"
    299    call filter(s, '"b" != v:val')
    300    call assert_equal('abc', s)
    301    call assert_equal('ac', filter('abc', '"b" != v:val'))
    302    call assert_equal('あいうえお', filter('あxいxうxえxお', '"x" != v:val'))
    303    call assert_equal('あa😊💕💕b💕', filter('あxax😊x💕💕b💕x', '"x" != v:val'))
    304    call assert_equal('xxxx', filter('あxax😊x💕💕b💕x', '"x" == v:val'))
    305    VAR t = "%),:;>?]}’”†‡…‰,‱‼⁇⁈⁉℃℉,、。〉》」,』】〕〗〙〛,!),.:,;?,]}"
    306    VAR u = "%):;>?]}’”†‡…‰‱‼⁇⁈⁉℃℉、。〉》」』】〕〗〙〛!),.:;?]}"
    307    call assert_equal(u, filter(t, '"," != v:val'))
    308    call assert_equal('', filter('abc', '0'))
    309    call assert_equal('ac', filter('abc', LSTART i, x LMIDDLE "b" != x LEND))
    310    call assert_equal('あいうえお', filter('あxいxうxえxお', LSTART i, x LMIDDLE "x" != x LEND))
    311    call assert_equal('', filter('abc', LSTART i, x LMIDDLE v:false LEND))
    312    call assert_equal('', filter('', "v:val == 'a'"))
    313    call assert_equal('', filter(v:_null_string, "v:val == 'a'"))
    314  END
    315  call CheckLegacyAndVim9Success(lines)
    316 
    317  " map()
    318  let lines =<< trim END
    319    VAR s = "abc"
    320    call map(s, 'nr2char(char2nr(v:val) + 2)')
    321    call assert_equal('abc', s)
    322    call assert_equal('cde', map('abc', 'nr2char(char2nr(v:val) + 2)'))
    323    call assert_equal('[あ][i][う][え][お]', map('あiうえお', '"[" .. v:val .. "]"'))
    324    call assert_equal('[あ][a][😊][,][‱][‼][⁇][⁈][⁉][💕][b][💕][c][💕]', map('あa😊,‱‼⁇⁈⁉💕b💕c💕', '"[" .. v:val .. "]"'))
    325    call assert_equal('', map('abc', '""'))
    326    call assert_equal('cde', map('abc', LSTART i, x LMIDDLE nr2char(char2nr(x) + 2) LEND))
    327    call assert_equal('[あ][i][う][え][お]', map('あiうえお', LSTART i, x LMIDDLE '[' .. x .. ']' LEND))
    328    call assert_equal('', map('abc', LSTART i, x LMIDDLE '' LEND))
    329    call assert_equal('', map('', "v:val == 'a'"))
    330    call assert_equal('', map(v:_null_string, "v:val == 'a'"))
    331    call assert_fails('echo map("abc", "10")', 'E928:')
    332    call assert_fails('echo map("abc", "a10")', 'E121:')
    333  END
    334  call CheckLegacyAndVim9Success(lines)
    335 
    336  " mapnew()
    337  let lines =<< trim END
    338    VAR s = "abc"
    339    call mapnew(s, 'nr2char(char2nr(v:val) + 2)')
    340    call assert_equal('abc', s)
    341    call assert_equal('cde', mapnew('abc', 'nr2char(char2nr(v:val) + 2)'))
    342    call assert_equal('[あ][i][う][え][お]', mapnew('あiうえお', '"[" .. v:val .. "]"'))
    343    call assert_equal('[あ][a][😊][,][‱][‼][⁇][⁈][⁉][💕][b][💕][c][💕]', mapnew('あa😊,‱‼⁇⁈⁉💕b💕c💕', '"[" .. v:val .. "]"'))
    344    call assert_equal('', mapnew('abc', '""'))
    345    call assert_equal('cde', mapnew('abc', LSTART i, x LMIDDLE nr2char(char2nr(x) + 2) LEND))
    346    call assert_equal('[あ][i][う][え][お]', mapnew('あiうえお', LSTART i, x LMIDDLE '[' .. x .. ']' LEND))
    347    call assert_equal('', mapnew('abc', LSTART i, x LMIDDLE '' LEND))
    348    call assert_equal('', mapnew('', "v:val == 'a'"))
    349    call assert_equal('', mapnew(v:_null_string, "v:val == 'a'"))
    350  END
    351  call CheckLegacyAndVim9Success(lines)
    352 
    353  " foreach()
    354  let lines =<< trim END
    355    VAR s = "abc"
    356    LET g:test_variable = []
    357    call assert_equal(s, foreach(s, 'call add(g:test_variable, v:val)'))
    358    call assert_equal(['a', 'b', 'c'], g:test_variable)
    359    LET g:test_variable = []
    360    LET s = 'あiうえお'
    361    call assert_equal(s, foreach(s, 'call add(g:test_variable, v:val)'))
    362    call assert_equal(['あ', 'i', 'う', 'え', 'お'], g:test_variable)
    363  END
    364  call CheckLegacyAndVim9Success(lines)
    365  func! s:foreach1(index, val) abort
    366    call add(g:test_variable, a:val)
    367    return [ 11, 12, 13, 14 ]
    368  endfunc
    369  let g:test_variable = []
    370  call assert_equal('abcd', foreach('abcd', function('s:foreach1')))
    371  call assert_equal(['a', 'b', 'c', 'd'], g:test_variable)
    372  let lines =<< trim END
    373    def Foreach1(_, val: string): list<number>
    374      add(g:test_variable, val)
    375      return [ 11, 12, 13, 14 ]
    376    enddef
    377    g:test_variable = []
    378    assert_equal('abcd', foreach('abcd', Foreach1))
    379    assert_equal(['a', 'b', 'c', 'd'], g:test_variable)
    380  END
    381  call CheckDefSuccess(lines)
    382  call remove(g:, 'test_variable')
    383 
    384  let lines =<< trim END
    385    #" map() and filter()
    386    call assert_equal('[あ][⁈][a][😊][⁉][💕][💕][b][💕]', map(filter('あx⁈ax😊x⁉💕💕b💕x', '"x" != v:val'), '"[" .. v:val .. "]"'))
    387 
    388    #" patterns-composing(\Z)
    389    call assert_equal('ॠॠ', filter('ऊॠॡ,ऊॠॡ', LSTART i, x LMIDDLE x =~ '\Z' .. nr2char(0x0960) LEND))
    390    call assert_equal('àà', filter('càt,càt', LSTART i, x LMIDDLE x =~ '\Za' LEND))
    391    call assert_equal('ÅÅ', filter('Åström,Åström', LSTART i, x LMIDDLE x =~ '\Z' .. nr2char(0xc5) LEND))
    392    call assert_equal('öö', filter('Åström,Åström', LSTART i, x LMIDDLE x =~ '\Z' .. nr2char(0xf6) LEND))
    393    call assert_equal('ऊ@ॡ', map('ऊॠॡ', LSTART i, x LMIDDLE x =~ '\Z' .. nr2char(0x0960) ? '@' : x LEND))
    394    call assert_equal('c@t', map('càt', LSTART i, x LMIDDLE x =~ '\Za' ? '@' : x LEND))
    395    call assert_equal('@ström', map('Åström', LSTART i, x LMIDDLE x =~ '\Z' .. nr2char(0xc5) ? '@' : x LEND))
    396    call assert_equal('Åstr@m', map('Åström', LSTART i, x LMIDDLE x =~ '\Z' .. nr2char(0xf6) ? '@' : x LEND))
    397 
    398    #" patterns-composing(\%C)
    399    call assert_equal('ॠॠ', filter('ऊॠॡ,ऊॠॡ', LSTART i, x LMIDDLE x =~ nr2char(0x0960) .. '\%C' LEND))
    400    call assert_equal('àà', filter('càt,càt', LSTART i, x LMIDDLE x =~ 'a' .. '\%C' LEND))
    401    call assert_equal('ÅÅ', filter('Åström,Åström', LSTART i, x LMIDDLE x =~ nr2char(0xc5) .. '\%C' LEND))
    402    call assert_equal('öö', filter('Åström,Åström', LSTART i, x LMIDDLE x =~ nr2char(0xf6) .. '\%C' LEND))
    403    call assert_equal('ऊ@ॡ', map('ऊॠॡ', LSTART i, x LMIDDLE x =~ nr2char(0x0960) .. '\%C' ? '@' : x LEND))
    404    call assert_equal('c@t', map('càt', LSTART i, x LMIDDLE x =~ 'a' .. '\%C' ? '@' : x LEND))
    405    call assert_equal('@ström', map('Åström', LSTART i, x LMIDDLE x =~ nr2char(0xc5) .. '\%C' ? '@' : x LEND))
    406    call assert_equal('Åstr@m', map('Åström', LSTART i, x LMIDDLE x =~ nr2char(0xf6) .. '\%C' ? '@' : x LEND))
    407  END
    408  call CheckLegacyAndVim9Success(lines)
    409 endfunc
    410 
    411 " vim: shiftwidth=2 sts=2 expandtab