summaryrefslogtreecommitdiffstats
path: root/src/testdir
diff options
context:
space:
mode:
authorErnie Rael <errael@raelity.com>2024-01-13 11:47:33 +0100
committerChristian Brabandt <cb@256bit.org>2024-01-13 11:47:33 +0100
commite79e2077607e8f829ba823308c91104a795736ba (patch)
treee3e126ee9503e37e90e83868aa1c0ac42e359ccb /src/testdir
parentd8cb1ddab7b8cb19267a8877d62bbe3a06626fa2 (diff)
patch 9.1.0027: Vim is missing a foreach() funcv9.1.0027
Problem: Vim is missing a foreach() func Solution: Implement foreach({expr1}, {expr2}) function, which applies {expr2} for each item in {expr1} without changing it (Ernie Rael) closes: #12166 Signed-off-by: Ernie Rael <errael@raelity.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
Diffstat (limited to 'src/testdir')
-rw-r--r--src/testdir/test_filter_map.vim142
1 files changed, 141 insertions, 1 deletions
diff --git a/src/testdir/test_filter_map.vim b/src/testdir/test_filter_map.vim
index 6a07bec215..37ebe847b1 100644
--- a/src/testdir/test_filter_map.vim
+++ b/src/testdir/test_filter_map.vim
@@ -14,6 +14,18 @@ func Test_filter_map_list_expr_string()
call assert_equal([0, 2, 4, 6], map([1, 2, 3, 4], 'v:key * 2'))
call assert_equal([9, 9, 9, 9], map([1, 2, 3, 4], 9))
call assert_equal([7, 7, 7], map([1, 2, 3], ' 7 '))
+
+ " foreach()
+ let list01 = [1, 2, 3, 4]
+ let list02 = []
+ call assert_equal([1, 2, 3, 4], foreach(list01, 'call add(list02, v:val * 2)'))
+ call assert_equal([2, 4, 6, 8], list02)
+ let list02 = []
+ call assert_equal([1, 2, 3, 4], foreach(list01, 'call add(list02, v:key * 2)'))
+ call assert_equal([0, 2, 4, 6], list02)
+ let list02 = []
+ call assert_equal([1, 2, 3, 4], foreach(list01, 'call add(list02, 9)'))
+ call assert_equal([9, 9, 9, 9], list02)
endfunc
" dict with expression string
@@ -29,6 +41,14 @@ func Test_filter_map_dict_expr_string()
call assert_equal({"foo": 2, "bar": 4, "baz": 6}, map(copy(dict), 'v:val * 2'))
call assert_equal({"foo": "f", "bar": "b", "baz": "b"}, map(copy(dict), 'v:key[0]'))
call assert_equal({"foo": 9, "bar": 9, "baz": 9}, map(copy(dict), 9))
+
+ " foreach()
+ let dict01 = {}
+ call assert_equal(dict, foreach(copy(dict), 'let dict01[v:key] = v:val * 2'))
+ call assert_equal({"foo": 2, "bar": 4, "baz": 6}, dict01)
+ let dict01 = {}
+ call assert_equal(dict, foreach(copy(dict), 'let dict01[v:key] = v:key[0]'))
+ call assert_equal({"foo": "f", "bar": "b", "baz": "b"}, dict01)
endfunc
" list with funcref
@@ -54,6 +74,16 @@ func Test_filter_map_list_expr_funcref()
return a:index * 2
endfunc
call assert_equal([0, 2, 4, 6], map([1, 2, 3, 4], function('s:filter4')))
+
+ " foreach()
+ func! s:foreach1(index, val) abort
+ call add(g:test_variable, a:val + 1)
+ return [ 11, 12, 13, 14 ]
+ endfunc
+ let g:test_variable = []
+ call assert_equal([0, 1, 2, 3, 4], foreach(range(5), function('s:foreach1')))
+ call assert_equal([1, 2, 3, 4, 5], g:test_variable)
+ call remove(g:, 'test_variable')
endfunc
func Test_filter_map_nested()
@@ -90,11 +120,46 @@ func Test_filter_map_dict_expr_funcref()
return a:key[0]
endfunc
call assert_equal({"foo": "f", "bar": "b", "baz": "b"}, map(copy(dict), function('s:filter4')))
+
+ " foreach()
+ func! s:foreach1(key, val) abort
+ call extend(g:test_variable, {a:key: a:val * 2})
+ return [ 11, 12, 13, 14 ]
+ endfunc
+ let g:test_variable = {}
+ call assert_equal(dict, foreach(copy(dict), function('s:foreach1')))
+ call assert_equal({"foo": 2, "bar": 4, "baz": 6}, g:test_variable)
+ call remove(g:, 'test_variable')
+endfunc
+
+func Test_map_filter_locked()
+ let list01 = [1, 2, 3, 4]
+ lockvar 1 list01
+ call assert_fails('call filter(list01, "v:val > 1")', 'E741:')
+ call assert_equal([2, 4, 6, 8], map(list01, 'v:val * 2'))
+ call assert_equal([1, 2, 3, 4], map(list01, 'v:val / 2'))
+ call assert_equal([2, 4, 6, 8], mapnew(list01, 'v:val * 2'))
+ let g:test_variable = []
+ call assert_equal([1, 2, 3, 4], foreach(list01, 'call add(g:test_variable, v:val * 2)'))
+ call remove(g:, 'test_variable')
+ call assert_fails('call filter(list01, "v:val > 1")', 'E741:')
+ unlockvar 1 list01
+ lockvar! list01
+ call assert_fails('call filter(list01, "v:val > 1")', 'E741:')
+ call assert_fails('call map(list01, "v:val * 2")', 'E741:')
+ call assert_equal([2, 4, 6, 8], mapnew(list01, 'v:val * 2'))
+ let g:test_variable = []
+ call assert_equal([1, 2, 3, 4], foreach(list01, 'call add(g:test_variable, v:val * 2)'))
+ call assert_fails('call foreach(list01, "let list01[0] = -1")', 'E741:')
+ call assert_fails('call filter(list01, "v:val > 1")', 'E741:')
+ call remove(g:, 'test_variable')
+ unlockvar! list01
endfunc
func Test_map_filter_fails()
call assert_fails('call map([1], "42 +")', 'E15:')
call assert_fails('call filter([1], "42 +")', 'E15:')
+ call assert_fails('call foreach([1], "let a = }")', 'E15:')
call assert_fails("let l = filter([1, 2, 3], '{}')", 'E728:')
call assert_fails("let l = filter({'k' : 10}, '{}')", 'E728:')
call assert_fails("let l = filter([1, 2], {})", 'E731:')
@@ -106,6 +171,8 @@ func Test_map_filter_fails()
call assert_fails("let l = filter([1, 2], function('min'))", 'E118:')
call assert_equal([1, 2, 3], filter([1, 2, 3], test_null_partial()))
call assert_fails("let l = filter([1, 2], {a, b, c -> 1})", 'E119:')
+ call assert_fails('call foreach([1], "xyzzy")', 'E492:')
+ call assert_fails('call foreach([1], "let a = foo")', 'E121:')
endfunc
func Test_map_and_modify()
@@ -123,7 +190,7 @@ endfunc
func Test_filter_and_modify()
let l = [0]
- " cannot change the list halfway a map()
+ " cannot change the list halfway thru filter()
call assert_fails('call filter(l, "remove(l, 0)")', 'E741:')
let d = #{a: 0, b: 0, c: 0}
@@ -133,6 +200,18 @@ func Test_filter_and_modify()
call assert_fails('call filter(b, "remove(b, 0)")', 'E741:')
endfunc
+func Test_foreach_and_modify()
+ let l = [0]
+ " cannot change the list halfway thru foreach()
+ call assert_fails('call foreach(l, "let a = remove(l, 0)")', 'E741:')
+
+ let d = #{a: 0, b: 0, c: 0}
+ call assert_fails('call foreach(d, "let a = remove(d, v:key)")', 'E741:')
+
+ let b = 0z1234
+ call assert_fails('call foreach(b, "let a = remove(b, 0)")', 'E741:')
+endfunc
+
func Test_mapnew_dict()
let din = #{one: 1, two: 2}
let dout = mapnew(din, {k, v -> string(v)})
@@ -160,6 +239,36 @@ func Test_mapnew_blob()
call assert_equal(0z129956, bout)
endfunc
+func Test_foreach_blob()
+ let lines =<< trim END
+ LET g:test_variable = []
+ call assert_equal(0z0001020304, foreach(0z0001020304, 'call add(g:test_variable, v:val)'))
+ call assert_equal([0, 1, 2, 3, 4], g:test_variable)
+ END
+ call v9.CheckLegacyAndVim9Success(lines)
+
+ func! s:foreach1(index, val) abort
+ call add(g:test_variable, a:val)
+ return [ 11, 12, 13, 14 ]
+ endfunc
+ let g:test_variable = []
+ call assert_equal(0z0001020304, foreach(0z0001020304, function('s:foreach1')))
+ call assert_equal([0, 1, 2, 3, 4], g:test_variable)
+
+ let lines =<< trim END
+ def Foreach1(_, val: any): list<number>
+ add(g:test_variable, val)
+ return [ 11, 12, 13, 14 ]
+ enddef
+ g:test_variable = []
+ assert_equal(0z0001020304, foreach(0z0001020304, Foreach1))
+ assert_equal([0, 1, 2, 3, 4], g:test_variable)
+ END
+ call v9.CheckDefSuccess(lines)
+
+ call remove(g:, 'test_variable')
+endfunc
+
" Test for using map(), filter() and mapnew() with a string
func Test_filter_map_string()
" filter()
@@ -219,6 +328,37 @@ func Test_filter_map_string()
END
call v9.CheckLegacyAndVim9Success(lines)
+ " foreach()
+ let lines =<< trim END
+ VAR s = "abc"
+ LET g:test_variable = []
+ call assert_equal(s, foreach(s, 'call add(g:test_variable, v:val)'))
+ call assert_equal(['a', 'b', 'c'], g:test_variable)
+ LET g:test_variable = []
+ LET s = 'あiうえお'
+ call assert_equal(s, foreach(s, 'call add(g:test_variable, v:val)'))
+ call assert_equal(['あ', 'i', 'う', 'え', 'お'], g:test_variable)
+ END
+ call v9.CheckLegacyAndVim9Success(lines)
+ func! s:foreach1(index, val) abort
+ call add(g:test_variable, a:val)
+ return [ 11, 12, 13, 14 ]
+ endfunc
+ let g:test_variable = []
+ call assert_equal('abcd', foreach('abcd', function('s:foreach1')))
+ call assert_equal(['a', 'b', 'c', 'd'], g:test_variable)
+ let lines =<< trim END
+ def Foreach1(_, val: string): list<number>
+ add(g:test_variable, val)
+ return [ 11, 12, 13, 14 ]
+ enddef
+ g:test_variable = []
+ assert_equal('abcd', foreach('abcd', Foreach1))
+ assert_equal(['a', 'b', 'c', 'd'], g:test_variable)
+ END
+ call v9.CheckDefSuccess(lines)
+ call remove(g:, 'test_variable')
+
let lines =<< trim END
#" map() and filter()
call assert_equal('[あ][⁈][a][😊][⁉][💕][💕][b][💕]', map(filter('あx⁈ax😊x⁉💕💕b💕x', '"x" != v:val'), '"[" .. v:val .. "]"'))