Merge pull request #29483 from bfredl/nonbinary

refactor(typval)!: remove binary distinction of binary and nonbinary strings
This commit is contained in:
bfredl 2024-06-27 18:45:18 +02:00 committed by GitHub
commit 46187117c9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 137 additions and 269 deletions

View File

@ -361,7 +361,7 @@ endfunction
let s:MSGPACK_STANDARD_TYPES = {
\type(0): 'integer',
\type(0.0): 'float',
\type(''): 'binary',
\type(''): 'string',
\type([]): 'array',
\type({}): 'map',
\type(v:true): 'boolean',
@ -412,9 +412,15 @@ endfunction
""
" Dump |msgpack-special-dict| that represents a string. If any additional
" parameter is given then it dumps binary string.
function s:msgpack_dump_string(v, ...) abort
let ret = [a:0 ? '"' : '="']
for v in a:v._VAL
function s:msgpack_dump_string(v) abort
if type(a:v) == type({})
let val = a:v
else
let val = {'_VAL': split(a:v, "\n", 1)}
end
let ret = ['"']
for v in val._VAL
call add(
\ret,
\substitute(
@ -426,16 +432,6 @@ function s:msgpack_dump_string(v, ...) abort
return join(ret, '')
endfunction
""
" Dump binary string.
function s:msgpack_dump_binary(v) abort
if type(a:v) == type({})
return s:msgpack_dump_string(a:v, 1)
else
return s:msgpack_dump_string({'_VAL': split(a:v, "\n", 1)}, 1)
endif
endfunction
""
" Dump array value.
function s:msgpack_dump_array(v) abort
@ -449,7 +445,7 @@ function s:msgpack_dump_map(v) abort
let ret = ['{']
if msgpack#special_type(a:v) is 0
for [k, v] in items(a:v)
let ret += [s:msgpack_dump_string({'_VAL': split(k, "\n", 1)}),
let ret += [s:msgpack_dump_string({'_VAL': split(k, "\n")}),
\': ',
\msgpack#string(v),
\', ']
@ -479,7 +475,7 @@ endfunction
" Dump extension value.
function s:msgpack_dump_ext(v) abort
return printf('+(%i)%s', a:v._VAL[0],
\s:msgpack_dump_string({'_VAL': a:v._VAL[1]}, 1))
\s:msgpack_dump_string({'_VAL': a:v._VAL[1]}))
endfunction
""
@ -619,9 +615,7 @@ function msgpack#eval(s, special_objs) abort
throw '"-invalid:Invalid string: ' . s
endif
call add(expr, '{''_TYPE'': v:msgpack_types.')
if empty(match[1])
call add(expr, 'binary')
elseif match[1] is# '='
if empty(match[1]) || match[1] is# '='
call add(expr, 'string')
else
call add(expr, 'ext')
@ -772,7 +766,7 @@ function msgpack#equal(a, b)
let a = aspecial is 0 ? a:a : a:a._VAL
let b = bspecial is 0 ? a:b : a:b._VAL
return msgpack#equal(a, b)
elseif atype is# 'binary'
elseif atype is# 'string'
let a = (aspecial is 0 ? split(a:a, "\n", 1) : a:a._VAL)
let b = (bspecial is 0 ? split(a:b, "\n", 1) : a:b._VAL)
return a ==# b
@ -787,13 +781,17 @@ function msgpack#equal(a, b)
" Non-special mapping cannot have non-string keys
return 0
endif
if (empty(k._VAL)
\|| k._VAL ==# [""]
\|| !empty(filter(copy(k._VAL), 'stridx(v:val, "\n") != -1')))
" Non-special mapping cannot have zero byte in key or an empty key
return 0
if type(k) == type({})
if (empty(k._VAL)
\|| k._VAL ==# [""]
\|| !empty(filter(copy(k._VAL), 'stridx(v:val, "\n") != -1')))
" Non-special mapping cannot have zero byte in key or an empty key
return 0
endif
let kstr = join(k._VAL, "\n")
else
let kstr = k
endif
let kstr = join(k._VAL, "\n")
if !has_key(akeys, kstr)
" Protects from both missing and duplicate keys
return 0

View File

@ -230,7 +230,7 @@ function s:shada_check_type(type, val) abort
return 0
elseif a:type is# 'bin'
" Binary string without zero bytes
if type isnot# 'binary'
if type isnot# 'string'
return 'Expected binary string'
elseif (type(a:val) == type({})
\&& !empty(filter(copy(a:val._VAL), 'stridx(v:val, "\n") != -1')))
@ -247,7 +247,7 @@ function s:shada_check_type(type, val) abort
if type isnot# 'array'
return 'Expected array value'
elseif !empty(filter(copy(type(a:val) == type({}) ? a:val._VAL : a:val),
\'msgpack#type(v:val) isnot# "binary"'))
\'msgpack#type(v:val) isnot# "string"'))
return 'Expected array of binary strings'
else
for element in (type(a:val) == type({}) ? a:val._VAL : a:val)

View File

@ -5152,12 +5152,7 @@ msgpackparse({data}) *msgpackparse()*
C parser does not support such values.
float |Float|. This value cannot possibly appear in
|msgpackparse()| output.
string |readfile()|-style list of strings. This value will
appear in |msgpackparse()| output if string contains
zero byte or if string is a mapping key and mapping is
being represented as special dictionary for other
reasons.
binary |String|, or |Blob| if binary string contains zero
string |String|, or |Blob| if binary string contains zero
byte. This value cannot appear in |msgpackparse()|
output since blobs were introduced.
array |List|. This value cannot appear in |msgpackparse()|

View File

@ -50,6 +50,12 @@ EDITOR
• |hl-CurSearch| now behaves the same as Vim and no longer updates on every
cursor movement.
VIM SCRIPT
• |v:msgpack_types| has the type "binary" removed. |msgpackparse()| no longer
treats BIN, STR and FIXSTR as separate types. Any of these is returned as a
string if possible, or a |blob| if the value contained embedded NUL:s.
EVENTS
• TODO

View File

@ -6177,12 +6177,7 @@ function vim.fn.msgpackdump(list, type) end
--- C parser does not support such values.
--- float |Float|. This value cannot possibly appear in
--- |msgpackparse()| output.
--- string |readfile()|-style list of strings. This value will
--- appear in |msgpackparse()| output if string contains
--- zero byte or if string is a mapping key and mapping is
--- being represented as special dictionary for other
--- reasons.
--- binary |String|, or |Blob| if binary string contains zero
--- string |String|, or |Blob| if binary string contains zero
--- byte. This value cannot appear in |msgpackparse()|
--- output since blobs were introduced.
--- array |List|. This value cannot appear in |msgpackparse()|

View File

@ -7,7 +7,9 @@
#include "nvim/api/private/converter.h"
#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
#include "nvim/ascii_defs.h"
#include "nvim/assert_defs.h"
#include "nvim/eval/decode.h"
#include "nvim/eval/typval.h"
#include "nvim/eval/typval_defs.h"
#include "nvim/eval/userfunc.h"
@ -302,15 +304,11 @@ void object_to_vim_take_luaref(Object *obj, typval_T *tv, bool take_luaref, Erro
tv->vval.v_float = obj->data.floating;
break;
case kObjectTypeString:
tv->v_type = VAR_STRING;
if (obj->data.string.data == NULL) {
tv->vval.v_string = NULL;
} else {
tv->vval.v_string = xmemdupz(obj->data.string.data,
obj->data.string.size);
}
case kObjectTypeString: {
String s = obj->data.string;
*tv = decode_string(s.data, s.size, false, false);
break;
}
case kObjectTypeArray: {
list_T *const list = tv_list_alloc((ptrdiff_t)obj->data.array.size);

View File

@ -331,7 +331,6 @@ static const char *const msgpack_type_names[] = {
[kMPInteger] = "integer",
[kMPFloat] = "float",
[kMPString] = "string",
[kMPBinary] = "binary",
[kMPArray] = "array",
[kMPMap] = "map",
[kMPExt] = "ext",
@ -342,7 +341,6 @@ const list_T *eval_msgpack_type_lists[] = {
[kMPInteger] = NULL,
[kMPFloat] = NULL,
[kMPString] = NULL,
[kMPBinary] = NULL,
[kMPArray] = NULL,
[kMPMap] = NULL,
[kMPExt] = NULL,

View File

@ -7444,12 +7444,7 @@ M.funcs = {
C parser does not support such values.
float |Float|. This value cannot possibly appear in
|msgpackparse()| output.
string |readfile()|-style list of strings. This value will
appear in |msgpackparse()| output if string contains
zero byte or if string is a mapping key and mapping is
being represented as special dictionary for other
reasons.
binary |String|, or |Blob| if binary string contains zero
string |String|, or |Blob| if binary string contains zero
byte. This value cannot appear in |msgpackparse()|
output since blobs were introduced.
array |List|. This value cannot appear in |msgpackparse()|

View File

@ -247,45 +247,29 @@ list_T *decode_create_map_special_dict(typval_T *const ret_tv, const ptrdiff_t l
///
/// @param[in] s String to decode.
/// @param[in] len String length.
/// @param[in] hasnul Whether string has NUL byte, not or it was not yet
/// determined.
/// @param[in] binary Determines decode type if string has NUL bytes.
/// If true convert string to VAR_BLOB, otherwise to the
/// kMPString special type.
/// @param[in] force_blob whether string always should be decoded as a blob,
/// or only when embedded NUL bytes were present
/// @param[in] s_allocated If true, then `s` was allocated and can be saved in
/// a returned structure. If it is not saved there, it
/// will be freed.
///
/// @return Decoded string.
typval_T decode_string(const char *const s, const size_t len, const TriState hasnul,
const bool binary, const bool s_allocated)
typval_T decode_string(const char *const s, const size_t len, bool force_blob,
const bool s_allocated)
FUNC_ATTR_WARN_UNUSED_RESULT
{
assert(s != NULL || len == 0);
const bool really_hasnul = (hasnul == kNone
? ((s != NULL) && (memchr(s, NUL, len) != NULL))
: (bool)hasnul);
if (really_hasnul) {
const bool use_blob = force_blob || ((s != NULL) && (memchr(s, NUL, len) != NULL));
if (use_blob) {
typval_T tv;
tv.v_lock = VAR_UNLOCKED;
if (binary) {
tv_blob_alloc_ret(&tv);
ga_concat_len(&tv.vval.v_blob->bv_ga, s, len);
blob_T *b = tv_blob_alloc_ret(&tv);
if (s_allocated) {
b->bv_ga.ga_data = (void *)s;
b->bv_ga.ga_len = (int)len;
b->bv_ga.ga_maxlen = (int)len;
} else {
list_T *const list = tv_list_alloc(kListLenMayKnow);
tv_list_ref(list);
create_special_dict(&tv, kMPString,
(typval_T){ .v_type = VAR_LIST,
.v_lock = VAR_UNLOCKED,
.vval = { .v_list = list } });
const int elw_ret = encode_list_write((void *)list, s, len);
if (s_allocated) {
xfree((void *)s);
}
if (elw_ret == -1) {
tv_clear(&tv);
return (typval_T) { .v_type = VAR_UNKNOWN, .v_lock = VAR_UNLOCKED };
}
ga_concat_len(&b->bv_ga, s, len);
}
return tv;
}
@ -405,7 +389,6 @@ static inline int parse_json_string(const char *const buf, const size_t buf_len,
char *str = xmalloc(len + 1);
int fst_in_pair = 0;
char *str_end = str;
bool hasnul = false;
#define PUT_FST_IN_PAIR(fst_in_pair, str_end) \
do { \
if ((fst_in_pair) != 0) { \
@ -426,9 +409,6 @@ static inline int parse_json_string(const char *const buf, const size_t buf_len,
uvarnumber_T ch;
vim_str2nr(ubuf, NULL, NULL,
STR2NR_HEX | STR2NR_FORCE, NULL, &ch, 4, true, NULL);
if (ch == 0) {
hasnul = true;
}
if (SURROGATE_HI_START <= ch && ch <= SURROGATE_HI_END) {
PUT_FST_IN_PAIR(fst_in_pair, str_end);
fst_in_pair = (int)ch;
@ -476,10 +456,7 @@ static inline int parse_json_string(const char *const buf, const size_t buf_len,
PUT_FST_IN_PAIR(fst_in_pair, str_end);
#undef PUT_FST_IN_PAIR
*str_end = NUL;
typval_T obj = decode_string(str, (size_t)(str_end - str), hasnul ? kTrue : kFalse, false, true);
if (obj.v_type == VAR_UNKNOWN) {
goto parse_json_string_fail;
}
typval_T obj = decode_string(str, (size_t)(str_end - str), false, true);
POP(obj, obj.v_type != VAR_STRING);
goto parse_json_string_ret;
parse_json_string_fail:
@ -982,18 +959,8 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
};
break;
case MSGPACK_OBJECT_STR:
*rettv = decode_string(mobj.via.bin.ptr, mobj.via.bin.size, kTrue, false,
false);
if (rettv->v_type == VAR_UNKNOWN) {
return FAIL;
}
break;
case MSGPACK_OBJECT_BIN:
*rettv = decode_string(mobj.via.bin.ptr, mobj.via.bin.size, kNone, true,
false);
if (rettv->v_type == VAR_UNKNOWN) {
return FAIL;
}
*rettv = decode_string(mobj.via.bin.ptr, mobj.via.bin.size, false, false);
break;
case MSGPACK_OBJECT_ARRAY: {
list_T *const list = tv_list_alloc((ptrdiff_t)mobj.via.array.size);
@ -1016,7 +983,8 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
}
case MSGPACK_OBJECT_MAP: {
for (size_t i = 0; i < mobj.via.map.size; i++) {
if (mobj.via.map.ptr[i].key.type != MSGPACK_OBJECT_STR
if ((mobj.via.map.ptr[i].key.type != MSGPACK_OBJECT_STR
&& mobj.via.map.ptr[i].key.type != MSGPACK_OBJECT_BIN)
|| mobj.via.map.ptr[i].key.via.str.size == 0
|| memchr(mobj.via.map.ptr[i].key.via.str.ptr, NUL,
mobj.via.map.ptr[i].key.via.str.size) != NULL) {

View File

@ -776,8 +776,7 @@ bool encode_check_json_key(const typval_T *const tv)
const dictitem_T *val_di;
if ((type_di = tv_dict_find(spdict, S_LEN("_TYPE"))) == NULL
|| type_di->di_tv.v_type != VAR_LIST
|| (type_di->di_tv.vval.v_list != eval_msgpack_type_lists[kMPString]
&& type_di->di_tv.vval.v_list != eval_msgpack_type_lists[kMPBinary])
|| type_di->di_tv.vval.v_list != eval_msgpack_type_lists[kMPString]
|| (val_di = tv_dict_find(spdict, S_LEN("_VAL"))) == NULL
|| val_di->di_tv.v_type != VAR_LIST) {
return false;

View File

@ -501,9 +501,7 @@ static int TYPVAL_ENCODE_CONVERT_ONE_VALUE(
}
TYPVAL_ENCODE_CONV_FLOAT(tv, val_di->di_tv.vval.v_float);
break;
case kMPString:
case kMPBinary: {
const bool is_string = ((MessagePackType)i == kMPString);
case kMPString: {
if (val_di->di_tv.v_type != VAR_LIST) {
goto _convert_one_value_regular_dict;
}
@ -513,11 +511,7 @@ static int TYPVAL_ENCODE_CONVERT_ONE_VALUE(
&buf)) {
goto _convert_one_value_regular_dict;
}
if (is_string) {
TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len);
} else {
TYPVAL_ENCODE_CONV_STRING(tv, buf, len);
}
TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len);
xfree(buf);
break;
}

View File

@ -9,7 +9,6 @@ typedef enum {
kMPInteger,
kMPFloat,
kMPString,
kMPBinary,
kMPArray,
kMPMap,
kMPExt,

View File

@ -219,12 +219,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
if (cur.special) {
list_T *const kv_pair = tv_list_alloc(2);
typval_T s_tv = decode_string(s, len, kTrue, false, false);
if (s_tv.v_type == VAR_UNKNOWN) {
ret = false;
tv_list_unref(kv_pair);
continue;
}
typval_T s_tv = decode_string(s, len, true, false);
tv_list_append_owned_tv(kv_pair, s_tv);
// Value: not populated yet, need to create list item to push.
@ -280,10 +275,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
case LUA_TSTRING: {
size_t len;
const char *s = lua_tolstring(lstate, -1, &len);
*cur.tv = decode_string(s, len, kNone, true, false);
if (cur.tv->v_type == VAR_UNKNOWN) {
ret = false;
}
*cur.tv = decode_string(s, len, false, false);
break;
}
case LUA_TNUMBER: {

View File

@ -1571,9 +1571,9 @@ describe('API', function()
eq(val2, request('vim_del_var', 'lua'))
end)
it('truncates values with NULs in them', function()
it('preserves values with NULs in them', function()
api.nvim_set_var('xxx', 'ab\0cd')
eq('ab', api.nvim_get_var('xxx'))
eq('ab\000cd', api.nvim_get_var('xxx'))
end)
end)

View File

@ -72,9 +72,9 @@ describe('luaeval()', function()
end)
it('are successfully converted to special dictionaries in table keys', function()
command([[let d = luaeval('{["\0"]=1}')]])
eq({_TYPE={}, _VAL={{{_TYPE={}, _VAL={'\n'}}, 1}}}, api.nvim_get_var('d'))
eq({_TYPE={}, _VAL={{'\000', 1}}}, api.nvim_get_var('d'))
eq(1, fn.eval('d._TYPE is v:msgpack_types.map'))
eq(1, fn.eval('d._VAL[0][0]._TYPE is v:msgpack_types.string'))
eq(eval('v:t_blob'), fn.eval('type(d._VAL[0][0])'))
end)
it('are successfully converted to blobs from a list', function()
command([[let l = luaeval('{"abc", "a\0b", "c\0d", "def"}')]])
@ -125,11 +125,11 @@ describe('luaeval()', function()
local level = 30
eq(nested_by_level[level].o, fn.luaeval(nested_by_level[level].s))
eq({_TYPE={}, _VAL={{{_TYPE={}, _VAL={'\n', '\n'}}, '\000\n\000\000'}}},
eq({_TYPE={}, _VAL={{'\000\n\000', '\000\n\000\000'}}},
fn.luaeval([[{['\0\n\0']='\0\n\0\0'}]]))
eq(1, eval([[luaeval('{["\0\n\0"]="\0\n\0\0"}')._TYPE is v:msgpack_types.map]]))
eq(1, eval([[luaeval('{["\0\n\0"]="\0\n\0\0"}')._VAL[0][0]._TYPE is v:msgpack_types.string]]))
eq({nested={{_TYPE={}, _VAL={{{_TYPE={}, _VAL={'\n', '\n'}}, '\000\n\000\000'}}}}},
eq(eval("v:t_blob"), eval([[type(luaeval('{["\0\n\0"]="\0\n\0\0"}')._VAL[0][0])]]))
eq({nested={{_TYPE={}, _VAL={{'\000\n\000', '\000\n\000\000'}}}}},
fn.luaeval([[{nested={{['\0\n\0']='\0\n\0\0'}}}]]))
end)
@ -177,12 +177,10 @@ describe('luaeval()', function()
end
it('correctly passes special dictionaries', function()
eq({0, '\000\n\000'}, luaevalarg(sp('binary', '["\\n", "\\n"]')))
eq({0, '\000\n\000'}, luaevalarg(sp('string', '["\\n", "\\n"]')))
eq({0, true}, luaevalarg(sp('boolean', 1)))
eq({0, false}, luaevalarg(sp('boolean', 0)))
eq({0, NIL}, luaevalarg(sp('nil', 0)))
eq({0, {[""]=""}}, luaevalarg(mapsp(sp('binary', '[""]'), '""')))
eq({0, {[""]=""}}, luaevalarg(mapsp(sp('string', '[""]'), '""')))
end)

View File

@ -58,23 +58,11 @@ describe('autoload/msgpack.vim', function()
msgpack_eq(1, '"abc\\ndef"', '"abc\\ndef"')
msgpack_eq(0, '"abc\\ndef"', '"abc\\nghi"')
end)
it('compares binary specials correctly', function()
msgpack_eq(1, sp('binary', '["abc\\n", "def"]'), sp('binary', '["abc\\n", "def"]'))
msgpack_eq(0, sp('binary', '["abc", "def"]'), sp('binary', '["abc\\n", "def"]'))
end)
it('compares binary specials with raw binaries correctly', function()
msgpack_eq(1, sp('binary', '["abc", "def"]'), '"abc\\ndef"')
msgpack_eq(0, sp('binary', '["abc", "def"]'), '"abcdef"')
end)
it('compares string specials correctly', function()
msgpack_eq(1, sp('string', '["abc\\n", "def"]'), sp('string', '["abc\\n", "def"]'))
msgpack_eq(0, sp('string', '["abc", "def"]'), sp('string', '["abc\\n", "def"]'))
end)
it('compares string specials with binary correctly', function()
msgpack_eq(0, sp('string', '["abc\\n", "def"]'), sp('binary', '["abc\\n", "def"]'))
msgpack_eq(0, sp('string', '["abc", "def"]'), '"abc\\ndef"')
msgpack_eq(0, sp('binary', '["abc\\n", "def"]'), sp('string', '["abc\\n", "def"]'))
msgpack_eq(0, '"abc\\ndef"', sp('string', '["abc", "def"]'))
msgpack_eq(1, sp('string', '["abc", "def"]'), '"abc\\ndef"')
msgpack_eq(1, '"abc\\ndef"', sp('string', '["abc", "def"]'))
end)
it('compares ext specials correctly', function()
msgpack_eq(1, sp('ext', '[1, ["", "ac"]]'), sp('ext', '[1, ["", "ac"]]'))
@ -92,20 +80,16 @@ describe('autoload/msgpack.vim', function()
end)
it('compares map specials correctly', function()
msgpack_eq(1, mapsp(), mapsp())
msgpack_eq(1, mapsp(sp('binary', '[""]'), '""'), mapsp(sp('binary', '[""]'), '""'))
msgpack_eq(
1,
mapsp(mapsp('1', '1'), mapsp('1', '1')),
mapsp(mapsp('1', '1'), mapsp('1', '1'))
)
msgpack_eq(0, mapsp(), mapsp('1', '1'))
msgpack_eq(0, mapsp(sp('binary', '["a"]'), '""'), mapsp(sp('binary', '[""]'), '""'))
msgpack_eq(0, mapsp(sp('binary', '[""]'), '"a"'), mapsp(sp('binary', '[""]'), '""'))
msgpack_eq(0, mapsp(sp('binary', '["a"]'), '"a"'), mapsp(sp('binary', '[""]'), '""'))
msgpack_eq(
0,
mapsp(mapsp('1', '1'), mapsp('1', '1')),
mapsp(sp('binary', '[""]'), mapsp('1', '1'))
mapsp(sp('string', '[""]'), mapsp('1', '1'))
)
msgpack_eq(
0,
@ -138,7 +122,7 @@ describe('autoload/msgpack.vim', function()
msgpack_eq(1, mapsp(sp('string', '["1"]'), '1'), '{"1": 1}')
msgpack_eq(1, mapsp(sp('string', '["1"]'), sp('integer', '[1, 0, 0, 1]')), '{"1": 1}')
msgpack_eq(0, mapsp(sp('integer', '[1, 0, 0, 1]'), sp('string', '["1"]')), '{1: "1"}')
msgpack_eq(0, mapsp('"1"', sp('integer', '[1, 0, 0, 1]')), '{"1": 1}')
msgpack_eq(1, mapsp('"1"', sp('integer', '[1, 0, 0, 1]')), '{"1": 1}')
msgpack_eq(0, mapsp(sp('string', '["1"]'), '1', sp('string', '["2"]'), '2'), '{"1": 1}')
msgpack_eq(0, mapsp(sp('string', '["1"]'), '1'), '{"1": 1, "2": 2}')
end)
@ -290,7 +274,6 @@ describe('autoload/msgpack.vim', function()
it('works for special dictionaries', function()
type_eq('string', sp('string', '[""]'))
type_eq('binary', sp('binary', '[""]'))
type_eq('ext', sp('ext', '[1, [""]]'))
type_eq('array', sp('array', '[]'))
type_eq('map', sp('map', '[]'))
@ -301,7 +284,7 @@ describe('autoload/msgpack.vim', function()
end)
it('works for regular values', function()
type_eq('binary', '""')
type_eq('string', '""')
type_eq('array', '[]')
type_eq('map', '{}')
type_eq('integer', '1')
@ -319,7 +302,6 @@ describe('autoload/msgpack.vim', function()
it('works for special dictionaries', function()
sp_type_eq('string', sp('string', '[""]'))
sp_type_eq('binary', sp('binary', '[""]'))
sp_type_eq('ext', sp('ext', '[1, [""]]'))
sp_type_eq('array', sp('array', '[]'))
sp_type_eq('map', sp('map', '[]'))
@ -347,12 +329,9 @@ describe('autoload/msgpack.vim', function()
end
it('works for special dictionaries', function()
string_eq('=""', sp('string', '[""]'))
string_eq('="\\n"', sp('string', '["", ""]'))
string_eq('="ab\\0c\\nde"', sp('string', '["ab\\nc", "de"]'))
string_eq('""', sp('binary', '[""]'))
string_eq('"\\n"', sp('binary', '["", ""]'))
string_eq('"ab\\0c\\nde"', sp('binary', '["ab\\nc", "de"]'))
string_eq('""', sp('string', '[""]'))
string_eq('"\\n"', sp('string', '["", ""]'))
string_eq('"ab\\0c\\nde"', sp('string', '["ab\\nc", "de"]'))
string_eq('+(2)""', sp('ext', '[2, [""]]'))
string_eq('+(2)"\\n"', sp('ext', '[2, ["", ""]]'))
string_eq('+(2)"ab\\0c\\nde"', sp('ext', '[2, ["ab\\nc", "de"]]'))
@ -397,8 +376,8 @@ describe('autoload/msgpack.vim', function()
string_eq('[]', '[]')
string_eq('[[[{}]]]', '[[[{}]]]')
string_eq('{}', '{}')
string_eq('{="2": 10}', '{2: 10}')
string_eq('{="2": [{}]}', '{2: [{}]}')
string_eq('{"2": 10}', '{2: 10}')
string_eq('{"2": [{}]}', '{2: [{}]}')
string_eq('1', '1')
string_eq('0.0', '0.0')
string_eq('inf', '(1.0/0.0)')
@ -422,7 +401,6 @@ describe('autoload/msgpack.vim', function()
nvim_command('let spflt = ' .. sp('float', '1.0'))
nvim_command('let spext = ' .. sp('ext', '[2, ["abc", "def"]]'))
nvim_command('let spstr = ' .. sp('string', '["abc", "def"]'))
nvim_command('let spbin = ' .. sp('binary', '["abc", "def"]'))
nvim_command('let spbln = ' .. sp('boolean', '0'))
nvim_command('let spnil = ' .. sp('nil', '0'))
@ -432,7 +410,6 @@ describe('autoload/msgpack.vim', function()
nvim_command('let spflt2 = msgpack#deepcopy(spflt)')
nvim_command('let spext2 = msgpack#deepcopy(spext)')
nvim_command('let spstr2 = msgpack#deepcopy(spstr)')
nvim_command('let spbin2 = msgpack#deepcopy(spbin)')
nvim_command('let spbln2 = msgpack#deepcopy(spbln)')
nvim_command('let spnil2 = msgpack#deepcopy(spnil)')
@ -442,7 +419,6 @@ describe('autoload/msgpack.vim', function()
eq('float', nvim_eval('msgpack#type(spflt2)'))
eq('ext', nvim_eval('msgpack#type(spext2)'))
eq('string', nvim_eval('msgpack#type(spstr2)'))
eq('binary', nvim_eval('msgpack#type(spbin2)'))
eq('boolean', nvim_eval('msgpack#type(spbln2)'))
eq('nil', nvim_eval('msgpack#type(spnil2)'))
@ -457,7 +433,6 @@ describe('autoload/msgpack.vim', function()
nvim_command('let spext._VAL[0] = 3')
nvim_command('let spext._VAL[1][0] = "gh"')
nvim_command('let spstr._VAL[0] = "gh"')
nvim_command('let spbin._VAL[0] = "gh"')
nvim_command('let spbln._VAL = 1')
nvim_command('let spnil._VAL = 1')
@ -467,7 +442,6 @@ describe('autoload/msgpack.vim', function()
eq({ _TYPE = {}, _VAL = 1.0 }, nvim_eval('spflt2'))
eq({ _TYPE = {}, _VAL = { 2, { 'abc', 'def' } } }, nvim_eval('spext2'))
eq({ _TYPE = {}, _VAL = { 'abc', 'def' } }, nvim_eval('spstr2'))
eq({ _TYPE = {}, _VAL = { 'abc', 'def' } }, nvim_eval('spbin2'))
eq({ _TYPE = {}, _VAL = 0 }, nvim_eval('spbln2'))
eq({ _TYPE = {}, _VAL = 0 }, nvim_eval('spnil2'))
@ -477,7 +451,6 @@ describe('autoload/msgpack.vim', function()
nvim_command('let spflt._TYPE = []')
nvim_command('let spext._TYPE = []')
nvim_command('let spstr._TYPE = []')
nvim_command('let spbin._TYPE = []')
nvim_command('let spbln._TYPE = []')
nvim_command('let spnil._TYPE = []')
@ -487,7 +460,6 @@ describe('autoload/msgpack.vim', function()
eq('float', nvim_eval('msgpack#special_type(spflt2)'))
eq('ext', nvim_eval('msgpack#special_type(spext2)'))
eq('string', nvim_eval('msgpack#special_type(spstr2)'))
eq('binary', nvim_eval('msgpack#special_type(spbin2)'))
eq('boolean', nvim_eval('msgpack#special_type(spbln2)'))
eq('nil', nvim_eval('msgpack#special_type(spnil2)'))
end)
@ -509,7 +481,7 @@ describe('autoload/msgpack.vim', function()
eq('map', nvim_eval('msgpack#type(map2)'))
eq('integer', nvim_eval('msgpack#type(int2)'))
eq('float', nvim_eval('msgpack#type(flt2)'))
eq('binary', nvim_eval('msgpack#type(bin2)'))
eq('string', nvim_eval('msgpack#type(bin2)'))
nvim_command('call add(arr, 0)')
nvim_command('call add(arr[0], 0)')
@ -566,21 +538,6 @@ describe('autoload/msgpack.vim', function()
nvim_command('unlet g:__val')
end
it('correctly loads binary strings', function()
eval_eq('binary', { 'abcdef' }, '"abcdef"')
eval_eq('binary', { 'abc', 'def' }, '"abc\\ndef"')
eval_eq('binary', { 'abc\ndef' }, '"abc\\0def"')
eval_eq('binary', { '\nabc\ndef\n' }, '"\\0abc\\0def\\0"')
eval_eq('binary', { 'abc\n\n\ndef' }, '"abc\\0\\0\\0def"')
eval_eq('binary', { 'abc\n', '\ndef' }, '"abc\\0\\n\\0def"')
eval_eq('binary', { 'abc', '', '', 'def' }, '"abc\\n\\n\\ndef"')
eval_eq('binary', { 'abc', '', '', 'def', '' }, '"abc\\n\\n\\ndef\\n"')
eval_eq('binary', { '', 'abc', '', '', 'def' }, '"\\nabc\\n\\n\\ndef"')
eval_eq('binary', { '' }, '""')
eval_eq('binary', { '"' }, '"\\""')
eval_eq('binary', { 'py3 print(sys.version_info)' }, '"py3 print(sys.version_info)"')
end)
it('correctly loads strings', function()
eval_eq('string', { 'abcdef' }, '="abcdef"')
eval_eq('string', { 'abc', 'def' }, '="abc\\ndef"')

View File

@ -68,7 +68,7 @@ describe('autoload/shada.vim', function()
endfor
return ret
elseif type(a:val) == type('')
return {'_TYPE': v:msgpack_types.binary, '_VAL': split(a:val, "\n", 1)}
return {'_TYPE': v:msgpack_types.string, '_VAL': split(a:val, "\n", 1)}
else
return a:val
endif
@ -253,8 +253,7 @@ describe('autoload/shada.vim', function()
' + sm magic value "TRUE"',
' # Expected integer',
' + so offset value "TRUE"',
' # Expected binary string',
' + sp pattern ="abc"',
' + sp pattern "abc"',
},
([[ [{'type': 1, 'timestamp': 0, 'data': {
'sm': 'TRUE',
@ -267,7 +266,7 @@ describe('autoload/shada.vim', function()
'n': -0x40,
'l': -10,
'c': 'abc',
'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["abc\ndef"]},
'f': {'_TYPE': v:msgpack_types.string, '_VAL': ["abc\ndef"]},
}}] ]]):gsub('\n', '')
)
sd2strings_eq(
@ -276,15 +275,14 @@ describe('autoload/shada.vim', function()
' % Key Description Value',
' # Expected no NUL bytes',
' + f file name "abc\\0def"',
' # Expected array of binary strings',
' + rc contents ["abc", ="abc"]',
' + rc contents ["abc", "abc"]',
' # Expected integer',
' + rt type "ABC"',
},
([[ [{'type': 1, 'timestamp': 0, 'data': {
'rt': 'ABC',
'rc': ["abc", {'_TYPE': v:msgpack_types.string, '_VAL': ["abc"]}],
'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["abc\ndef"]},
'f': {'_TYPE': v:msgpack_types.string, '_VAL': ["abc\ndef"]},
}}] ]]):gsub('\n', '')
)
sd2strings_eq(
@ -295,7 +293,7 @@ describe('autoload/shada.vim', function()
' + rc contents ["abc", "a\\nd\\0"]',
},
([[ [{'type': 1, 'timestamp': 0, 'data': {
'rc': ["abc", {'_TYPE': v:msgpack_types.binary, '_VAL': ["a", "d\n"]}],
'rc': ["abc", {'_TYPE': v:msgpack_types.string, '_VAL': ["a", "d\n"]}],
}}] ]]):gsub('\n', '')
)
end)
@ -468,7 +466,7 @@ describe('autoload/shada.vim', function()
sd2strings_eq({
'Replacement string with timestamp ' .. epoch .. ':',
' # Unexpected type: map instead of array',
' = {="a": [10]}',
' = {"a": [10]}',
}, { { type = 3, timestamp = 0, data = { a = { 10 } } } })
sd2strings_eq(
{
@ -498,7 +496,7 @@ describe('autoload/shada.vim', function()
' - :s replacement string "abc\\0def"',
},
([[ [{'type': 3, 'timestamp': 0, 'data': [
{'_TYPE': v:msgpack_types.binary, '_VAL': ["abc\ndef"]},
{'_TYPE': v:msgpack_types.string, '_VAL': ["abc\ndef"]},
]}] ]]):gsub('\n', '')
)
sd2strings_eq(
@ -508,7 +506,7 @@ describe('autoload/shada.vim', function()
' - :s replacement string "abc\\ndef"',
},
([[ [{'type': 3, 'timestamp': 0, 'data': [
{'_TYPE': v:msgpack_types.binary, '_VAL': ["abc", "def"]},
{'_TYPE': v:msgpack_types.string, '_VAL': ["abc", "def"]},
]}] ]]):gsub('\n', '')
)
sd2strings_eq(
@ -519,7 +517,7 @@ describe('autoload/shada.vim', function()
' - 0',
},
([[ [{'type': 3, 'timestamp': 0, 'data': [
{'_TYPE': v:msgpack_types.binary, '_VAL': ["abc", "def"]},
{'_TYPE': v:msgpack_types.string, '_VAL': ["abc", "def"]},
0,
]}] ]]):gsub('\n', '')
)
@ -529,7 +527,7 @@ describe('autoload/shada.vim', function()
sd2strings_eq({
'History entry with timestamp ' .. epoch .. ':',
' # Unexpected type: map instead of array',
' = {="a": [10]}',
' = {"a": [10]}',
}, { { type = 4, timestamp = 0, data = { a = { 10 } } } })
sd2strings_eq(
{
@ -682,7 +680,7 @@ describe('autoload/shada.vim', function()
},
([[ [{'type': 4, 'timestamp': 0, 'data': [
4,
{'_TYPE': v:msgpack_types.binary, '_VAL': ["abc\ndef"]},
{'_TYPE': v:msgpack_types.string, '_VAL': ["abc\ndef"]},
]}] ]]):gsub('\n', '')
)
sd2strings_eq(
@ -909,7 +907,7 @@ describe('autoload/shada.vim', function()
sd2strings_eq({
'Variable with timestamp ' .. epoch .. ':',
' # Unexpected type: map instead of array',
' = {="a": [10]}',
' = {"a": [10]}',
}, { { type = 6, timestamp = 0, data = { a = { 10 } } } })
sd2strings_eq(
{
@ -941,7 +939,7 @@ describe('autoload/shada.vim', function()
' # Expected more elements in list',
},
([[ [{'type': 6, 'timestamp': 0, 'data': [
{'_TYPE': v:msgpack_types.binary, '_VAL': ["\n"]},
{'_TYPE': v:msgpack_types.string, '_VAL': ["\n"]},
]}] ]]):gsub('\n', '')
)
sd2strings_eq(
@ -952,7 +950,7 @@ describe('autoload/shada.vim', function()
' # Expected more elements in list',
},
([[ [{'type': 6, 'timestamp': 0, 'data': [
{'_TYPE': v:msgpack_types.binary, '_VAL': ["foo"]},
{'_TYPE': v:msgpack_types.string, '_VAL': ["foo"]},
]}] ]]):gsub('\n', '')
)
sd2strings_eq(
@ -963,7 +961,7 @@ describe('autoload/shada.vim', function()
' - value NIL',
},
([[ [{'type': 6, 'timestamp': 0, 'data': [
{'_TYPE': v:msgpack_types.binary, '_VAL': ["foo"]},
{'_TYPE': v:msgpack_types.string, '_VAL': ["foo"]},
{'_TYPE': v:msgpack_types.nil, '_VAL': ["foo"]},
]}] ]]):gsub('\n', '')
)
@ -976,7 +974,7 @@ describe('autoload/shada.vim', function()
' - NIL',
},
([[ [{'type': 6, 'timestamp': 0, 'data': [
{'_TYPE': v:msgpack_types.binary, '_VAL': ["foo"]},
{'_TYPE': v:msgpack_types.string, '_VAL': ["foo"]},
{'_TYPE': v:msgpack_types.nil, '_VAL': ["foo"]},
{'_TYPE': v:msgpack_types.nil, '_VAL': ["foo"]},
]}] ]]):gsub('\n', '')
@ -1041,7 +1039,7 @@ describe('autoload/shada.vim', function()
},
([[ [{'type': 7, 'timestamp': 0, 'data': {
'n': -10,
'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["\n"]},
'f': {'_TYPE': v:msgpack_types.string, '_VAL': ["\n"]},
}}] ]]):gsub('\n', '')
)
sd2strings_eq(
@ -1174,7 +1172,7 @@ describe('autoload/shada.vim', function()
},
([[ [{'type': 8, 'timestamp': 0, 'data': {
'n': -10,
'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["\n"]},
'f': {'_TYPE': v:msgpack_types.string, '_VAL': ["\n"]},
}}] ]]):gsub('\n', '')
)
sd2strings_eq(
@ -1237,7 +1235,7 @@ describe('autoload/shada.vim', function()
sd2strings_eq({
'Buffer list with timestamp ' .. epoch .. ':',
' # Unexpected type: map instead of array',
' = {="a": [10]}',
' = {"a": [10]}',
}, { { type = 9, timestamp = 0, data = { a = { 10 } } } })
sd2strings_eq({
'Buffer list with timestamp ' .. epoch .. ':',
@ -1247,7 +1245,7 @@ describe('autoload/shada.vim', function()
sd2strings_eq({
'Buffer list with timestamp ' .. epoch .. ':',
' # Expected array of maps',
' = [{="a": 10}, []]',
' = [{"a": 10}, []]',
}, { { type = 9, timestamp = 0, data = { { a = 10 }, {} } } })
sd2strings_eq({
'Buffer list with timestamp ' .. epoch .. ':',
@ -1322,7 +1320,7 @@ describe('autoload/shada.vim', function()
},
([[ [{'type': 9, 'timestamp': 0, 'data': [
{'f': 10},
{'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["\n"]}},
{'f': {'_TYPE': v:msgpack_types.string, '_VAL': ["\n"]}},
]}] ]]):gsub('\n', '')
)
end)
@ -1385,7 +1383,7 @@ describe('autoload/shada.vim', function()
},
([[ [{'type': 10, 'timestamp': 0, 'data': {
'n': -10,
'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["\n"]},
'f': {'_TYPE': v:msgpack_types.string, '_VAL': ["\n"]},
}}] ]]):gsub('\n', '')
)
sd2strings_eq(
@ -1504,7 +1502,7 @@ describe('autoload/shada.vim', function()
},
([[ [{'type': 11, 'timestamp': 0, 'data': {
'n': -10,
'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["\n"]},
'f': {'_TYPE': v:msgpack_types.string, '_VAL': ["\n"]},
}}] ]]):gsub('\n', '')
)
sd2strings_eq(
@ -1616,7 +1614,7 @@ describe('autoload/shada.vim', function()
timestamp = 0,
data = {
c = 'abc',
f = { '!binary', { 'abc\ndef' } },
f = { '!string', { 'abc\ndef' } },
l = -10,
n = -64,
rc = '10',
@ -1711,7 +1709,7 @@ describe('autoload/shada.vim', function()
timestamp = 0,
data = {
c = 'abc',
f = { '!binary', { 'abc\ndef' } },
f = { '!string', { 'abc\ndef' } },
l = -10,
n = -64,
rc = '10',
@ -1892,7 +1890,7 @@ describe('autoload/shada.vim', function()
} } }, {
'Replacement string with timestamp ' .. epoch .. ':',
' # Unexpected type: map instead of array',
' = {="a": [10]}',
' = {"a": [10]}',
})
strings2sd_eq({ { type = 3, timestamp = 0, data = {} } }, {
'Replacement string with timestamp ' .. epoch .. ':',
@ -1934,7 +1932,7 @@ describe('autoload/shada.vim', function()
} } }, {
'History entry with timestamp ' .. epoch .. ':',
' # Unexpected type: map instead of array',
' = {="a": [10]}',
' = {"a": [10]}',
})
strings2sd_eq({ { type = 4, timestamp = 0, data = {} } }, {
'History entry with timestamp ' .. epoch .. ':',
@ -2184,7 +2182,7 @@ describe('autoload/shada.vim', function()
} } }, {
'Variable with timestamp ' .. epoch .. ':',
' # Unexpected type: map instead of array',
' = {="a": [10]}',
' = {"a": [10]}',
})
strings2sd_eq({ { type = 6, timestamp = 0, data = {} } }, {
'Variable with timestamp ' .. epoch .. ':',
@ -2315,7 +2313,7 @@ describe('autoload/shada.vim', function()
} } }, {
'Buffer list with timestamp ' .. epoch .. ':',
' # Unexpected type: map instead of array',
' = {="a": [10]}',
' = {"a": [10]}',
})
strings2sd_eq(
{ { type = 9, timestamp = 0, data = {
@ -2325,7 +2323,7 @@ describe('autoload/shada.vim', function()
{
'Buffer list with timestamp ' .. epoch .. ':',
' # Expected array of maps',
' = [{="a": 10}, []]',
' = [{"a": 10}, []]',
}
)
strings2sd_eq({ { type = 9, timestamp = 0, data = {
@ -2421,7 +2419,7 @@ describe('autoload/shada.vim', function()
timestamp = 0,
data = {
{ f = 10 },
{ f = { '!binary', { '\n' } } },
{ f = { '!string', { '\n' } } },
},
},
}, {
@ -2955,7 +2953,7 @@ describe('ftplugin/shada.vim', function()
' - :s replacement string "abc\\ndef"',
' Buffer list with timestamp ' .. epoch .. ':',
' # Expected array of maps',
'= [{="a": 10}, []]',
'= [{"a": 10}, []]',
' Buffer list with timestamp ' .. epoch .. ':',
' % Key Description Value',
' # Expected binary string',
@ -2992,7 +2990,7 @@ describe('ftplugin/shada.vim', function()
' - :s replacement string "abc\\ndef"',
'Buffer list with timestamp ' .. epoch .. ':',
' # Expected array of maps',
' = [{="a": 10}, []]',
' = [{"a": 10}, []]',
'Buffer list with timestamp ' .. epoch .. ':',
' % Key Description Value',
' # Expected binary string',
@ -3083,7 +3081,7 @@ describe('syntax/shada.vim', function()
' - :s replacement string DEBUG',
'Buffer list with timestamp ' .. epoch .. ':',
' # Expected array of maps',
' = [{="a": +(10)"ac\\0df\\ngi\\"tt\\.", TRUE: FALSE}, [NIL, +(-10)""]]',
' = [{"a": +(10)"ac\\0df\\ngi\\"tt\\.", TRUE: FALSE}, [NIL, +(-10)""]]',
'Buffer list with timestamp ' .. epoch .. ':',
' % Key Description Value',
'',
@ -3119,8 +3117,8 @@ describe('syntax/shada.vim', function()
{1: -} {4::s replacement string} {1:DEBUG} |
{1:Buffer list} with timestamp 1970{1:-}01{1:-}01{1:T}00{1::}00{1::}00: |
{4: # Expected array of maps} |
= {1:[{="}{3:a}{1:":} {1:+(}{5:10}{1:)"}{3:ac}{6:\0}{3:df}{6:\n}{3:gi}{6:\"}{3:tt\.}{1:",} {1:TRUE:} {1:FALSE},} {1:[NIL,} {1:+(}{5:-}|
{5:10}{1:)""]]} |
= {1:[{"}{3:a}{1:":} {1:+(}{5:10}{1:)"}{3:ac}{6:\0}{3:df}{6:\n}{3:gi}{6:\"}{3:tt\.}{1:",} {1:TRUE:} {1:FALSE},} {1:[NIL,} {1:+(}{5:-1}|
{5:0}{1:)""]]} |
{1:Buffer list} with timestamp 1970{1:-}01{1:-}01{1:T}00{1::}00{1::}00: |
{2: % Key Description Value} |
|
@ -3464,7 +3462,6 @@ describe('syntax/shada.vim', function()
{ { 'ShaDaEntryRawMsgpack' }, ' = ' },
{ { 'ShaDaMsgpackArray', 'ShaDaMsgpackArrayBraces' }, '[' },
{ { 'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackMapBraces' }, '{' },
{ { 'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackString' }, '=' },
{
{
'ShaDaMsgpackArray',

View File

@ -502,9 +502,9 @@ describe('json_decode() function', function()
end
it('parses strings with NUL properly', function()
sp_decode_eq({ _TYPE = 'string', _VAL = { '\n' } }, '"\\u0000"')
sp_decode_eq({ _TYPE = 'string', _VAL = { '\n', '\n' } }, '"\\u0000\\n\\u0000"')
sp_decode_eq({ _TYPE = 'string', _VAL = { '\n«\n' } }, '"\\u0000\\u00AB\\u0000"')
sp_decode_eq('\000', '"\\u0000"')
sp_decode_eq('\000\n\000', '"\\u0000\\n\\u0000"')
sp_decode_eq('\000«\000', '"\\u0000\\u00AB\\u0000"')
end)
it('parses dictionaries with duplicate keys to special maps', function()
@ -580,14 +580,8 @@ describe('json_decode() function', function()
end)
it('parses dictionaries with keys with NUL bytes to special maps', function()
sp_decode_eq(
{ _TYPE = 'map', _VAL = { { { _TYPE = 'string', _VAL = { 'a\n', 'b' } }, 4 } } },
'{"a\\u0000\\nb": 4}'
)
sp_decode_eq(
{ _TYPE = 'map', _VAL = { { { _TYPE = 'string', _VAL = { 'a\n', 'b', '' } }, 4 } } },
'{"a\\u0000\\nb\\n": 4}'
)
sp_decode_eq({ _TYPE = 'map', _VAL = { { 'a\000\nb', 4 } } }, '{"a\\u0000\\nb": 4}')
sp_decode_eq({ _TYPE = 'map', _VAL = { { 'a\000\nb\n', 4 } } }, '{"a\\u0000\\nb\\n": 4}')
sp_decode_eq({
_TYPE = 'map',
_VAL = {
@ -595,10 +589,7 @@ describe('json_decode() function', function()
{ 'a', 1 },
{ 'c', 4 },
{ 'd', 2 },
{
{ _TYPE = 'string', _VAL = { '\n' } },
4,
},
{ '\000', 4 },
},
}, '{"b": 3, "a": 1, "c": 4, "d": 2, "\\u0000": 4}')
end)
@ -738,22 +729,11 @@ describe('json_encode() function', function()
eq('{"\\u0000": 1}', eval('json_encode(todump)'))
end)
it('can dump generic mapping with BIN special key and NUL', function()
command('let todump = {"_TYPE": v:msgpack_types.binary, "_VAL": ["\\n"]}')
command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [[todump, 1]]}')
eq('{"\\u0000": 1}', eval('json_encode(todump)'))
end)
it('can dump STR special mapping with NUL and NL', function()
command('let todump = {"_TYPE": v:msgpack_types.string, "_VAL": ["\\n", ""]}')
eq('"\\u0000\\n"', eval('json_encode(todump)'))
end)
it('can dump BIN special mapping with NUL and NL', function()
command('let todump = {"_TYPE": v:msgpack_types.binary, "_VAL": ["\\n", ""]}')
eq('"\\u0000\\n"', eval('json_encode(todump)'))
end)
it('cannot dump special ext mapping', function()
command('let todump = {"_TYPE": v:msgpack_types.ext, "_VAL": [5, ["",""]]}')
eq('Vim(call):E474: Unable to convert EXT string to JSON', exc_exec('call json_encode(todump)'))

View File

@ -371,13 +371,14 @@ describe('msgpack*() functions', function()
eq(1, eval('dumped ==# dumped2'))
end)
it('can restore and dump STR string with zero byte', function()
it('can restore and dump STR string contents with zero byte', function()
command('let dumped = ["\\xA1\\n"]')
command('let parsed = msgpackparse(dumped)')
command('let dumped2 = msgpackdump(parsed)')
eq({ { _TYPE = {}, _VAL = { '\n' } } }, eval('parsed'))
eq(1, eval('parsed[0]._TYPE is v:msgpack_types.string'))
eq(1, eval('dumped ==# dumped2'))
eq({ '\000' }, eval('parsed'))
eq(eval('v:t_blob'), eval('type(parsed[0])'))
-- type is not preserved: prefer BIN for binary contents
eq(0, eval('dumped ==# dumped2'))
end)
it('can restore and dump BIN string with NL', function()
@ -428,9 +429,8 @@ describe('msgpackparse() function', function()
parse_eq({ true }, { '\195' })
end)
it('restores FIXSTR as special dict', function()
parse_eq({ { _TYPE = {}, _VAL = { 'ab' } } }, { '\162ab' })
eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.string'))
it('restores FIXSTR as string', function()
parse_eq({ 'ab' }, { '\162ab' })
end)
it('restores BIN 8 as string', function()
@ -442,9 +442,8 @@ describe('msgpackparse() function', function()
eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.ext'))
end)
it('restores MAP with BIN key as special dictionary', function()
parse_eq({ { _TYPE = {}, _VAL = { { 'a', '' } } } }, { '\129\196\001a\196\n' })
eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.map'))
it('restores MAP with BIN key as ordinary dictionary', function()
parse_eq({ { a = '' } }, { '\129\196\001a\196\n' })
end)
it('restores MAP with duplicate STR keys as special dictionary', function()
@ -455,14 +454,14 @@ describe('msgpackparse() function', function()
{
_TYPE = {},
_VAL = {
{ { _TYPE = {}, _VAL = { 'a' } }, '' },
{ { _TYPE = {}, _VAL = { 'a' } }, '' },
{ 'a', '' },
{ 'a', '' },
},
},
}, eval('parsed'))
eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.map'))
eq(1, eval('g:parsed[0]._VAL[0][0]._TYPE is v:msgpack_types.string'))
eq(1, eval('g:parsed[0]._VAL[1][0]._TYPE is v:msgpack_types.string'))
eq(eval('v:t_string'), eval('type(g:parsed[0]._VAL[0][0])'))
eq(eval('v:t_string'), eval('type(g:parsed[0]._VAL[1][0])'))
end)
it('restores MAP with MAP key as special dictionary', function()
@ -802,7 +801,7 @@ describe('msgpackdump() function', function()
it('can dump NULL string', function()
dump_eq({ '\196\n' }, '[$XXX_UNEXISTENT_VAR_XXX]')
dump_eq({ '\196\n' }, '[{"_TYPE": v:msgpack_types.binary, "_VAL": [$XXX_UNEXISTENT_VAR_XXX]}]')
dump_eq({ '\196\n' }, '[v:_null_blob]')
dump_eq({ '\160' }, '[{"_TYPE": v:msgpack_types.string, "_VAL": [$XXX_UNEXISTENT_VAR_XXX]}]')
end)