aboutsummaryrefslogtreecommitdiff
path: root/test/unit/eval/typval_spec.lua
diff options
context:
space:
mode:
authorZyX <kp-pav@yandex.ru>2016-09-24 00:51:34 +0300
committerZyX <kp-pav@yandex.ru>2017-03-29 10:08:06 +0300
commit7ceebacb3fad49ba8321397cf839948caa55b3f5 (patch)
tree4c7179f83001d9c7f0b25045e6779bc8df26b81e /test/unit/eval/typval_spec.lua
parent56e4c2f67e54b88f637d30e565313bc6b2c22f29 (diff)
downloadrneovim-7ceebacb3fad49ba8321397cf839948caa55b3f5.tar.gz
rneovim-7ceebacb3fad49ba8321397cf839948caa55b3f5.tar.bz2
rneovim-7ceebacb3fad49ba8321397cf839948caa55b3f5.zip
eval/typval,tests: Fix extending list with itself, add tests
Adds unit test for tv_list_extend and regression test for extend() VimL function.
Diffstat (limited to 'test/unit/eval/typval_spec.lua')
-rw-r--r--test/unit/eval/typval_spec.lua184
1 files changed, 158 insertions, 26 deletions
diff --git a/test/unit/eval/typval_spec.lua b/test/unit/eval/typval_spec.lua
index 2cc22053f3..926bf1c478 100644
--- a/test/unit/eval/typval_spec.lua
+++ b/test/unit/eval/typval_spec.lua
@@ -19,10 +19,9 @@ local type_key = eval_helpers.type_key
local li_alloc = eval_helpers.li_alloc
local int_type = eval_helpers.int_type
local first_di = eval_helpers.first_di
-local dict_type = eval_helpers.dict_type
-local list_type = eval_helpers.list_type
local null_list = eval_helpers.null_list
local null_dict = eval_helpers.null_dict
+local empty_list = eval_helpers.empty_list
local lua2typvalt = eval_helpers.lua2typvalt
local typvalt2lua = eval_helpers.typvalt2lua
local null_string = eval_helpers.null_string
@@ -168,7 +167,7 @@ describe('typval.c', function()
eq(1, l.lv_refcount)
li = li_alloc(true)
- tv = lua2typvalt({[type_key]=dict_type})
+ tv = lua2typvalt({})
tv.vval.v_dict.dv_refcount = 2
li.li_tv = tv
lib.tv_list_item_free(li)
@@ -290,8 +289,8 @@ describe('typval.c', function()
describe('alloc()/free()', function()
itp('recursively frees list with', function()
local l1 = ffi.gc(list(1, 'abc'), nil)
- local l2 = ffi.gc(list({[type_key]=dict_type}), nil)
- local l3 = ffi.gc(list({[type_key]=list_type}), nil)
+ local l2 = ffi.gc(list({}), nil)
+ local l3 = ffi.gc(list(empty_list), nil)
local alloc_rets = {}
alloc_log:check(get_alloc_rets({
a.list(l1),
@@ -325,8 +324,8 @@ describe('typval.c', function()
alloc_rets:freed(8),
})
end)
- itp('frees all containers inside a list', function()
- local l1 = ffi.gc(list('abc', {[type_key]=dict_type}, {[type_key]=list_type}), nil)
+ itp('does not free container items with recurse=false', function()
+ local l1 = ffi.gc(list('abc', {}, empty_list), nil)
local alloc_rets = {}
alloc_log:check(get_alloc_rets({
a.list(l1),
@@ -351,7 +350,7 @@ describe('typval.c', function()
end)
describe('unref()', function()
itp('recursively frees list when reference count goes to 0', function()
- local l = ffi.gc(list({[type_key]=list_type}), nil)
+ local l = ffi.gc(list(empty_list), nil)
local alloc_rets = {}
alloc_log:check(get_alloc_rets({
a.list(l),
@@ -395,7 +394,7 @@ describe('typval.c', function()
eq({lis[4], lis[9], nil}, {lws[1].lw_item, lws[2].lw_item, lws[3].lw_item == nil and nil})
lib.tv_list_remove_items(l, lis[4], lis[10])
- eq({[type_key]=list_type}, typvalt2lua(l_tv))
+ eq(empty_list, typvalt2lua(l_tv))
eq({true, true, true}, {lws[1].lw_item == nil, lws[2].lw_item == nil, lws[3].lw_item == nil})
alloc_log:check({})
@@ -428,7 +427,7 @@ describe('typval.c', function()
eq({0, 1, 2, 3, 4, 4.5, 5, 6, 7, 100500}, typvalt2lua(l_tv))
end)
itp('works with an empty list', function()
- local l_tv = lua2typvalt({[type_key]=list_type})
+ local l_tv = lua2typvalt(empty_list)
local l = l_tv.vval.v_list
eq(nil, l.lv_first)
@@ -443,10 +442,10 @@ describe('typval.c', function()
end)
describe('tv()', function()
itp('works', function()
- local l_tv = lua2typvalt({[type_key]=list_type})
+ local l_tv = lua2typvalt(empty_list)
local l = l_tv.vval.v_list
- local l_l_tv = lua2typvalt({[type_key]=list_type})
+ local l_l_tv = lua2typvalt(empty_list)
alloc_log:clear()
local l_l = l_l_tv.vval.v_list
eq(1, l_l.lv_refcount)
@@ -467,14 +466,14 @@ describe('typval.c', function()
a.str(l.lv_first.li_tv.vval.v_string, 'test'),
})
- eq({'test', {[type_key]=list_type}}, typvalt2lua(l_tv))
+ eq({'test', empty_list}, typvalt2lua(l_tv))
end)
end)
end)
describe('append', function()
describe('list()', function()
itp('works', function()
- local l_tv = lua2typvalt({[type_key]=list_type})
+ local l_tv = lua2typvalt(empty_list)
local l = l_tv.vval.v_list
local l_l = list(1)
@@ -497,7 +496,7 @@ describe('typval.c', function()
end)
describe('dict()', function()
itp('works', function()
- local l_tv = lua2typvalt({[type_key]=list_type})
+ local l_tv = lua2typvalt(empty_list)
local l = l_tv.vval.v_list
local l_d_tv = lua2typvalt({test=1})
@@ -521,7 +520,7 @@ describe('typval.c', function()
end)
describe('string()', function()
itp('works', function()
- local l_tv = lua2typvalt({[type_key]=list_type})
+ local l_tv = lua2typvalt(empty_list)
local l = l_tv.vval.v_list
alloc_log:clear()
@@ -552,7 +551,7 @@ describe('typval.c', function()
end)
describe('allocated string()', function()
itp('works', function()
- local l_tv = lua2typvalt({[type_key]=list_type})
+ local l_tv = lua2typvalt(empty_list)
local l = l_tv.vval.v_list
local s = lib.xstrdup('test')
@@ -577,7 +576,7 @@ describe('typval.c', function()
end)
describe('number()', function()
itp('works', function()
- local l_tv = lua2typvalt({[type_key]=list_type})
+ local l_tv = lua2typvalt(empty_list)
local l = l_tv.vval.v_list
alloc_log:clear()
@@ -710,7 +709,7 @@ describe('typval.c', function()
})
end)
itp('returns different/same containers with(out) copyID', function()
- local l_inner_tv = lua2typvalt({[type_key]=list_type})
+ local l_inner_tv = lua2typvalt(empty_list)
local l_tv = lua2typvalt({l_inner_tv, l_inner_tv})
eq(3, l_inner_tv.vval.v_list.lv_refcount)
local l = l_tv.vval.v_list
@@ -718,16 +717,16 @@ describe('typval.c', function()
local l_copy1 = tv_list_copy(nil, l, true, 0)
neq(l_copy1.lv_first.li_tv.vval.v_list, l_copy1.lv_last.li_tv.vval.v_list)
- eq({{[type_key]=list_type}, {[type_key]=list_type}}, lst2tbl(l_copy1))
+ eq({empty_list, empty_list}, lst2tbl(l_copy1))
local l_copy2 = tv_list_copy(nil, l, true, 2)
eq(l_copy2.lv_first.li_tv.vval.v_list, l_copy2.lv_last.li_tv.vval.v_list)
- eq({{[type_key]=list_type}, {[type_key]=list_type}}, lst2tbl(l_copy2))
+ eq({empty_list, empty_list}, lst2tbl(l_copy2))
eq(3, l_inner_tv.vval.v_list.lv_refcount)
end)
itp('works with self-referencing list with copyID', function()
- local l_tv = lua2typvalt({[type_key]=list_type})
+ local l_tv = lua2typvalt(empty_list)
local l = l_tv.vval.v_list
eq(1, l.lv_refcount)
lib.tv_list_append_list(l, l)
@@ -748,6 +747,139 @@ describe('typval.c', function()
eq(1, l_copy1.lv_refcount)
end)
end)
+ describe('extend()', function()
+ itp('can extend list with itself', function()
+ local l
+
+ l = list(1, {})
+ alloc_log:clear()
+ eq(1, l.lv_refcount)
+ eq(1, l.lv_last.li_tv.vval.v_dict.dv_refcount)
+
+ lib.tv_list_extend(l, l, nil)
+ alloc_log:check({
+ a.li(l.lv_last.li_prev),
+ a.li(l.lv_last),
+ })
+ eq(1, l.lv_refcount)
+ eq(2, l.lv_last.li_tv.vval.v_dict.dv_refcount)
+ eq({1, {}, 1, {}}, lst2tbl(l))
+
+ l = list(1, {})
+ alloc_log:clear()
+ eq(1, l.lv_refcount)
+ eq(1, l.lv_last.li_tv.vval.v_dict.dv_refcount)
+
+ lib.tv_list_extend(l, l, l.lv_last)
+ alloc_log:check({
+ a.li(l.lv_last.li_prev.li_prev),
+ a.li(l.lv_last.li_prev),
+ })
+ eq({1, 1, {}, {}}, lst2tbl(l))
+ eq(1, l.lv_refcount)
+ eq(2, l.lv_last.li_tv.vval.v_dict.dv_refcount)
+
+ l = list(1, {})
+ alloc_log:clear()
+ eq(1, l.lv_refcount)
+ eq(1, l.lv_last.li_tv.vval.v_dict.dv_refcount)
+
+ lib.tv_list_extend(l, l, l.lv_first)
+ alloc_log:check({
+ a.li(l.lv_first),
+ a.li(l.lv_first.li_next),
+ })
+ eq({1, {}, 1, {}}, lst2tbl(l))
+ eq(1, l.lv_refcount)
+ eq(2, l.lv_last.li_tv.vval.v_dict.dv_refcount)
+ end)
+ itp('can extend list with an empty list', function()
+ local l = list(1, {})
+ local el = list()
+ alloc_log:clear()
+ eq(1, l.lv_refcount)
+ eq(1, l.lv_last.li_tv.vval.v_dict.dv_refcount)
+ eq(1, el.lv_refcount)
+
+ lib.tv_list_extend(l, el, nil)
+ alloc_log:check({
+ })
+ eq(1, l.lv_refcount)
+ eq(1, l.lv_last.li_tv.vval.v_dict.dv_refcount)
+ eq(1, el.lv_refcount)
+ eq({1, {}}, lst2tbl(l))
+
+ lib.tv_list_extend(l, el, l.lv_first)
+ alloc_log:check({
+ })
+ eq(1, l.lv_refcount)
+ eq(1, l.lv_last.li_tv.vval.v_dict.dv_refcount)
+ eq(1, el.lv_refcount)
+ eq({1, {}}, lst2tbl(l))
+
+ lib.tv_list_extend(l, el, l.lv_last)
+ alloc_log:check({
+ })
+ eq(1, l.lv_refcount)
+ eq(1, l.lv_last.li_tv.vval.v_dict.dv_refcount)
+ eq(1, el.lv_refcount)
+ eq({1, {}}, lst2tbl(l))
+ end)
+ itp('can extend list with another non-empty list', function()
+ local l
+ local l2 = list(42, empty_list)
+ eq(1, l2.lv_refcount)
+ eq(1, l2.lv_last.li_tv.vval.v_list.lv_refcount)
+
+ l = ffi.gc(list(1, {}), nil)
+ alloc_log:clear()
+ eq(1, l.lv_refcount)
+ eq(1, l.lv_last.li_tv.vval.v_dict.dv_refcount)
+
+ lib.tv_list_extend(l, l2, nil)
+ alloc_log:check({
+ a.li(l.lv_last.li_prev),
+ a.li(l.lv_last),
+ })
+ eq(1, l2.lv_refcount)
+ eq(2, l2.lv_last.li_tv.vval.v_list.lv_refcount)
+ eq({1, {}, 42, empty_list}, lst2tbl(l))
+ lib.tv_list_free(l)
+ eq(1, l2.lv_last.li_tv.vval.v_list.lv_refcount)
+
+ l = ffi.gc(list(1, {}), nil)
+ alloc_log:clear()
+ eq(1, l.lv_refcount)
+ eq(1, l.lv_last.li_tv.vval.v_dict.dv_refcount)
+
+ lib.tv_list_extend(l, l2, l.lv_first)
+ alloc_log:check({
+ a.li(l.lv_first),
+ a.li(l.lv_first.li_next),
+ })
+ eq(1, l2.lv_refcount)
+ eq(2, l2.lv_last.li_tv.vval.v_list.lv_refcount)
+ eq({42, empty_list, 1, {}}, lst2tbl(l))
+ lib.tv_list_free(l)
+ eq(1, l2.lv_last.li_tv.vval.v_list.lv_refcount)
+
+ l = ffi.gc(list(1, {}), nil)
+ alloc_log:clear()
+ eq(1, l.lv_refcount)
+ eq(1, l.lv_last.li_tv.vval.v_dict.dv_refcount)
+
+ lib.tv_list_extend(l, l2, l.lv_last)
+ alloc_log:check({
+ a.li(l.lv_first.li_next),
+ a.li(l.lv_first.li_next.li_next),
+ })
+ eq(1, l2.lv_refcount)
+ eq(2, l2.lv_last.li_tv.vval.v_list.lv_refcount)
+ eq({1, 42, empty_list, {}}, lst2tbl(l))
+ lib.tv_list_free(l)
+ eq(1, l2.lv_last.li_tv.vval.v_list.lv_refcount)
+ end)
+ end)
describe('concat()', function()
itp('works with NULL lists', function()
local l = list(1, {})
@@ -789,7 +921,7 @@ describe('typval.c', function()
end)
itp('works with two different lists', function()
local l1 = list(1, {})
- local l2 = list(3, {[type_key]=list_type})
+ local l2 = list(3, empty_list)
eq(1, l1.lv_refcount)
eq(1, l1.lv_last.li_tv.vval.v_dict.dv_refcount)
eq(1, l2.lv_refcount)
@@ -809,7 +941,7 @@ describe('typval.c', function()
a.li(rettv.vval.v_list.lv_last.li_prev),
a.li(rettv.vval.v_list.lv_last),
})
- eq({1, {}, 3, {[type_key]=list_type}}, typvalt2lua(rettv))
+ eq({1, {}, 3, empty_list}, typvalt2lua(rettv))
end)
itp('can concatenate list with itself', function()
local l = list(1, {})
@@ -875,7 +1007,7 @@ describe('typval.c', function()
alloc_log:check({
a.list(rettv3.vval.v_list),
})
- eq({[type_key]=list_type}, typvalt2lua(rettv3))
+ eq(empty_list, typvalt2lua(rettv3))
local rettv4 = typvalt()
eq(OK, lib.tv_list_concat(le, le2, rettv4))
@@ -886,7 +1018,7 @@ describe('typval.c', function()
alloc_log:check({
a.list(rettv4.vval.v_list),
})
- eq({[type_key]=list_type}, typvalt2lua(rettv4))
+ eq(empty_list, typvalt2lua(rettv4))
end)
end)
end)