mirror of
				https://github.com/neovim/neovim.git
				synced 2025-11-04 01:34:25 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			188 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			188 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
local helpers = require("test.unit.helpers")(after_each)
 | 
						||
local itp = helpers.gen_itp(it)
 | 
						||
 | 
						||
local cimport = helpers.cimport
 | 
						||
local eq = helpers.eq
 | 
						||
local ffi = helpers.ffi
 | 
						||
local to_cstr = helpers.to_cstr
 | 
						||
 | 
						||
local strings = cimport('stdlib.h', './src/nvim/strings.h',
 | 
						||
                        './src/nvim/memory.h')
 | 
						||
 | 
						||
describe('vim_strsave_escaped()', function()
 | 
						||
  local vim_strsave_escaped = function(s, chars)
 | 
						||
    local res = strings.vim_strsave_escaped(to_cstr(s), to_cstr(chars))
 | 
						||
    local ret = ffi.string(res)
 | 
						||
 | 
						||
    -- Explicitly free memory so we are sure it is allocated: if it was not it
 | 
						||
    -- will crash.
 | 
						||
    strings.xfree(res)
 | 
						||
    return ret
 | 
						||
  end
 | 
						||
 | 
						||
  itp('precedes by a backslash all chars from second argument', function()
 | 
						||
    eq([[\a\b\c\d]], vim_strsave_escaped('abcd','abcd'))
 | 
						||
  end)
 | 
						||
 | 
						||
  itp('precedes by a backslash chars only from second argument', function()
 | 
						||
    eq([[\a\bcd]], vim_strsave_escaped('abcd','ab'))
 | 
						||
  end)
 | 
						||
 | 
						||
  itp('returns a copy of passed string if second argument is empty', function()
 | 
						||
    eq('text \n text', vim_strsave_escaped('text \n text',''))
 | 
						||
  end)
 | 
						||
 | 
						||
  itp('returns an empty string if first argument is empty string', function()
 | 
						||
    eq('', vim_strsave_escaped('','\r'))
 | 
						||
  end)
 | 
						||
 | 
						||
  itp('returns a copy of passed string if it does not contain chars from 2nd argument', function()
 | 
						||
    eq('some text', vim_strsave_escaped('some text', 'a'))
 | 
						||
  end)
 | 
						||
end)
 | 
						||
 | 
						||
describe('vim_strnsave_unquoted()', function()
 | 
						||
  local vim_strnsave_unquoted = function(s, len)
 | 
						||
    local res = strings.vim_strnsave_unquoted(to_cstr(s), len or #s)
 | 
						||
    local ret = ffi.string(res)
 | 
						||
    -- Explicitly free memory so we are sure it is allocated: if it was not it
 | 
						||
    -- will crash.
 | 
						||
    strings.xfree(res)
 | 
						||
    return ret
 | 
						||
  end
 | 
						||
 | 
						||
  itp('copies unquoted strings as-is', function()
 | 
						||
    eq('-c', vim_strnsave_unquoted('-c'))
 | 
						||
    eq('', vim_strnsave_unquoted(''))
 | 
						||
  end)
 | 
						||
 | 
						||
  itp('respects length argument', function()
 | 
						||
    eq('', vim_strnsave_unquoted('-c', 0))
 | 
						||
    eq('-', vim_strnsave_unquoted('-c', 1))
 | 
						||
    eq('-', vim_strnsave_unquoted('"-c', 2))
 | 
						||
  end)
 | 
						||
 | 
						||
  itp('unquotes fully quoted word', function()
 | 
						||
    eq('/bin/sh', vim_strnsave_unquoted('"/bin/sh"'))
 | 
						||
  end)
 | 
						||
 | 
						||
  itp('unquotes partially quoted word', function()
 | 
						||
    eq('/Program Files/sh', vim_strnsave_unquoted('/Program" "Files/sh'))
 | 
						||
  end)
 | 
						||
 | 
						||
  itp('removes ""', function()
 | 
						||
    eq('/Program Files/sh', vim_strnsave_unquoted('/""Program" "Files/sh'))
 | 
						||
  end)
 | 
						||
 | 
						||
  itp('performs unescaping of "', function()
 | 
						||
    eq('/"Program Files"/sh', vim_strnsave_unquoted('/"\\""Program Files"\\""/sh'))
 | 
						||
  end)
 | 
						||
 | 
						||
  itp('performs unescaping of \\', function()
 | 
						||
    eq('/\\Program Files\\foo/sh', vim_strnsave_unquoted('/"\\\\"Program Files"\\\\foo"/sh'))
 | 
						||
  end)
 | 
						||
 | 
						||
  itp('strips quote when there is no pair to it', function()
 | 
						||
    eq('/Program Files/sh', vim_strnsave_unquoted('/Program" Files/sh'))
 | 
						||
    eq('', vim_strnsave_unquoted('"'))
 | 
						||
  end)
 | 
						||
 | 
						||
  itp('allows string to end with one backslash unescaped', function()
 | 
						||
    eq('/Program Files/sh\\', vim_strnsave_unquoted('/Program" Files/sh\\'))
 | 
						||
  end)
 | 
						||
 | 
						||
  itp('does not perform unescaping out of quotes', function()
 | 
						||
    eq('/Program\\ Files/sh\\', vim_strnsave_unquoted('/Program\\ Files/sh\\'))
 | 
						||
  end)
 | 
						||
 | 
						||
  itp('does not unescape \\n', function()
 | 
						||
    eq('/Program\\nFiles/sh', vim_strnsave_unquoted('/Program"\\n"Files/sh'))
 | 
						||
  end)
 | 
						||
end)
 | 
						||
 | 
						||
describe('vim_strchr()', function()
 | 
						||
  local vim_strchr = function(s, c)
 | 
						||
    local str = to_cstr(s)
 | 
						||
    local res = strings.vim_strchr(str, c)
 | 
						||
    if res == nil then
 | 
						||
      return nil
 | 
						||
    else
 | 
						||
      return res - str
 | 
						||
    end
 | 
						||
  end
 | 
						||
  itp('handles NUL and <0 correctly', function()
 | 
						||
    eq(nil, vim_strchr('abc', 0))
 | 
						||
    eq(nil, vim_strchr('abc', -1))
 | 
						||
  end)
 | 
						||
  itp('works', function()
 | 
						||
    eq(0, vim_strchr('abc', ('a'):byte()))
 | 
						||
    eq(1, vim_strchr('abc', ('b'):byte()))
 | 
						||
    eq(2, vim_strchr('abc', ('c'):byte()))
 | 
						||
    eq(0, vim_strchr('a«b»c', ('a'):byte()))
 | 
						||
    eq(3, vim_strchr('a«b»c', ('b'):byte()))
 | 
						||
    eq(6, vim_strchr('a«b»c', ('c'):byte()))
 | 
						||
 | 
						||
    eq(nil, vim_strchr('«»', ('«'):byte()))
 | 
						||
    -- 0xAB == 171 == '«'
 | 
						||
    eq(nil, vim_strchr('\171', 0xAB))
 | 
						||
    eq(0, vim_strchr('«»', 0xAB))
 | 
						||
    eq(3, vim_strchr('„«»“', 0xAB))
 | 
						||
 | 
						||
    eq(7, vim_strchr('„«»“', 0x201C))
 | 
						||
    eq(nil, vim_strchr('„«»“', 0x201D))
 | 
						||
    eq(0, vim_strchr('„«»“', 0x201E))
 | 
						||
 | 
						||
    eq(0, vim_strchr('\244\143\188\128', 0x10FF00))
 | 
						||
    eq(2, vim_strchr('«\244\143\188\128»', 0x10FF00))
 | 
						||
    --                   |0xDBFF     |0xDF00  - surrogate pair for 0x10FF00
 | 
						||
    eq(nil, vim_strchr('«\237\175\191\237\188\128»', 0x10FF00))
 | 
						||
  end)
 | 
						||
end)
 | 
						||
 | 
						||
describe('strcase_save()' , function()
 | 
						||
  local strcase_save = function(input_string, upper)
 | 
						||
    local res = strings.strcase_save(to_cstr(input_string), upper)
 | 
						||
    return ffi.string(res)
 | 
						||
  end
 | 
						||
 | 
						||
  itp('decodes overlong encoded characters.', function()
 | 
						||
    eq("A", strcase_save("\xc1\x81", true))
 | 
						||
    eq("a", strcase_save("\xc1\x81", false))
 | 
						||
  end)
 | 
						||
end)
 | 
						||
 | 
						||
describe("reverse_text", function()
 | 
						||
  local reverse_text = function(str)
 | 
						||
    return helpers.internalize(strings.reverse_text(to_cstr(str)))
 | 
						||
  end
 | 
						||
 | 
						||
  itp("handles empty string", function()
 | 
						||
    eq("", reverse_text(""))
 | 
						||
  end)
 | 
						||
 | 
						||
  itp("handles simple cases", function()
 | 
						||
    eq("a", reverse_text("a"))
 | 
						||
    eq("ba", reverse_text("ab"))
 | 
						||
  end)
 | 
						||
 | 
						||
  itp("handles multibyte characters", function()
 | 
						||
    eq("bα", reverse_text("αb"))
 | 
						||
    eq("Yötön yö", reverse_text("öy nötöY"))
 | 
						||
  end)
 | 
						||
 | 
						||
  itp("handles combining chars", function()
 | 
						||
    local utf8_COMBINING_RING_ABOVE = "\204\138"
 | 
						||
    local utf8_COMBINING_RING_BELOW = "\204\165"
 | 
						||
    eq("bba" .. utf8_COMBINING_RING_ABOVE .. utf8_COMBINING_RING_BELOW .. "aa",
 | 
						||
       reverse_text("aaa" .. utf8_COMBINING_RING_ABOVE .. utf8_COMBINING_RING_BELOW .. "bb"))
 | 
						||
  end)
 | 
						||
 | 
						||
  itp("treats invalid utf as separate characters", function()
 | 
						||
    eq("\192ba", reverse_text("ab\192"))
 | 
						||
  end)
 | 
						||
 | 
						||
  itp("treats an incomplete utf continuation sequence as valid", function()
 | 
						||
    eq("\194ba", reverse_text("ab\194"))
 | 
						||
  end)
 | 
						||
end)
 |