neovim

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

vim_str2nr_spec.lua (24432B)


      1 local t = require('test.unit.testutil')
      2 local bit = require('bit')
      3 
      4 local itp = t.gen_itp(it)
      5 
      6 local child_call_once = t.child_call_once
      7 local cimport = t.cimport
      8 local ffi = t.ffi
      9 
     10 local lib = cimport('./src/nvim/charset.h')
     11 
     12 local ARGTYPES
     13 
     14 child_call_once(function()
     15  ARGTYPES = {
     16    num = ffi.typeof('varnumber_T[1]'),
     17    unum = ffi.typeof('uvarnumber_T[1]'),
     18    pre = ffi.typeof('int[1]'),
     19    len = ffi.typeof('int[1]'),
     20  }
     21 end)
     22 
     23 local icnt = -42
     24 local ucnt = 4242
     25 
     26 local function arginit(arg)
     27  if arg == 'unum' then
     28    ucnt = ucnt + 1
     29    return ARGTYPES[arg]({ ucnt })
     30  else
     31    icnt = icnt - 1
     32    return ARGTYPES[arg]({ icnt })
     33  end
     34 end
     35 
     36 local function argreset(arg, args)
     37  if arg == 'unum' then
     38    ucnt = ucnt + 1
     39    args[arg][0] = ucnt
     40  else
     41    icnt = icnt - 1
     42    args[arg][0] = icnt
     43  end
     44 end
     45 
     46 local function test_vim_str2nr(s, what, exp, maxlen, strict)
     47  if strict == nil then
     48    strict = true
     49  end
     50  local bits = {}
     51  for k, _ in pairs(exp) do
     52    bits[#bits + 1] = k
     53  end
     54  maxlen = maxlen or #s
     55  local args = {}
     56  for k, _ in pairs(ARGTYPES) do
     57    args[k] = arginit(k)
     58  end
     59  for case = 0, ((2 ^ #bits) - 1) do
     60    local cv = {}
     61    for b = 0, (#bits - 1) do
     62      if bit.band(case, (2 ^ b)) == 0 then
     63        local k = bits[b + 1]
     64        argreset(k, args)
     65        cv[k] = args[k]
     66      end
     67    end
     68    lib.vim_str2nr(s, cv.pre, cv.len, what, cv.num, cv.unum, maxlen, strict, nil)
     69    for cck, ccv in pairs(cv) do
     70      if exp[cck] ~= tonumber(ccv[0]) then
     71        error(
     72          ('Failed check (%s = %d) in test (s=%s, w=%u, m=%d, strict=%s): %d'):format(
     73            cck,
     74            exp[cck],
     75            s,
     76            tonumber(what),
     77            maxlen,
     78            tostring(strict),
     79            tonumber(ccv[0])
     80          )
     81        )
     82      end
     83    end
     84  end
     85 end
     86 
     87 local _itp = itp
     88 itp = function(...)
     89  collectgarbage('restart')
     90  _itp(...)
     91 end
     92 
     93 describe('vim_str2nr()', function()
     94  itp('works fine when it has nothing to do', function()
     95    test_vim_str2nr('', 0, { len = 0, num = 0, unum = 0, pre = 0 }, 0)
     96    test_vim_str2nr('', lib.STR2NR_ALL, { len = 0, num = 0, unum = 0, pre = 0 }, 0)
     97    test_vim_str2nr('', lib.STR2NR_BIN, { len = 0, num = 0, unum = 0, pre = 0 }, 0)
     98    test_vim_str2nr('', lib.STR2NR_OCT, { len = 0, num = 0, unum = 0, pre = 0 }, 0)
     99    test_vim_str2nr('', lib.STR2NR_OOCT, { len = 0, num = 0, unum = 0, pre = 0 }, 0)
    100    test_vim_str2nr('', lib.STR2NR_HEX, { len = 0, num = 0, unum = 0, pre = 0 }, 0)
    101    test_vim_str2nr(
    102      '',
    103      lib.STR2NR_FORCE + lib.STR2NR_DEC,
    104      { len = 0, num = 0, unum = 0, pre = 0 },
    105      0
    106    )
    107    test_vim_str2nr(
    108      '',
    109      lib.STR2NR_FORCE + lib.STR2NR_BIN,
    110      { len = 0, num = 0, unum = 0, pre = 0 },
    111      0
    112    )
    113    test_vim_str2nr(
    114      '',
    115      lib.STR2NR_FORCE + lib.STR2NR_OCT,
    116      { len = 0, num = 0, unum = 0, pre = 0 },
    117      0
    118    )
    119    test_vim_str2nr(
    120      '',
    121      lib.STR2NR_FORCE + lib.STR2NR_OOCT,
    122      { len = 0, num = 0, unum = 0, pre = 0 },
    123      0
    124    )
    125    test_vim_str2nr(
    126      '',
    127      lib.STR2NR_FORCE + lib.STR2NR_OCT + lib.STR2NR_OOCT,
    128      { len = 0, num = 0, unum = 0, pre = 0 },
    129      0
    130    )
    131    test_vim_str2nr(
    132      '',
    133      lib.STR2NR_FORCE + lib.STR2NR_HEX,
    134      { len = 0, num = 0, unum = 0, pre = 0 },
    135      0
    136    )
    137  end)
    138  itp('works with decimal numbers', function()
    139    for _, flags in ipairs({
    140      0,
    141      lib.STR2NR_BIN,
    142      lib.STR2NR_OCT,
    143      lib.STR2NR_HEX,
    144      lib.STR2NR_OOCT,
    145      lib.STR2NR_BIN + lib.STR2NR_OCT,
    146      lib.STR2NR_BIN + lib.STR2NR_HEX,
    147      lib.STR2NR_OCT + lib.STR2NR_HEX,
    148      lib.STR2NR_OOCT + lib.STR2NR_HEX,
    149      lib.STR2NR_ALL,
    150      lib.STR2NR_FORCE + lib.STR2NR_DEC,
    151    }) do
    152      -- Check that all digits are recognized
    153      test_vim_str2nr('12345', flags, { len = 5, num = 12345, unum = 12345, pre = 0 }, 0)
    154      test_vim_str2nr('67890', flags, { len = 5, num = 67890, unum = 67890, pre = 0 }, 0)
    155      test_vim_str2nr('12345A', flags, { len = 0 }, 0)
    156      test_vim_str2nr('67890A', flags, { len = 0 }, 0)
    157      test_vim_str2nr('12345A', flags, { len = 5, num = 12345, unum = 12345, pre = 0 }, 0, false)
    158      test_vim_str2nr('67890A', flags, { len = 5, num = 67890, unum = 67890, pre = 0 }, 0, false)
    159 
    160      test_vim_str2nr('42', flags, { len = 2, num = 42, unum = 42, pre = 0 }, 0)
    161      test_vim_str2nr('42', flags, { len = 1, num = 4, unum = 4, pre = 0 }, 1)
    162      test_vim_str2nr('42', flags, { len = 2, num = 42, unum = 42, pre = 0 }, 2)
    163      test_vim_str2nr('42', flags, { len = 2, num = 42, unum = 42, pre = 0 }, 3) -- includes NUL byte in maxlen
    164 
    165      test_vim_str2nr('42x', flags, { len = 0 }, 0)
    166      test_vim_str2nr('42x', flags, { len = 0 }, 3)
    167      test_vim_str2nr('42x', flags, { len = 2, num = 42, unum = 42, pre = 0 }, 0, false)
    168      test_vim_str2nr('42x', flags, { len = 2, num = 42, unum = 42, pre = 0 }, 3, false)
    169 
    170      test_vim_str2nr('-42', flags, { len = 3, num = -42, unum = 42, pre = 0 }, 3)
    171      test_vim_str2nr('-42', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 1)
    172 
    173      test_vim_str2nr('-42x', flags, { len = 0 }, 0)
    174      test_vim_str2nr('-42x', flags, { len = 0 }, 4)
    175      test_vim_str2nr('-42x', flags, { len = 3, num = -42, unum = 42, pre = 0 }, 0, false)
    176      test_vim_str2nr('-42x', flags, { len = 3, num = -42, unum = 42, pre = 0 }, 4, false)
    177    end
    178  end)
    179  itp('works with binary numbers', function()
    180    for _, flags in ipairs({
    181      lib.STR2NR_BIN,
    182      lib.STR2NR_BIN + lib.STR2NR_OCT,
    183      lib.STR2NR_BIN + lib.STR2NR_HEX,
    184      lib.STR2NR_ALL,
    185      lib.STR2NR_FORCE + lib.STR2NR_BIN,
    186    }) do
    187      local bin
    188      local BIN
    189      if flags > lib.STR2NR_FORCE then
    190        bin = 0
    191        BIN = 0
    192      else
    193        bin = ('b'):byte()
    194        BIN = ('B'):byte()
    195      end
    196 
    197      test_vim_str2nr('0b101', flags, { len = 5, num = 5, unum = 5, pre = bin }, 0)
    198      test_vim_str2nr('0b101', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 1)
    199      test_vim_str2nr('0b101', flags, { len = 0 }, 2)
    200      test_vim_str2nr('0b101', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 2, false)
    201      test_vim_str2nr('0b101', flags, { len = 3, num = 1, unum = 1, pre = bin }, 3)
    202      test_vim_str2nr('0b101', flags, { len = 4, num = 2, unum = 2, pre = bin }, 4)
    203      test_vim_str2nr('0b101', flags, { len = 5, num = 5, unum = 5, pre = bin }, 5)
    204      test_vim_str2nr('0b101', flags, { len = 5, num = 5, unum = 5, pre = bin }, 6)
    205 
    206      test_vim_str2nr('0b1012', flags, { len = 0 }, 0)
    207      test_vim_str2nr('0b1012', flags, { len = 0 }, 6)
    208      test_vim_str2nr('0b1012', flags, { len = 5, num = 5, unum = 5, pre = bin }, 0, false)
    209      test_vim_str2nr('0b1012', flags, { len = 5, num = 5, unum = 5, pre = bin }, 6, false)
    210 
    211      test_vim_str2nr('-0b101', flags, { len = 6, num = -5, unum = 5, pre = bin }, 0)
    212      test_vim_str2nr('-0b101', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 1)
    213      test_vim_str2nr('-0b101', flags, { len = 2, num = 0, unum = 0, pre = 0 }, 2)
    214      test_vim_str2nr('-0b101', flags, { len = 0 }, 3)
    215      test_vim_str2nr('-0b101', flags, { len = 2, num = 0, unum = 0, pre = 0 }, 3, false)
    216      test_vim_str2nr('-0b101', flags, { len = 4, num = -1, unum = 1, pre = bin }, 4)
    217      test_vim_str2nr('-0b101', flags, { len = 5, num = -2, unum = 2, pre = bin }, 5)
    218      test_vim_str2nr('-0b101', flags, { len = 6, num = -5, unum = 5, pre = bin }, 6)
    219      test_vim_str2nr('-0b101', flags, { len = 6, num = -5, unum = 5, pre = bin }, 7)
    220 
    221      test_vim_str2nr('-0b1012', flags, { len = 0 }, 0)
    222      test_vim_str2nr('-0b1012', flags, { len = 0 }, 7)
    223      test_vim_str2nr('-0b1012', flags, { len = 6, num = -5, unum = 5, pre = bin }, 0, false)
    224      test_vim_str2nr('-0b1012', flags, { len = 6, num = -5, unum = 5, pre = bin }, 7, false)
    225 
    226      test_vim_str2nr('0B101', flags, { len = 5, num = 5, unum = 5, pre = BIN }, 0)
    227      test_vim_str2nr('0B101', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 1)
    228      test_vim_str2nr('0B101', flags, { len = 0 }, 2)
    229      test_vim_str2nr('0B101', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 2, false)
    230      test_vim_str2nr('0B101', flags, { len = 3, num = 1, unum = 1, pre = BIN }, 3)
    231      test_vim_str2nr('0B101', flags, { len = 4, num = 2, unum = 2, pre = BIN }, 4)
    232      test_vim_str2nr('0B101', flags, { len = 5, num = 5, unum = 5, pre = BIN }, 5)
    233      test_vim_str2nr('0B101', flags, { len = 5, num = 5, unum = 5, pre = BIN }, 6)
    234 
    235      test_vim_str2nr('0B1012', flags, { len = 0 }, 0)
    236      test_vim_str2nr('0B1012', flags, { len = 0 }, 6)
    237      test_vim_str2nr('0B1012', flags, { len = 5, num = 5, unum = 5, pre = BIN }, 0, false)
    238      test_vim_str2nr('0B1012', flags, { len = 5, num = 5, unum = 5, pre = BIN }, 6, false)
    239 
    240      test_vim_str2nr('-0B101', flags, { len = 6, num = -5, unum = 5, pre = BIN }, 0)
    241      test_vim_str2nr('-0B101', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 1)
    242      test_vim_str2nr('-0B101', flags, { len = 2, num = 0, unum = 0, pre = 0 }, 2)
    243      test_vim_str2nr('-0B101', flags, { len = 0 }, 3)
    244      test_vim_str2nr('-0B101', flags, { len = 2, num = 0, unum = 0, pre = 0 }, 3, false)
    245      test_vim_str2nr('-0B101', flags, { len = 4, num = -1, unum = 1, pre = BIN }, 4)
    246      test_vim_str2nr('-0B101', flags, { len = 5, num = -2, unum = 2, pre = BIN }, 5)
    247      test_vim_str2nr('-0B101', flags, { len = 6, num = -5, unum = 5, pre = BIN }, 6)
    248      test_vim_str2nr('-0B101', flags, { len = 6, num = -5, unum = 5, pre = BIN }, 7)
    249 
    250      test_vim_str2nr('-0B1012', flags, { len = 0 }, 0)
    251      test_vim_str2nr('-0B1012', flags, { len = 0 }, 7)
    252      test_vim_str2nr('-0B1012', flags, { len = 6, num = -5, unum = 5, pre = BIN }, 0, false)
    253      test_vim_str2nr('-0B1012', flags, { len = 6, num = -5, unum = 5, pre = BIN }, 7, false)
    254 
    255      if flags > lib.STR2NR_FORCE then
    256        test_vim_str2nr('-101', flags, { len = 4, num = -5, unum = 5, pre = 0 }, 0)
    257      end
    258    end
    259  end)
    260  itp('works with octal numbers (0 prefix)', function()
    261    for _, flags in ipairs({
    262      lib.STR2NR_OCT,
    263      lib.STR2NR_OCT + lib.STR2NR_BIN,
    264      lib.STR2NR_OCT + lib.STR2NR_HEX,
    265      lib.STR2NR_OCT + lib.STR2NR_OOCT,
    266      lib.STR2NR_ALL,
    267      lib.STR2NR_FORCE + lib.STR2NR_OCT,
    268      lib.STR2NR_FORCE + lib.STR2NR_OOCT,
    269      lib.STR2NR_FORCE + lib.STR2NR_OCT + lib.STR2NR_OOCT,
    270    }) do
    271      local oct
    272      if flags > lib.STR2NR_FORCE then
    273        oct = 0
    274      else
    275        oct = ('0'):byte()
    276      end
    277 
    278      -- Check that all digits are recognized
    279      test_vim_str2nr('012345670', flags, { len = 9, num = 2739128, unum = 2739128, pre = oct }, 0)
    280 
    281      test_vim_str2nr('054', flags, { len = 3, num = 44, unum = 44, pre = oct }, 0)
    282      test_vim_str2nr('054', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 1)
    283      test_vim_str2nr('054', flags, { len = 2, num = 5, unum = 5, pre = oct }, 2)
    284      test_vim_str2nr('054', flags, { len = 3, num = 44, unum = 44, pre = oct }, 3)
    285      test_vim_str2nr('0548', flags, { len = 3, num = 44, unum = 44, pre = oct }, 3)
    286      test_vim_str2nr('054', flags, { len = 3, num = 44, unum = 44, pre = oct }, 4)
    287 
    288      test_vim_str2nr('054x', flags, { len = 0 }, 4)
    289      test_vim_str2nr('054x', flags, { len = 0 }, 0)
    290      test_vim_str2nr('054x', flags, { len = 3, num = 44, unum = 44, pre = oct }, 4, false)
    291      test_vim_str2nr('054x', flags, { len = 3, num = 44, unum = 44, pre = oct }, 0, false)
    292 
    293      test_vim_str2nr('-054', flags, { len = 4, num = -44, unum = 44, pre = oct }, 0)
    294      test_vim_str2nr('-054', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 1)
    295      test_vim_str2nr('-054', flags, { len = 2, num = 0, unum = 0, pre = 0 }, 2)
    296      test_vim_str2nr('-054', flags, { len = 3, num = -5, unum = 5, pre = oct }, 3)
    297      test_vim_str2nr('-054', flags, { len = 4, num = -44, unum = 44, pre = oct }, 4)
    298      test_vim_str2nr('-0548', flags, { len = 4, num = -44, unum = 44, pre = oct }, 4)
    299      test_vim_str2nr('-054', flags, { len = 4, num = -44, unum = 44, pre = oct }, 5)
    300 
    301      test_vim_str2nr('-054x', flags, { len = 0 }, 5)
    302      test_vim_str2nr('-054x', flags, { len = 0 }, 0)
    303      test_vim_str2nr('-054x', flags, { len = 4, num = -44, unum = 44, pre = oct }, 5, false)
    304      test_vim_str2nr('-054x', flags, { len = 4, num = -44, unum = 44, pre = oct }, 0, false)
    305 
    306      if flags > lib.STR2NR_FORCE then
    307        test_vim_str2nr('-54', flags, { len = 3, num = -44, unum = 44, pre = 0 }, 0)
    308        test_vim_str2nr('-0548', flags, { len = 0 }, 5)
    309        test_vim_str2nr('-0548', flags, { len = 0 }, 0)
    310        test_vim_str2nr('-0548', flags, { len = 4, num = -44, unum = 44, pre = 0 }, 5, false)
    311        test_vim_str2nr('-0548', flags, { len = 4, num = -44, unum = 44, pre = 0 }, 0, false)
    312      else
    313        test_vim_str2nr('-0548', flags, { len = 5, num = -548, unum = 548, pre = 0 }, 5)
    314        test_vim_str2nr('-0548', flags, { len = 5, num = -548, unum = 548, pre = 0 }, 0)
    315      end
    316    end
    317  end)
    318  itp('works with octal numbers (0o or 0O prefix)', function()
    319    for _, flags in ipairs({
    320      lib.STR2NR_OOCT,
    321      lib.STR2NR_OOCT + lib.STR2NR_BIN,
    322      lib.STR2NR_OOCT + lib.STR2NR_HEX,
    323      lib.STR2NR_OCT + lib.STR2NR_OOCT,
    324      lib.STR2NR_OCT + lib.STR2NR_OOCT + lib.STR2NR_BIN,
    325      lib.STR2NR_OCT + lib.STR2NR_OOCT + lib.STR2NR_HEX,
    326      lib.STR2NR_ALL,
    327      lib.STR2NR_FORCE + lib.STR2NR_OCT,
    328      lib.STR2NR_FORCE + lib.STR2NR_OOCT,
    329      lib.STR2NR_FORCE + lib.STR2NR_OCT + lib.STR2NR_OOCT,
    330    }) do
    331      local oct
    332      local OCT
    333      if flags > lib.STR2NR_FORCE then
    334        oct = 0
    335        OCT = 0
    336      else
    337        oct = ('o'):byte()
    338        OCT = ('O'):byte()
    339      end
    340 
    341      test_vim_str2nr('0o054', flags, { len = 5, num = 44, unum = 44, pre = oct }, 0)
    342      test_vim_str2nr('0o054', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 1)
    343      test_vim_str2nr('0o054', flags, { len = 0 }, 2)
    344      test_vim_str2nr('0o054', flags, { len = 3, num = 0, unum = 0, pre = oct }, 3)
    345      test_vim_str2nr('0o054', flags, { len = 4, num = 5, unum = 5, pre = oct }, 4)
    346      test_vim_str2nr('0o054', flags, { len = 5, num = 44, unum = 44, pre = oct }, 5)
    347      test_vim_str2nr('0o0548', flags, { len = 5, num = 44, unum = 44, pre = oct }, 5)
    348      test_vim_str2nr('0o054', flags, { len = 5, num = 44, unum = 44, pre = oct }, 6)
    349 
    350      test_vim_str2nr('0o054x', flags, { len = 0 }, 6)
    351      test_vim_str2nr('0o054x', flags, { len = 0 }, 0)
    352      test_vim_str2nr('0o054x', flags, { len = 5, num = 44, unum = 44, pre = oct }, 6, false)
    353      test_vim_str2nr('0o054x', flags, { len = 5, num = 44, unum = 44, pre = oct }, 0, false)
    354 
    355      test_vim_str2nr('-0o054', flags, { len = 6, num = -44, unum = 44, pre = oct }, 0)
    356      test_vim_str2nr('-0o054', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 1)
    357      test_vim_str2nr('-0o054', flags, { len = 2, num = 0, unum = 0, pre = 0 }, 2)
    358      test_vim_str2nr('-0o054', flags, { len = 0 }, 3)
    359      test_vim_str2nr('-0o054', flags, { len = 4, num = 0, unum = 0, pre = oct }, 4)
    360      test_vim_str2nr('-0o054', flags, { len = 5, num = -5, unum = 5, pre = oct }, 5)
    361      test_vim_str2nr('-0o054', flags, { len = 6, num = -44, unum = 44, pre = oct }, 6)
    362      test_vim_str2nr('-0o0548', flags, { len = 6, num = -44, unum = 44, pre = oct }, 6)
    363      test_vim_str2nr('-0o054', flags, { len = 6, num = -44, unum = 44, pre = oct }, 7)
    364 
    365      test_vim_str2nr('-0o054x', flags, { len = 0 }, 7)
    366      test_vim_str2nr('-0o054x', flags, { len = 0 }, 0)
    367      test_vim_str2nr('-0o054x', flags, { len = 6, num = -44, unum = 44, pre = oct }, 7, false)
    368      test_vim_str2nr('-0o054x', flags, { len = 6, num = -44, unum = 44, pre = oct }, 0, false)
    369 
    370      test_vim_str2nr('0O054', flags, { len = 5, num = 44, unum = 44, pre = OCT }, 0)
    371      test_vim_str2nr('0O054', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 1)
    372      test_vim_str2nr('0O054', flags, { len = 0 }, 2)
    373      test_vim_str2nr('0O054', flags, { len = 3, num = 0, unum = 0, pre = OCT }, 3)
    374      test_vim_str2nr('0O054', flags, { len = 4, num = 5, unum = 5, pre = OCT }, 4)
    375      test_vim_str2nr('0O054', flags, { len = 5, num = 44, unum = 44, pre = OCT }, 5)
    376      test_vim_str2nr('0O0548', flags, { len = 5, num = 44, unum = 44, pre = OCT }, 5)
    377      test_vim_str2nr('0O054', flags, { len = 5, num = 44, unum = 44, pre = OCT }, 6)
    378 
    379      test_vim_str2nr('0O054x', flags, { len = 0 }, 6)
    380      test_vim_str2nr('0O054x', flags, { len = 0 }, 0)
    381      test_vim_str2nr('0O054x', flags, { len = 5, num = 44, unum = 44, pre = OCT }, 6, false)
    382      test_vim_str2nr('0O054x', flags, { len = 5, num = 44, unum = 44, pre = OCT }, 0, false)
    383 
    384      test_vim_str2nr('-0O054', flags, { len = 6, num = -44, unum = 44, pre = OCT }, 0)
    385      test_vim_str2nr('-0O054', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 1)
    386      test_vim_str2nr('-0O054', flags, { len = 2, num = 0, unum = 0, pre = 0 }, 2)
    387      test_vim_str2nr('-0O054', flags, { len = 0 }, 3)
    388      test_vim_str2nr('-0O054', flags, { len = 4, num = 0, unum = 0, pre = OCT }, 4)
    389      test_vim_str2nr('-0O054', flags, { len = 5, num = -5, unum = 5, pre = OCT }, 5)
    390      test_vim_str2nr('-0O054', flags, { len = 6, num = -44, unum = 44, pre = OCT }, 6)
    391      test_vim_str2nr('-0O0548', flags, { len = 6, num = -44, unum = 44, pre = OCT }, 6)
    392      test_vim_str2nr('-0O054', flags, { len = 6, num = -44, unum = 44, pre = OCT }, 7)
    393 
    394      test_vim_str2nr('-0O054x', flags, { len = 0 }, 7)
    395      test_vim_str2nr('-0O054x', flags, { len = 0 }, 0)
    396      test_vim_str2nr('-0O054x', flags, { len = 6, num = -44, unum = 44, pre = OCT }, 7, false)
    397      test_vim_str2nr('-0O054x', flags, { len = 6, num = -44, unum = 44, pre = OCT }, 0, false)
    398 
    399      if flags > lib.STR2NR_FORCE then
    400        test_vim_str2nr('-0548', flags, { len = 0 }, 5)
    401        test_vim_str2nr('-0548', flags, { len = 0 }, 0)
    402        test_vim_str2nr('-0548', flags, { len = 4, num = -44, unum = 44, pre = 0 }, 5, false)
    403        test_vim_str2nr('-0548', flags, { len = 4, num = -44, unum = 44, pre = 0 }, 0, false)
    404        test_vim_str2nr('-055', flags, { len = 4, num = -45, unum = 45, pre = 0 }, 0)
    405      else
    406        test_vim_str2nr('-0548', flags, { len = 5, num = -548, unum = 548, pre = 0 }, 5)
    407        test_vim_str2nr('-0548', flags, { len = 5, num = -548, unum = 548, pre = 0 }, 0)
    408      end
    409    end
    410  end)
    411  itp('works with hexadecimal numbers', function()
    412    for _, flags in ipairs({
    413      lib.STR2NR_HEX,
    414      lib.STR2NR_HEX + lib.STR2NR_BIN,
    415      lib.STR2NR_HEX + lib.STR2NR_OCT,
    416      lib.STR2NR_ALL,
    417      lib.STR2NR_FORCE + lib.STR2NR_HEX,
    418    }) do
    419      local hex
    420      local HEX
    421      if flags > lib.STR2NR_FORCE then
    422        hex = 0
    423        HEX = 0
    424      else
    425        hex = ('x'):byte()
    426        HEX = ('X'):byte()
    427      end
    428 
    429      -- Check that all digits are recognized
    430      test_vim_str2nr('0x12345', flags, { len = 7, num = 74565, unum = 74565, pre = hex }, 0)
    431      test_vim_str2nr('0x67890', flags, { len = 7, num = 424080, unum = 424080, pre = hex }, 0)
    432      test_vim_str2nr('0xABCDEF', flags, { len = 8, num = 11259375, unum = 11259375, pre = hex }, 0)
    433      test_vim_str2nr('0xabcdef', flags, { len = 8, num = 11259375, unum = 11259375, pre = hex }, 0)
    434 
    435      test_vim_str2nr('0x101', flags, { len = 5, num = 257, unum = 257, pre = hex }, 0)
    436      test_vim_str2nr('0x101', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 1)
    437      test_vim_str2nr('0x101', flags, { len = 0 }, 2)
    438      test_vim_str2nr('0x101', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 2, false)
    439      test_vim_str2nr('0x101', flags, { len = 3, num = 1, unum = 1, pre = hex }, 3)
    440      test_vim_str2nr('0x101', flags, { len = 4, num = 16, unum = 16, pre = hex }, 4)
    441      test_vim_str2nr('0x101', flags, { len = 5, num = 257, unum = 257, pre = hex }, 5)
    442      test_vim_str2nr('0x101', flags, { len = 5, num = 257, unum = 257, pre = hex }, 6)
    443 
    444      test_vim_str2nr('0x101G', flags, { len = 0 }, 0)
    445      test_vim_str2nr('0x101G', flags, { len = 0 }, 6)
    446      test_vim_str2nr('0x101G', flags, { len = 5, num = 257, unum = 257, pre = hex }, 0, false)
    447      test_vim_str2nr('0x101G', flags, { len = 5, num = 257, unum = 257, pre = hex }, 6, false)
    448 
    449      test_vim_str2nr('-0x101', flags, { len = 6, num = -257, unum = 257, pre = hex }, 0)
    450      test_vim_str2nr('-0x101', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 1)
    451      test_vim_str2nr('-0x101', flags, { len = 2, num = 0, unum = 0, pre = 0 }, 2)
    452      test_vim_str2nr('-0x101', flags, { len = 0 }, 3)
    453      test_vim_str2nr('-0x101', flags, { len = 2, num = 0, unum = 0, pre = 0 }, 3, false)
    454      test_vim_str2nr('-0x101', flags, { len = 4, num = -1, unum = 1, pre = hex }, 4)
    455      test_vim_str2nr('-0x101', flags, { len = 5, num = -16, unum = 16, pre = hex }, 5)
    456      test_vim_str2nr('-0x101', flags, { len = 6, num = -257, unum = 257, pre = hex }, 6)
    457      test_vim_str2nr('-0x101', flags, { len = 6, num = -257, unum = 257, pre = hex }, 7)
    458 
    459      test_vim_str2nr('-0x101G', flags, { len = 0 }, 0)
    460      test_vim_str2nr('-0x101G', flags, { len = 0 }, 7)
    461      test_vim_str2nr('-0x101G', flags, { len = 6, num = -257, unum = 257, pre = hex }, 0, false)
    462      test_vim_str2nr('-0x101G', flags, { len = 6, num = -257, unum = 257, pre = hex }, 7, false)
    463 
    464      test_vim_str2nr('0X101', flags, { len = 5, num = 257, unum = 257, pre = HEX }, 0)
    465      test_vim_str2nr('0X101', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 1)
    466      test_vim_str2nr('0X101', flags, { len = 0 }, 2)
    467      test_vim_str2nr('0X101', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 2, false)
    468      test_vim_str2nr('0X101', flags, { len = 3, num = 1, unum = 1, pre = HEX }, 3)
    469      test_vim_str2nr('0X101', flags, { len = 4, num = 16, unum = 16, pre = HEX }, 4)
    470      test_vim_str2nr('0X101', flags, { len = 5, num = 257, unum = 257, pre = HEX }, 5)
    471      test_vim_str2nr('0X101', flags, { len = 5, num = 257, unum = 257, pre = HEX }, 6)
    472 
    473      test_vim_str2nr('0X101G', flags, { len = 0 }, 0)
    474      test_vim_str2nr('0X101G', flags, { len = 0 }, 6)
    475      test_vim_str2nr('0X101G', flags, { len = 5, num = 257, unum = 257, pre = HEX }, 0, false)
    476      test_vim_str2nr('0X101G', flags, { len = 5, num = 257, unum = 257, pre = HEX }, 6, false)
    477 
    478      test_vim_str2nr('-0X101', flags, { len = 6, num = -257, unum = 257, pre = HEX }, 0)
    479      test_vim_str2nr('-0X101', flags, { len = 1, num = 0, unum = 0, pre = 0 }, 1)
    480      test_vim_str2nr('-0X101', flags, { len = 2, num = 0, unum = 0, pre = 0 }, 2)
    481      test_vim_str2nr('-0X101', flags, { len = 0 }, 3)
    482      test_vim_str2nr('-0X101', flags, { len = 2, num = 0, unum = 0, pre = 0 }, 3, false)
    483      test_vim_str2nr('-0X101', flags, { len = 4, num = -1, unum = 1, pre = HEX }, 4)
    484      test_vim_str2nr('-0X101', flags, { len = 5, num = -16, unum = 16, pre = HEX }, 5)
    485      test_vim_str2nr('-0X101', flags, { len = 6, num = -257, unum = 257, pre = HEX }, 6)
    486      test_vim_str2nr('-0X101', flags, { len = 6, num = -257, unum = 257, pre = HEX }, 7)
    487 
    488      test_vim_str2nr('-0X101G', flags, { len = 0 }, 0)
    489      test_vim_str2nr('-0X101G', flags, { len = 0 }, 7)
    490      test_vim_str2nr('-0X101G', flags, { len = 6, num = -257, unum = 257, pre = HEX }, 0, false)
    491      test_vim_str2nr('-0X101G', flags, { len = 6, num = -257, unum = 257, pre = HEX }, 7, false)
    492 
    493      if flags > lib.STR2NR_FORCE then
    494        test_vim_str2nr('-101', flags, { len = 4, num = -257, unum = 257, pre = 0 }, 0)
    495      end
    496    end
    497  end)
    498  -- Test_str2nr() in test_functions.vim already tests normal usage
    499  itp('works with weirdly quoted numbers', function()
    500    local flags = lib.STR2NR_DEC + lib.STR2NR_QUOTE
    501    test_vim_str2nr("'027", flags, { len = 0 }, 0)
    502    test_vim_str2nr("'027", flags, { len = 0 }, 0, false)
    503    test_vim_str2nr("1'2'3'4", flags, { len = 7, num = 1234, unum = 1234, pre = 0 }, 0)
    504 
    505    -- counter-intuitive, but like Vim, strict=true should partially accept
    506    -- these: (' and - are not alphanumeric)
    507    test_vim_str2nr("7''331", flags, { len = 1, num = 7, unum = 7, pre = 0 }, 0)
    508    test_vim_str2nr("123'x4", flags, { len = 3, num = 123, unum = 123, pre = 0 }, 0)
    509    test_vim_str2nr("1337'", flags, { len = 4, num = 1337, unum = 1337, pre = 0 }, 0)
    510    test_vim_str2nr("-'", flags, { len = 1, num = 0, unum = 0, pre = 0 }, 0)
    511 
    512    flags = lib.STR2NR_HEX + lib.STR2NR_QUOTE
    513    local hex = ('x'):byte()
    514    test_vim_str2nr("0x'abcd", flags, { len = 0 }, 0)
    515    test_vim_str2nr("0x'abcd", flags, { len = 1, num = 0, unum = 0, pre = 0 }, 0, false)
    516    test_vim_str2nr("0xab''cd", flags, { len = 4, num = 171, unum = 171, pre = hex }, 0)
    517  end)
    518 end)