strings_spec.lua 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. local helpers = require("test.unit.helpers")(after_each)
  2. local itp = helpers.gen_itp(it)
  3. local cimport = helpers.cimport
  4. local eq = helpers.eq
  5. local ffi = helpers.ffi
  6. local to_cstr = helpers.to_cstr
  7. local strings = cimport('stdlib.h', './src/nvim/strings.h',
  8. './src/nvim/memory.h')
  9. describe('vim_strsave_escaped()', function()
  10. local vim_strsave_escaped = function(s, chars)
  11. local res = strings.vim_strsave_escaped(to_cstr(s), to_cstr(chars))
  12. local ret = ffi.string(res)
  13. -- Explicitly free memory so we are sure it is allocated: if it was not it
  14. -- will crash.
  15. strings.xfree(res)
  16. return ret
  17. end
  18. itp('precedes by a backslash all chars from second argument', function()
  19. eq([[\a\b\c\d]], vim_strsave_escaped('abcd','abcd'))
  20. end)
  21. itp('precedes by a backslash chars only from second argument', function()
  22. eq([[\a\bcd]], vim_strsave_escaped('abcd','ab'))
  23. end)
  24. itp('returns a copy of passed string if second argument is empty', function()
  25. eq('text \n text', vim_strsave_escaped('text \n text',''))
  26. end)
  27. itp('returns an empty string if first argument is empty string', function()
  28. eq('', vim_strsave_escaped('','\r'))
  29. end)
  30. itp('returns a copy of passed string if it does not contain chars from 2nd argument', function()
  31. eq('some text', vim_strsave_escaped('some text', 'a'))
  32. end)
  33. end)
  34. describe('vim_strnsave_unquoted()', function()
  35. local vim_strnsave_unquoted = function(s, len)
  36. local res = strings.vim_strnsave_unquoted(to_cstr(s), len or #s)
  37. local ret = ffi.string(res)
  38. -- Explicitly free memory so we are sure it is allocated: if it was not it
  39. -- will crash.
  40. strings.xfree(res)
  41. return ret
  42. end
  43. itp('copies unquoted strings as-is', function()
  44. eq('-c', vim_strnsave_unquoted('-c'))
  45. eq('', vim_strnsave_unquoted(''))
  46. end)
  47. itp('respects length argument', function()
  48. eq('', vim_strnsave_unquoted('-c', 0))
  49. eq('-', vim_strnsave_unquoted('-c', 1))
  50. eq('-', vim_strnsave_unquoted('"-c', 2))
  51. end)
  52. itp('unquotes fully quoted word', function()
  53. eq('/bin/sh', vim_strnsave_unquoted('"/bin/sh"'))
  54. end)
  55. itp('unquotes partially quoted word', function()
  56. eq('/Program Files/sh', vim_strnsave_unquoted('/Program" "Files/sh'))
  57. end)
  58. itp('removes ""', function()
  59. eq('/Program Files/sh', vim_strnsave_unquoted('/""Program" "Files/sh'))
  60. end)
  61. itp('performs unescaping of "', function()
  62. eq('/"Program Files"/sh', vim_strnsave_unquoted('/"\\""Program Files"\\""/sh'))
  63. end)
  64. itp('performs unescaping of \\', function()
  65. eq('/\\Program Files\\foo/sh', vim_strnsave_unquoted('/"\\\\"Program Files"\\\\foo"/sh'))
  66. end)
  67. itp('strips quote when there is no pair to it', function()
  68. eq('/Program Files/sh', vim_strnsave_unquoted('/Program" Files/sh'))
  69. eq('', vim_strnsave_unquoted('"'))
  70. end)
  71. itp('allows string to end with one backslash unescaped', function()
  72. eq('/Program Files/sh\\', vim_strnsave_unquoted('/Program" Files/sh\\'))
  73. end)
  74. itp('does not perform unescaping out of quotes', function()
  75. eq('/Program\\ Files/sh\\', vim_strnsave_unquoted('/Program\\ Files/sh\\'))
  76. end)
  77. itp('does not unescape \\n', function()
  78. eq('/Program\\nFiles/sh', vim_strnsave_unquoted('/Program"\\n"Files/sh'))
  79. end)
  80. end)
  81. describe('vim_strchr()', function()
  82. local vim_strchr = function(s, c)
  83. local str = to_cstr(s)
  84. local res = strings.vim_strchr(str, c)
  85. if res == nil then
  86. return nil
  87. else
  88. return res - str
  89. end
  90. end
  91. itp('handles NUL and <0 correctly', function()
  92. eq(nil, vim_strchr('abc', 0))
  93. eq(nil, vim_strchr('abc', -1))
  94. end)
  95. itp('works', function()
  96. eq(0, vim_strchr('abc', ('a'):byte()))
  97. eq(1, vim_strchr('abc', ('b'):byte()))
  98. eq(2, vim_strchr('abc', ('c'):byte()))
  99. eq(0, vim_strchr('a«b»c', ('a'):byte()))
  100. eq(3, vim_strchr('a«b»c', ('b'):byte()))
  101. eq(6, vim_strchr('a«b»c', ('c'):byte()))
  102. eq(nil, vim_strchr('«»', ('«'):byte()))
  103. -- 0xAB == 171 == '«'
  104. eq(nil, vim_strchr('\171', 0xAB))
  105. eq(0, vim_strchr('«»', 0xAB))
  106. eq(3, vim_strchr('„«»“', 0xAB))
  107. eq(7, vim_strchr('„«»“', 0x201C))
  108. eq(nil, vim_strchr('„«»“', 0x201D))
  109. eq(0, vim_strchr('„«»“', 0x201E))
  110. eq(0, vim_strchr('\244\143\188\128', 0x10FF00))
  111. eq(2, vim_strchr('«\244\143\188\128»', 0x10FF00))
  112. -- |0xDBFF |0xDF00 - surrogate pair for 0x10FF00
  113. eq(nil, vim_strchr('«\237\175\191\237\188\128»', 0x10FF00))
  114. end)
  115. end)