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); |       nr = prompt_for_number(false); | ||||||
|       msg_starthere(); |       msg_starthere(); | ||||||
|       if (nr > 0 && nr <= l->lv_len) { |       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) { |         if (p == NULL) { | ||||||
|           return; |           return; | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -731,7 +731,7 @@ listitem_T *tv_list_find(list_T *const l, int n) | |||||||
| ///                         `*ret_error` is not touched. | ///                         `*ret_error` is not touched. | ||||||
| /// | /// | ||||||
| /// @return Integer value at the given index or -1. | /// @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 |   FUNC_ATTR_WARN_UNUSED_RESULT | ||||||
| { | { | ||||||
|   const listitem_T *const li = tv_list_find(l, n); |   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); |   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]  l  List to index. | ||||||
| /// @param[in]  n  Index in a list. | /// @param[in]  n  Index in a list. | ||||||
| /// | /// | ||||||
| /// @return [allocated] Copy of the list item string value. | /// @return List item string value or NULL in case of error. | ||||||
| const char *tv_list_find_str(list_T *l, int n) | const char *tv_list_find_str(list_T *const l, const int n) | ||||||
|   FUNC_ATTR_MALLOC |   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) { |   if (li == NULL) { | ||||||
|     EMSGN(_(e_listidx), n); |     EMSGN(_(e_listidx), n); | ||||||
|     return NULL; |     return NULL; | ||||||
|   | |||||||
| @@ -8424,7 +8424,7 @@ eval_vars ( | |||||||
|           return NULL; |           return NULL; | ||||||
|         } |         } | ||||||
|         result = (char_u *)tv_list_find_str(get_vim_var_list(VV_OLDFILES), |         result = (char_u *)tv_list_find_str(get_vim_var_list(VV_OLDFILES), | ||||||
|                                             (long)i); |                                             i - 1); | ||||||
|         if (result == NULL) { |         if (result == NULL) { | ||||||
|           *errormsg = (char_u *)""; |           *errormsg = (char_u *)""; | ||||||
|           return NULL; |           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, |   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 { | return { | ||||||
|  |   int=int, | ||||||
|  |  | ||||||
|   null_string=null_string, |   null_string=null_string, | ||||||
|   null_list=null_list, |   null_list=null_list, | ||||||
|   null_dict=null_dict, |   null_dict=null_dict, | ||||||
|   | |||||||
| @@ -12,6 +12,7 @@ local to_cstr = helpers.to_cstr | |||||||
| local alloc_log_new = helpers.alloc_log_new | local alloc_log_new = helpers.alloc_log_new | ||||||
|  |  | ||||||
| local a = eval_helpers.alloc_logging_helpers | local a = eval_helpers.alloc_logging_helpers | ||||||
|  | local int = eval_helpers.int | ||||||
| local list = eval_helpers.list | local list = eval_helpers.list | ||||||
| local lst2tbl = eval_helpers.lst2tbl | local lst2tbl = eval_helpers.lst2tbl | ||||||
| local typvalt = eval_helpers.typvalt | local typvalt = eval_helpers.typvalt | ||||||
| @@ -1134,5 +1135,194 @@ describe('typval.c', function() | |||||||
|         eq(false, lib.tv_list_equal(l1, l9, true, false)) |         eq(false, lib.tv_list_equal(l1, l9, true, false)) | ||||||
|       end) |       end) | ||||||
|     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) | ||||||
| end) | end) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 ZyX
					ZyX