view src/testdir/test_blob.vim @ 34336:d2ad8733db75 v9.1.0101

patch 9.1.0101: upper-case of German sharp s should be U+1E9E Commit: https://github.com/vim/vim/commit/bd1232a1faf56b614a1e74c4ce51bc6e0650ae00 Author: glepnir <glephunter@gmail.com> Date: Mon Feb 12 22:14:53 2024 +0100 patch 9.1.0101: upper-case of German sharp s should be U+1E9E Problem: upper-case of ? should be U+1E9E (CAPITAL LETTER SHARP S) (fenuks) Solution: Make gU, ~ and g~ convert the U+00DF LATIN SMALL LETTER SHARP S (?) to U+1E9E LATIN CAPITAL LETTER SHARP S (?), update tests (glepnir) This is part of Unicode 5.1.0 from April 2008, so should be fairly safe to use now and since 2017 is part of the German standard orthography, according to Wikipedia: https://en.wikipedia.org/wiki/Capital_%E1%BA%9E#cite_note-auto-12 There is however one exception: UnicodeData.txt for U+00DF LATIN SMALL LETTER SHARP S does NOT define U+1E9E LATIN CAPITAL LETTER SHARP S as its upper case version. Therefore, toupper() won't be able to convert from lower sharp s to upper case sharp s (the other way around however works, since U+00DF is considered the lower case character of U+1E9E and therefore tolower() works correctly for the upper case version). fixes: #5573 closes: #14018 Signed-off-by: glepnir <glephunter@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
author Christian Brabandt <cb@256bit.org>
date Mon, 12 Feb 2024 22:45:02 +0100
parents dbec60b8c253
children f2b94f240b7d
line wrap: on
line source

" Tests for the Blob types

import './vim9.vim' as v9

func TearDown()
  " Run garbage collection after every test
  call test_garbagecollect_now()
endfunc

" Tests for Blob type

" Blob creation from constant
func Test_blob_create()
  let lines =<< trim END
      VAR b = 0zDEADBEEF
      call assert_equal(v:t_blob, type(b))
      call assert_equal(4, len(b))
      call assert_equal(0xDE, b[0])
      call assert_equal(0xAD, b[1])
      call assert_equal(0xBE, b[2])
      call assert_equal(0xEF, b[3])
      call assert_fails('VAR x = b[4]')

      call assert_equal(0xDE, get(b, 0))
      call assert_equal(0xEF, get(b, 3))

      call assert_fails('VAR b = 0z1', 'E973:')
      call assert_fails('VAR b = 0z1x', 'E973:')
      call assert_fails('VAR b = 0z12345', 'E973:')

      call assert_equal(0z, test_null_blob())

      LET b = 0z001122.33445566.778899.aabbcc.dd
      call assert_equal(0z00112233445566778899aabbccdd, b)
      call assert_fails('VAR b = 0z1.1')
      call assert_fails('VAR b = 0z.')
      call assert_fails('VAR b = 0z001122.')
      call assert_fails('call get("", 1)', 'E896:')
      call assert_equal(0, len(test_null_blob()))
      call assert_equal(0z, copy(test_null_blob()))
  END
  call v9.CheckLegacyAndVim9Success(lines)
endfunc

" assignment to a blob
func Test_blob_assign()
  let lines =<< trim END
      VAR b = 0zDEADBEEF
      VAR b2 = b[1 : 2]
      call assert_equal(0zADBE, b2)

      VAR bcopy = b[:]
      call assert_equal(b, bcopy)
      call assert_false(b is bcopy)

      LET b = 0zDEADBEEF
      LET b2 = b
      call assert_true(b is b2)
      LET b[:] = 0z11223344
      call assert_equal(0z11223344, b)
      call assert_equal(0z11223344, b2)
      call assert_true(b is b2)

      LET b = 0zDEADBEEF
      LET b[3 :] = 0z66
      call assert_equal(0zDEADBE66, b)
      LET b[: 1] = 0z8899
      call assert_equal(0z8899BE66, b)

      LET b = 0zDEADBEEF
      LET b += 0z99
      call assert_equal(0zDEADBEEF99, b)

      VAR l = [0z12]
      VAR m = deepcopy(l)
      LET m[0] = 0z34	#" E742 or E741 should not occur.
  END
  call v9.CheckLegacyAndVim9Success(lines)

  let lines =<< trim END
      VAR b = 0zDEADBEEF
      LET b[2 : 3] = 0z112233
  END
  call v9.CheckLegacyAndVim9Failure(lines, 'E972:')

  let lines =<< trim END
      VAR b = 0zDEADBEEF
      LET b[2 : 3] = 0z11
  END
  call v9.CheckLegacyAndVim9Failure(lines, 'E972:')

  let lines =<< trim END
      VAR b = 0zDEADBEEF
      LET b[3 : 2] = 0z
  END
  call v9.CheckLegacyAndVim9Failure(lines, 'E979:')

  let lines =<< trim END
      VAR b = 0zDEADBEEF
      LET b ..= 0z33
  END
  call v9.CheckLegacyAndVim9Failure(lines, ['E734:', 'E1019:', 'E734:'])

  let lines =<< trim END
      VAR b = 0zDEADBEEF
      LET b ..= "xx"
  END
  call v9.CheckLegacyAndVim9Failure(lines, ['E734:', 'E1019:', 'E734:'])

  let lines =<< trim END
      VAR b = 0zDEADBEEF
      LET b += "xx"
  END
  call v9.CheckLegacyAndVim9Failure(lines, ['E734:', 'E1012:', 'E734:'])

  let lines =<< trim END
      VAR b = 0zDEADBEEF
      LET b[1 : 1] ..= 0z55
  END
  call v9.CheckLegacyAndVim9Failure(lines, ['E734:', 'E1183:', 'E734:'])

  call assert_fails('let b = readblob("a1b2c3")', 'E484:')
endfunc

func Test_blob_get_range()
  let lines =<< trim END
      VAR b = 0z0011223344
      call assert_equal(0z2233, b[2 : 3])
      call assert_equal(0z223344, b[2 : -1])
      call assert_equal(0z00, b[0 : -5])
      call assert_equal(0z, b[0 : -11])
      call assert_equal(0z44, b[-1 :])
      call assert_equal(0z0011223344, b[:])
      call assert_equal(0z0011223344, b[: -1])
      call assert_equal(0z, b[5 : 6])
      call assert_equal(0z0011, b[-10 : 1])
  END
  call v9.CheckLegacyAndVim9Success(lines)

  " legacy script white space
  let b = 0z0011223344
  call assert_equal(0z2233, b[2:3])
endfunc

func Test_blob_get()
  let lines =<< trim END
      VAR b = 0z0011223344
      call assert_equal(0x00, get(b, 0))
      call assert_equal(0x22, get(b, 2, 999))
      call assert_equal(0x44, get(b, 4))
      call assert_equal(0x44, get(b, -1))
      call assert_equal(-1, get(b, 5))
      call assert_equal(999, get(b, 5, 999))
      call assert_equal(-1, get(b, -8))
      call assert_equal(999, get(b, -8, 999))
      call assert_equal(10, get(test_null_blob(), 2, 10))

      call assert_equal(0x00, b[0])
      call assert_equal(0x22, b[2])
      call assert_equal(0x44, b[4])
      call assert_equal(0x44, b[-1])
  END
  call v9.CheckLegacyAndVim9Success(lines)

  let lines =<< trim END
      VAR b = 0z0011223344
      echo b[5]
  END
  call v9.CheckLegacyAndVim9Failure(lines, 'E979:')

  let lines =<< trim END
      VAR b = 0z0011223344
      echo b[-8]
  END
  call v9.CheckLegacyAndVim9Failure(lines, 'E979:')
endfunc

func Test_blob_to_string()
  let lines =<< trim END
      VAR b = 0z00112233445566778899aabbccdd
      call assert_equal('0z00112233.44556677.8899AABB.CCDD', string(b))
      call assert_equal(b, eval(string(b)))
      call remove(b, 4, -1)
      call assert_equal('0z00112233', string(b))
      call remove(b, 0, 3)
      call assert_equal('0z', string(b))
      call assert_equal('0z', string(test_null_blob()))
  END
  call v9.CheckLegacyAndVim9Success(lines)
endfunc

func Test_blob_compare()
  let lines =<< trim END
      VAR b1 = 0z0011
      VAR b2 = 0z1100
      VAR b3 = 0z001122
      call assert_true(b1 == b1)
      call assert_false(b1 == b2)
      call assert_false(b1 == b3)
      call assert_true(b1 != b2)
      call assert_true(b1 != b3)
      call assert_true(b1 == 0z0011)

      call assert_false(b1 is b2)
      LET b2 = b1
      call assert_true(b1 == b2)
      call assert_true(b1 is b2)
      LET b2 = copy(b1)
      call assert_true(b1 == b2)
      call assert_false(b1 is b2)
      LET b2 = b1[:]
      call assert_true(b1 == b2)
      call assert_false(b1 is b2)
      call assert_true(b1 isnot b2)
      call assert_true(0z != 0z10)
      call assert_true(0z10 != 0z)
  END
  call v9.CheckLegacyAndVim9Success(lines)

  let lines =<< trim END
      VAR b1 = 0z0011
      echo b1 == 9
  END
  call v9.CheckLegacyAndVim9Failure(lines, ['E977:', 'E1072', 'E1072'])

  let lines =<< trim END
      VAR b1 = 0z0011
      echo b1 != 9
  END
  call v9.CheckLegacyAndVim9Failure(lines, ['E977:', 'E1072', 'E1072'])

  let lines =<< trim END
      VAR b1 = 0z0011
      VAR b2 = 0z1100
      VAR x = b1 > b2
  END
  call v9.CheckLegacyAndVim9Failure(lines, ['E978:', 'E1072:', 'E1072:'])

  let lines =<< trim END
      VAR b1 = 0z0011
      VAR b2 = 0z1100
      VAR x = b1 < b2
  END
  call v9.CheckLegacyAndVim9Failure(lines, ['E978:', 'E1072:', 'E1072:'])

  let lines =<< trim END
      VAR b1 = 0z0011
      VAR b2 = 0z1100
      VAR x = b1 - b2
  END
  call v9.CheckLegacyAndVim9Failure(lines, ['E974:', 'E1036:', 'E974:'])

  let lines =<< trim END
      VAR b1 = 0z0011
      VAR b2 = 0z1100
      VAR x = b1 / b2
  END
  call v9.CheckLegacyAndVim9Failure(lines, ['E974:', 'E1036:', 'E974:'])

  let lines =<< trim END
      VAR b1 = 0z0011
      VAR b2 = 0z1100
      VAR x = b1 * b2
  END
  call v9.CheckLegacyAndVim9Failure(lines, ['E974:', 'E1036:', 'E974:'])
endfunc

func Test_blob_index_assign()
  let lines =<< trim END
      VAR b = 0z00
      LET b[1] = 0x11
      LET b[2] = 0x22
      LET b[0] = 0x33
      call assert_equal(0z331122, b)
  END
  call v9.CheckLegacyAndVim9Success(lines)

  let lines =<< trim END
      VAR b = 0z00
      LET b[2] = 0x33
  END
  call v9.CheckLegacyAndVim9Failure(lines, 'E979:')

  let lines =<< trim END
      VAR b = 0z00
      LET b[-2] = 0x33
  END
  call v9.CheckLegacyAndVim9Failure(lines, 'E979:')

  let lines =<< trim END
      VAR b = 0z00010203
      LET b[0 : -1] = 0z33
  END
  call v9.CheckLegacyAndVim9Failure(lines, 'E979:')

  let lines =<< trim END
      VAR b = 0z00010203
      LET b[3 : 4] = 0z3344
  END
  call v9.CheckLegacyAndVim9Failure(lines, 'E979:')
endfunc

func Test_blob_for_loop()
  let lines =<< trim END
      VAR blob = 0z00010203
      VAR i = 0
      for byte in blob
        call assert_equal(i, byte)
        LET i += 1
      endfor
      call assert_equal(4, i)

      LET blob = 0z00
      call remove(blob, 0)
      call assert_equal(0, len(blob))
      for byte in blob
        call assert_report('loop over empty blob')
      endfor

      LET blob = 0z0001020304
      LET i = 0
      for byte in blob
        call assert_equal(i, byte)
        if i == 1
          call remove(blob, 0)
        elseif i == 3
          call remove(blob, 3)
        endif
        LET i += 1
      endfor
      call assert_equal(5, i)
  END
  call v9.CheckLegacyAndVim9Success(lines)
endfunc

func Test_blob_concatenate()
  let lines =<< trim END
      VAR b = 0z0011
      LET b += 0z2233
      call assert_equal(0z00112233, b)

      LET b = 0zDEAD + 0zBEEF
      call assert_equal(0zDEADBEEF, b)
  END
  call v9.CheckLegacyAndVim9Success(lines)

  let lines =<< trim END
      VAR b = 0z0011
      LET b += "a"
  END
  call v9.CheckLegacyAndVim9Failure(lines, ['E734:', 'E1012:', 'E734:'])

  let lines =<< trim END
      VAR b = 0z0011
      LET b += 88
  END
  call v9.CheckLegacyAndVim9Failure(lines, ['E734:', 'E1012:', 'E734:'])
endfunc

func Test_blob_add()
  let lines =<< trim END
      VAR b = 0z0011
      call add(b, 0x22)
      call assert_equal(0z001122, b)
  END
  call v9.CheckLegacyAndVim9Success(lines)

  " Only works in legacy script
  let b = 0z0011
  call add(b, '51')
  call assert_equal(0z001133, b)
  call assert_equal(1, add(test_null_blob(), 0x22))

  let lines =<< trim END
      VAR b = 0z0011
      call add(b, [9])
  END
  call v9.CheckLegacyAndVim9Failure(lines, ['E745:', 'E1012:', 'E1210:'])

  let lines =<< trim END
      VAR b = 0z0011
      call add("", 0x01)
  END
  call v9.CheckLegacyAndVim9Failure(lines, ['E897:', 'E1013:', 'E1226:'])

  let lines =<< trim END
      add(test_null_blob(), 0x22)
  END
  call v9.CheckDefExecAndScriptFailure(lines, 'E1131:')

  let lines =<< trim END
      let b = 0zDEADBEEF
      lockvar b
      call add(b, 0)
      unlockvar b
  END
  call v9.CheckScriptFailure(lines, 'E741:')
endfunc

func Test_blob_empty()
  call assert_false(empty(0z001122))
  call assert_true(empty(0z))
  call assert_true(empty(test_null_blob()))
endfunc

" Test removing items in blob
func Test_blob_func_remove()
  let lines =<< trim END
      #" Test removing 1 element
      VAR b = 0zDEADBEEF
      call assert_equal(0xDE, remove(b, 0))
      call assert_equal(0zADBEEF, b)

      LET b = 0zDEADBEEF
      call assert_equal(0xEF, remove(b, -1))
      call assert_equal(0zDEADBE, b)

      LET b = 0zDEADBEEF
      call assert_equal(0xAD, remove(b, 1))
      call assert_equal(0zDEBEEF, b)

      #" Test removing range of element(s)
      LET b = 0zDEADBEEF
      call assert_equal(0zBE, remove(b, 2, 2))
      call assert_equal(0zDEADEF, b)

      LET b = 0zDEADBEEF
      call assert_equal(0zADBE, remove(b, 1, 2))
      call assert_equal(0zDEEF, b)
  END
  call v9.CheckLegacyAndVim9Success(lines)

  " Test invalid cases
  let lines =<< trim END
      VAR b = 0zDEADBEEF
      call remove(b, 5)
  END
  call v9.CheckLegacyAndVim9Failure(lines, 'E979:')

  let lines =<< trim END
      VAR b = 0zDEADBEEF
      call remove(b, 1, 5)
  END
  call v9.CheckLegacyAndVim9Failure(lines, 'E979:')

  let lines =<< trim END
      VAR b = 0zDEADBEEF
      call remove(b, -10)
  END
  call v9.CheckLegacyAndVim9Failure(lines, 'E979:')

  let lines =<< trim END
      VAR b = 0zDEADBEEF
      call remove(b, 3, 2)
  END
  call v9.CheckLegacyAndVim9Failure(lines, 'E979:')

  let lines =<< trim END
      VAR b = 0zDEADBEEF
      call remove(test_null_blob(), 1, 2)
  END
  call v9.CheckLegacyAndVim9Failure(lines, 'E979:')

  let lines =<< trim END
      let b = 0zDEADBEEF
      lockvar b
      call remove(b, 0)
      unlockvar b
  END
  call v9.CheckScriptFailure(lines, 'E741:')

  " can only check at script level, not in a :def function
  let lines =<< trim END
      vim9script
      var b = 0zDEADBEEF
      lockvar b
      remove(b, 0)
  END
  call v9.CheckScriptFailure(lines, 'E741:')

  call assert_fails('echo remove(0z1020, [])', 'E745:')
  call assert_fails('echo remove(0z1020, 0, [])', 'E745:')
endfunc

func Test_blob_read_write()
  let lines =<< trim END
      VAR b = 0zDEADBEEF
      call writefile(b, 'Xblob')
      VAR br = readfile('Xblob', 'B')
      call assert_equal(b, br)
      VAR br2 = readblob('Xblob')
      call assert_equal(b, br2)
      VAR br3 = readblob('Xblob', 1)
      call assert_equal(b[1 :], br3)
      VAR br4 = readblob('Xblob', 1, 2)
      call assert_equal(b[1 : 2], br4)
      VAR br5 = readblob('Xblob', -3)
      call assert_equal(b[-3 :], br5)
      VAR br6 = readblob('Xblob', -3, 2)
      call assert_equal(b[-3 : -2], br6)

      #" reading past end of file, empty result
      VAR br1e = readblob('Xblob', 10000)
      call assert_equal(0z, br1e)

      #" reading too much, result is truncated
      VAR blong = readblob('Xblob', -1000)
      call assert_equal(b, blong)
      LET blong = readblob('Xblob', -10, 8)
      call assert_equal(b, blong)
      LET blong = readblob('Xblob', 0, 10)
      call assert_equal(b, blong)

      call delete('Xblob')
  END
  call v9.CheckLegacyAndVim9Success(lines)

  if filereadable('/dev/random')
    let b = readblob('/dev/random', 0, 10)
    call assert_equal(10, len(b))
  endif

  call assert_fails("call readblob('notexist')", 'E484:')
  " TODO: How do we test for the E485 error?

  " This was crashing when calling readfile() with a directory.
  call assert_fails("call readfile('.', 'B')", 'E17: "." is a directory')
endfunc

" filter() item in blob
func Test_blob_filter()
  let lines =<< trim END
      call assert_equal(test_null_blob(), filter(test_null_blob(), '0'))
      call assert_equal(0z, filter(0zDEADBEEF, '0'))
      call assert_equal(0zADBEEF, filter(0zDEADBEEF, 'v:val != 0xDE'))
      call assert_equal(0zDEADEF, filter(0zDEADBEEF, 'v:val != 0xBE'))
      call assert_equal(0zDEADBE, filter(0zDEADBEEF, 'v:val != 0xEF'))
      call assert_equal(0zDEADBEEF, filter(0zDEADBEEF, '1'))
      call assert_equal(0z01030103, filter(0z010203010203, 'v:val != 0x02'))
      call assert_equal(0zADEF, filter(0zDEADBEEF, 'v:key % 2'))
  END
  call v9.CheckLegacyAndVim9Success(lines)
  call assert_fails('echo filter(0z10, "a10")', 'E121:')
endfunc

" map() item in blob
func Test_blob_map()
  let lines =<< trim END
      call assert_equal(0zDFAEBFF0, map(0zDEADBEEF, 'v:val + 1'))
      call assert_equal(0z00010203, map(0zDEADBEEF, 'v:key'))
      call assert_equal(0zDEAEC0F2, map(0zDEADBEEF, 'v:key + v:val'))
  END
  call v9.CheckLegacyAndVim9Success(lines)

  let lines =<< trim END
      call map(0z00, '[9]')
  END
  call v9.CheckLegacyAndVim9Failure(lines, 'E978:')
  call assert_fails('echo map(0z10, "a10")', 'E121:')
endfunc

func Test_blob_index()
  let lines =<< trim END
      call assert_equal(2, index(0zDEADBEEF, 0xBE))
      call assert_equal(-1, index(0zDEADBEEF, 0))
      call assert_equal(2, index(0z11111111, 0x11, 2))
      call assert_equal(3, 0z11110111->index(0x11, 2))
      call assert_equal(2, index(0z11111111, 0x11, -2))
      call assert_equal(3, index(0z11110111, 0x11, -2))
      call assert_equal(0, index(0z11110111, 0x11, -10))
      call assert_equal(-1, index(test_null_blob(), 1))
  END
  call v9.CheckLegacyAndVim9Success(lines)
endfunc

func Test_blob_insert()
  let lines =<< trim END
      VAR b = 0zDEADBEEF
      call insert(b, 0x33)
      call assert_equal(0z33DEADBEEF, b)

      LET b = 0zDEADBEEF
      call insert(b, 0x33, 2)
      call assert_equal(0zDEAD33BEEF, b)
  END
  call v9.CheckLegacyAndVim9Success(lines)

  " only works in legacy script
  call assert_equal(0, insert(test_null_blob(), 0x33))

  let lines =<< trim END
      VAR b = 0zDEADBEEF
      call insert(b, -1)
  END
  call v9.CheckLegacyAndVim9Failure(lines, 'E475:')

  let lines =<< trim END
      VAR b = 0zDEADBEEF
      call insert(b, 257)
  END
  call v9.CheckLegacyAndVim9Failure(lines, 'E475:')

  let lines =<< trim END
      VAR b = 0zDEADBEEF
      call insert(b, 0, [9])
  END
  call v9.CheckLegacyAndVim9Failure(lines, ['E745:', 'E1013:', 'E1210:'])

  let lines =<< trim END
      VAR b = 0zDEADBEEF
      call insert(b, 0, -20)
  END
  call v9.CheckLegacyAndVim9Failure(lines, 'E475:')

  let lines =<< trim END
      VAR b = 0zDEADBEEF
      call insert(b, 0, 20)
  END
  call v9.CheckLegacyAndVim9Failure(lines, 'E475:')

  let lines =<< trim END
      VAR b = 0zDEADBEEF
      call insert(b, [])
  END
  call v9.CheckLegacyAndVim9Failure(lines, ['E745:', 'E1013:', 'E1210:'])

  let lines =<< trim END
      insert(test_null_blob(), 0x33)
  END
  call v9.CheckDefExecAndScriptFailure(lines, 'E1131:')

  let lines =<< trim END
      let b = 0zDEADBEEF
      lockvar b
      call insert(b, 3)
      unlockvar b
  END
  call v9.CheckScriptFailure(lines, 'E741:')

  let lines =<< trim END
      vim9script
      var b = 0zDEADBEEF
      lockvar b
      insert(b, 3)
  END
  call v9.CheckScriptFailure(lines, 'E741:')
endfunc

func Test_blob_reverse()
  let lines =<< trim END
      call assert_equal(0zEFBEADDE, reverse(0zDEADBEEF))
      call assert_equal(0zBEADDE, reverse(0zDEADBE))
      call assert_equal(0zADDE, reverse(0zDEAD))
      call assert_equal(0zDE, reverse(0zDE))
      call assert_equal(0z, reverse(test_null_blob()))
  END
  call v9.CheckLegacyAndVim9Success(lines)
endfunc

func Test_blob_json_encode()
  let lines =<< trim END
      call assert_equal('[222,173,190,239]', json_encode(0zDEADBEEF))
      call assert_equal('[]', json_encode(0z))
  END
  call v9.CheckLegacyAndVim9Success(lines)
endfunc

func Test_blob_lock()
  let lines =<< trim END
      let b = 0z112233
      lockvar b
      unlockvar b
      let b = 0z44
  END
  call v9.CheckScriptSuccess(lines)

  let lines =<< trim END
      vim9script
      var b = 0z112233
      lockvar b
      unlockvar b
      b = 0z44
  END
  call v9.CheckScriptSuccess(lines)

  let lines =<< trim END
      let b = 0z112233
      lockvar b
      let b = 0z44
  END
  call v9.CheckScriptFailure(lines, 'E741:')

  let lines =<< trim END
      vim9script
      var b = 0z112233
      lockvar b
      b = 0z44
  END
  call v9.CheckScriptFailure(lines, 'E741:')
endfunc

func Test_blob_sort()
  call v9.CheckLegacyAndVim9Failure(['call sort([1.0, 0z11], "f")'], 'E975:')
  call v9.CheckLegacyAndVim9Failure(['call sort([11, 0z11], "N")'], 'E974:')
endfunc

" Tests for the blob2list() function
func Test_blob2list()
  call assert_fails('let v = blob2list(10)', 'E1238: Blob required for argument 1')
  eval 0zFFFF->blob2list()->assert_equal([255, 255])
  let tests = [[0z0102, [1, 2]],
        \ [0z00, [0]],
        \ [0z, []],
        \ [0z00000000, [0, 0, 0, 0]],
        \ [0zAABB.CCDD, [170, 187, 204, 221]]]
  for t in tests
    call assert_equal(t[0]->blob2list(), t[1])
  endfor
  exe 'let v = 0z' .. repeat('000102030405060708090A0B0C0D0E0F', 64)
  call assert_equal(1024, blob2list(v)->len())
  call assert_equal([4, 8, 15], [v[100], v[1000], v[1023]])
  call assert_equal([], blob2list(test_null_blob()))
endfunc

" Tests for the list2blob() function
func Test_list2blob()
  call assert_fails('let b = list2blob(0z10)', 'E1211: List required for argument 1')
  let tests = [[[1, 2], 0z0102],
        \ [[0], 0z00],
        \ [[], 0z],
        \ [[0, 0, 0, 0], 0z00000000],
        \ [[255, 255], 0zFFFF],
        \ [[170, 187, 204, 221], 0zAABB.CCDD],
        \ ]
  for t in tests
    call assert_equal(t[1], t[0]->list2blob())
  endfor
  call assert_fails('let b = list2blob([1, []])', 'E745:')
  call assert_fails('let b = list2blob([-1])', 'E1239:')
  call assert_fails('let b = list2blob([256])', 'E1239:')
  let b = range(16)->repeat(64)->list2blob()
  call assert_equal(1024, b->len())
  call assert_equal([4, 8, 15], [b[100], b[1000], b[1023]])

  call assert_equal(0z, list2blob(test_null_list()))
  call assert_equal(0z00010203, list2blob(range(4)))
endfunc

" The following used to cause an out-of-bounds memory access
func Test_blob2string()
  let v = '0z' .. repeat('01010101.', 444)
  let v ..= '01'
  exe 'let b = ' .. v
  call assert_equal(v, string(b))
endfunc

func Test_blob_repeat()
  call assert_equal(0z, repeat(0z00, 0))
  call assert_equal(0z00, repeat(0z00, 1))
  call assert_equal(0z0000, repeat(0z00, 2))
  call assert_equal(0z00000000, repeat(0z0000, 2))

  call assert_equal(0z, repeat(0z12, 0))
  call assert_equal(0z, repeat(0z1234, 0))
  call assert_equal(0z1234, repeat(0z1234, 1))
  call assert_equal(0z12341234, repeat(0z1234, 2))
endfunc

" Test for blob allocation failure
func Test_blob_alloc_failure()
  " blob variable
  call test_alloc_fail(GetAllocId('blob_alloc'), 0, 0)
  call assert_fails('let v = 0z10', 'E342:')

  " blob slice
  let v = 0z1020
  call test_alloc_fail(GetAllocId('blob_alloc'), 0, 0)
  call assert_fails('let x = v[0:0]', 'E342:')
  call assert_equal(0z1020, x)

  " blob remove()
  let v = 0z10203040
  call test_alloc_fail(GetAllocId('blob_alloc'), 0, 0)
  call assert_fails('let x = remove(v, 1, 2)', 'E342:')
  call assert_equal(0, x)

  " list2blob()
  call test_alloc_fail(GetAllocId('blob_alloc'), 0, 0)
  call assert_fails('let a = list2blob([1, 2, 4])', 'E342:')
  call assert_equal(0, a)

  " mapnew()
  call test_alloc_fail(GetAllocId('blob_alloc'), 0, 0)
  call assert_fails('let x = mapnew(0z1234, {_, v -> 1})', 'E342:')
  call assert_equal(0, x)

  " copy()
  call test_alloc_fail(GetAllocId('blob_alloc'), 0, 0)
  call assert_fails('let x = copy(v)', 'E342:')
  call assert_equal(0z, x)

  " readblob()
  call test_alloc_fail(GetAllocId('blob_alloc'), 0, 0)
  call assert_fails('let x = readblob("test_blob.vim")', 'E342:')
  call assert_equal(0, x)
endfunc

" Test for the indexof() function
func Test_indexof()
  let b = 0zdeadbeef
  call assert_equal(0, indexof(b, {i, v -> v == 0xde}))
  call assert_equal(3, indexof(b, {i, v -> v == 0xef}))
  call assert_equal(-1, indexof(b, {i, v -> v == 0x1}))
  call assert_equal(1, indexof(b, "v:val == 0xad"))
  call assert_equal(-1, indexof(b, "v:val == 0xff"))
  call assert_equal(-1, indexof(b, {_, v -> "v == 0xad"}))

  call assert_equal(-1, indexof(0z, "v:val == 0x0"))
  call assert_equal(-1, indexof(test_null_blob(), "v:val == 0xde"))
  call assert_equal(-1, indexof(b, test_null_string()))
  call assert_equal(-1, indexof(b, test_null_function()))

  let b = 0z01020102
  call assert_equal(1, indexof(b, "v:val == 0x02", #{startidx: 0}))
  call assert_equal(2, indexof(b, "v:val == 0x01", #{startidx: -2}))
  call assert_equal(-1, indexof(b, "v:val == 0x01", #{startidx: 5}))
  call assert_equal(0, indexof(b, "v:val == 0x01", #{startidx: -5}))
  call assert_equal(0, indexof(b, "v:val == 0x01", test_null_dict()))

  " failure cases
  call assert_fails('let i = indexof(b, "val == 0xde")', 'E121:')
  call assert_fails('let i = indexof(b, {})', 'E1256:')
endfunc

" vim: shiftwidth=2 sts=2 expandtab