mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +00:00 
			
		
		
		
	unittests: Add tests for tv_list_find*() functions
Additional modifications: - More `const` qualifiers in tested functions. - `tv_list_find_str()` second argument is more in-line with other `tv_list_find*()` functions.
This commit is contained in:
		| @@ -21783,7 +21783,7 @@ void ex_oldfiles(exarg_T *eap) | ||||
|       nr = prompt_for_number(false); | ||||
|       msg_starthere(); | ||||
|       if (nr > 0 && nr <= l->lv_len) { | ||||
|         const char *const p = tv_list_find_str(l, nr); | ||||
|         const char *const p = tv_list_find_str(l, nr - 1); | ||||
|         if (p == NULL) { | ||||
|           return; | ||||
|         } | ||||
|   | ||||
| @@ -731,7 +731,7 @@ listitem_T *tv_list_find(list_T *const l, int n) | ||||
| ///                         `*ret_error` is not touched. | ||||
| /// | ||||
| /// @return Integer value at the given index or -1. | ||||
| varnumber_T tv_list_find_nr(list_T *const l, const int n, bool *ret_error) | ||||
| varnumber_T tv_list_find_nr(list_T *const l, const int n, bool *const ret_error) | ||||
|   FUNC_ATTR_WARN_UNUSED_RESULT | ||||
| { | ||||
|   const listitem_T *const li = tv_list_find(l, n); | ||||
| @@ -744,16 +744,16 @@ varnumber_T tv_list_find_nr(list_T *const l, const int n, bool *ret_error) | ||||
|   return tv_get_number_chk(&li->li_tv, ret_error); | ||||
| } | ||||
|  | ||||
| /// Get list item l[n - 1] as a string | ||||
| /// Get list item l[n] as a string | ||||
| /// | ||||
| /// @param[in]  l  List to index. | ||||
| /// @param[in]  n  Index in a list. | ||||
| /// | ||||
| /// @return [allocated] Copy of the list item string value. | ||||
| const char *tv_list_find_str(list_T *l, int n) | ||||
|   FUNC_ATTR_MALLOC | ||||
| /// @return List item string value or NULL in case of error. | ||||
| const char *tv_list_find_str(list_T *const l, const int n) | ||||
|   FUNC_ATTR_WARN_UNUSED_RESULT | ||||
| { | ||||
|   const listitem_T *const li = tv_list_find(l, n - 1); | ||||
|   const listitem_T *const li = tv_list_find(l, n); | ||||
|   if (li == NULL) { | ||||
|     EMSGN(_(e_listidx), n); | ||||
|     return NULL; | ||||
|   | ||||
| @@ -8424,7 +8424,7 @@ eval_vars ( | ||||
|           return NULL; | ||||
|         } | ||||
|         result = (char_u *)tv_list_find_str(get_vim_var_list(VV_OLDFILES), | ||||
|                                             (long)i); | ||||
|                                             i - 1); | ||||
|         if (result == NULL) { | ||||
|           *errormsg = (char_u *)""; | ||||
|           return NULL; | ||||
|   | ||||
| @@ -405,7 +405,13 @@ local alloc_logging_helpers = { | ||||
|   freed = function(p) return {func='free', args={type(p) == 'table' and p or void(p)}} end, | ||||
| } | ||||
|  | ||||
| local function int(n) | ||||
|   return {[type_key]=int_type, value=n} | ||||
| end | ||||
|  | ||||
| return { | ||||
|   int=int, | ||||
|  | ||||
|   null_string=null_string, | ||||
|   null_list=null_list, | ||||
|   null_dict=null_dict, | ||||
|   | ||||
| @@ -12,6 +12,7 @@ local to_cstr = helpers.to_cstr | ||||
| local alloc_log_new = helpers.alloc_log_new | ||||
|  | ||||
| local a = eval_helpers.alloc_logging_helpers | ||||
| local int = eval_helpers.int | ||||
| local list = eval_helpers.list | ||||
| local lst2tbl = eval_helpers.lst2tbl | ||||
| local typvalt = eval_helpers.typvalt | ||||
| @@ -1134,5 +1135,194 @@ describe('typval.c', function() | ||||
|         eq(false, lib.tv_list_equal(l1, l9, true, false)) | ||||
|       end) | ||||
|     end) | ||||
|     describe('find', function() | ||||
|       describe('()', function() | ||||
|         itp('correctly indexes list', function() | ||||
|           local l = list(1, 2, 3, 4, 5) | ||||
|           local lis = list_items(l) | ||||
|           clear_alloc_log() | ||||
|  | ||||
|           eq(nil, lib.tv_list_find(nil, -1)) | ||||
|           eq(nil, lib.tv_list_find(nil, 0)) | ||||
|           eq(nil, lib.tv_list_find(nil, 1)) | ||||
|  | ||||
|           eq(nil, lib.tv_list_find(l, 5)) | ||||
|           eq(nil, lib.tv_list_find(l, -6)) | ||||
|           eq(lis[1], lib.tv_list_find(l, -5)) | ||||
|           eq(lis[5], lib.tv_list_find(l, 4)) | ||||
|           eq(lis[3], lib.tv_list_find(l, 2)) | ||||
|           eq(lis[3], lib.tv_list_find(l, -3)) | ||||
|           eq(lis[3], lib.tv_list_find(l, 2)) | ||||
|           eq(lis[3], lib.tv_list_find(l, 2)) | ||||
|           eq(lis[3], lib.tv_list_find(l, -3)) | ||||
|  | ||||
|           l.lv_idx_item = nil | ||||
|           eq(lis[1], lib.tv_list_find(l, -5)) | ||||
|           l.lv_idx_item = nil | ||||
|           eq(lis[5], lib.tv_list_find(l, 4)) | ||||
|           l.lv_idx_item = nil | ||||
|           eq(lis[3], lib.tv_list_find(l, 2)) | ||||
|           l.lv_idx_item = nil | ||||
|           eq(lis[3], lib.tv_list_find(l, -3)) | ||||
|           l.lv_idx_item = nil | ||||
|           eq(lis[3], lib.tv_list_find(l, 2)) | ||||
|           l.lv_idx_item = nil | ||||
|           eq(lis[3], lib.tv_list_find(l, 2)) | ||||
|           l.lv_idx_item = nil | ||||
|           eq(lis[3], lib.tv_list_find(l, -3)) | ||||
|  | ||||
|           l.lv_idx_item = nil | ||||
|           eq(lis[3], lib.tv_list_find(l, 2)) | ||||
|           eq(lis[1], lib.tv_list_find(l, -5)) | ||||
|           eq(lis[3], lib.tv_list_find(l, 2)) | ||||
|           eq(lis[5], lib.tv_list_find(l, 4)) | ||||
|           eq(lis[3], lib.tv_list_find(l, 2)) | ||||
|           eq(lis[3], lib.tv_list_find(l, 2)) | ||||
|           eq(lis[3], lib.tv_list_find(l, 2)) | ||||
|           eq(lis[3], lib.tv_list_find(l, -3)) | ||||
|           eq(lis[3], lib.tv_list_find(l, 2)) | ||||
|           eq(lis[3], lib.tv_list_find(l, 2)) | ||||
|           eq(lis[3], lib.tv_list_find(l, 2)) | ||||
|           eq(lis[3], lib.tv_list_find(l, -3)) | ||||
|  | ||||
|           check_alloc_log({}) | ||||
|         end) | ||||
|       end) | ||||
|       local function check_emsg(f, msg) | ||||
|         local saved_last_msg_hist = lib.last_msg_hist | ||||
|         local ret = {f()} | ||||
|         if msg ~= nil then | ||||
|           neq(saved_last_msg_hist, lib.last_msg_hist) | ||||
|           eq(msg, ffi.string(lib.last_msg_hist.msg)) | ||||
|         else | ||||
|           eq(saved_last_msg_hist, lib.last_msg_hist) | ||||
|         end | ||||
|         return unpack(ret) | ||||
|       end | ||||
|       describe('nr()', function() | ||||
|         local function tv_list_find_nr(l, n, msg) | ||||
|           return check_emsg(function() | ||||
|             local err = ffi.new('bool[1]', {false}) | ||||
|             local ret = lib.tv_list_find_nr(l, n, err) | ||||
|             return (err[0] == true), ret | ||||
|           end, msg) | ||||
|         end | ||||
|         it('returns correct number', function() | ||||
|           local l = list(int(1), int(2), int(3), int(4), int(5)) | ||||
|           clear_alloc_log() | ||||
|  | ||||
|           eq({false, 1}, {tv_list_find_nr(l, -5)}) | ||||
|           eq({false, 5}, {tv_list_find_nr(l, 4)}) | ||||
|           eq({false, 3}, {tv_list_find_nr(l, 2)}) | ||||
|           eq({false, 3}, {tv_list_find_nr(l, -3)}) | ||||
|  | ||||
|           check_alloc_log({}) | ||||
|         end) | ||||
|         it('returns correct number when given a string', function() | ||||
|           local l = list('1', '2', '3', '4', '5') | ||||
|           clear_alloc_log() | ||||
|  | ||||
|           eq({false, 1}, {tv_list_find_nr(l, -5)}) | ||||
|           eq({false, 5}, {tv_list_find_nr(l, 4)}) | ||||
|           eq({false, 3}, {tv_list_find_nr(l, 2)}) | ||||
|           eq({false, 3}, {tv_list_find_nr(l, -3)}) | ||||
|  | ||||
|           check_alloc_log({}) | ||||
|         end) | ||||
|         it('returns zero when given a NULL string', function() | ||||
|           local l = list(null_string) | ||||
|           clear_alloc_log() | ||||
|  | ||||
|           eq({false, 0}, {tv_list_find_nr(l, 0)}) | ||||
|  | ||||
|           check_alloc_log({}) | ||||
|         end) | ||||
|         it('errors out on NULL lists', function() | ||||
|           eq({true, -1}, {tv_list_find_nr(nil, -5)}) | ||||
|           eq({true, -1}, {tv_list_find_nr(nil, 4)}) | ||||
|           eq({true, -1}, {tv_list_find_nr(nil, 2)}) | ||||
|           eq({true, -1}, {tv_list_find_nr(nil, -3)}) | ||||
|  | ||||
|           check_alloc_log({}) | ||||
|         end) | ||||
|         it('errors out on out-of-range indexes', function() | ||||
|           local l = list(int(1), int(2), int(3), int(4), int(5)) | ||||
|           clear_alloc_log() | ||||
|  | ||||
|           eq({true, -1}, {tv_list_find_nr(l, -6)}) | ||||
|           eq({true, -1}, {tv_list_find_nr(l, 5)}) | ||||
|  | ||||
|           check_alloc_log({}) | ||||
|         end) | ||||
|         it('errors out on invalid types', function() | ||||
|           local l = list(1, empty_list, {}) | ||||
|  | ||||
|           eq({true, 0}, {tv_list_find_nr(l, 0, 'E805: Using a Float as a Number')}) | ||||
|           eq({true, 0}, {tv_list_find_nr(l, 1, 'E745: Using a List as a Number')}) | ||||
|           eq({true, 0}, {tv_list_find_nr(l, 2, 'E728: Using a Dictionary as a Number')}) | ||||
|           eq({true, 0}, {tv_list_find_nr(l, -1, 'E728: Using a Dictionary as a Number')}) | ||||
|           eq({true, 0}, {tv_list_find_nr(l, -2, 'E745: Using a List as a Number')}) | ||||
|           eq({true, 0}, {tv_list_find_nr(l, -3, 'E805: Using a Float as a Number')}) | ||||
|         end) | ||||
|       end) | ||||
|       local function tv_list_find_str(l, n, msg) | ||||
|         return check_emsg(function() | ||||
|           local ret = lib.tv_list_find_str(l, n) | ||||
|           local s = nil | ||||
|           if ret ~= nil then | ||||
|             s = ffi.string(ret) | ||||
|           end | ||||
|           return s | ||||
|         end, msg) | ||||
|       end | ||||
|       describe('str()', function() | ||||
|         it('returns correct string', function() | ||||
|           local l = list(int(1), int(2), int(3), int(4), int(5)) | ||||
|           clear_alloc_log() | ||||
|  | ||||
|           eq('1', tv_list_find_str(l, -5)) | ||||
|           eq('5', tv_list_find_str(l, 4)) | ||||
|           eq('3', tv_list_find_str(l, 2)) | ||||
|           eq('3', tv_list_find_str(l, -3)) | ||||
|  | ||||
|           check_alloc_log({}) | ||||
|         end) | ||||
|         it('returns string when used with VAR_STRING items', function() | ||||
|           local l = list('1', '2', '3', '4', '5') | ||||
|           clear_alloc_log() | ||||
|  | ||||
|           eq('1', tv_list_find_str(l, -5)) | ||||
|           eq('5', tv_list_find_str(l, 4)) | ||||
|           eq('3', tv_list_find_str(l, 2)) | ||||
|           eq('3', tv_list_find_str(l, -3)) | ||||
|  | ||||
|           check_alloc_log({}) | ||||
|         end) | ||||
|         it('returns empty when used with NULL string', function() | ||||
|           local l = list(null_string) | ||||
|           clear_alloc_log() | ||||
|  | ||||
|           eq('', tv_list_find_str(l, 0)) | ||||
|  | ||||
|           check_alloc_log({}) | ||||
|         end) | ||||
|         it('fails with error message when index is out of range', function() | ||||
|           local l = list(int(1), int(2), int(3), int(4), int(5)) | ||||
|  | ||||
|           eq(nil, tv_list_find_str(l, -6, 'E684: list index out of range: -6')) | ||||
|           eq(nil, tv_list_find_str(l, 5, 'E684: list index out of range: 5')) | ||||
|         end) | ||||
|         it('fails with error message on invalid types', function() | ||||
|           local l = list(1, empty_list, {}) | ||||
|  | ||||
|           eq('', tv_list_find_str(l, 0, 'E806: using Float as a String')) | ||||
|           eq('', tv_list_find_str(l, 1, 'E730: using List as a String')) | ||||
|           eq('', tv_list_find_str(l, 2, 'E731: using Dictionary as a String')) | ||||
|           eq('', tv_list_find_str(l, -1, 'E731: using Dictionary as a String')) | ||||
|           eq('', tv_list_find_str(l, -2, 'E730: using List as a String')) | ||||
|           eq('', tv_list_find_str(l, -3, 'E806: using Float as a String')) | ||||
|         end) | ||||
|       end) | ||||
|     end) | ||||
|   end) | ||||
| end) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 ZyX
					ZyX