aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/buffer_defs.h3
-rw-r--r--src/nvim/eval.c4
-rw-r--r--src/nvim/event/libuv_process.h5
-rw-r--r--src/nvim/ex_docmd.c29
-rw-r--r--src/nvim/file_search.c30
-rw-r--r--src/nvim/fold.c24
-rw-r--r--src/nvim/getchar.c71
-rw-r--r--src/nvim/memline.c2
-rw-r--r--src/nvim/memory.c7
-rw-r--r--src/nvim/ops.c49
-rw-r--r--src/nvim/option.c2
-rw-r--r--src/nvim/terminal.c1
-rw-r--r--src/nvim/testdir/test_fold.vim16
-rw-r--r--src/nvim/window.c41
-rw-r--r--test/README.md101
-rw-r--r--test/config/paths.lua.in9
-rw-r--r--test/functional/autocmd/dirchanged_spec.lua78
-rw-r--r--test/helpers.lua28
-rw-r--r--test/unit/api/helpers.lua88
-rw-r--r--test/unit/api/private_helpers_spec.lua11
-rw-r--r--test/unit/buffer_spec.lua27
-rw-r--r--test/unit/eval/decode_spec.lua30
-rw-r--r--test/unit/eval/encode_spec.lua25
-rw-r--r--test/unit/eval/helpers.lua164
-rw-r--r--test/unit/eval/tricks_spec.lua9
-rw-r--r--test/unit/eval/tv_clear_spec.lua11
-rw-r--r--test/unit/fileio_spec.lua33
-rw-r--r--test/unit/fixtures/posix.h11
-rw-r--r--test/unit/garray_spec.lua35
-rw-r--r--test/unit/helpers.lua528
-rw-r--r--test/unit/mbyte_spec.lua15
-rw-r--r--test/unit/memory_spec.lua9
-rw-r--r--test/unit/message_spec.lua13
-rw-r--r--test/unit/multiqueue_spec.lua57
-rw-r--r--test/unit/option_spec.lua13
-rw-r--r--test/unit/os/env_spec.lua37
-rw-r--r--test/unit/os/fileio_spec.lua59
-rw-r--r--test/unit/os/fs_spec.lua198
-rw-r--r--test/unit/os/shell_spec.lua41
-rw-r--r--test/unit/os/users_spec.lua19
-rw-r--r--test/unit/path_spec.lua132
-rw-r--r--test/unit/preload.lua2
-rw-r--r--test/unit/profile_spec.lua43
-rw-r--r--test/unit/rbuffer_spec.lua100
-rw-r--r--test/unit/set.lua16
-rw-r--r--test/unit/strings_spec.lua35
-rw-r--r--test/unit/tempfile_spec.lua45
47 files changed, 1431 insertions, 875 deletions
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index a1b5633c32..3e9767adde 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -825,8 +825,7 @@ struct tabpage_S {
frame_T *(tp_snapshot[SNAP_COUNT]); ///< window layout snapshots
dictitem_T tp_winvar; ///< variable for "t:" Dictionary
dict_T *tp_vars; ///< internal variables, local to tab page
- char_u *localdir; ///< Absolute path of local directory or
- ///< NULL
+ char_u *tp_localdir; ///< Absolute path of local CWD or NULL
};
/*
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 6dc7e5606e..78f470b10a 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -10901,7 +10901,7 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
case kCdScopeTab: // FALLTHROUGH
assert(tp);
- from = tp->localdir;
+ from = tp->tp_localdir;
if (from) {
break;
}
@@ -12015,7 +12015,7 @@ static void f_haslocaldir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
break;
case kCdScopeTab:
assert(tp);
- rettv->vval.v_number = tp->localdir ? 1 : 0;
+ rettv->vval.v_number = tp->tp_localdir ? 1 : 0;
break;
case kCdScopeGlobal:
// The global scope never has a local directory
diff --git a/src/nvim/event/libuv_process.h b/src/nvim/event/libuv_process.h
index aaaa896e10..1132ce79ca 100644
--- a/src/nvim/event/libuv_process.h
+++ b/src/nvim/event/libuv_process.h
@@ -14,8 +14,9 @@ typedef struct libuv_process {
static inline LibuvProcess libuv_process_init(Loop *loop, void *data)
{
- LibuvProcess rv;
- rv.process = process_init(loop, kProcessTypeUv, data);
+ LibuvProcess rv = {
+ .process = process_init(loop, kProcessTypeUv, data)
+ };
return rv;
}
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 87b6959101..774380b2f0 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -6943,24 +6943,27 @@ void free_cd_dir(void)
/// @param scope Scope of the function call (global, tab or window).
void post_chdir(CdScope scope)
{
- // The local directory of the current window is always overwritten.
+ // Always overwrite the window-local CWD.
xfree(curwin->w_localdir);
curwin->w_localdir = NULL;
- // Overwrite the local directory of the current tab page for `cd` and `tcd`
+ // Overwrite the tab-local CWD for :cd, :tcd.
if (scope >= kCdScopeTab) {
- xfree(curtab->localdir);
- curtab->localdir = NULL;
+ xfree(curtab->tp_localdir);
+ curtab->tp_localdir = NULL;
}
if (scope < kCdScopeGlobal) {
- // If still in global directory, need to remember current directory as
- // global directory.
+ // If still in global directory, set CWD as the global directory.
if (globaldir == NULL && prev_dir != NULL) {
globaldir = vim_strsave(prev_dir);
}
}
+ char cwd[MAXPATHL];
+ if (os_dirname((char_u *)cwd, MAXPATHL) != OK) {
+ return;
+ }
switch (scope) {
case kCdScopeGlobal:
// We are now in the global directory, no need to remember its name.
@@ -6968,23 +6971,17 @@ void post_chdir(CdScope scope)
globaldir = NULL;
break;
case kCdScopeTab:
- // Remember this local directory for the tab page.
- if (os_dirname(NameBuff, MAXPATHL) == OK) {
- curtab->localdir = vim_strsave(NameBuff);
- }
+ curtab->tp_localdir = (char_u *)xstrdup(cwd);
break;
case kCdScopeWindow:
- // Remember this local directory for the window.
- if (os_dirname(NameBuff, MAXPATHL) == OK) {
- curwin->w_localdir = vim_strsave(NameBuff);
- }
+ curwin->w_localdir = (char_u *)xstrdup(cwd);
break;
case kCdScopeInvalid:
- // We should never get here
assert(false);
}
- shorten_fnames(TRUE);
+ shorten_fnames(true);
+ do_autocmd_dirchanged(cwd, scope);
}
/// `:cd`, `:tcd`, `:lcd`, `:chdir`, `:tchdir` and `:lchdir`.
diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c
index 79a39c6503..b73d9944ce 100644
--- a/src/nvim/file_search.c
+++ b/src/nvim/file_search.c
@@ -1519,7 +1519,7 @@ theend:
return file_name;
}
-static void do_autocmd_dirchanged(char_u *new_dir, CdScope scope)
+void do_autocmd_dirchanged(char *new_dir, CdScope scope)
{
static bool recursive = false;
@@ -1550,10 +1550,11 @@ static void do_autocmd_dirchanged(char_u *new_dir, CdScope scope)
}
dict_add_nr_str(dict, "scope", 0L, (char_u *)buf);
- dict_add_nr_str(dict, "cwd", 0L, new_dir);
+ dict_add_nr_str(dict, "cwd", 0L, (char_u *)new_dir);
dict_set_keys_readonly(dict);
- apply_autocmds(EVENT_DIRCHANGED, (char_u *)buf, new_dir, false, NULL);
+ apply_autocmds(EVENT_DIRCHANGED, (char_u *)buf, (char_u *)new_dir, false,
+ NULL);
dict_clear(dict);
@@ -1565,14 +1566,25 @@ static void do_autocmd_dirchanged(char_u *new_dir, CdScope scope)
/// @return OK or FAIL
int vim_chdirfile(char_u *fname)
{
- char_u dir[MAXPATHL];
+ char dir[MAXPATHL];
STRLCPY(dir, fname, MAXPATHL);
- *path_tail_with_sep(dir) = NUL;
- if (os_chdir((char *)dir) != 0) {
+ *path_tail_with_sep((char_u *)dir) = NUL;
+
+ if (os_dirname(NameBuff, sizeof(NameBuff)) != OK) {
+ NameBuff[0] = NUL;
+ }
+
+ if (os_chdir(dir) != 0) {
return FAIL;
}
- do_autocmd_dirchanged(dir, kCdScopeWindow);
+
+#ifdef BACKSLASH_IN_FILENAME
+ slash_adjust(dir);
+#endif
+ if (!strequal(dir, (char *)NameBuff)) {
+ do_autocmd_dirchanged(dir, kCdScopeWindow);
+ }
return OK;
}
@@ -1587,10 +1599,6 @@ int vim_chdir(char_u *new_dir, CdScope scope)
}
int r = os_chdir((char *)dir_name);
- if (r == 0) {
- do_autocmd_dirchanged(dir_name, scope);
- }
-
xfree(dir_name);
return r;
}
diff --git a/src/nvim/fold.c b/src/nvim/fold.c
index 1423463800..7c0283971e 100644
--- a/src/nvim/fold.c
+++ b/src/nvim/fold.c
@@ -29,6 +29,7 @@
#include "nvim/strings.h"
#include "nvim/syntax.h"
#include "nvim/undo.h"
+#include "nvim/ops.h"
/* local declarations. {{{1 */
/* typedef fold_T {{{2 */
@@ -1593,29 +1594,32 @@ static void foldCreateMarkers(linenr_T start, linenr_T end)
/*
* Add "marker[markerlen]" in 'commentstring' to line "lnum".
*/
-static void foldAddMarker(linenr_T lnum, char_u *marker, size_t markerlen)
+static void foldAddMarker(linenr_T lnum, const char_u *marker, size_t markerlen)
{
char_u *cms = curbuf->b_p_cms;
char_u *line;
char_u *newline;
char_u *p = (char_u *)strstr((char *)curbuf->b_p_cms, "%s");
+ bool line_is_comment = false;
- /* Allocate a new line: old-line + 'cms'-start + marker + 'cms'-end */
+ // Allocate a new line: old-line + 'cms'-start + marker + 'cms'-end
line = ml_get(lnum);
size_t line_len = STRLEN(line);
if (u_save(lnum - 1, lnum + 1) == OK) {
+ // Check if the line ends with an unclosed comment
+ skip_comment(line, false, false, &line_is_comment);
newline = xmalloc(line_len + markerlen + STRLEN(cms) + 1);
STRCPY(newline, line);
- if (p == NULL)
+ // Append the marker to the end of the line
+ if (p == NULL || line_is_comment) {
STRLCPY(newline + line_len, marker, markerlen + 1);
- else {
+ } else {
STRCPY(newline + line_len, cms);
memcpy(newline + line_len + (p - cms), marker, markerlen);
STRCPY(newline + line_len + (p - cms) + markerlen, p + 2);
}
-
- ml_replace(lnum, newline, FALSE);
+ ml_replace(lnum, newline, false);
}
}
@@ -2535,10 +2539,10 @@ static void foldSplit(garray_T *gap, int i, linenr_T top, linenr_T bot)
* 1 2 3
* 1 2 3
* top 2 3 4 5
- * 2 3 4 5
- * bot 2 3 4 5
- * 3 5 6
- * 3 5 6
+ * 2 3 4 5
+ * bot 2 3 4 5
+ * 3 5 6
+ * 3 5 6
*
* 1: not changed
* 2: truncate to stop above "top"
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c
index b7c6fd41f2..0ba0559bc1 100644
--- a/src/nvim/getchar.c
+++ b/src/nvim/getchar.c
@@ -1913,59 +1913,30 @@ static int vgetorpeek(int advance)
if ((mp == NULL || max_mlen >= mp_match_len)
&& keylen != KEYLEN_PART_MAP) {
- // When no matching mapping found or found a non-matching mapping
- // that matches at least what the matching mapping matched:
- // Check if we have a terminal code, when:
- // mapping is allowed,
- // keys have not been mapped,
- // and not an ESC sequence, not in insert mode,
- // and when not timed out.
- if ((no_mapping == 0 || allow_keys != 0)
- && (typebuf.tb_maplen == 0
- || (p_remap && typebuf.tb_noremap[
- typebuf.tb_off] == RM_YES))
- && !timedout) {
- keylen = 0;
- } else
- keylen = 0;
- if (keylen == 0) { /* no matching terminal code */
- /* When there was a matching mapping and no
- * termcode could be replaced after another one,
- * use that mapping (loop around). If there was
- * no mapping use the character from the
- * typeahead buffer right here. */
- if (mp == NULL) {
- /*
- * get a character: 2. from the typeahead buffer
- */
- c = typebuf.tb_buf[typebuf.tb_off] & 255;
- if (advance) { /* remove chars from tb_buf */
- cmd_silent = (typebuf.tb_silent > 0);
- if (typebuf.tb_maplen > 0)
- KeyTyped = FALSE;
- else {
- KeyTyped = TRUE;
- /* write char to script file(s) */
- gotchars(typebuf.tb_buf
- + typebuf.tb_off, 1);
- }
- KeyNoremap = typebuf.tb_noremap[
- typebuf.tb_off];
- del_typebuf(1, 0);
+ // No matching mapping found or found a non-matching mapping that
+ // matches at least what the matching mapping matched
+ keylen = 0;
+ // If there was no mapping, use the character from the typeahead
+ // buffer right here. Otherwise, use the mapping (loop around).
+ if (mp == NULL) {
+ // get a character: 2. from the typeahead buffer
+ c = typebuf.tb_buf[typebuf.tb_off] & 255;
+ if (advance) { // remove chars from tb_buf
+ cmd_silent = (typebuf.tb_silent > 0);
+ if (typebuf.tb_maplen > 0) {
+ KeyTyped = false;
+ } else {
+ KeyTyped = true;
+ // write char to script file(s)
+ gotchars(typebuf.tb_buf + typebuf.tb_off, 1);
}
- break; /* got character, break for loop */
+ KeyNoremap = typebuf.tb_noremap[typebuf.tb_off];
+ del_typebuf(1, 0);
}
- }
- if (keylen > 0) { /* full matching terminal code */
- continue; /* try mapping again */
- }
-
- /* Partial match: get some more characters. When a
- * matching mapping was found use that one. */
- if (mp == NULL || keylen < 0)
- keylen = KEYLEN_PART_KEY;
- else
+ break; // got character, break for loop
+ } else {
keylen = mp_match_len;
+ }
}
/* complete match */
diff --git a/src/nvim/memline.c b/src/nvim/memline.c
index b67f550358..1a315fce8b 100644
--- a/src/nvim/memline.c
+++ b/src/nvim/memline.c
@@ -2318,7 +2318,7 @@ ml_append_int (
*
* return FAIL for failure, OK otherwise
*/
-int ml_replace(linenr_T lnum, char_u *line, int copy)
+int ml_replace(linenr_T lnum, char_u *line, bool copy)
{
if (line == NULL) /* just checking... */
return FAIL;
diff --git a/src/nvim/memory.c b/src/nvim/memory.c
index b593936d7b..58c01fbe7a 100644
--- a/src/nvim/memory.c
+++ b/src/nvim/memory.c
@@ -475,6 +475,13 @@ void *xmemdup(const void *data, size_t len)
return memcpy(xmalloc(len), data, len);
}
+/// Returns true if strings `a` and `b` are equal. Arguments may be NULL.
+bool strequal(const char *a, const char *b)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ return (a == NULL && b == NULL) || (a && b && strcmp(a, b) == 0);
+}
+
/*
* Avoid repeating the error message many times (they take 1 second each).
* Did_outofmem_msg is reset when a character is read.
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index 530193bd41..1e4d392754 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -3438,43 +3438,47 @@ dis_msg (
os_breakcheck();
}
-/*
- * If "process" is TRUE and the line begins with a comment leader (possibly
- * after some white space), return a pointer to the text after it. Put a boolean
- * value indicating whether the line ends with an unclosed comment in
- * "is_comment".
- * line - line to be processed,
- * process - if FALSE, will only check whether the line ends with an unclosed
- * comment,
- * include_space - whether to also skip space following the comment leader,
- * is_comment - will indicate whether the current line ends with an unclosed
- * comment.
- */
-static char_u *skip_comment(char_u *line, int process, int include_space, int *is_comment)
+/// If \p "process" is true and the line begins with a comment leader (possibly
+/// after some white space), return a pointer to the text after it.
+/// Put a boolean value indicating whether the line ends with an unclosed
+/// comment in "is_comment".
+///
+/// @param line - line to be processed
+/// @param process - if false, will only check whether the line ends
+/// with an unclosed comment,
+/// @param include_space - whether to skip space following the comment leader
+/// @param[out] is_comment - whether the current line ends with an unclosed
+/// comment.
+char_u *skip_comment(
+ char_u *line, bool process, bool include_space, bool *is_comment
+)
{
char_u *comment_flags = NULL;
int lead_len;
int leader_offset = get_last_leader_offset(line, &comment_flags);
- *is_comment = FALSE;
+ *is_comment = false;
if (leader_offset != -1) {
/* Let's check whether the line ends with an unclosed comment.
* If the last comment leader has COM_END in flags, there's no comment.
*/
while (*comment_flags) {
if (*comment_flags == COM_END
- || *comment_flags == ':')
+ || *comment_flags == ':') {
break;
- ++comment_flags;
+ }
+ comment_flags++;
+ }
+ if (*comment_flags != COM_END) {
+ *is_comment = true;
}
- if (*comment_flags != COM_END)
- *is_comment = TRUE;
}
- if (process == FALSE)
+ if (process == false) {
return line;
+ }
- lead_len = get_leader_len(line, &comment_flags, FALSE, include_space);
+ lead_len = get_leader_len(line, &comment_flags, false, include_space);
if (lead_len == 0)
return line;
@@ -3496,8 +3500,9 @@ static char_u *skip_comment(char_u *line, int process, int include_space, int *i
* starting with a closing part of a three-part comment. That's good,
* because we don't want to remove those as this would be annoying.
*/
- if (*comment_flags == ':' || *comment_flags == NUL)
+ if (*comment_flags == ':' || *comment_flags == NUL) {
line += lead_len;
+ }
return line;
}
@@ -3531,7 +3536,7 @@ int do_join(size_t count,
int *comments = NULL;
int remove_comments = (use_formatoptions == TRUE)
&& has_format_option(FO_REMOVE_COMS);
- int prev_was_comment;
+ bool prev_was_comment;
if (save_undo && u_save(curwin->w_cursor.lnum - 1,
curwin->w_cursor.lnum + (linenr_T)count) == FAIL) {
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 8990b59f57..4a8ca741db 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -1490,7 +1490,7 @@ do_set (
new_value_alloced = true;
if (newval == NULL) {
newval = empty_option;
- } else if (!(options[opt_idx].flags | P_NO_DEF_EXP)) {
+ } else if (!(options[opt_idx].flags & P_NO_DEF_EXP)) {
s = option_expand(opt_idx, newval);
if (s == NULL) {
s = newval;
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c
index cec7fc84a5..bd925a8106 100644
--- a/src/nvim/terminal.c
+++ b/src/nvim/terminal.c
@@ -238,6 +238,7 @@ Terminal *terminal_open(TerminalOptions opts)
set_option_value((uint8_t *)"wrap", false, NULL, OPT_LOCAL);
set_option_value((uint8_t *)"number", false, NULL, OPT_LOCAL);
set_option_value((uint8_t *)"relativenumber", false, NULL, OPT_LOCAL);
+ set_option_value((uint8_t *)"list", false, NULL, OPT_LOCAL);
buf_set_term_title(curbuf, (char *)curbuf->b_ffname);
RESET_BINDING(curwin);
// Reset cursor in current window.
diff --git a/src/nvim/testdir/test_fold.vim b/src/nvim/testdir/test_fold.vim
index 1f835b876f..7cb9faa75f 100644
--- a/src/nvim/testdir/test_fold.vim
+++ b/src/nvim/testdir/test_fold.vim
@@ -96,6 +96,22 @@ func! Test_indent_fold2()
bw!
endfunc
+func Test_folds_marker_in_comment()
+ new
+ call setline(1, ['" foo', 'bar', 'baz'])
+ setl fen fdm=marker
+ setl com=sO:\"\ -,mO:\"\ \ ,eO:\"\",:\" cms=\"%s
+ norm! zf2j
+ setl nofen
+ :1y
+ call assert_equal(['" foo{{{'], getreg(0,1,1))
+ :+2y
+ call assert_equal(['baz"}}}'], getreg(0,1,1))
+
+ set foldmethod&
+ bwipe!
+endfunc
+
func Test_manual_fold_with_filter()
if !executable('cat')
return
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 73a60b2e04..7c7d73fdfb 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -2998,8 +2998,7 @@ void free_tabpage(tabpage_T *tp)
hash_init(&tp->tp_vars->dv_hashtab);
unref_var_dict(tp->tp_vars);
-
- xfree(tp->localdir); // Free tab-local working directory
+ xfree(tp->tp_localdir);
xfree(tp);
}
@@ -3025,7 +3024,7 @@ int win_new_tabpage(int after, char_u *filename)
return FAIL;
}
- newtp->localdir = tp->localdir ? vim_strsave(tp->localdir) : NULL;
+ newtp->tp_localdir = tp->tp_localdir ? vim_strsave(tp->tp_localdir) : NULL;
curtab = newtp;
@@ -3617,28 +3616,38 @@ static void win_enter_ext(win_T *wp, bool undo_sync, int curwin_invalid,
curwin->w_cursor.coladd = 0;
changed_line_abv_curs(); /* assume cursor position needs updating */
- // The new directory is either the local directory of the window, of the tab
- // or NULL.
- char_u *new_dir = curwin->w_localdir ? curwin->w_localdir : curtab->localdir;
+ // New directory is either the local directory of the window, tab or NULL.
+ char *new_dir = (char *)(curwin->w_localdir
+ ? curwin->w_localdir : curtab->tp_localdir);
+
+ char cwd[MAXPATHL];
+ if (os_dirname((char_u *)cwd, MAXPATHL) != OK) {
+ cwd[0] = NUL;
+ }
if (new_dir) {
// Window/tab has a local directory: Save current directory as global
- // directory (unless that was done already) and change to the local
- // directory.
+ // (unless that was done already) and change to the local directory.
if (globaldir == NULL) {
- char_u cwd[MAXPATHL];
-
- if (os_dirname(cwd, MAXPATHL) == OK) {
- globaldir = vim_strsave(cwd);
+ if (cwd[0] != NUL) {
+ globaldir = (char_u *)xstrdup(cwd);
}
}
- if (os_chdir((char *)new_dir) == 0) {
+ if (os_chdir(new_dir) == 0) {
+ if (!p_acd && !strequal(new_dir, cwd)) {
+ do_autocmd_dirchanged(new_dir, curwin->w_localdir
+ ? kCdScopeWindow : kCdScopeTab);
+ }
shorten_fnames(true);
}
} else if (globaldir != NULL) {
- /* Window doesn't have a local directory and we are not in the global
- * directory: Change to the global directory. */
- ignored = os_chdir((char *)globaldir);
+ // Window doesn't have a local directory and we are not in the global
+ // directory: Change to the global directory.
+ if (os_chdir((char *)globaldir) == 0) {
+ if (!p_acd && !strequal((char *)globaldir, cwd)) {
+ do_autocmd_dirchanged((char *)globaldir, kCdScopeGlobal);
+ }
+ }
xfree(globaldir);
globaldir = NULL;
shorten_fnames(TRUE);
diff --git a/test/README.md b/test/README.md
new file mode 100644
index 0000000000..df66f24626
--- /dev/null
+++ b/test/README.md
@@ -0,0 +1,101 @@
+# Tests
+
+Tests are run by `/cmake/RunTests.cmake` file, using busted.
+
+## Directory structure
+
+Directories with tests: `/test/benchmark` for benchmarks, `/test/functional` for
+functional tests, `/test/unit` for unit tests. `/test/config` contains `*.in`
+files (currently a single one) which are transformed into `*.lua` files using
+`configure_file` CMake command: this is for acessing CMake variables in lua
+tests. `/test/includes` contains include files for use by luajit `ffi.cdef`
+C definitions parser: normally used to make macros not accessible via this
+mechanism accessible the other way.
+
+Files `/test/*/preload.lua` contain modules which will be preloaded by busted,
+via `--helper` option. `/test/**/helpers.lua` contain various “library”
+functions, (intended to be) used by a number of tests and not just a single one.
+
+`/test/*/**/*_spec.lua` are files containing actual tests. Files that do not end
+with a `_spec.lua` are libraries like `/test/**/helpers.lua`, except that they
+have some common topic.
+
+Tests inside `/test/unit` and `/test/functional` are normally divided into
+groups by the semantic component they are testing.
+
+## Environment variables
+
+Test behaviour is affected by environment variables. Currently supported
+(Functional, Unit, Benchmarks) (when Defined; when set to _1_; when defined,
+treated as Integer; when defined, treated as String; !must be defined to
+function properly):
+
+`GDB` (F) (D): makes nvim instances to be run under `gdbserver`. It will be
+accessible on `localhost:7777`: use `gdb build/bin/nvim`, type `target remote
+:7777` inside.
+
+`GDBSERVER_PORT` (F) (I): overrides port used for `GDB`.
+
+`VALGRIND` (F) (D): makes nvim instances to be run under `valgrind`. Log files
+are named `valgrind-%p.log` in this case. Note that non-empty valgrind log may
+fail tests. Valgrind arguments may be seen in `/test/functional/helpers.lua`.
+May be used in conjunction with `GDB`.
+
+`VALGRIND_LOG` (F) (S): overrides valgrind log file name used for `VALGRIND`.
+
+`TEST_SKIP_FRAGILE` (F) (D): makes test suite skip some fragile tests.
+
+`NVIM_PROG`, `NVIM_PRG` (F) (S): override path to Neovim executable (default to
+`build/bin/nvim`).
+
+`CC` (U) (S): specifies which C compiler to use to preprocess files. Currently
+only compilers with gcc-compatible arguments are supported.
+
+`NVIM_TEST_MAIN_CDEFS` (U) (1): makes `ffi.cdef` run in main process. This
+raises a possibility of bugs due to conflicts in header definitions, despite the
+counters, but greatly speeds up unit tests by not requiring `ffi.cdef` to do
+parsing of big strings with C definitions.
+
+`NVIM_TEST_PRINT_I` (U) (1): makes `cimport` print preprocessed, but not yet
+filtered through `formatc` headers. Used to debug `formatc`. Printing is done
+with the line numbers.
+
+`NVIM_TEST_PRINT_CDEF` (U) (1): makes `cimport` print final lines which will be
+then passed to `ffi.cdef`. Used to debug errors `ffi.cdef` happens to throw
+sometimes.
+
+`NVIM_TEST_PRINT_SYSCALLS` (U) (1): makes it print to stderr when syscall
+wrappers are called and what they returned. Used to debug code which makes unit
+tests be executed in separate processes.
+
+`NVIM_TEST_RUN_FAILING_TESTS` (U) (1): makes `itp` run tests which are known to
+fail (marked by setting third argument to `true`).
+
+`LOG_DIR` (FU) (S!): specifies where to seek for valgrind and ASAN log files.
+
+`NVIM_TEST_CORE_*` (FU) (S): a set of environment variables which specify where
+to search for core files. Are supposed to be defined all at once.
+
+`NVIM_TEST_CORE_GLOB_DIRECTORY` (FU) (S): directory where core files are
+located. May be `.`. This directory is then recursively searched for core files.
+Note: this variable must be defined for any of the following to have any effect.
+
+`NVIM_TEST_CORE_GLOB_RE` (FU) (S): regular expression which must be matched by
+core files. E.g. `/core[^/]*$`. May be absent, in which case any file is
+considered to be matched.
+
+`NVIM_TEST_CORE_EXC_RE` (FU) (S): regular expression which excludes certain
+directories from searching for core files inside. E.g. use `^/%.deps$` to not
+search inside `/.deps`. If absent, nothing is excluded.
+
+`NVIM_TEST_CORE_DB_CMD` (FU) (S): command to get backtrace out of the debugger.
+E.g. `gdb -n -batch -ex "thread apply all bt full" "$_NVIM_TEST_APP" -c
+"$_NVIM_TEST_CORE"`. Defaults to the example command. This debug command may use
+environment variables `_NVIM_TEST_APP` (path to application which is being
+debugged: normally either nvim or luajit) and `_NVIM_TEST_CORE` (core file to
+get backtrace from).
+
+`NVIM_TEST_CORE_RANDOM_SKIP` (FU) (D): makes `check_cores` not check cores after
+approximately 90% of the tests. Should be used when finding cores is too hard
+for some reason. Normally (on OS X or when `NVIM_TEST_CORE_GLOB_DIRECTORY` is
+defined and this variable is not) cores are checked for after each test.
diff --git a/test/config/paths.lua.in b/test/config/paths.lua.in
index 80cc5629d1..8dd4de75db 100644
--- a/test/config/paths.lua.in
+++ b/test/config/paths.lua.in
@@ -8,6 +8,15 @@ end
module.test_include_path = "${CMAKE_BINARY_DIR}/test/includes/post"
module.test_libnvim_path = "${TEST_LIBNVIM_PATH}"
module.test_source_path = "${CMAKE_SOURCE_DIR}"
+module.test_lua_prg = "${LUA_PRG}"
+module.test_luajit_prg = ""
+if module.test_luajit_prg == '' then
+ if module.test_lua_prg:sub(-6) == 'luajit' then
+ module.test_luajit_prg = module.test_lua_prg
+ else
+ module.test_luajit_prg = nil
+ end
+end
table.insert(module.include_paths, "${CMAKE_BINARY_DIR}/include")
return module
diff --git a/test/functional/autocmd/dirchanged_spec.lua b/test/functional/autocmd/dirchanged_spec.lua
index 15196dbd44..63cf0bc410 100644
--- a/test/functional/autocmd/dirchanged_spec.lua
+++ b/test/functional/autocmd/dirchanged_spec.lua
@@ -20,29 +20,44 @@ describe('autocmd DirChanged', function()
before_each(function()
clear()
- command('autocmd DirChanged * let [g:event, g:scope, g:cdcount] = [copy(v:event), expand("<amatch>"), 1 + get(g:, "cdcount", 0)]')
+ command('autocmd DirChanged * let [g:getcwd, g:ev, g:amatch, g:cdcount] '
+ ..' = [getcwd(), copy(v:event), expand("<amatch>"), 1 + get(g:, "cdcount", 0)]')
+ -- Normalize path separators.
+ command([[autocmd DirChanged * let g:ev['cwd'] = substitute(g:ev['cwd'], '\\', '/', 'g')]])
+ command([[autocmd DirChanged * let g:getcwd = substitute(g:getcwd, '\\', '/', 'g')]])
end)
it('sets v:event', function()
command('lcd '..dirs[1])
- eq({cwd=dirs[1], scope='window'}, eval('g:event'))
+ eq({cwd=dirs[1], scope='window'}, eval('g:ev'))
eq(1, eval('g:cdcount'))
command('tcd '..dirs[2])
- eq({cwd=dirs[2], scope='tab'}, eval('g:event'))
+ eq({cwd=dirs[2], scope='tab'}, eval('g:ev'))
eq(2, eval('g:cdcount'))
command('cd '..dirs[3])
- eq({cwd=dirs[3], scope='global'}, eval('g:event'))
+ eq({cwd=dirs[3], scope='global'}, eval('g:ev'))
eq(3, eval('g:cdcount'))
end)
+ it('sets getcwd() during event #6260', function()
+ command('lcd '..dirs[1])
+ eq(dirs[1], eval('g:getcwd'))
+
+ command('tcd '..dirs[2])
+ eq(dirs[2], eval('g:getcwd'))
+
+ command('cd '..dirs[3])
+ eq(dirs[3], eval('g:getcwd'))
+ end)
+
it('disallows recursion', function()
command('set shellslash')
-- Set up a _nested_ handler.
command('autocmd DirChanged * nested lcd '..dirs[3])
command('lcd '..dirs[1])
- eq({cwd=dirs[1], scope='window'}, eval('g:event'))
+ eq({cwd=dirs[1], scope='window'}, eval('g:ev'))
eq(1, eval('g:cdcount'))
-- autocmd changed to dirs[3], but did NOT trigger another DirChanged.
eq(dirs[3], eval('getcwd()'))
@@ -50,32 +65,32 @@ describe('autocmd DirChanged', function()
it('sets <amatch> to CWD "scope"', function()
command('lcd '..dirs[1])
- eq('window', eval('g:scope'))
+ eq('window', eval('g:amatch'))
command('tcd '..dirs[2])
- eq('tab', eval('g:scope'))
+ eq('tab', eval('g:amatch'))
command('cd '..dirs[3])
- eq('global', eval('g:scope'))
+ eq('global', eval('g:amatch'))
end)
it('does not trigger if :cd fails', function()
- command('let g:event = {}')
+ command('let g:ev = {}')
local status1, err1 = pcall(function()
command('lcd '..dirs[1] .. '/doesnotexist')
end)
- eq({}, eval('g:event'))
+ eq({}, eval('g:ev'))
local status2, err2 = pcall(function()
command('lcd '..dirs[2] .. '/doesnotexist')
end)
- eq({}, eval('g:event'))
+ eq({}, eval('g:ev'))
local status3, err3 = pcall(function()
command('lcd '..dirs[3] .. '/doesnotexist')
end)
- eq({}, eval('g:event'))
+ eq({}, eval('g:ev'))
eq(false, status1)
eq(false, status2)
@@ -90,24 +105,53 @@ describe('autocmd DirChanged', function()
command('set autochdir')
command('split '..dirs[1]..'/foo')
- eq({cwd=dirs[1], scope='window'}, eval('g:event'))
+ eq({cwd=dirs[1], scope='window'}, eval('g:ev'))
command('split '..dirs[2]..'/bar')
- eq({cwd=dirs[2], scope='window'}, eval('g:event'))
+ eq({cwd=dirs[2], scope='window'}, eval('g:ev'))
+
+ eq(2, eval('g:cdcount'))
+ end)
+
+ it("is triggered by switching to win/tab with different CWD #6054", function()
+ command('lcd '..dirs[3]) -- window 3
+ command('split '..dirs[2]..'/foo') -- window 2
+ command('lcd '..dirs[2])
+ command('split '..dirs[1]..'/bar') -- window 1
+ command('lcd '..dirs[1])
+
+ command('2wincmd w') -- window 2
+ eq({cwd=dirs[2], scope='window'}, eval('g:ev'))
+
+ eq(4, eval('g:cdcount'))
+ command('tabnew') -- tab 2 (tab-local CWD)
+ eq(4, eval('g:cdcount')) -- same CWD, no DirChanged event
+ command('tcd '..dirs[3])
+ command('tabnext') -- tab 1 (no tab-local CWD)
+ eq({cwd=dirs[2], scope='window'}, eval('g:ev'))
+ command('tabnext') -- tab 2
+ eq({cwd=dirs[3], scope='tab'}, eval('g:ev'))
+ eq(7, eval('g:cdcount'))
+
+ command('tabnext') -- tab 1
+ command('3wincmd w') -- window 3
+ eq(9, eval('g:cdcount'))
+ command('tabnext') -- tab 2 (has the *same* CWD)
+ eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
end)
it('is triggered by nvim_set_current_dir()', function()
request('nvim_set_current_dir', dirs[1])
- eq({cwd=dirs[1], scope='global'}, eval('g:event'))
+ eq({cwd=dirs[1], scope='global'}, eval('g:ev'))
request('nvim_set_current_dir', dirs[2])
- eq({cwd=dirs[2], scope='global'}, eval('g:event'))
+ eq({cwd=dirs[2], scope='global'}, eval('g:ev'))
local status, err = pcall(function()
request('nvim_set_current_dir', '/doesnotexist')
end)
eq(false, status)
eq('Failed to change directory', string.match(err, ': (.*)'))
- eq({cwd=dirs[2], scope='global'}, eval('g:event'))
+ eq({cwd=dirs[2], scope='global'}, eval('g:ev'))
end)
end)
diff --git a/test/helpers.lua b/test/helpers.lua
index 25ab80bb50..e5224349c2 100644
--- a/test/helpers.lua
+++ b/test/helpers.lua
@@ -30,13 +30,15 @@ local function glob(initial_path, re, exc_re)
if ((not exc_re or not checked_path:match(exc_re))
and e:sub(1, 1) ~= '.') then
local attrs = lfs.attributes(full_path)
- local check_key = attrs.dev .. ':' .. tostring(attrs.ino)
- if not checked_files[check_key] then
- checked_files[check_key] = true
- if attrs.mode == 'directory' then
- paths_to_check[#paths_to_check + 1] = full_path
- elseif not re or checked_path:match(re) then
- ret[#ret + 1] = full_path
+ if attrs then
+ local check_key = attrs.dev .. ':' .. tostring(attrs.ino)
+ if not checked_files[check_key] then
+ checked_files[check_key] = true
+ if attrs.mode == 'directory' then
+ paths_to_check[#paths_to_check + 1] = full_path
+ elseif not re or checked_path:match(re) then
+ ret[#ret + 1] = full_path
+ end
end
end
end
@@ -212,6 +214,17 @@ local function check_cores(app)
end
end
+local function which(exe)
+ local pipe = io.popen('which ' .. exe, 'r')
+ local ret = pipe:read('*a')
+ pipe:close()
+ if ret == '' then
+ return nil
+ else
+ return ret:sub(1, -2)
+ end
+end
+
return {
eq = eq,
neq = neq,
@@ -224,4 +237,5 @@ return {
glob = glob,
check_cores = check_cores,
hasenv = hasenv,
+ which = which,
}
diff --git a/test/unit/api/helpers.lua b/test/unit/api/helpers.lua
index 166456d2a1..4fb1cee4b3 100644
--- a/test/unit/api/helpers.lua
+++ b/test/unit/api/helpers.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.unit.helpers')
+local helpers = require('test.unit.helpers')(nil)
local eval_helpers = require('test.unit.eval.helpers')
local cimport = helpers.cimport
@@ -19,47 +19,55 @@ local api = cimport('./src/nvim/api/private/defs.h',
local obj2lua
-local obj2lua_tab = {
- [tonumber(api.kObjectTypeArray)] = function(obj)
- local ret = {[type_key]=list_type}
- for i = 1,tonumber(obj.data.array.size) do
- ret[i] = obj2lua(obj.data.array.items[i - 1])
- end
- if ret[1] then
- ret[type_key] = nil
- end
- return ret
- end,
- [tonumber(api.kObjectTypeDictionary)] = function(obj)
- local ret = {}
- for i = 1,tonumber(obj.data.dictionary.size) do
- local kv_pair = obj.data.dictionary.items[i - 1]
- ret[ffi.string(kv_pair.key.data, kv_pair.key.size)] = obj2lua(kv_pair.value)
- end
- return ret
- end,
- [tonumber(api.kObjectTypeBoolean)] = function(obj)
- if obj.data.boolean == false then
- return false
- else
- return true
- end
- end,
- [tonumber(api.kObjectTypeNil)] = function(_)
- return nil_value
- end,
- [tonumber(api.kObjectTypeFloat)] = function(obj)
- return tonumber(obj.data.floating)
- end,
- [tonumber(api.kObjectTypeInteger)] = function(obj)
- return {[type_key]=int_type, value=tonumber(obj.data.integer)}
- end,
- [tonumber(api.kObjectTypeString)] = function(obj)
- return ffi.string(obj.data.string.data, obj.data.string.size)
- end,
-}
+local obj2lua_tab = nil
+
+local function init_obj2lua_tab()
+ if obj2lua_tab then
+ return
+ end
+ obj2lua_tab = {
+ [tonumber(api.kObjectTypeArray)] = function(obj)
+ local ret = {[type_key]=list_type}
+ for i = 1,tonumber(obj.data.array.size) do
+ ret[i] = obj2lua(obj.data.array.items[i - 1])
+ end
+ if ret[1] then
+ ret[type_key] = nil
+ end
+ return ret
+ end,
+ [tonumber(api.kObjectTypeDictionary)] = function(obj)
+ local ret = {}
+ for i = 1,tonumber(obj.data.dictionary.size) do
+ local kv_pair = obj.data.dictionary.items[i - 1]
+ ret[ffi.string(kv_pair.key.data, kv_pair.key.size)] = obj2lua(kv_pair.value)
+ end
+ return ret
+ end,
+ [tonumber(api.kObjectTypeBoolean)] = function(obj)
+ if obj.data.boolean == false then
+ return false
+ else
+ return true
+ end
+ end,
+ [tonumber(api.kObjectTypeNil)] = function(_)
+ return nil_value
+ end,
+ [tonumber(api.kObjectTypeFloat)] = function(obj)
+ return tonumber(obj.data.floating)
+ end,
+ [tonumber(api.kObjectTypeInteger)] = function(obj)
+ return {[type_key]=int_type, value=tonumber(obj.data.integer)}
+ end,
+ [tonumber(api.kObjectTypeString)] = function(obj)
+ return ffi.string(obj.data.string.data, obj.data.string.size)
+ end,
+ }
+end
obj2lua = function(obj)
+ init_obj2lua_tab()
return ((obj2lua_tab[tonumber(obj['type'])] or function(obj_inner)
assert(false, 'Converting ' .. tostring(tonumber(obj_inner['type'])) .. ' is not implementing yet')
end)(obj))
diff --git a/test/unit/api/private_helpers_spec.lua b/test/unit/api/private_helpers_spec.lua
index 8c54ea6a2a..a534d83165 100644
--- a/test/unit/api/private_helpers_spec.lua
+++ b/test/unit/api/private_helpers_spec.lua
@@ -1,4 +1,5 @@
-local helpers = require('test.unit.helpers')
+local helpers = require('test.unit.helpers')(after_each)
+local itp = helpers.gen_itp(it)
local eval_helpers = require('test.unit.eval.helpers')
local api_helpers = require('test.unit.api.helpers')
@@ -25,7 +26,7 @@ describe('vim_to_object', function()
end
local different_output_test = function(name, input, output)
- it(name, function()
+ itp(name, function()
eq(output, vim_to_object(input))
end)
end
@@ -76,19 +77,19 @@ describe('vim_to_object', function()
different_output_test('outputs nil for nested lists (2 level, in dict)',
lst3, {{lst=nil_value}, true, false, 'ttest'})
- it('outputs empty list for NULL list', function()
+ itp('outputs empty list for NULL list', function()
local tt = typvalt('VAR_LIST', {v_list=NULL})
eq(nil, tt.vval.v_list)
eq({[type_key]=list_type}, obj2lua(api.vim_to_object(tt)))
end)
- it('outputs empty dict for NULL dict', function()
+ itp('outputs empty dict for NULL dict', function()
local tt = typvalt('VAR_DICT', {v_dict=NULL})
eq(nil, tt.vval.v_dict)
eq({}, obj2lua(api.vim_to_object(tt)))
end)
- it('regression: partials in a list', function()
+ itp('regression: partials in a list', function()
local llist = {
{
[type_key]=func_type,
diff --git a/test/unit/buffer_spec.lua b/test/unit/buffer_spec.lua
index 49a4d84279..f7124b2782 100644
--- a/test/unit/buffer_spec.lua
+++ b/test/unit/buffer_spec.lua
@@ -1,5 +1,6 @@
-local helpers = require("test.unit.helpers")
+local helpers = require("test.unit.helpers")(after_each)
+local itp = helpers.gen_itp(it)
local to_cstr = helpers.to_cstr
local get_str = helpers.ffi.string
@@ -39,17 +40,17 @@ describe('buffer functions', function()
describe('buf_valid', function()
- it('should view NULL as an invalid buffer', function()
+ itp('should view NULL as an invalid buffer', function()
eq(false, buffer.buf_valid(NULL))
end)
- it('should view an open buffer as valid', function()
+ itp('should view an open buffer as valid', function()
local buf = buflist_new(path1, buffer.BLN_LISTED)
eq(true, buffer.buf_valid(buf))
end)
- it('should view a closed and hidden buffer as valid', function()
+ itp('should view a closed and hidden buffer as valid', function()
local buf = buflist_new(path1, buffer.BLN_LISTED)
close_buffer(NULL, buf, 0, 0)
@@ -57,7 +58,7 @@ describe('buffer functions', function()
eq(true, buffer.buf_valid(buf))
end)
- it('should view a closed and unloaded buffer as valid', function()
+ itp('should view a closed and unloaded buffer as valid', function()
local buf = buflist_new(path1, buffer.BLN_LISTED)
close_buffer(NULL, buf, buffer.DOBUF_UNLOAD, 0)
@@ -65,7 +66,7 @@ describe('buffer functions', function()
eq(true, buffer.buf_valid(buf))
end)
- it('should view a closed and wiped buffer as invalid', function()
+ itp('should view a closed and wiped buffer as invalid', function()
local buf = buflist_new(path1, buffer.BLN_LISTED)
close_buffer(NULL, buf, buffer.DOBUF_WIPE, 0)
@@ -84,7 +85,7 @@ describe('buffer functions', function()
return buffer.buflist_findpat(to_cstr(pat), NULL, allow_unlisted, 0, 0)
end
- it('should find exact matches', function()
+ itp('should find exact matches', function()
local buf = buflist_new(path1, buffer.BLN_LISTED)
eq(buf.handle, buflist_findpat(path1, ONLY_LISTED))
@@ -92,7 +93,7 @@ describe('buffer functions', function()
close_buffer(NULL, buf, buffer.DOBUF_WIPE, 0)
end)
- it('should prefer to match the start of a file path', function()
+ itp('should prefer to match the start of a file path', function()
local buf1 = buflist_new(path1, buffer.BLN_LISTED)
local buf2 = buflist_new(path2, buffer.BLN_LISTED)
local buf3 = buflist_new(path3, buffer.BLN_LISTED)
@@ -106,7 +107,7 @@ describe('buffer functions', function()
close_buffer(NULL, buf3, buffer.DOBUF_WIPE, 0)
end)
- it('should prefer to match the end of a file over the middle', function()
+ itp('should prefer to match the end of a file over the middle', function()
--{ Given: Two buffers, where 'test' appears in both
-- And: 'test' appears at the end of buf3 but in the middle of buf2
local buf2 = buflist_new(path2, buffer.BLN_LISTED)
@@ -130,7 +131,7 @@ describe('buffer functions', function()
close_buffer(NULL, buf3, buffer.DOBUF_WIPE, 0)
end)
- it('should match a unique fragment of a file path', function()
+ itp('should match a unique fragment of a file path', function()
local buf1 = buflist_new(path1, buffer.BLN_LISTED)
local buf2 = buflist_new(path2, buffer.BLN_LISTED)
local buf3 = buflist_new(path3, buffer.BLN_LISTED)
@@ -142,7 +143,7 @@ describe('buffer functions', function()
close_buffer(NULL, buf3, buffer.DOBUF_WIPE, 0)
end)
- it('should include / ignore unlisted buffers based on the flag.', function()
+ itp('should include / ignore unlisted buffers based on the flag.', function()
--{ Given: A buffer
local buf3 = buflist_new(path3, buffer.BLN_LISTED)
@@ -169,7 +170,7 @@ describe('buffer functions', function()
--}
end)
- it('should prefer listed buffers to unlisted buffers.', function()
+ itp('should prefer listed buffers to unlisted buffers.', function()
--{ Given: Two buffers that match a pattern
local buf1 = buflist_new(path1, buffer.BLN_LISTED)
local buf2 = buflist_new(path2, buffer.BLN_LISTED)
@@ -265,7 +266,7 @@ describe('buffer functions', function()
local expected_cell_count = option.expected_cell_count or statusline_cell_count
local expected_byte_length = option.expected_byte_length or expected_cell_count
- it(description, function()
+ itp(description, function()
if option.file_name then
buffer.setfname(globals.curbuf, to_cstr(option.file_name), NULL, 1)
else
diff --git a/test/unit/eval/decode_spec.lua b/test/unit/eval/decode_spec.lua
index 742b754d8a..2d7597c0f4 100644
--- a/test/unit/eval/decode_spec.lua
+++ b/test/unit/eval/decode_spec.lua
@@ -1,4 +1,5 @@
-local helpers = require('test.unit.helpers')
+local helpers = require('test.unit.helpers')(after_each)
+local itp = helpers.gen_itp(it)
local cimport = helpers.cimport
local to_cstr = helpers.to_cstr
@@ -11,25 +12,11 @@ local decode = cimport('./src/nvim/eval/decode.h', './src/nvim/eval_defs.h',
'./src/nvim/message.h')
describe('json_decode_string()', function()
- local saved_p_enc = nil
-
- before_each(function()
- saved_p_enc = decode.p_enc
- end)
-
- after_each(function()
- decode.emsg_silent = 0
- decode.p_enc = saved_p_enc
- while decode.delete_first_msg() == 1 do
- -- Delete all messages
- end
- end)
-
local char = function(c)
return ffi.gc(decode.xmemdup(c, 1), decode.xfree)
end
- it('does not overflow when running with `n…`, `t…`, `f…`', function()
+ itp('does not overflow when running with `n…`, `t…`, `f…`', function()
local rettv = ffi.new('typval_T', {v_type=decode.VAR_UNKNOWN})
decode.emsg_silent = 1
-- This will not crash, but if `len` argument will be ignored it will parse
@@ -56,7 +43,7 @@ describe('json_decode_string()', function()
eq(decode.VAR_UNKNOWN, rettv.v_type)
end)
- it('does not overflow and crash when running with `n`, `t`, `f`', function()
+ itp('does not overflow and crash when running with `n`, `t`, `f`', function()
local rettv = ffi.new('typval_T', {v_type=decode.VAR_UNKNOWN})
decode.emsg_silent = 1
eq(0, decode.json_decode_string(char('n'), 1, rettv))
@@ -67,7 +54,7 @@ describe('json_decode_string()', function()
eq(decode.VAR_UNKNOWN, rettv.v_type)
end)
- it('does not overflow when running with `"…`', function()
+ itp('does not overflow when running with `"…`', function()
local rettv = ffi.new('typval_T', {v_type=decode.VAR_UNKNOWN})
decode.emsg_silent = 1
eq(0, decode.json_decode_string('"t"', 2, rettv))
@@ -84,7 +71,8 @@ describe('json_decode_string()', function()
eq(msg, ffi.string(decode.last_msg_hist.msg))
end
- it('does not overflow in error messages', function()
+ itp('does not overflow in error messages', function()
+ local saved_p_enc = decode.p_enc
check_failure(']test', 1, 'E474: No container to close: ]')
check_failure('[}test', 2, 'E474: Closing list with curly bracket: }')
check_failure('{]test', 2,
@@ -129,11 +117,11 @@ describe('json_decode_string()', function()
check_failure('[1test', 2, 'E474: Unexpected end of input: [1')
end)
- it('does not overflow with `-`', function()
+ itp('does not overflow with `-`', function()
check_failure('-0', 1, 'E474: Missing number after minus sign: -')
end)
- it('does not overflow and crash when running with `"`', function()
+ itp('does not overflow and crash when running with `"`', function()
local rettv = ffi.new('typval_T', {v_type=decode.VAR_UNKNOWN})
decode.emsg_silent = 1
eq(0, decode.json_decode_string(char('"'), 1, rettv))
diff --git a/test/unit/eval/encode_spec.lua b/test/unit/eval/encode_spec.lua
index 98fc8305e0..058c55093e 100644
--- a/test/unit/eval/encode_spec.lua
+++ b/test/unit/eval/encode_spec.lua
@@ -1,4 +1,5 @@
-local helpers = require('test.unit.helpers')
+local helpers = require('test.unit.helpers')(after_each)
+local itp = helpers.gen_itp(it)
local eval_helpers = require('test.unit.eval.helpers')
local cimport = helpers.cimport
@@ -18,25 +19,25 @@ describe('encode_list_write()', function()
return encode.encode_list_write(l, to_cstr(s), #s)
end
- it('writes empty string', function()
+ itp('writes empty string', function()
local l = list()
eq(0, encode_list_write(l, ''))
eq({[type_key]=list_type}, lst2tbl(l))
end)
- it('writes ASCII string literal with printable characters', function()
+ itp('writes ASCII string literal with printable characters', function()
local l = list()
eq(0, encode_list_write(l, 'abc'))
eq({'abc'}, lst2tbl(l))
end)
- it('writes string starting with NL', function()
+ itp('writes string starting with NL', function()
local l = list()
eq(0, encode_list_write(l, '\nabc'))
eq({null_string, 'abc'}, lst2tbl(l))
end)
- it('writes string starting with NL twice', function()
+ itp('writes string starting with NL twice', function()
local l = list()
eq(0, encode_list_write(l, '\nabc'))
eq({null_string, 'abc'}, lst2tbl(l))
@@ -44,13 +45,13 @@ describe('encode_list_write()', function()
eq({null_string, 'abc', 'abc'}, lst2tbl(l))
end)
- it('writes string ending with NL', function()
+ itp('writes string ending with NL', function()
local l = list()
eq(0, encode_list_write(l, 'abc\n'))
eq({'abc', null_string}, lst2tbl(l))
end)
- it('writes string ending with NL twice', function()
+ itp('writes string ending with NL twice', function()
local l = list()
eq(0, encode_list_write(l, 'abc\n'))
eq({'abc', null_string}, lst2tbl(l))
@@ -58,7 +59,7 @@ describe('encode_list_write()', function()
eq({'abc', 'abc', null_string}, lst2tbl(l))
end)
- it('writes string starting, ending and containing NL twice', function()
+ itp('writes string starting, ending and containing NL twice', function()
local l = list()
eq(0, encode_list_write(l, '\na\nb\n'))
eq({null_string, 'a', 'b', null_string}, lst2tbl(l))
@@ -66,7 +67,7 @@ describe('encode_list_write()', function()
eq({null_string, 'a', 'b', null_string, 'a', 'b', null_string}, lst2tbl(l))
end)
- it('writes string starting, ending and containing NUL with NL between twice', function()
+ itp('writes string starting, ending and containing NUL with NL between twice', function()
local l = list()
eq(0, encode_list_write(l, '\0\n\0\n\0'))
eq({'\n', '\n', '\n'}, lst2tbl(l))
@@ -74,7 +75,7 @@ describe('encode_list_write()', function()
eq({'\n', '\n', '\n\n', '\n', '\n'}, lst2tbl(l))
end)
- it('writes string starting, ending and containing NL with NUL between twice', function()
+ itp('writes string starting, ending and containing NL with NUL between twice', function()
local l = list()
eq(0, encode_list_write(l, '\n\0\n\0\n'))
eq({null_string, '\n', '\n', null_string}, lst2tbl(l))
@@ -82,7 +83,7 @@ describe('encode_list_write()', function()
eq({null_string, '\n', '\n', null_string, '\n', '\n', null_string}, lst2tbl(l))
end)
- it('writes string containing a single NL twice', function()
+ itp('writes string containing a single NL twice', function()
local l = list()
eq(0, encode_list_write(l, '\n'))
eq({null_string, null_string}, lst2tbl(l))
@@ -90,7 +91,7 @@ describe('encode_list_write()', function()
eq({null_string, null_string, null_string}, lst2tbl(l))
end)
- it('writes string containing a few NLs twice', function()
+ itp('writes string containing a few NLs twice', function()
local l = list()
eq(0, encode_list_write(l, '\n\n\n'))
eq({null_string, null_string, null_string, null_string}, lst2tbl(l))
diff --git a/test/unit/eval/helpers.lua b/test/unit/eval/helpers.lua
index c3c27e4fed..1377d5b501 100644
--- a/test/unit/eval/helpers.lua
+++ b/test/unit/eval/helpers.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.unit.helpers')
+local helpers = require('test.unit.helpers')(nil)
local cimport = helpers.cimport
local to_cstr = helpers.to_cstr
@@ -46,12 +46,6 @@ local function list(...)
return ret
end
-local special_tab = {
- [eval.kSpecialVarFalse] = false,
- [eval.kSpecialVarNull] = nil_value,
- [eval.kSpecialVarTrue] = true,
-}
-
local ptr2key = function(ptr)
return tostring(ptr)
end
@@ -60,64 +54,74 @@ local lst2tbl
local dct2tbl
local typvalt2lua
-local typvalt2lua_tab
+local typvalt2lua_tab = nil
-typvalt2lua_tab = {
- [tonumber(eval.VAR_SPECIAL)] = function(t)
- return special_tab[t.vval.v_special]
- end,
- [tonumber(eval.VAR_NUMBER)] = function(t)
- return {[type_key]=int_type, value=tonumber(t.vval.v_number)}
- end,
- [tonumber(eval.VAR_FLOAT)] = function(t)
- return tonumber(t.vval.v_float)
- end,
- [tonumber(eval.VAR_STRING)] = function(t)
- local str = t.vval.v_string
- if str == nil then
- return null_string
- else
- return ffi.string(str)
- end
- end,
- [tonumber(eval.VAR_LIST)] = function(t, processed)
- return lst2tbl(t.vval.v_list, processed)
- end,
- [tonumber(eval.VAR_DICT)] = function(t, processed)
- return dct2tbl(t.vval.v_dict, processed)
- end,
- [tonumber(eval.VAR_FUNC)] = function(t, processed)
- return {[type_key]=func_type, value=typvalt2lua_tab[eval.VAR_STRING](t, processed or {})}
- end,
- [tonumber(eval.VAR_PARTIAL)] = function(t, processed)
- local p_key = ptr2key(t)
- if processed[p_key] then
- return processed[p_key]
- end
- local pt = t.vval.v_partial
- local value, auto, dict, argv = nil, nil, nil, nil
- if pt ~= nil then
- value = ffi.string(pt.pt_name)
- auto = pt.pt_auto and true or nil
- argv = {}
- for i = 1, pt.pt_argc do
- argv[i] = typvalt2lua(pt.pt_argv[i - 1], processed)
+local function typvalt2lua_tab_init()
+ if typvalt2lua_tab then
+ return
+ end
+ typvalt2lua_tab = {
+ [tonumber(eval.VAR_SPECIAL)] = function(t)
+ return ({
+ [eval.kSpecialVarFalse] = false,
+ [eval.kSpecialVarNull] = nil_value,
+ [eval.kSpecialVarTrue] = true,
+ })[t.vval.v_special]
+ end,
+ [tonumber(eval.VAR_NUMBER)] = function(t)
+ return {[type_key]=int_type, value=tonumber(t.vval.v_number)}
+ end,
+ [tonumber(eval.VAR_FLOAT)] = function(t)
+ return tonumber(t.vval.v_float)
+ end,
+ [tonumber(eval.VAR_STRING)] = function(t)
+ local str = t.vval.v_string
+ if str == nil then
+ return null_string
+ else
+ return ffi.string(str)
end
- if pt.pt_dict ~= nil then
- dict = dct2tbl(pt.pt_dict)
+ end,
+ [tonumber(eval.VAR_LIST)] = function(t, processed)
+ return lst2tbl(t.vval.v_list, processed)
+ end,
+ [tonumber(eval.VAR_DICT)] = function(t, processed)
+ return dct2tbl(t.vval.v_dict, processed)
+ end,
+ [tonumber(eval.VAR_FUNC)] = function(t, processed)
+ return {[type_key]=func_type, value=typvalt2lua_tab[eval.VAR_STRING](t, processed or {})}
+ end,
+ [tonumber(eval.VAR_PARTIAL)] = function(t, processed)
+ local p_key = ptr2key(t)
+ if processed[p_key] then
+ return processed[p_key]
end
- end
- return {
- [type_key]=func_type,
- value=value,
- auto=auto,
- args=argv,
- dict=dict,
- }
- end,
-}
+ local pt = t.vval.v_partial
+ local value, auto, dict, argv = nil, nil, nil, nil
+ if pt ~= nil then
+ value = ffi.string(pt.pt_name)
+ auto = pt.pt_auto and true or nil
+ argv = {}
+ for i = 1, pt.pt_argc do
+ argv[i] = typvalt2lua(pt.pt_argv[i - 1], processed)
+ end
+ if pt.pt_dict ~= nil then
+ dict = dct2tbl(pt.pt_dict)
+ end
+ end
+ return {
+ [type_key]=func_type,
+ value=value,
+ auto=auto,
+ args=argv,
+ dict=dict,
+ }
+ end,
+ }
+end
typvalt2lua = function(t, processed)
+ typvalt2lua_tab_init()
return ((typvalt2lua_tab[tonumber(t.v_type)] or function(t_inner)
assert(false, 'Converting ' .. tonumber(t_inner.v_type) .. ' was not implemented yet')
end)(t, processed or {}))
@@ -169,9 +173,10 @@ lst2tbl = function(l, processed)
return ret
end
-local hi_key_removed = eval._hash_key_removed()
+local hi_key_removed = nil
local function dict_iter(d, return_hi)
+ hi_key_removed = hi_key_removed or eval._hash_key_removed()
local init_s = {
todo=d.dv_hashtab.ht_used,
hi=d.dv_hashtab.ht_array,
@@ -320,25 +325,28 @@ local lua2typvalt_type_tab = {
end,
}
-local special_vals = {
- [null_string] = {eval.VAR_STRING, {v_string=ffi.cast('char_u*', nil)}},
- [null_list] = {eval.VAR_LIST, {v_list=ffi.cast('list_T*', nil)}},
- [null_dict] = {eval.VAR_DICT, {v_dict=ffi.cast('dict_T*', nil)}},
- [nil_value] = {eval.VAR_SPECIAL, {v_special=eval.kSpecialVarNull}},
- [true] = {eval.VAR_SPECIAL, {v_special=eval.kSpecialVarTrue}},
- [false] = {eval.VAR_SPECIAL, {v_special=eval.kSpecialVarFalse}},
-}
+local special_vals = nil
-for k, v in pairs(special_vals) do
- local tmp = function(typ, vval)
- special_vals[k] = function()
- return typvalt(typ, vval)
+lua2typvalt = function(l, processed)
+ if not special_vals then
+ special_vals = {
+ [null_string] = {'VAR_STRING', {v_string=ffi.cast('char_u*', nil)}},
+ [null_list] = {'VAR_LIST', {v_list=ffi.cast('list_T*', nil)}},
+ [null_dict] = {'VAR_DICT', {v_dict=ffi.cast('dict_T*', nil)}},
+ [nil_value] = {'VAR_SPECIAL', {v_special=eval.kSpecialVarNull}},
+ [true] = {'VAR_SPECIAL', {v_special=eval.kSpecialVarTrue}},
+ [false] = {'VAR_SPECIAL', {v_special=eval.kSpecialVarFalse}},
+ }
+
+ for k, v in pairs(special_vals) do
+ local tmp = function(typ, vval)
+ special_vals[k] = function()
+ return typvalt(eval[typ], vval)
+ end
+ end
+ tmp(v[1], v[2])
end
end
- tmp(v[1], v[2])
-end
-
-lua2typvalt = function(l, processed)
processed = processed or {}
if l == nil or l == nil_value then
return special_vals[nil_value]()
@@ -360,7 +368,7 @@ lua2typvalt = function(l, processed)
return typvalt(eval.VAR_STRING, {v_string=eval.xmemdupz(to_cstr(l), #l)})
elseif type(l) == 'cdata' then
local tv = typvalt(eval.VAR_UNKNOWN)
- eval.tv_copy(l, tv)
+ eval.copy_tv(l, tv)
return tv
end
end
diff --git a/test/unit/eval/tricks_spec.lua b/test/unit/eval/tricks_spec.lua
index 4c5184995c..ec79a9cad5 100644
--- a/test/unit/eval/tricks_spec.lua
+++ b/test/unit/eval/tricks_spec.lua
@@ -1,4 +1,5 @@
-local helpers = require('test.unit.helpers')
+local helpers = require('test.unit.helpers')(after_each)
+local itp = helpers.gen_itp(it)
local cimport = helpers.cimport
local to_cstr = helpers.to_cstr
@@ -15,7 +16,7 @@ local eval_expr = function(expr)
end
describe('NULL typval_T', function()
- it('is produced by $XXX_UNEXISTENT_VAR_XXX', function()
+ itp('is produced by $XXX_UNEXISTENT_VAR_XXX', function()
-- Required for various tests which need to check whether typval_T with NULL
-- string works correctly. This test checks that unexistent environment
-- variable produces NULL string, not that some specific environment
@@ -29,13 +30,13 @@ describe('NULL typval_T', function()
eq(nil, rettv.vval.v_string)
end)
- it('is produced by v:_null_list', function()
+ itp('is produced by v:_null_list', function()
local rettv = eval_expr('v:_null_list')
eq(eval.VAR_LIST, rettv.v_type)
eq(nil, rettv.vval.v_list)
end)
- it('is produced by v:_null_dict', function()
+ itp('is produced by v:_null_dict', function()
local rettv = eval_expr('v:_null_dict')
eq(eval.VAR_DICT, rettv.v_type)
eq(nil, rettv.vval.v_dict)
diff --git a/test/unit/eval/tv_clear_spec.lua b/test/unit/eval/tv_clear_spec.lua
index 96eccdbd71..47d4661ad8 100644
--- a/test/unit/eval/tv_clear_spec.lua
+++ b/test/unit/eval/tv_clear_spec.lua
@@ -1,4 +1,5 @@
-local helpers = require('test.unit.helpers')
+local helpers = require('test.unit.helpers')(after_each)
+local itp = helpers.gen_itp(it)
local eval_helpers = require('test.unit.eval.helpers')
local alloc_log_new = helpers.alloc_log_new
@@ -26,7 +27,7 @@ after_each(function()
end)
describe('clear_tv()', function()
- it('successfully frees all lists in [&l [1], *l, *l]', function()
+ itp('successfully frees all lists in [&l [1], *l, *l]', function()
local l_inner = {1}
local list = {l_inner, l_inner, l_inner}
local list_tv = ffi.gc(lua2typvalt(list), nil)
@@ -53,7 +54,7 @@ describe('clear_tv()', function()
a.freed(list_p),
})
end)
- it('successfully frees all lists in [&l [], *l, *l]', function()
+ itp('successfully frees all lists in [&l [], *l, *l]', function()
local l_inner = {[type_key]=list_type}
local list = {l_inner, l_inner, l_inner}
local list_tv = ffi.gc(lua2typvalt(list), nil)
@@ -77,7 +78,7 @@ describe('clear_tv()', function()
a.freed(list_p),
})
end)
- it('successfully frees all dictionaries in [&d {}, *d]', function()
+ itp('successfully frees all dictionaries in [&d {}, *d]', function()
local d_inner = {}
local list = {d_inner, d_inner}
local list_tv = ffi.gc(lua2typvalt(list), nil)
@@ -99,7 +100,7 @@ describe('clear_tv()', function()
a.freed(list_p),
})
end)
- it('successfully frees all dictionaries in [&d {a: 1}, *d]', function()
+ itp('successfully frees all dictionaries in [&d {a: 1}, *d]', function()
local d_inner = {a=1}
local list = {d_inner, d_inner}
local list_tv = ffi.gc(lua2typvalt(list), nil)
diff --git a/test/unit/fileio_spec.lua b/test/unit/fileio_spec.lua
index 3e3c36617d..066d013b19 100644
--- a/test/unit/fileio_spec.lua
+++ b/test/unit/fileio_spec.lua
@@ -1,4 +1,5 @@
-local helpers = require("test.unit.helpers")
+local helpers = require("test.unit.helpers")(after_each)
+local itp = helpers.gen_itp(it)
--{:cimport, :internalize, :eq, :neq, :ffi, :lib, :cstr, :to_cstr} = require 'test.unit.helpers'
local eq = helpers.eq
@@ -16,67 +17,67 @@ describe('file_pat functions', function()
return ffi.string(res)
end
- it('returns ^path$ regex for literal path input', function()
+ itp('returns ^path$ regex for literal path input', function()
eq( '^path$', file_pat_to_reg_pat('path'))
end)
- it('does not prepend ^ when there is a starting glob (*)', function()
+ itp('does not prepend ^ when there is a starting glob (*)', function()
eq('path$', file_pat_to_reg_pat('*path'))
end)
- it('does not append $ when there is an ending glob (*)', function()
+ itp('does not append $ when there is an ending glob (*)', function()
eq('^path', file_pat_to_reg_pat('path*'))
end)
- it('does not include ^ or $ when surrounded by globs (*)', function()
+ itp('does not include ^ or $ when surrounded by globs (*)', function()
eq('path', file_pat_to_reg_pat('*path*'))
end)
- it('replaces the bash any character (?) with the regex any character (.)', function()
+ itp('replaces the bash any character (?) with the regex any character (.)', function()
eq('^foo.bar$', file_pat_to_reg_pat('foo?bar'))
end)
- it('replaces a glob (*) in the middle of a path with regex multiple any character (.*)',
+ itp('replaces a glob (*) in the middle of a path with regex multiple any character (.*)',
function()
eq('^foo.*bar$', file_pat_to_reg_pat('foo*bar'))
end)
- it([[unescapes \? to ?]], function()
+ itp([[unescapes \? to ?]], function()
eq('^foo?bar$', file_pat_to_reg_pat([[foo\?bar]]))
end)
- it([[unescapes \% to %]], function()
+ itp([[unescapes \% to %]], function()
eq('^foo%bar$', file_pat_to_reg_pat([[foo\%bar]]))
end)
- it([[unescapes \, to ,]], function()
+ itp([[unescapes \, to ,]], function()
eq('^foo,bar$', file_pat_to_reg_pat([[foo\,bar]]))
end)
- it([[unescapes '\ ' to ' ']], function()
+ itp([[unescapes '\ ' to ' ']], function()
eq('^foo bar$', file_pat_to_reg_pat([[foo\ bar]]))
end)
- it([[escapes . to \.]], function()
+ itp([[escapes . to \.]], function()
eq([[^foo\.bar$]], file_pat_to_reg_pat('foo.bar'))
end)
- it('Converts bash brace expansion {a,b} to regex options (a|b)', function()
+ itp('Converts bash brace expansion {a,b} to regex options (a|b)', function()
eq([[^foo\(bar\|baz\)$]], file_pat_to_reg_pat('foo{bar,baz}'))
end)
- it('Collapses multiple consecutive * into a single character', function()
+ itp('Collapses multiple consecutive * into a single character', function()
eq([[^foo.*bar$]], file_pat_to_reg_pat('foo*******bar'))
eq([[foobar$]], file_pat_to_reg_pat('********foobar'))
eq([[^foobar]], file_pat_to_reg_pat('foobar********'))
end)
- it('Does not escape ^', function()
+ itp('Does not escape ^', function()
eq([[^^blah$]], file_pat_to_reg_pat('^blah'))
eq([[^foo^bar$]], file_pat_to_reg_pat('foo^bar'))
end)
- it('Does not escape $', function()
+ itp('Does not escape $', function()
eq([[^blah$$]], file_pat_to_reg_pat('blah$'))
eq([[^foo$bar$]], file_pat_to_reg_pat('foo$bar'))
end)
diff --git a/test/unit/fixtures/posix.h b/test/unit/fixtures/posix.h
new file mode 100644
index 0000000000..f6f24cd9dc
--- /dev/null
+++ b/test/unit/fixtures/posix.h
@@ -0,0 +1,11 @@
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/wait.h>
+#include <stdlib.h>
+
+enum {
+ kPOSIXErrnoEINTR = EINTR,
+ kPOSIXErrnoECHILD = ECHILD,
+ kPOSIXWaitWUNTRACED = WUNTRACED,
+};
diff --git a/test/unit/garray_spec.lua b/test/unit/garray_spec.lua
index 422ef7b36a..28df8a6e3f 100644
--- a/test/unit/garray_spec.lua
+++ b/test/unit/garray_spec.lua
@@ -1,4 +1,5 @@
-local helpers = require("test.unit.helpers")
+local helpers = require("test.unit.helpers")(after_each)
+local itp = helpers.gen_itp(it)
local cimport = helpers.cimport
local internalize = helpers.internalize
@@ -8,7 +9,7 @@ local ffi = helpers.ffi
local to_cstr = helpers.to_cstr
local NULL = helpers.NULL
-local garray = cimport('stdlib.h', './src/nvim/garray.h')
+local garray = cimport('./src/nvim/garray.h')
local itemsize = 14
local growsize = 95
@@ -156,7 +157,7 @@ local ga_append_ints = function(garr, ...)
end
-- enhanced constructors
-local garray_ctype = ffi.typeof('garray_T[1]')
+local garray_ctype = function(...) return ffi.typeof('garray_T[1]')(...) end
local new_garray = function()
local garr = garray_ctype()
return ffi.gc(garr, ga_clear)
@@ -183,7 +184,7 @@ end
describe('garray', function()
describe('ga_init', function()
- it('initializes the values of the garray', function()
+ itp('initializes the values of the garray', function()
local garr = new_garray()
ga_init(garr, itemsize, growsize)
eq(0, ga_len(garr))
@@ -204,7 +205,7 @@ describe('garray', function()
return garr
end
- it('grows by growsize items if num < growsize', function()
+ itp('grows by growsize items if num < growsize', function()
itemsize = 16
growsize = 4
local grow_by = growsize - 1
@@ -213,7 +214,7 @@ describe('garray', function()
eq(growsize, ga_maxlen(garr)) -- we requested LESS than growsize, so...
end)
- it('grows by num items if num > growsize', function()
+ itp('grows by num items if num > growsize', function()
itemsize = 16
growsize = 4
local grow_by = growsize + 1
@@ -222,7 +223,7 @@ describe('garray', function()
eq(grow_by, ga_maxlen(garr)) -- we requested MORE than growsize, so...
end)
- it('does not grow when nothing is requested', function()
+ itp('does not grow when nothing is requested', function()
local garr = new_and_grow(16, 4, 0)
eq(NULL, ga_data(garr))
eq(0, ga_maxlen(garr))
@@ -230,7 +231,7 @@ describe('garray', function()
end)
describe('ga_clear', function()
- it('clears an already allocated array', function()
+ itp('clears an already allocated array', function()
-- allocate and scramble an array
local garr = garray_ctype()
ga_init(garr, itemsize, growsize)
@@ -247,7 +248,7 @@ describe('garray', function()
end)
describe('ga_append', function()
- it('can append bytes', function()
+ itp('can append bytes', function()
-- this is the actual ga_append, the others are just emulated lua
-- versions
local garr = new_garray()
@@ -262,7 +263,7 @@ describe('garray', function()
eq('hello', ffi.string(bytes))
end)
- it('can append integers', function()
+ itp('can append integers', function()
local garr = new_garray()
ga_init(garr, ffi.sizeof("int"), 1)
local input = {
@@ -279,7 +280,7 @@ describe('garray', function()
end
end)
- it('can append strings to a growing array of strings', function()
+ itp('can append strings to a growing array of strings', function()
local garr = new_string_garray()
local input = {
"some",
@@ -298,7 +299,7 @@ describe('garray', function()
end)
describe('ga_concat', function()
- it('concatenates the parameter to the growing byte array', function()
+ itp('concatenates the parameter to the growing byte array', function()
local garr = new_garray()
ga_init(garr, ffi.sizeof("char"), 1)
local str = "ohwell●●"
@@ -329,11 +330,11 @@ describe('garray', function()
end
describe('ga_concat_strings', function()
- it('returns an empty string when concatenating an empty array', function()
+ itp('returns an empty string when concatenating an empty array', function()
test_concat_fn({ }, ga_concat_strings)
end)
- it('can concatenate a non-empty array', function()
+ itp('can concatenate a non-empty array', function()
test_concat_fn({
'oh',
'my',
@@ -343,11 +344,11 @@ describe('garray', function()
end)
describe('ga_concat_strings_sep', function()
- it('returns an empty string when concatenating an empty array', function()
+ itp('returns an empty string when concatenating an empty array', function()
test_concat_fn({ }, ga_concat_strings_sep, '---')
end)
- it('can concatenate a non-empty array', function()
+ itp('can concatenate a non-empty array', function()
local sep = '-●●-'
test_concat_fn({
'oh',
@@ -358,7 +359,7 @@ describe('garray', function()
end)
describe('ga_remove_duplicate_strings', function()
- it('sorts and removes duplicate strings', function()
+ itp('sorts and removes duplicate strings', function()
local garr = new_string_garray()
local input = {
'ccc',
diff --git a/test/unit/helpers.lua b/test/unit/helpers.lua
index 4af078b486..612b337ee7 100644
--- a/test/unit/helpers.lua
+++ b/test/unit/helpers.lua
@@ -4,8 +4,15 @@ local Set = require('test.unit.set')
local Preprocess = require('test.unit.preprocess')
local Paths = require('test.config.paths')
local global_helpers = require('test.helpers')
+local assert = require('luassert')
+local say = require('say')
+local posix = nil
+local syscall = nil
+
+local check_cores = global_helpers.check_cores
local neq = global_helpers.neq
+local map = global_helpers.map
local eq = global_helpers.eq
local ok = global_helpers.ok
@@ -15,20 +22,110 @@ local NULL = ffi.cast('void*', 0)
local OK = 1
local FAIL = 0
+local cimport
+
-- add some standard header locations
for _, p in ipairs(Paths.include_paths) do
Preprocess.add_to_include_path(p)
end
--- load neovim shared library
-local libnvim = ffi.load(Paths.test_libnvim_path)
+local child_pid = nil
+local function only_separate(func)
+ return function(...)
+ if child_pid ~= 0 then
+ error('This function must be run in a separate process only')
+ end
+ return func(...)
+ end
+end
+local child_calls_init = {}
+local child_calls_mod = nil
+local child_calls_mod_once = nil
+local function child_call(func, ret)
+ return function(...)
+ local child_calls = child_calls_mod or child_calls_init
+ if child_pid ~= 0 then
+ child_calls[#child_calls + 1] = {func=func, args={...}}
+ return ret
+ else
+ return func(...)
+ end
+ end
+end
+
+-- Run some code at the start of the child process, before running the test
+-- itself. Is supposed to be run in `before_each`.
+local function child_call_once(func, ...)
+ if child_pid ~= 0 then
+ child_calls_mod_once[#child_calls_mod_once + 1] = {
+ func=func, args={...}}
+ else
+ func(...)
+ end
+end
+
+local child_cleanups_mod_once = nil
+
+-- Run some code at the end of the child process, before exiting. Is supposed to
+-- be run in `before_each` because `after_each` is run after child has exited.
+local function child_cleanup_once(func, ...)
+ local child_cleanups = child_cleanups_mod_once
+ if child_pid ~= 0 then
+ child_cleanups[#child_cleanups + 1] = {func=func, args={...}}
+ else
+ func(...)
+ end
+end
+
+local libnvim = nil
+
+local lib = setmetatable({}, {
+ __index = only_separate(function(_, idx)
+ return libnvim[idx]
+ end),
+ __newindex = child_call(function(_, idx, val)
+ libnvim[idx] = val
+ end),
+})
+
+local init = only_separate(function()
+ -- load neovim shared library
+ libnvim = ffi.load(Paths.test_libnvim_path)
+ for _, c in ipairs(child_calls_init) do
+ c.func(unpack(c.args))
+ end
+ libnvim.time_init()
+ libnvim.early_init()
+ libnvim.event_init()
+ if child_calls_mod then
+ for _, c in ipairs(child_calls_mod) do
+ c.func(unpack(c.args))
+ end
+ end
+ if child_calls_mod_once then
+ for _, c in ipairs(child_calls_mod_once) do
+ c.func(unpack(c.args))
+ end
+ child_calls_mod_once = nil
+ end
+end)
+
+local deinit = only_separate(function()
+ if child_cleanups_mod_once then
+ for _, c in ipairs(child_cleanups_mod_once) do
+ c.func(unpack(c.args))
+ end
+ child_cleanups_mod_once = nil
+ end
+end)
local function trim(s)
return s:match('^%s*(.*%S)') or ''
end
-- a Set that keeps around the lines we've already seen
-local cdefs = Set:new()
+local cdefs_init = Set:new()
+local cdefs_mod = nil
local imported = Set:new()
local pragma_pack_id = 1
@@ -51,84 +148,120 @@ local function filter_complex_blocks(body)
return table.concat(result, "\n")
end
-local previous_defines = ''
--- use this helper to import C files, you can pass multiple paths at once,
--- this helper will return the C namespace of the nvim library.
-local function cimport(...)
- local paths = {}
- local args = {...}
-
- -- filter out paths we've already imported
- for _,path in pairs(args) do
- if path ~= nil and not imported:contains(path) then
- paths[#paths + 1] = path
- end
- end
+local cdef = ffi.cdef
- for _,path in pairs(paths) do
- imported:add(path)
- end
+local cimportstr
- if #paths == 0 then
- return libnvim
- end
+local previous_defines_init = ''
+local preprocess_cache_init = {}
+local previous_defines_mod = ''
+local preprocess_cache_mod = nil
- local body
- body, previous_defines = Preprocess.preprocess(previous_defines, unpack(paths))
+local function is_child_cdefs()
+ return (os.getenv('NVIM_TEST_MAIN_CDEFS') ~= '1')
+end
- -- format it (so that the lines are "unique" statements), also filter out
- -- Objective-C blocks
- if os.getenv('NVIM_TEST_PRINT_I') == '1' then
- local lnum = 0
- for line in body:gmatch('[^\n]+') do
- lnum = lnum + 1
- print(lnum, line)
- end
+-- use this helper to import C files, you can pass multiple paths at once,
+-- this helper will return the C namespace of the nvim library.
+cimport = function(...)
+ local previous_defines, preprocess_cache, cdefs
+ if is_child_cdefs() and preprocess_cache_mod then
+ preprocess_cache = preprocess_cache_mod
+ previous_defines = previous_defines_mod
+ cdefs = cdefs_mod
+ else
+ preprocess_cache = preprocess_cache_init
+ previous_defines = previous_defines_init
+ cdefs = cdefs_init
end
- body = formatc(body)
- body = filter_complex_blocks(body)
+ for _, path in ipairs({...}) do
+ if not (path:sub(1, 1) == '/' or path:sub(1, 1) == '.'
+ or path:sub(2, 2) == ':') then
+ path = './' .. path
+ end
+ if not preprocess_cache[path] then
+ local body
+ body, previous_defines = Preprocess.preprocess(previous_defines, path)
+ -- format it (so that the lines are "unique" statements), also filter out
+ -- Objective-C blocks
+ if os.getenv('NVIM_TEST_PRINT_I') == '1' then
+ local lnum = 0
+ for line in body:gmatch('[^\n]+') do
+ lnum = lnum + 1
+ print(lnum, line)
+ end
+ end
+ body = formatc(body)
+ body = filter_complex_blocks(body)
+ -- add the formatted lines to a set
+ local new_cdefs = Set:new()
+ for line in body:gmatch("[^\r\n]+") do
+ line = trim(line)
+ -- give each #pragma pack an unique id, so that they don't get removed
+ -- if they are inserted into the set
+ -- (they are needed in the right order with the struct definitions,
+ -- otherwise luajit has wrong memory layouts for the sturcts)
+ if line:match("#pragma%s+pack") then
+ line = line .. " // " .. pragma_pack_id
+ pragma_pack_id = pragma_pack_id + 1
+ end
+ new_cdefs:add(line)
+ end
- -- add the formatted lines to a set
- local new_cdefs = Set:new()
- for line in body:gmatch("[^\r\n]+") do
- line = trim(line)
- -- give each #pragma pack an unique id, so that they don't get removed
- -- if they are inserted into the set
- -- (they are needed in the right order with the struct definitions,
- -- otherwise luajit has wrong memory layouts for the sturcts)
- if line:match("#pragma%s+pack") then
- line = line .. " // " .. pragma_pack_id
- pragma_pack_id = pragma_pack_id + 1
+ -- subtract the lines we've already imported from the new lines, then add
+ -- the new unique lines to the old lines (so they won't be imported again)
+ new_cdefs:diff(cdefs)
+ cdefs:union(new_cdefs)
+ -- request a sorted version of the new lines (same relative order as the
+ -- original preprocessed file) and feed that to the LuaJIT ffi
+ local new_lines = new_cdefs:to_table()
+ if os.getenv('NVIM_TEST_PRINT_CDEF') == '1' then
+ for lnum, line in ipairs(new_lines) do
+ print(lnum, line)
+ end
+ end
+ body = table.concat(new_lines, '\n')
+
+ preprocess_cache[path] = body
end
- new_cdefs:add(line)
+ cimportstr(preprocess_cache, path)
end
+ return lib
+end
- -- subtract the lines we've already imported from the new lines, then add
- -- the new unique lines to the old lines (so they won't be imported again)
- new_cdefs:diff(cdefs)
- cdefs:union(new_cdefs)
-
- if new_cdefs:size() == 0 then
- -- if there's no new lines, just return
- return libnvim
+local cimport_immediate = function(...)
+ local saved_pid = child_pid
+ child_pid = 0
+ local err, emsg = pcall(cimport, ...)
+ child_pid = saved_pid
+ if not err then
+ emsg = tostring(emsg)
+ io.stderr:write(emsg .. '\n')
+ assert(false)
+ else
+ return lib
end
+end
- -- request a sorted version of the new lines (same relative order as the
- -- original preprocessed file) and feed that to the LuaJIT ffi
- local new_lines = new_cdefs:to_table()
- if os.getenv('NVIM_TEST_PRINT_CDEF') == '1' then
- for lnum, line in ipairs(new_lines) do
- print(lnum, line)
- end
+local function _cimportstr(preprocess_cache, path)
+ if imported:contains(path) then
+ return lib
end
- ffi.cdef(table.concat(new_lines, "\n"))
+ local body = preprocess_cache[path]
+ if body == '' then
+ return lib
+ end
+ cdef(body)
+ imported:add(path)
- return libnvim
+ return lib
end
-local function cppimport(path)
- return cimport(Paths.test_include_path .. '/' .. path)
+if is_child_cdefs() then
+ cimportstr = child_call(_cimportstr, lib)
+else
+ cimportstr = _cimportstr
end
local function alloc_log_new()
@@ -141,9 +274,12 @@ local function alloc_log_new()
local allocator_functions = {'malloc', 'free', 'calloc', 'realloc'}
function log:save_original_functions()
for _, funcname in ipairs(allocator_functions) do
- self.original_functions[funcname] = self.lib['mem_' .. funcname]
+ if not self.original_functions[funcname] then
+ self.original_functions[funcname] = self.lib['mem_' .. funcname]
+ end
end
end
+ log.save_original_functions = child_call(log.save_original_functions)
function log:set_mocks()
for _, k in ipairs(allocator_functions) do
do
@@ -170,6 +306,7 @@ local function alloc_log_new()
end
end
end
+ log.set_mocks = child_call(log.set_mocks)
function log:clear()
self.log = {}
end
@@ -178,22 +315,28 @@ local function alloc_log_new()
self:clear()
end
function log:restore_original_functions()
- for k, v in pairs(self.original_functions) do
- self.lib['mem_' .. k] = v
- end
+ -- Do nothing: set mocks live in a separate process
+ return
+ --[[
+ [ for k, v in pairs(self.original_functions) do
+ [ self.lib['mem_' .. k] = v
+ [ end
+ ]]
end
- function log:before_each()
+ function log:setup()
log:save_original_functions()
log:set_mocks()
end
+ function log:before_each()
+ return
+ end
function log:after_each()
log:restore_original_functions()
end
+ log:setup()
return log
end
-cimport('./src/nvim/types.h')
-
-- take a pointer to a C-allocated string and return an interned
-- version while also freeing the memory
local function internalize(cdata, len)
@@ -206,17 +349,226 @@ local function to_cstr(string)
return cstr(#string + 1, string)
end
--- initialize some global variables, this is still necessary to unit test
--- functions that rely on global state.
-do
- local main = cimport('./src/nvim/main.h')
- local time = cimport('./src/nvim/os/time.h')
- time.time_init()
- main.early_init()
- main.event_init()
+local sc
+
+if posix ~= nil then
+ sc = {
+ fork = posix.fork,
+ pipe = posix.pipe,
+ read = posix.read,
+ write = posix.write,
+ close = posix.close,
+ wait = posix.wait,
+ exit = posix._exit,
+ }
+elseif syscall ~= nil then
+ sc = {
+ fork = syscall.fork,
+ pipe = function()
+ local ret = {syscall.pipe()}
+ return ret[3], ret[4]
+ end,
+ read = function(rd, len)
+ return rd:read(nil, len)
+ end,
+ write = function(wr, s)
+ return wr:write(s)
+ end,
+ close = function(p)
+ return p:close()
+ end,
+ wait = syscall.wait,
+ exit = syscall.exit,
+ }
+else
+ cimport_immediate('./test/unit/fixtures/posix.h')
+ sc = {
+ fork = function()
+ return tonumber(ffi.C.fork())
+ end,
+ pipe = function()
+ local ret = ffi.new('int[2]', {-1, -1})
+ ffi.errno(0)
+ local res = ffi.C.pipe(ret)
+ if (res ~= 0) then
+ local err = ffi.errno(0)
+ assert(res == 0, ("pipe() error: %u: %s"):format(
+ err, ffi.string(ffi.C.strerror(err))))
+ end
+ assert(ret[0] ~= -1 and ret[1] ~= -1)
+ return ret[0], ret[1]
+ end,
+ read = function(rd, len)
+ local ret = ffi.new('char[?]', len, {0})
+ local total_bytes_read = 0
+ ffi.errno(0)
+ while total_bytes_read < len do
+ local bytes_read = tonumber(ffi.C.read(
+ rd,
+ ffi.cast('void*', ret + total_bytes_read),
+ len - total_bytes_read))
+ if bytes_read == -1 then
+ local err = ffi.errno(0)
+ if err ~= ffi.C.kPOSIXErrnoEINTR then
+ assert(false, ("read() error: %u: %s"):format(
+ err, ffi.string(ffi.C.strerror(err))))
+ end
+ elseif bytes_read == 0 then
+ break
+ else
+ total_bytes_read = total_bytes_read + bytes_read
+ end
+ end
+ return ffi.string(ret, total_bytes_read)
+ end,
+ write = function(wr, s)
+ local wbuf = to_cstr(s)
+ local total_bytes_written = 0
+ ffi.errno(0)
+ while total_bytes_written < #s do
+ local bytes_written = tonumber(ffi.C.write(
+ wr,
+ ffi.cast('void*', wbuf + total_bytes_written),
+ #s - total_bytes_written))
+ if bytes_written == -1 then
+ local err = ffi.errno(0)
+ if err ~= ffi.C.kPOSIXErrnoEINTR then
+ assert(false, ("write() error: %u: %s"):format(
+ err, ffi.string(ffi.C.strerror(err))))
+ end
+ elseif bytes_written == 0 then
+ break
+ else
+ total_bytes_written = total_bytes_written + bytes_written
+ end
+ end
+ return total_bytes_written
+ end,
+ close = ffi.C.close,
+ wait = function(pid)
+ ffi.errno(0)
+ while true do
+ local r = ffi.C.waitpid(pid, nil, ffi.C.kPOSIXWaitWUNTRACED)
+ if r == -1 then
+ local err = ffi.errno(0)
+ if err == ffi.C.kPOSIXErrnoECHILD then
+ break
+ elseif err ~= ffi.C.kPOSIXErrnoEINTR then
+ assert(false, ("waitpid() error: %u: %s"):format(
+ err, ffi.string(ffi.C.strerror(err))))
+ end
+ else
+ assert(r == pid)
+ end
+ end
+ end,
+ exit = ffi.C._exit,
+ }
end
-return {
+local function format_list(lst)
+ local ret = ''
+ for _, v in ipairs(lst) do
+ if ret ~= '' then ret = ret .. ', ' end
+ ret = ret .. assert:format({v, n=1})[1]
+ end
+ return ret
+end
+
+if os.getenv('NVIM_TEST_PRINT_SYSCALLS') == '1' then
+ for k_, v_ in pairs(sc) do
+ (function(k, v)
+ sc[k] = function(...)
+ local rets = {v(...)}
+ io.stderr:write(('%s(%s) = %s\n'):format(k, format_list({...}),
+ format_list(rets)))
+ return unpack(rets)
+ end
+ end)(k_, v_)
+ end
+end
+
+local function gen_itp(it)
+ child_calls_mod = {}
+ child_calls_mod_once = {}
+ child_cleanups_mod_once = {}
+ preprocess_cache_mod = map(function(v) return v end, preprocess_cache_init)
+ previous_defines_mod = previous_defines_init
+ cdefs_mod = cdefs_init:copy()
+ local function just_fail(_)
+ return false
+ end
+ say:set('assertion.just_fail.positive', '%s')
+ say:set('assertion.just_fail.negative', '%s')
+ assert:register('assertion', 'just_fail', just_fail,
+ 'assertion.just_fail.positive',
+ 'assertion.just_fail.negative')
+ local function itp(name, func, allow_failure)
+ if allow_failure and os.getenv('NVIM_TEST_RUN_FAILING_TESTS') ~= '1' then
+ -- FIXME Fix tests with this true
+ return
+ end
+ it(name, function()
+ local rd, wr = sc.pipe()
+ child_pid = sc.fork()
+ if child_pid == 0 then
+ init()
+ sc.close(rd)
+ collectgarbage('stop')
+ local err, emsg = pcall(func)
+ collectgarbage('restart')
+ emsg = tostring(emsg)
+ if not err then
+ sc.write(wr, ('-\n%05u\n%s'):format(#emsg, emsg))
+ deinit()
+ sc.close(wr)
+ sc.exit(1)
+ else
+ sc.write(wr, '+\n')
+ deinit()
+ sc.close(wr)
+ sc.exit(0)
+ end
+ else
+ sc.close(wr)
+ sc.wait(child_pid)
+ child_pid = nil
+ local function check()
+ local res = sc.read(rd, 2)
+ eq(2, #res)
+ if res == '+\n' then
+ return
+ end
+ eq('-\n', res)
+ local len_s = sc.read(rd, 5)
+ local len = tonumber(len_s)
+ neq(0, len)
+ local err = sc.read(rd, len + 1)
+ assert.just_fail(err)
+ end
+ local err, emsg = pcall(check)
+ sc.close(rd)
+ if not err then
+ if allow_failure then
+ io.stderr:write('Errorred out:\n' .. tostring(emsg) .. '\n')
+ os.execute([[sh -c "source .ci/common/test.sh ; check_core_dumps --delete \"]] .. Paths.test_luajit_prg .. [[\""]])
+ else
+ error(emsg)
+ end
+ end
+ end
+ end)
+ end
+ return itp
+end
+
+local function cppimport(path)
+ return cimport(Paths.test_include_path .. '/' .. path)
+end
+
+cimport('./src/nvim/types.h', './src/nvim/main.h', './src/nvim/os/time.h')
+
+local module = {
cimport = cimport,
cppimport = cppimport,
internalize = internalize,
@@ -224,11 +576,23 @@ return {
eq = eq,
neq = neq,
ffi = ffi,
- lib = libnvim,
+ lib = lib,
cstr = cstr,
to_cstr = to_cstr,
NULL = NULL,
OK = OK,
FAIL = FAIL,
alloc_log_new = alloc_log_new,
+ gen_itp = gen_itp,
+ only_separate = only_separate,
+ child_call_once = child_call_once,
+ child_cleanup_once = child_cleanup_once,
}
+return function(after_each)
+ if after_each then
+ after_each(function()
+ check_cores(Paths.test_luajit_prg)
+ end)
+ end
+ return module
+end
diff --git a/test/unit/mbyte_spec.lua b/test/unit/mbyte_spec.lua
index 9b2415a93f..6feef4e601 100644
--- a/test/unit/mbyte_spec.lua
+++ b/test/unit/mbyte_spec.lua
@@ -1,4 +1,5 @@
-local helpers = require("test.unit.helpers")
+local helpers = require("test.unit.helpers")(after_each)
+local itp = helpers.gen_itp(it)
local ffi = helpers.ffi
local eq = helpers.eq
@@ -26,7 +27,7 @@ describe('mbyte', function()
before_each(function()
end)
- it('utf_ptr2char', function()
+ itp('utf_ptr2char', function()
-- For strings with length 1 the first byte is returned.
for c = 0, 255 do
eq(c, mbyte.utf_ptr2char(to_string({c, 0})))
@@ -44,7 +45,7 @@ describe('mbyte', function()
describe('utfc_ptr2char_len', function()
- it('1-byte sequences', function()
+ itp('1-byte sequences', function()
local pcc = to_intp()
for c = 0, 255 do
eq(c, mbyte.utfc_ptr2char_len(to_string({c}), pcc, 1))
@@ -52,7 +53,7 @@ describe('mbyte', function()
end
end)
- it('2-byte sequences', function()
+ itp('2-byte sequences', function()
local pcc = to_intp()
-- No combining characters
eq(0x007f, mbyte.utfc_ptr2char_len(to_string({0x7f, 0x7f}), pcc, 2))
@@ -76,7 +77,7 @@ describe('mbyte', function()
eq(0, pcc[0])
end)
- it('3-byte sequences', function()
+ itp('3-byte sequences', function()
local pcc = to_intp()
-- No second UTF-8 character
@@ -108,7 +109,7 @@ describe('mbyte', function()
eq(0, pcc[0])
end)
- it('4-byte sequences', function()
+ itp('4-byte sequences', function()
local pcc = to_intp()
-- No following combining character
@@ -145,7 +146,7 @@ describe('mbyte', function()
eq(0, pcc[0])
end)
- it('5+-byte sequences', function()
+ itp('5+-byte sequences', function()
local pcc = to_intp()
-- No following combining character
diff --git a/test/unit/memory_spec.lua b/test/unit/memory_spec.lua
index 73a32724ef..bd72c8bf47 100644
--- a/test/unit/memory_spec.lua
+++ b/test/unit/memory_spec.lua
@@ -1,4 +1,5 @@
-local helpers = require("test.unit.helpers")
+local helpers = require("test.unit.helpers")(after_each)
+local itp = helpers.gen_itp(it)
local cimport = helpers.cimport
local cstr = helpers.cstr
@@ -26,7 +27,7 @@ describe('xstrlcat()', function()
return ffi.string(dst_cstr)
end
- it('concatenates strings', function()
+ itp('concatenates strings', function()
eq('ab', test_xstrlcat('a', 'b', 3))
eq('ab', test_xstrlcat('a', 'b', 4096))
eq('ABCיהZdefgiיהZ', test_xstrlcat('ABCיהZ', 'defgiיהZ', 4096))
@@ -34,7 +35,7 @@ describe('xstrlcat()', function()
eq('a', test_xstrlcat('a', '', 4096))
end)
- it('concatenates overlapping strings', function()
+ itp('concatenates overlapping strings', function()
eq('abcabc', test_xstrlcat_overlap('abc', 0, 7))
eq('abca', test_xstrlcat_overlap('abc', 0, 5))
eq('abcb', test_xstrlcat_overlap('abc', 1, 5))
@@ -42,7 +43,7 @@ describe('xstrlcat()', function()
eq('abcabc', test_xstrlcat_overlap('abc', 0, 2343))
end)
- it('truncates if `dsize` is too small', function()
+ itp('truncates if `dsize` is too small', function()
eq('a', test_xstrlcat('a', 'b', 2))
eq('', test_xstrlcat('', 'b', 1))
eq('ABCיהZd', test_xstrlcat('ABCיהZ', 'defgiיהZ', 10))
diff --git a/test/unit/message_spec.lua b/test/unit/message_spec.lua
index afb572347f..7e92b5c857 100644
--- a/test/unit/message_spec.lua
+++ b/test/unit/message_spec.lua
@@ -1,4 +1,5 @@
-local helpers = require("test.unit.helpers")
+local helpers = require("test.unit.helpers")(after_each)
+local itp = helpers.gen_itp(it)
local ffi = helpers.ffi
local eq = helpers.eq
@@ -35,23 +36,23 @@ describe('trunc_string', function()
for _,t in ipairs(permutations) do
describe('populates buf '..t.desc, function()
- it('with a small string', function()
+ itp('with a small string', function()
t.func('text', 'text')
end)
- it('with a medium string', function()
+ itp('with a medium string', function()
t.func('a short text', 'a short text')
end)
- it('with a string of length == 1/2 room', function()
+ itp('with a string of length == 1/2 room', function()
t.func('a text that fits', 'a text that fits', 34)
end)
- it('with a string exactly the truncate size', function()
+ itp('with a string exactly the truncate size', function()
t.func('a text tha just fits', 'a text tha just fits')
end)
- it('with a string that must be truncated', function()
+ itp('with a string that must be truncated', function()
t.func('a text that nott fits', 'a text t...nott fits')
end)
end)
diff --git a/test/unit/multiqueue_spec.lua b/test/unit/multiqueue_spec.lua
index c7f8dd8328..bb08a8386f 100644
--- a/test/unit/multiqueue_spec.lua
+++ b/test/unit/multiqueue_spec.lua
@@ -1,9 +1,12 @@
-local helpers = require("test.unit.helpers")
+local helpers = require("test.unit.helpers")(after_each)
+local itp = helpers.gen_itp(it)
-local ffi = helpers.ffi
-local eq = helpers.eq
+local child_call_once = helpers.child_call_once
+local cimport = helpers.cimport
+local ffi = helpers.ffi
+local eq = helpers.eq
-local multiqueue = helpers.cimport("./test/unit/fixtures/multiqueue.h")
+local multiqueue = cimport("./test/unit/fixtures/multiqueue.h")
describe("multiqueue (multi-level event-queue)", function()
local parent, child1, child2, child3
@@ -21,28 +24,30 @@ describe("multiqueue (multi-level event-queue)", function()
end
before_each(function()
- parent = multiqueue.multiqueue_new_parent(ffi.NULL, ffi.NULL)
- child1 = multiqueue.multiqueue_new_child(parent)
- child2 = multiqueue.multiqueue_new_child(parent)
- child3 = multiqueue.multiqueue_new_child(parent)
- put(child1, 'c1i1')
- put(child1, 'c1i2')
- put(child2, 'c2i1')
- put(child1, 'c1i3')
- put(child2, 'c2i2')
- put(child2, 'c2i3')
- put(child2, 'c2i4')
- put(child3, 'c3i1')
- put(child3, 'c3i2')
+ child_call_once(function()
+ parent = multiqueue.multiqueue_new_parent(ffi.NULL, ffi.NULL)
+ child1 = multiqueue.multiqueue_new_child(parent)
+ child2 = multiqueue.multiqueue_new_child(parent)
+ child3 = multiqueue.multiqueue_new_child(parent)
+ put(child1, 'c1i1')
+ put(child1, 'c1i2')
+ put(child2, 'c2i1')
+ put(child1, 'c1i3')
+ put(child2, 'c2i2')
+ put(child2, 'c2i3')
+ put(child2, 'c2i4')
+ put(child3, 'c3i1')
+ put(child3, 'c3i2')
+ end)
end)
- it('keeps count of added events', function()
+ itp('keeps count of added events', function()
eq(3, multiqueue.multiqueue_size(child1))
eq(4, multiqueue.multiqueue_size(child2))
eq(2, multiqueue.multiqueue_size(child3))
end)
- it('keeps count of removed events', function()
+ itp('keeps count of removed events', function()
multiqueue.multiqueue_get(child1)
eq(2, multiqueue.multiqueue_size(child1))
multiqueue.multiqueue_get(child1)
@@ -57,7 +62,7 @@ describe("multiqueue (multi-level event-queue)", function()
eq(0, multiqueue.multiqueue_size(child1))
end)
- it('removing from parent removes from child', function()
+ itp('removing from parent removes from child', function()
eq('c1i1', get(parent))
eq('c1i2', get(parent))
eq('c2i1', get(parent))
@@ -67,7 +72,7 @@ describe("multiqueue (multi-level event-queue)", function()
eq('c2i4', get(parent))
end)
- it('removing from child removes from parent', function()
+ itp('removing from child removes from parent', function()
eq('c2i1', get(child2))
eq('c2i2', get(child2))
eq('c1i1', get(child1))
@@ -77,13 +82,13 @@ describe("multiqueue (multi-level event-queue)", function()
eq('c2i4', get(parent))
end)
- it('removing from child at the beginning of parent', function()
+ itp('removing from child at the beginning of parent', function()
eq('c1i1', get(child1))
eq('c1i2', get(child1))
eq('c2i1', get(parent))
end)
- it('removing from parent after get from parent and put to child', function()
+ itp('removing from parent after get from parent and put to child', function()
eq('c1i1', get(parent))
eq('c1i2', get(parent))
eq('c2i1', get(parent))
@@ -99,7 +104,7 @@ describe("multiqueue (multi-level event-queue)", function()
eq('c1i22', get(parent))
end)
- it('removing from parent after get and put to child', function()
+ itp('removing from parent after get and put to child', function()
eq('c1i1', get(child1))
eq('c1i2', get(child1))
eq('c2i1', get(child2))
@@ -117,7 +122,7 @@ describe("multiqueue (multi-level event-queue)", function()
eq('c1i12', get(parent))
end)
- it('put after removing from child at the end of parent', function()
+ itp('put after removing from child at the end of parent', function()
eq('c3i1', get(child3))
eq('c3i2', get(child3))
put(child1, 'c1i11')
@@ -133,7 +138,7 @@ describe("multiqueue (multi-level event-queue)", function()
eq('c2i11', get(parent))
end)
- it('removes from parent queue when child is freed', function()
+ itp('removes from parent queue when child is freed', function()
free(child2)
eq('c1i1', get(parent))
eq('c1i2', get(parent))
diff --git a/test/unit/option_spec.lua b/test/unit/option_spec.lua
index 8bab0194a2..b8b8a435bc 100644
--- a/test/unit/option_spec.lua
+++ b/test/unit/option_spec.lua
@@ -1,4 +1,5 @@
-local helpers = require("test.unit.helpers")
+local helpers = require("test.unit.helpers")(after_each)
+local itp = helpers.gen_itp(it)
local to_cstr = helpers.to_cstr
local eq = helpers.eq
@@ -12,23 +13,23 @@ end
describe('check_ff_value', function()
- it('views empty string as valid', function()
+ itp('views empty string as valid', function()
eq(1, check_ff_value(""))
end)
- it('views "unix", "dos" and "mac" as valid', function()
+ itp('views "unix", "dos" and "mac" as valid', function()
eq(1, check_ff_value("unix"))
eq(1, check_ff_value("dos"))
eq(1, check_ff_value("mac"))
end)
- it('views "foo" as invalid', function()
+ itp('views "foo" as invalid', function()
eq(0, check_ff_value("foo"))
end)
end)
describe('get_sts_value', function()
- it([[returns 'softtabstop' when it is non-negative]], function()
+ itp([[returns 'softtabstop' when it is non-negative]], function()
globals.curbuf.b_p_sts = 5
eq(5, option.get_sts_value())
@@ -36,7 +37,7 @@ describe('get_sts_value', function()
eq(0, option.get_sts_value())
end)
- it([[returns "effective shiftwidth" when 'softtabstop' is negative]], function()
+ itp([[returns "effective shiftwidth" when 'softtabstop' is negative]], function()
local shiftwidth = 2
globals.curbuf.b_p_sw = shiftwidth
local tabstop = 5
diff --git a/test/unit/os/env_spec.lua b/test/unit/os/env_spec.lua
index 3c2cc164c9..1ffed784ff 100644
--- a/test/unit/os/env_spec.lua
+++ b/test/unit/os/env_spec.lua
@@ -1,4 +1,5 @@
-local helpers = require('test.unit.helpers')
+local helpers = require('test.unit.helpers')(after_each)
+local itp = helpers.gen_itp(it)
local cimport = helpers.cimport
local eq = helpers.eq
@@ -33,7 +34,7 @@ describe('env function', function()
describe('os_setenv', function()
local OK = 0
- it('sets an env variable and returns OK', function()
+ itp('sets an env variable and returns OK', function()
local name = 'NEOVIM_UNIT_TEST_SETENV_1N'
local value = 'NEOVIM_UNIT_TEST_SETENV_1V'
eq(nil, os.getenv(name))
@@ -41,7 +42,7 @@ describe('env function', function()
eq(value, os.getenv(name))
end)
- it("dosn't overwrite an env variable if overwrite is 0", function()
+ itp("dosn't overwrite an env variable if overwrite is 0", function()
local name = 'NEOVIM_UNIT_TEST_SETENV_2N'
local value = 'NEOVIM_UNIT_TEST_SETENV_2V'
local value_updated = 'NEOVIM_UNIT_TEST_SETENV_2V_UPDATED'
@@ -53,13 +54,13 @@ describe('env function', function()
end)
describe('os_setenv_append_path', function()
- it('appends /foo/bar to $PATH', function()
+ itp('appends /foo/bar to $PATH', function()
local original_path = os.getenv('PATH')
eq(true, cimp.os_setenv_append_path(to_cstr('/foo/bar/baz')))
eq(original_path..':/foo/bar', os.getenv('PATH'))
end)
- it('returns false if `fname` is not absolute', function()
+ itp('returns false if `fname` is not absolute', function()
local original_path = os.getenv('PATH')
eq(false, cimp.os_setenv_append_path(to_cstr('foo/bar/baz')))
eq(original_path, os.getenv('PATH'))
@@ -67,7 +68,7 @@ describe('env function', function()
end)
describe('os_getenv', function()
- it('reads an env variable', function()
+ itp('reads an env variable', function()
local name = 'NEOVIM_UNIT_TEST_GETENV_1N'
local value = 'NEOVIM_UNIT_TEST_GETENV_1V'
eq(NULL, os_getenv(name))
@@ -76,14 +77,14 @@ describe('env function', function()
eq(value, os_getenv(name))
end)
- it('returns NULL if the env variable is not found', function()
+ itp('returns NULL if the env variable is not found', function()
local name = 'NEOVIM_UNIT_TEST_GETENV_NOTFOUND'
return eq(NULL, os_getenv(name))
end)
end)
describe('os_unsetenv', function()
- it('unsets environment variable', function()
+ itp('unsets environment variable', function()
local name = 'TEST_UNSETENV'
local value = 'TESTVALUE'
os_setenv(name, value, 1)
@@ -95,7 +96,7 @@ describe('env function', function()
end)
describe('os_getenvname_at_index', function()
- it('returns names of environment variables', function()
+ itp('returns names of environment variables', function()
local test_name = 'NEOVIM_UNIT_TEST_GETENVNAME_AT_INDEX_1N'
local test_value = 'NEOVIM_UNIT_TEST_GETENVNAME_AT_INDEX_1V'
os_setenv(test_name, test_value, 1)
@@ -115,7 +116,7 @@ describe('env function', function()
eq(true, found_name)
end)
- it('returns NULL if the index is out of bounds', function()
+ itp('returns NULL if the index is out of bounds', function()
local huge = ffi.new('size_t', 10000)
local maxuint32 = ffi.new('size_t', 4294967295)
eq(NULL, cimp.os_getenvname_at_index(huge))
@@ -132,7 +133,7 @@ describe('env function', function()
end)
describe('os_get_pid', function()
- it('returns the process ID', function()
+ itp('returns the process ID', function()
local stat_file = io.open('/proc/self/stat')
if stat_file then
local stat_str = stat_file:read('*l')
@@ -147,7 +148,7 @@ describe('env function', function()
end)
describe('os_get_hostname', function()
- it('returns the hostname', function()
+ itp('returns the hostname', function()
local handle = io.popen('hostname')
local hostname = handle:read('*l')
handle:close()
@@ -158,7 +159,7 @@ describe('env function', function()
end)
describe('expand_env_esc', function()
- it('expands environment variables', function()
+ itp('expands environment variables', function()
local name = 'NEOVIM_UNIT_TEST_EXPAND_ENV_ESCN'
local value = 'NEOVIM_UNIT_TEST_EXPAND_ENV_ESCV'
os_setenv(name, value, 1)
@@ -175,7 +176,7 @@ describe('env function', function()
eq(output_expected, ffi.string(output_buff2))
end)
- it('expands ~ once when `one` is true', function()
+ itp('expands ~ once when `one` is true', function()
local input = '~/foo ~ foo'
local homedir = cstr(255, '')
cimp.expand_env_esc(to_cstr('~'), homedir, 255, false, true, NULL)
@@ -185,7 +186,7 @@ describe('env function', function()
eq(ffi.string(output), ffi.string(output_expected))
end)
- it('expands ~ every time when `one` is false', function()
+ itp('expands ~ every time when `one` is false', function()
local input = to_cstr('~/foo ~ foo')
local dst = cstr(255, '')
cimp.expand_env_esc(to_cstr('~'), dst, 255, false, true, NULL)
@@ -196,7 +197,7 @@ describe('env function', function()
eq(output_expected, ffi.string(output))
end)
- it('does not crash #3725', function()
+ itp('does not crash #3725', function()
local name_out = ffi.new('char[100]')
cimp.os_get_user_name(name_out, 100)
local curuser = ffi.string(name_out)
@@ -209,7 +210,7 @@ describe('env function', function()
assert.True(len < 99)
end)
- it('respects `dstlen` without expansion', function()
+ itp('respects `dstlen` without expansion', function()
local input = to_cstr('this is a very long thing that will not fit')
-- The buffer is long enough to actually contain the full input in case the
-- test fails, but we don't tell expand_env_esc that
@@ -223,7 +224,7 @@ describe('env function', function()
eq(0, output[4])
end)
- it('respects `dstlen` with expansion', function()
+ itp('respects `dstlen` with expansion', function()
local varname = to_cstr('NVIM_UNIT_TEST_EXPAND_ENV_ESC_DSTLENN')
local varval = to_cstr('NVIM_UNIT_TEST_EXPAND_ENV_ESC_DSTLENV')
cimp.os_setenv(varname, varval, 1)
diff --git a/test/unit/os/fileio_spec.lua b/test/unit/os/fileio_spec.lua
index 5358022422..7a738ce85c 100644
--- a/test/unit/os/fileio_spec.lua
+++ b/test/unit/os/fileio_spec.lua
@@ -1,6 +1,7 @@
local lfs = require('lfs')
-local helpers = require('test.unit.helpers')
+local helpers = require('test.unit.helpers')(after_each)
+local itp = helpers.gen_itp(it)
local eq = helpers.eq
local ffi = helpers.ffi
@@ -88,7 +89,7 @@ local function file_skip(fp, size)
end
describe('file_open', function()
- it('can create a rwx------ file with kFileCreate', function()
+ itp('can create a rwx------ file with kFileCreate', function()
local err, fp = file_open(filec, m.kFileCreate, 448)
eq(0, err)
local attrs = lfs.attributes(filec)
@@ -96,7 +97,7 @@ describe('file_open', function()
eq(0, m.file_close(fp))
end)
- it('can create a rw------- file with kFileCreate', function()
+ itp('can create a rw------- file with kFileCreate', function()
local err, fp = file_open(filec, m.kFileCreate, 384)
eq(0, err)
local attrs = lfs.attributes(filec)
@@ -104,7 +105,7 @@ describe('file_open', function()
eq(0, m.file_close(fp))
end)
- it('can create a rwx------ file with kFileCreateOnly', function()
+ itp('can create a rwx------ file with kFileCreateOnly', function()
local err, fp = file_open(filec, m.kFileCreateOnly, 448)
eq(0, err)
local attrs = lfs.attributes(filec)
@@ -112,7 +113,7 @@ describe('file_open', function()
eq(0, m.file_close(fp))
end)
- it('can create a rw------- file with kFileCreateOnly', function()
+ itp('can create a rw------- file with kFileCreateOnly', function()
local err, fp = file_open(filec, m.kFileCreateOnly, 384)
eq(0, err)
local attrs = lfs.attributes(filec)
@@ -120,47 +121,47 @@ describe('file_open', function()
eq(0, m.file_close(fp))
end)
- it('fails to open an existing file with kFileCreateOnly', function()
+ itp('fails to open an existing file with kFileCreateOnly', function()
local err, _ = file_open(file1, m.kFileCreateOnly, 384)
eq(m.UV_EEXIST, err)
end)
- it('fails to open an symlink with kFileNoSymlink', function()
+ itp('fails to open an symlink with kFileNoSymlink', function()
local err, _ = file_open(linkf, m.kFileNoSymlink, 384)
-- err is UV_EMLINK in FreeBSD, but if I use `ok(err == m.UV_ELOOP or err ==
-- m.UV_EMLINK)`, then I loose the ability to see actual `err` value.
if err ~= m.UV_ELOOP then eq(m.UV_EMLINK, err) end
end)
- it('can open an existing file write-only with kFileCreate', function()
+ itp('can open an existing file write-only with kFileCreate', function()
local err, fp = file_open(file1, m.kFileCreate, 384)
eq(0, err)
eq(true, fp.wr)
eq(0, m.file_close(fp))
end)
- it('can open an existing file read-only with zero', function()
+ itp('can open an existing file read-only with zero', function()
local err, fp = file_open(file1, 0, 384)
eq(0, err)
eq(false, fp.wr)
eq(0, m.file_close(fp))
end)
- it('can open an existing file read-only with kFileReadOnly', function()
+ itp('can open an existing file read-only with kFileReadOnly', function()
local err, fp = file_open(file1, m.kFileReadOnly, 384)
eq(0, err)
eq(false, fp.wr)
eq(0, m.file_close(fp))
end)
- it('can open an existing file read-only with kFileNoSymlink', function()
+ itp('can open an existing file read-only with kFileNoSymlink', function()
local err, fp = file_open(file1, m.kFileNoSymlink, 384)
eq(0, err)
eq(false, fp.wr)
eq(0, m.file_close(fp))
end)
- it('can truncate an existing file with kFileTruncate', function()
+ itp('can truncate an existing file with kFileTruncate', function()
local err, fp = file_open(file1, m.kFileTruncate, 384)
eq(0, err)
eq(true, fp.wr)
@@ -169,7 +170,7 @@ describe('file_open', function()
eq(0, attrs.size)
end)
- it('can open an existing file write-only with kFileWriteOnly', function()
+ itp('can open an existing file write-only with kFileWriteOnly', function()
local err, fp = file_open(file1, m.kFileWriteOnly, 384)
eq(0, err)
eq(true, fp.wr)
@@ -178,14 +179,14 @@ describe('file_open', function()
eq(4096, attrs.size)
end)
- it('fails to create a file with just kFileWriteOnly', function()
+ itp('fails to create a file with just kFileWriteOnly', function()
local err, _ = file_open(filec, m.kFileWriteOnly, 384)
eq(m.UV_ENOENT, err)
local attrs = lfs.attributes(filec)
eq(nil, attrs)
end)
- it('can truncate an existing file with kFileTruncate when opening a symlink',
+ itp('can truncate an existing file with kFileTruncate when opening a symlink',
function()
local err, fp = file_open(linkf, m.kFileTruncate, 384)
eq(0, err)
@@ -195,31 +196,31 @@ describe('file_open', function()
eq(0, attrs.size)
end)
- it('fails to open a directory write-only', function()
+ itp('fails to open a directory write-only', function()
local err, _ = file_open(dir, m.kFileWriteOnly, 384)
eq(m.UV_EISDIR, err)
end)
- it('fails to open a broken symbolic link write-only', function()
+ itp('fails to open a broken symbolic link write-only', function()
local err, _ = file_open(linkb, m.kFileWriteOnly, 384)
eq(m.UV_ENOENT, err)
end)
- it('fails to open a broken symbolic link read-only', function()
+ itp('fails to open a broken symbolic link read-only', function()
local err, _ = file_open(linkb, m.kFileReadOnly, 384)
eq(m.UV_ENOENT, err)
end)
end)
describe('file_open_new', function()
- it('can open a file read-only', function()
+ itp('can open a file read-only', function()
local err, fp = file_open_new(file1, 0, 384)
eq(0, err)
eq(false, fp.wr)
eq(0, m.file_free(fp))
end)
- it('fails to open an existing file with kFileCreateOnly', function()
+ itp('fails to open an existing file with kFileCreateOnly', function()
local err, fp = file_open_new(file1, m.kFileCreateOnly, 384)
eq(m.UV_EEXIST, err)
eq(nil, fp)
@@ -229,7 +230,7 @@ end)
-- file_close is called above, so it is not tested directly
describe('file_fsync', function()
- it('can flush writes to disk', function()
+ itp('can flush writes to disk', function()
local err, fp = file_open(filec, m.kFileCreateOnly, 384)
eq(0, file_fsync(fp))
eq(0, err)
@@ -244,7 +245,7 @@ describe('file_fsync', function()
end)
describe('file_read', function()
- it('can read small chunks of input until eof', function()
+ itp('can read small chunks of input until eof', function()
local err, fp = file_open(file1, 0, 384)
eq(0, err)
eq(false, fp.wr)
@@ -264,7 +265,7 @@ describe('file_read', function()
eq(0, m.file_close(fp))
end)
- it('can read the whole file at once', function()
+ itp('can read the whole file at once', function()
local err, fp = file_open(file1, 0, 384)
eq(0, err)
eq(false, fp.wr)
@@ -273,7 +274,7 @@ describe('file_read', function()
eq(0, m.file_close(fp))
end)
- it('can read more then 1024 bytes after reading a small chunk', function()
+ itp('can read more then 1024 bytes after reading a small chunk', function()
local err, fp = file_open(file1, 0, 384)
eq(0, err)
eq(false, fp.wr)
@@ -283,7 +284,7 @@ describe('file_read', function()
eq(0, m.file_close(fp))
end)
- it('can read file by 768-byte-chunks', function()
+ itp('can read file by 768-byte-chunks', function()
local err, fp = file_open(file1, 0, 384)
eq(0, err)
eq(false, fp.wr)
@@ -305,7 +306,7 @@ describe('file_read', function()
end)
describe('file_write', function()
- it('can write the whole file at once', function()
+ itp('can write the whole file at once', function()
local err, fp = file_open(filec, m.kFileCreateOnly, 384)
eq(0, err)
eq(true, fp.wr)
@@ -316,7 +317,7 @@ describe('file_write', function()
eq(fcontents, io.open(filec):read('*a'))
end)
- it('can write the whole file by small chunks', function()
+ itp('can write the whole file by small chunks', function()
local err, fp = file_open(filec, m.kFileCreateOnly, 384)
eq(0, err)
eq(true, fp.wr)
@@ -333,7 +334,7 @@ describe('file_write', function()
eq(fcontents, io.open(filec):read('*a'))
end)
- it('can write the whole file by 768-byte-chunks', function()
+ itp('can write the whole file by 768-byte-chunks', function()
local err, fp = file_open(filec, m.kFileCreateOnly, 384)
eq(0, err)
eq(true, fp.wr)
@@ -352,7 +353,7 @@ describe('file_write', function()
end)
describe('file_skip', function()
- it('can skip 3 bytes', function()
+ itp('can skip 3 bytes', function()
local err, fp = file_open(file1, 0, 384)
eq(0, err)
eq(false, fp.wr)
diff --git a/test/unit/os/fs_spec.lua b/test/unit/os/fs_spec.lua
index 516fb5a7d1..860ebfdbcb 100644
--- a/test/unit/os/fs_spec.lua
+++ b/test/unit/os/fs_spec.lua
@@ -1,7 +1,8 @@
local lfs = require('lfs')
local bit = require('bit')
-local helpers = require('test.unit.helpers')
+local helpers = require('test.unit.helpers')(after_each)
+local itp = helpers.gen_itp(it)
local cimport = helpers.cimport
local cppimport = helpers.cppimport
@@ -15,10 +16,10 @@ local to_cstr = helpers.to_cstr
local OK = helpers.OK
local FAIL = helpers.FAIL
local NULL = helpers.NULL
+
local NODE_NORMAL = 0
local NODE_WRITABLE = 1
-cimport('unistd.h')
cimport('./src/nvim/os/shell.h')
cimport('./src/nvim/option_defs.h')
cimport('./src/nvim/main.h')
@@ -65,13 +66,10 @@ local function os_getperm(filename)
end
describe('fs function', function()
- local orig_test_file_perm
-
- setup(function()
+ before_each(function()
lfs.mkdir('unit-test-directory');
io.open('unit-test-directory/test.file', 'w').close()
- orig_test_file_perm = os_getperm('unit-test-directory/test.file')
io.open('unit-test-directory/test_2.file', 'w').close()
lfs.link('test.file', 'unit-test-directory/test_link.file', true)
@@ -83,7 +81,7 @@ describe('fs function', function()
directory, executable_name = string.match(absolute_executable, '^(.*)/(.*)$')
end)
- teardown(function()
+ after_each(function()
os.remove('unit-test-directory/test.file')
os.remove('unit-test-directory/test_2.file')
os.remove('unit-test-directory/test_link.file')
@@ -104,13 +102,13 @@ describe('fs function', function()
buffer = cstr(length, '')
end)
- it('returns OK and writes current directory into the buffer if it is large\n enough', function()
+ itp('returns OK and writes current directory into the buffer if it is large\n enough', function()
eq(OK, (os_dirname(buffer, length)))
eq(lfs.currentdir(), (ffi.string(buffer)))
end)
-- What kind of other failing cases are possible?
- it('returns FAIL if the buffer is too small', function()
+ itp('returns FAIL if the buffer is too small', function()
local buf = cstr((length - 1), '')
eq(FAIL, (os_dirname(buf, (length - 1))))
end)
@@ -121,35 +119,35 @@ describe('fs function', function()
end
describe('os_isdir', function()
- it('returns false if an empty string is given', function()
+ itp('returns false if an empty string is given', function()
eq(false, (os_isdir('')))
end)
- it('returns false if a nonexisting directory is given', function()
+ itp('returns false if a nonexisting directory is given', function()
eq(false, (os_isdir('non-existing-directory')))
end)
- it('returns false if a nonexisting absolute directory is given', function()
+ itp('returns false if a nonexisting absolute directory is given', function()
eq(false, (os_isdir('/non-existing-directory')))
end)
- it('returns false if an existing file is given', function()
+ itp('returns false if an existing file is given', function()
eq(false, (os_isdir('unit-test-directory/test.file')))
end)
- it('returns true if the current directory is given', function()
+ itp('returns true if the current directory is given', function()
eq(true, (os_isdir('.')))
end)
- it('returns true if the parent directory is given', function()
+ itp('returns true if the parent directory is given', function()
eq(true, (os_isdir('..')))
end)
- it('returns true if an arbitrary directory is given', function()
+ itp('returns true if an arbitrary directory is given', function()
eq(true, (os_isdir('unit-test-directory')))
end)
- it('returns true if an absolute directory is given', function()
+ itp('returns true if an absolute directory is given', function()
eq(true, (os_isdir(directory)))
end)
end)
@@ -179,24 +177,24 @@ describe('fs function', function()
return os_can_exe(name)
end
- it('returns false when given a directory', function()
+ itp('returns false when given a directory', function()
cant_exe('./unit-test-directory')
end)
- it('returns false when given a regular file without executable bit set', function()
+ itp('returns false when given a regular file without executable bit set', function()
cant_exe('unit-test-directory/test.file')
end)
- it('returns false when the given file does not exists', function()
+ itp('returns false when the given file does not exists', function()
cant_exe('does-not-exist.file')
end)
- it('returns the absolute path when given an executable inside $PATH', function()
+ itp('returns the absolute path when given an executable inside $PATH', function()
local fullpath = exe('ls')
eq(1, fs.path_is_absolute_path(to_cstr(fullpath)))
end)
- it('returns the absolute path when given an executable relative to the current dir', function()
+ itp('returns the absolute path when given an executable relative to the current dir', function()
local old_dir = lfs.currentdir()
lfs.chdir(directory)
@@ -216,10 +214,6 @@ describe('fs function', function()
end)
describe('file permissions', function()
- before_each(function()
- os_setperm('unit-test-directory/test.file', orig_test_file_perm)
- end)
-
local function os_fchown(filename, user_id, group_id)
local fd = ffi.C.open(filename, 0)
local res = fs.os_fchown(fd, user_id, group_id)
@@ -240,22 +234,22 @@ describe('fs function', function()
end
describe('os_getperm', function()
- it('returns UV_ENOENT when the given file does not exist', function()
+ itp('returns UV_ENOENT when the given file does not exist', function()
eq(ffi.C.UV_ENOENT, (os_getperm('non-existing-file')))
end)
- it('returns a perm > 0 when given an existing file', function()
+ itp('returns a perm > 0 when given an existing file', function()
assert.is_true((os_getperm('unit-test-directory')) > 0)
end)
- it('returns S_IRUSR when the file is readable', function()
+ itp('returns S_IRUSR when the file is readable', function()
local perm = os_getperm('unit-test-directory')
assert.is_true((bit_set(perm, ffi.C.kS_IRUSR)))
end)
end)
describe('os_setperm', function()
- it('can set and unset the executable bit of a file', function()
+ itp('can set and unset the executable bit of a file', function()
local perm = os_getperm('unit-test-directory/test.file')
perm = unset_bit(perm, ffi.C.kS_IXUSR)
eq(OK, (os_setperm('unit-test-directory/test.file', perm)))
@@ -267,7 +261,7 @@ describe('fs function', function()
assert.is_true((bit_set(perm, ffi.C.kS_IXUSR)))
end)
- it('fails if given file does not exist', function()
+ itp('fails if given file does not exist', function()
local perm = ffi.C.kS_IXUSR
eq(FAIL, (os_setperm('non-existing-file', perm)))
end)
@@ -275,7 +269,7 @@ describe('fs function', function()
describe('os_fchown', function()
local filename = 'unit-test-directory/test.file'
- it('does not change owner and group if respective IDs are equal to -1', function()
+ itp('does not change owner and group if respective IDs are equal to -1', function()
local uid = lfs.attributes(filename, 'uid')
local gid = lfs.attributes(filename, 'gid')
eq(0, os_fchown(filename, -1, -1))
@@ -287,7 +281,7 @@ describe('fs function', function()
if (os.execute('id -G > /dev/null 2>&1') ~= 0) then
pending('skipped (missing `id` utility)', function() end)
else
- it('owner of a file may change the group of the file to any group of which that owner is a member', function()
+ itp('owner of a file may change the group of the file to any group of which that owner is a member', function()
local file_gid = lfs.attributes(filename, 'gid')
-- Gets ID of any group of which current user is a member except the
@@ -311,7 +305,7 @@ describe('fs function', function()
if (ffi.os == 'Windows' or ffi.C.geteuid() == 0) then
pending('skipped (uv_fs_chown is no-op on Windows)', function() end)
else
- it('returns nonzero if process has not enough permissions', function()
+ itp('returns nonzero if process has not enough permissions', function()
-- chown to root
neq(0, os_fchown(filename, 0, 0))
end)
@@ -320,7 +314,7 @@ describe('fs function', function()
describe('os_file_is_readable', function()
- it('returns false if the file is not readable', function()
+ itp('returns false if the file is not readable', function()
local perm = os_getperm('unit-test-directory/test.file')
perm = unset_bit(perm, ffi.C.kS_IRUSR)
perm = unset_bit(perm, ffi.C.kS_IRGRP)
@@ -329,19 +323,19 @@ describe('fs function', function()
eq(false, os_file_is_readable('unit-test-directory/test.file'))
end)
- it('returns false if the file does not exist', function()
+ itp('returns false if the file does not exist', function()
eq(false, os_file_is_readable(
'unit-test-directory/what_are_you_smoking.gif'))
end)
- it('returns true if the file is readable', function()
+ itp('returns true if the file is readable', function()
eq(true, os_file_is_readable(
'unit-test-directory/test.file'))
end)
end)
describe('os_file_is_writable', function()
- it('returns 0 if the file is readonly', function()
+ itp('returns 0 if the file is readonly', function()
local perm = os_getperm('unit-test-directory/test.file')
perm = unset_bit(perm, ffi.C.kS_IWUSR)
perm = unset_bit(perm, ffi.C.kS_IWGRP)
@@ -350,11 +344,11 @@ describe('fs function', function()
eq(0, os_file_is_writable('unit-test-directory/test.file'))
end)
- it('returns 1 if the file is writable', function()
+ itp('returns 1 if the file is writable', function()
eq(1, os_file_is_writable('unit-test-directory/test.file'))
end)
- it('returns 2 when given a folder with rights to write into', function()
+ itp('returns 2 when given a folder with rights to write into', function()
eq(2, os_file_is_writable('unit-test-directory'))
end)
end)
@@ -420,19 +414,19 @@ describe('fs function', function()
end
describe('os_path_exists', function()
- it('returns false when given a non-existing file', function()
+ itp('returns false when given a non-existing file', function()
eq(false, (os_path_exists('non-existing-file')))
end)
- it('returns true when given an existing file', function()
+ itp('returns true when given an existing file', function()
eq(true, (os_path_exists('unit-test-directory/test.file')))
end)
- it('returns false when given a broken symlink', function()
+ itp('returns false when given a broken symlink', function()
eq(false, (os_path_exists('unit-test-directory/test_broken_link.file')))
end)
- it('returns true when given a directory', function()
+ itp('returns true when given a directory', function()
eq(true, (os_path_exists('unit-test-directory')))
end)
end)
@@ -441,18 +435,18 @@ describe('fs function', function()
local test = 'unit-test-directory/test.file'
local not_exist = 'unit-test-directory/not_exist.file'
- it('can rename file if destination file does not exist', function()
+ itp('can rename file if destination file does not exist', function()
eq(OK, (os_rename(test, not_exist)))
eq(false, (os_path_exists(test)))
eq(true, (os_path_exists(not_exist)))
eq(OK, (os_rename(not_exist, test))) -- restore test file
end)
- it('fail if source file does not exist', function()
+ itp('fail if source file does not exist', function()
eq(FAIL, (os_rename(not_exist, test)))
end)
- it('can overwrite destination file if it exists', function()
+ itp('can overwrite destination file if it exists', function()
local other = 'unit-test-directory/other.file'
local file = io.open(other, 'w')
file:write('other')
@@ -477,11 +471,11 @@ describe('fs function', function()
os.remove('unit-test-directory/test_remove.file')
end)
- it('returns non-zero when given a non-existing file', function()
+ itp('returns non-zero when given a non-existing file', function()
neq(0, (os_remove('non-existing-file')))
end)
- it('removes the given file and returns 0', function()
+ itp('removes the given file and returns 0', function()
local f = 'unit-test-directory/test_remove.file'
assert_file_exists(f)
eq(0, (os_remove(f)))
@@ -502,30 +496,30 @@ describe('fs function', function()
os.remove(new_file)
end)
- it('returns UV_ENOENT for O_RDWR on a non-existing file', function()
+ itp('returns UV_ENOENT for O_RDWR on a non-existing file', function()
eq(ffi.C.UV_ENOENT, (os_open('non-existing-file', ffi.C.kO_RDWR, 0)))
end)
- it('returns non-negative for O_CREAT on a non-existing file which then can be closed', function()
+ itp('returns non-negative for O_CREAT on a non-existing file which then can be closed', function()
assert_file_does_not_exist(new_file)
local fd = os_open(new_file, ffi.C.kO_CREAT, 0)
assert.is_true(0 <= fd)
eq(0, os_close(fd))
end)
- it('returns non-negative for O_CREAT on a existing file which then can be closed', function()
+ itp('returns non-negative for O_CREAT on a existing file which then can be closed', function()
assert_file_exists(existing_file)
local fd = os_open(existing_file, ffi.C.kO_CREAT, 0)
assert.is_true(0 <= fd)
eq(0, os_close(fd))
end)
- it('returns UV_EEXIST for O_CREAT|O_EXCL on a existing file', function()
+ itp('returns UV_EEXIST for O_CREAT|O_EXCL on a existing file', function()
assert_file_exists(existing_file)
eq(ffi.C.kUV_EEXIST, (os_open(existing_file, (bit.bor(ffi.C.kO_CREAT, ffi.C.kO_EXCL)), 0)))
end)
- it('sets `rwx` permissions for O_CREAT 700 which then can be closed', function()
+ itp('sets `rwx` permissions for O_CREAT 700 which then can be closed', function()
assert_file_does_not_exist(new_file)
--create the file
local fd = os_open(new_file, ffi.C.kO_CREAT, tonumber("700", 8))
@@ -534,7 +528,7 @@ describe('fs function', function()
eq(0, os_close(fd))
end)
- it('sets `rw` permissions for O_CREAT 600 which then can be closed', function()
+ itp('sets `rw` permissions for O_CREAT 600 which then can be closed', function()
assert_file_does_not_exist(new_file)
--create the file
local fd = os_open(new_file, ffi.C.kO_CREAT, tonumber("600", 8))
@@ -543,7 +537,7 @@ describe('fs function', function()
eq(0, os_close(fd))
end)
- it('returns a non-negative file descriptor for an existing file which then can be closed', function()
+ itp('returns a non-negative file descriptor for an existing file which then can be closed', function()
local fd = os_open(existing_file, ffi.C.kO_RDWR, 0)
assert.is_true(0 <= fd)
eq(0, os_close(fd))
@@ -551,7 +545,7 @@ describe('fs function', function()
end)
describe('os_close', function()
- it('returns EBADF for negative file descriptors', function()
+ itp('returns EBADF for negative file descriptors', function()
eq(ffi.C.UV_EBADF, os_close(-1))
eq(ffi.C.UV_EBADF, os_close(-1000))
end)
@@ -570,7 +564,7 @@ describe('fs function', function()
os.remove(file)
end)
- it('can read zero bytes from a file', function()
+ itp('can read zero bytes from a file', function()
local fd = os_open(file, ffi.C.kO_RDONLY, 0)
ok(fd >= 0)
eq({false, 0, ''}, {os_read(fd, nil)})
@@ -578,7 +572,7 @@ describe('fs function', function()
eq(0, os_close(fd))
end)
- it('can read from a file multiple times', function()
+ itp('can read from a file multiple times', function()
local fd = os_open(file, ffi.C.kO_RDONLY, 0)
ok(fd >= 0)
eq({false, 2, '\000\001'}, {os_read(fd, 2)})
@@ -586,7 +580,7 @@ describe('fs function', function()
eq(0, os_close(fd))
end)
- it('can read the whole file at once and then report eof', function()
+ itp('can read the whole file at once and then report eof', function()
local fd = os_open(file, ffi.C.kO_RDONLY, 0)
ok(fd >= 0)
eq({false, #fcontents, fcontents}, {os_read(fd, #fcontents)})
@@ -594,7 +588,7 @@ describe('fs function', function()
eq(0, os_close(fd))
end)
- it('can read the whole file in two calls, one partially', function()
+ itp('can read the whole file in two calls, one partially', function()
local fd = os_open(file, ffi.C.kO_RDONLY, 0)
ok(fd >= 0)
eq({false, #fcontents * 3/4, fcontents:sub(1, #fcontents * 3/4)},
@@ -624,7 +618,7 @@ describe('fs function', function()
os.remove(file)
end)
- it('can read zero bytes from a file', function()
+ itp('can read zero bytes from a file', function()
local fd = os_open(file, ffi.C.kO_RDONLY, 0)
ok(fd >= 0)
eq({false, 0, {}}, {os_readv(fd, {})})
@@ -632,7 +626,7 @@ describe('fs function', function()
eq(0, os_close(fd))
end)
- it('can read from a file multiple times to a differently-sized buffers', function()
+ itp('can read from a file multiple times to a differently-sized buffers', function()
local fd = os_open(file, ffi.C.kO_RDONLY, 0)
ok(fd >= 0)
eq({false, 2, {'\000\001'}}, {os_readv(fd, {2})})
@@ -640,7 +634,7 @@ describe('fs function', function()
eq(0, os_close(fd))
end)
- it('can read the whole file at once and then report eof', function()
+ itp('can read the whole file at once and then report eof', function()
local fd = os_open(file, ffi.C.kO_RDONLY, 0)
ok(fd >= 0)
eq({false,
@@ -657,7 +651,7 @@ describe('fs function', function()
eq(0, os_close(fd))
end)
- it('can read the whole file in two calls, one partially', function()
+ itp('can read the whole file in two calls, one partially', function()
local fd = os_open(file, ffi.C.kO_RDONLY, 0)
ok(fd >= 0)
eq({false, #fcontents * 3/4, {fcontents:sub(1, #fcontents * 3/4)}},
@@ -684,7 +678,7 @@ describe('fs function', function()
os.remove(file)
end)
- it('can write zero bytes to a file', function()
+ itp('can write zero bytes to a file', function()
local fd = os_open(file, ffi.C.kO_WRONLY, 0)
ok(fd >= 0)
eq(0, os_write(fd, ''))
@@ -693,7 +687,7 @@ describe('fs function', function()
eq(0, os_close(fd))
end)
- it('can write some data to a file', function()
+ itp('can write some data to a file', function()
local fd = os_open(file, ffi.C.kO_WRONLY, 0)
ok(fd >= 0)
eq(3, os_write(fd, 'abc'))
@@ -708,11 +702,11 @@ describe('fs function', function()
os.remove('non-existing-file')
end)
- it('returns NODE_NORMAL for non-existing file', function()
+ itp('returns NODE_NORMAL for non-existing file', function()
eq(NODE_NORMAL, fs.os_nodetype(to_cstr('non-existing-file')))
end)
- it('returns NODE_WRITABLE for /dev/stderr', function()
+ itp('returns NODE_WRITABLE for /dev/stderr', function()
eq(NODE_WRITABLE, fs.os_nodetype(to_cstr('/dev/stderr')))
end)
end)
@@ -738,12 +732,12 @@ describe('fs function', function()
end
describe('os_mkdir', function()
- it('returns non-zero when given an already existing directory', function()
+ itp('returns non-zero when given an already existing directory', function()
local mode = ffi.C.kS_IRUSR + ffi.C.kS_IWUSR + ffi.C.kS_IXUSR
neq(0, (os_mkdir('unit-test-directory', mode)))
end)
- it('creates a directory and returns 0', function()
+ itp('creates a directory and returns 0', function()
local mode = ffi.C.kS_IRUSR + ffi.C.kS_IWUSR + ffi.C.kS_IXUSR
eq(false, (os_isdir('unit-test-directory/new-dir')))
eq(0, (os_mkdir('unit-test-directory/new-dir', mode)))
@@ -753,14 +747,14 @@ describe('fs function', function()
end)
describe('os_mkdir_recurse', function()
- it('returns zero when given an already existing directory', function()
+ itp('returns zero when given an already existing directory', function()
local mode = ffi.C.kS_IRUSR + ffi.C.kS_IWUSR + ffi.C.kS_IXUSR
local ret, failed_str = os_mkdir_recurse('unit-test-directory', mode)
eq(0, ret)
eq(nil, failed_str)
end)
- it('fails to create a directory where there is a file', function()
+ itp('fails to create a directory where there is a file', function()
local mode = ffi.C.kS_IRUSR + ffi.C.kS_IWUSR + ffi.C.kS_IXUSR
local ret, failed_str = os_mkdir_recurse(
'unit-test-directory/test.file', mode)
@@ -768,7 +762,7 @@ describe('fs function', function()
eq('unit-test-directory/test.file', failed_str)
end)
- it('fails to create a directory where there is a file in path', function()
+ itp('fails to create a directory where there is a file in path', function()
local mode = ffi.C.kS_IRUSR + ffi.C.kS_IWUSR + ffi.C.kS_IXUSR
local ret, failed_str = os_mkdir_recurse(
'unit-test-directory/test.file/test', mode)
@@ -776,7 +770,7 @@ describe('fs function', function()
eq('unit-test-directory/test.file', failed_str)
end)
- it('succeeds to create a directory', function()
+ itp('succeeds to create a directory', function()
local mode = ffi.C.kS_IRUSR + ffi.C.kS_IWUSR + ffi.C.kS_IXUSR
local ret, failed_str = os_mkdir_recurse(
'unit-test-directory/new-dir-recurse', mode)
@@ -787,7 +781,7 @@ describe('fs function', function()
eq(false, os_isdir('unit-test-directory/new-dir-recurse'))
end)
- it('succeeds to create a directory ending with ///', function()
+ itp('succeeds to create a directory ending with ///', function()
local mode = ffi.C.kS_IRUSR + ffi.C.kS_IWUSR + ffi.C.kS_IXUSR
local ret, failed_str = os_mkdir_recurse(
'unit-test-directory/new-dir-recurse///', mode)
@@ -798,7 +792,7 @@ describe('fs function', function()
eq(false, os_isdir('unit-test-directory/new-dir-recurse'))
end)
- it('succeeds to create a directory ending with /', function()
+ itp('succeeds to create a directory ending with /', function()
local mode = ffi.C.kS_IRUSR + ffi.C.kS_IWUSR + ffi.C.kS_IXUSR
local ret, failed_str = os_mkdir_recurse(
'unit-test-directory/new-dir-recurse/', mode)
@@ -809,7 +803,7 @@ describe('fs function', function()
eq(false, os_isdir('unit-test-directory/new-dir-recurse'))
end)
- it('succeeds to create a directory tree', function()
+ itp('succeeds to create a directory tree', function()
local mode = ffi.C.kS_IRUSR + ffi.C.kS_IWUSR + ffi.C.kS_IXUSR
local ret, failed_str = os_mkdir_recurse(
'unit-test-directory/new-dir-recurse/1/2/3', mode)
@@ -828,11 +822,11 @@ describe('fs function', function()
end)
describe('os_rmdir', function()
- it('returns non_zero when given a non-existing directory', function()
+ itp('returns non_zero when given a non-existing directory', function()
neq(0, (os_rmdir('non-existing-directory')))
end)
- it('removes the given directory and returns 0', function()
+ itp('removes the given directory and returns 0', function()
lfs.mkdir('unit-test-directory/new-dir')
eq(0, os_rmdir('unit-test-directory/new-dir'))
eq(false, (os_isdir('unit-test-directory/new-dir')))
@@ -860,19 +854,19 @@ describe('fs function', function()
end
describe('os_fileinfo', function()
- it('returns false if given a non-existing file', function()
+ itp('returns false if given a non-existing file', function()
local file_info = file_info_new()
assert.is_false((fs.os_fileinfo('/non-existent', file_info)))
end)
- it('returns true if given an existing file and fills file_info', function()
+ itp('returns true if given an existing file and fills file_info', function()
local file_info = file_info_new()
local path = 'unit-test-directory/test.file'
assert.is_true((fs.os_fileinfo(path, file_info)))
assert.is_true((is_file_info_filled(file_info)))
end)
- it('returns the file info of the linked file, not the link', function()
+ itp('returns the file info of the linked file, not the link', function()
local file_info = file_info_new()
local path = 'unit-test-directory/test_link.file'
assert.is_true((fs.os_fileinfo(path, file_info)))
@@ -883,19 +877,19 @@ describe('fs function', function()
end)
describe('os_fileinfo_link', function()
- it('returns false if given a non-existing file', function()
+ itp('returns false if given a non-existing file', function()
local file_info = file_info_new()
assert.is_false((fs.os_fileinfo_link('/non-existent', file_info)))
end)
- it('returns true if given an existing file and fills file_info', function()
+ itp('returns true if given an existing file and fills file_info', function()
local file_info = file_info_new()
local path = 'unit-test-directory/test.file'
assert.is_true((fs.os_fileinfo_link(path, file_info)))
assert.is_true((is_file_info_filled(file_info)))
end)
- it('returns the file info of the link, not the linked file', function()
+ itp('returns the file info of the link, not the linked file', function()
local file_info = file_info_new()
local path = 'unit-test-directory/test_link.file'
assert.is_true((fs.os_fileinfo_link(path, file_info)))
@@ -906,12 +900,12 @@ describe('fs function', function()
end)
describe('os_fileinfo_fd', function()
- it('returns false if given an invalid file descriptor', function()
+ itp('returns false if given an invalid file descriptor', function()
local file_info = file_info_new()
assert.is_false((fs.os_fileinfo_fd(-1, file_info)))
end)
- it('returns true if given a file descriptor and fills file_info', function()
+ itp('returns true if given a file descriptor and fills file_info', function()
local file_info = file_info_new()
local path = 'unit-test-directory/test.file'
local fd = ffi.C.open(path, 0)
@@ -922,7 +916,7 @@ describe('fs function', function()
end)
describe('os_fileinfo_id_equal', function()
- it('returns false if file infos represent different files', function()
+ itp('returns false if file infos represent different files', function()
local file_info_1 = file_info_new()
local file_info_2 = file_info_new()
local path_1 = 'unit-test-directory/test.file'
@@ -932,7 +926,7 @@ describe('fs function', function()
assert.is_false((fs.os_fileinfo_id_equal(file_info_1, file_info_2)))
end)
- it('returns true if file infos represent the same file', function()
+ itp('returns true if file infos represent the same file', function()
local file_info_1 = file_info_new()
local file_info_2 = file_info_new()
local path = 'unit-test-directory/test.file'
@@ -941,7 +935,7 @@ describe('fs function', function()
assert.is_true((fs.os_fileinfo_id_equal(file_info_1, file_info_2)))
end)
- it('returns true if file infos represent the same file (symlink)', function()
+ itp('returns true if file infos represent the same file (symlink)', function()
local file_info_1 = file_info_new()
local file_info_2 = file_info_new()
local path_1 = 'unit-test-directory/test.file'
@@ -953,7 +947,7 @@ describe('fs function', function()
end)
describe('os_fileinfo_id', function()
- it('extracts ino/dev from file_info into file_id', function()
+ itp('extracts ino/dev from file_info into file_id', function()
local file_info = file_info_new()
local file_id = file_id_new()
local path = 'unit-test-directory/test.file'
@@ -965,7 +959,7 @@ describe('fs function', function()
end)
describe('os_fileinfo_inode', function()
- it('returns the inode from file_info', function()
+ itp('returns the inode from file_info', function()
local file_info = file_info_new()
local path = 'unit-test-directory/test.file'
assert.is_true((fs.os_fileinfo(path, file_info)))
@@ -975,7 +969,7 @@ describe('fs function', function()
end)
describe('os_fileinfo_size', function()
- it('returns the correct size of a file', function()
+ itp('returns the correct size of a file', function()
local path = 'unit-test-directory/test.file'
local file = io.open(path, 'w')
file:write('some bytes to get filesize != 0')
@@ -989,7 +983,7 @@ describe('fs function', function()
end)
describe('os_fileinfo_hardlinks', function()
- it('returns the correct number of hardlinks', function()
+ itp('returns the correct number of hardlinks', function()
local path = 'unit-test-directory/test.file'
local path_link = 'unit-test-directory/test_hlink.file'
local file_info = file_info_new()
@@ -1002,7 +996,7 @@ describe('fs function', function()
end)
describe('os_fileinfo_blocksize', function()
- it('returns the correct blocksize of a file', function()
+ itp('returns the correct blocksize of a file', function()
local path = 'unit-test-directory/test.file'
-- there is a bug in luafilesystem where
-- `lfs.attributes path, 'blksize'` returns the worng value:
@@ -1023,12 +1017,12 @@ describe('fs function', function()
end)
describe('os_fileid', function()
- it('returns false if given an non-existing file', function()
+ itp('returns false if given an non-existing file', function()
local file_id = file_id_new()
assert.is_false((fs.os_fileid('/non-existent', file_id)))
end)
- it('returns true if given an existing file and fills file_id', function()
+ itp('returns true if given an existing file and fills file_id', function()
local file_id = file_id_new()
local path = 'unit-test-directory/test.file'
assert.is_true((fs.os_fileid(path, file_id)))
@@ -1038,14 +1032,14 @@ describe('fs function', function()
end)
describe('os_fileid_equal', function()
- it('returns true if two FileIDs are equal', function()
+ itp('returns true if two FileIDs are equal', function()
local file_id = file_id_new()
local path = 'unit-test-directory/test.file'
assert.is_true((fs.os_fileid(path, file_id)))
assert.is_true((fs.os_fileid_equal(file_id, file_id)))
end)
- it('returns false if two FileIDs are not equal', function()
+ itp('returns false if two FileIDs are not equal', function()
local file_id_1 = file_id_new()
local file_id_2 = file_id_new()
local path_1 = 'unit-test-directory/test.file'
@@ -1057,7 +1051,7 @@ describe('fs function', function()
end)
describe('os_fileid_equal_fileinfo', function()
- it('returns true if file_id and file_info represent the same file', function()
+ itp('returns true if file_id and file_info represent the same file', function()
local file_id = file_id_new()
local file_info = file_info_new()
local path = 'unit-test-directory/test.file'
@@ -1066,7 +1060,7 @@ describe('fs function', function()
assert.is_true((fs.os_fileid_equal_fileinfo(file_id, file_info)))
end)
- it('returns false if file_id and file_info represent different files', function()
+ itp('returns false if file_id and file_info represent different files', function()
local file_id = file_id_new()
local file_info = file_info_new()
local path_1 = 'unit-test-directory/test.file'
diff --git a/test/unit/os/shell_spec.lua b/test/unit/os/shell_spec.lua
index 3603403daf..e883301cfb 100644
--- a/test/unit/os/shell_spec.lua
+++ b/test/unit/os/shell_spec.lua
@@ -1,4 +1,5 @@
-local helpers = require('test.unit.helpers')
+local helpers = require('test.unit.helpers')(after_each)
+local itp = helpers.gen_itp(it)
local cimported = helpers.cimport(
'./src/nvim/os/shell.h',
'./src/nvim/option_defs.h',
@@ -51,63 +52,51 @@ describe('shell functions', function()
end
describe('os_system', function()
- it('can echo some output (shell builtin)', function()
+ itp('can echo some output (shell builtin)', function()
local cmd, text = 'echo -n', 'some text'
local status, output = os_system(cmd .. ' ' .. text)
eq(text, output)
eq(0, status)
end)
- it('can deal with empty output', function()
+ itp('can deal with empty output', function()
local cmd = 'echo -n'
local status, output = os_system(cmd)
eq('', output)
eq(0, status)
end)
- it('can pass input on stdin', function()
+ itp('can pass input on stdin', function()
local cmd, input = 'cat -', 'some text\nsome other text'
local status, output = os_system(cmd, input)
eq(input, output)
eq(0, status)
end)
- it ('returns non-zero exit code', function()
+ itp('returns non-zero exit code', function()
local status = os_system('exit 2')
eq(2, status)
end)
end)
describe('shell_build_argv', function()
- local saved_opts = {}
-
- setup(function()
- saved_opts.p_sh = cimported.p_sh
- saved_opts.p_shcf = cimported.p_shcf
- end)
-
- teardown(function()
- cimported.p_sh = saved_opts.p_sh
- cimported.p_shcf = saved_opts.p_shcf
- end)
-
- it('works with NULL arguments', function()
+ itp('works with NULL arguments', function()
eq({'/bin/bash'}, shell_build_argv(nil, nil))
end)
- it('works with cmd', function()
+ itp('works with cmd', function()
eq({'/bin/bash', '-c', 'abc def'}, shell_build_argv('abc def', nil))
end)
- it('works with extra_args', function()
+ itp('works with extra_args', function()
eq({'/bin/bash', 'ghi jkl'}, shell_build_argv(nil, 'ghi jkl'))
end)
- it('works with cmd and extra_args', function()
+ itp('works with cmd and extra_args', function()
eq({'/bin/bash', 'ghi jkl', '-c', 'abc def'}, shell_build_argv('abc def', 'ghi jkl'))
end)
- it('splits and unquotes &shell and &shellcmdflag', function()
+ itp('splits and unquotes &shell and &shellcmdflag', function()
cimported.p_sh = to_cstr('/Program" "Files/zsh -f')
cimported.p_shcf = to_cstr('-x -o "sh word split" "-"c')
eq({'/Program Files/zsh', '-f',
@@ -117,7 +106,7 @@ describe('shell functions', function()
shell_build_argv('abc def', 'ghi jkl'))
end)
- it('applies shellxescape (p_sxe) and shellxquote (p_sxq)', function()
+ itp('applies shellxescape (p_sxe) and shellxquote (p_sxq)', function()
cimported.p_sxq = to_cstr('(')
cimported.p_sxe = to_cstr('"&|<>()@^')
@@ -129,7 +118,7 @@ describe('shell functions', function()
eq(nil, argv[3])
end)
- it('applies shellxquote="(', function()
+ itp('applies shellxquote="(', function()
cimported.p_sxq = to_cstr('"(')
cimported.p_sxe = to_cstr('"&|<>()@^')
@@ -141,7 +130,7 @@ describe('shell functions', function()
eq(nil, argv[3])
end)
- it('applies shellxquote="', function()
+ itp('applies shellxquote="', function()
cimported.p_sxq = to_cstr('"')
cimported.p_sxe = to_cstr('')
@@ -153,7 +142,7 @@ describe('shell functions', function()
eq(nil, argv[3])
end)
- it('with empty shellxquote/shellxescape', function()
+ itp('with empty shellxquote/shellxescape', function()
local argv = ffi.cast('char**', cimported.shell_build_argv(
to_cstr('echo -n some text'), nil))
eq(ffi.string(argv[0]), '/bin/bash')
diff --git a/test/unit/os/users_spec.lua b/test/unit/os/users_spec.lua
index 236481e9e7..f92413c7de 100644
--- a/test/unit/os/users_spec.lua
+++ b/test/unit/os/users_spec.lua
@@ -1,4 +1,5 @@
-local helpers = require('test.unit.helpers')
+local helpers = require('test.unit.helpers')(after_each)
+local itp = helpers.gen_itp(it)
local cimport = helpers.cimport
local eq = helpers.eq
@@ -27,11 +28,11 @@ describe('users function', function()
local current_username = os.getenv('USER')
describe('os_get_usernames', function()
- it('returns FAIL if called with NULL', function()
+ itp('returns FAIL if called with NULL', function()
eq(FAIL, users.os_get_usernames(NULL))
end)
- it('fills the names garray with os usernames and returns OK', function()
+ itp('fills the names garray with os usernames and returns OK', function()
local ga_users = garray_new()
eq(OK, users.os_get_usernames(ga_users))
local user_count = garray_get_len(ga_users)
@@ -48,7 +49,7 @@ describe('users function', function()
end)
describe('os_get_user_name', function()
- it('should write the username into the buffer and return OK', function()
+ itp('should write the username into the buffer and return OK', function()
local name_out = ffi.new('char[100]')
eq(OK, users.os_get_user_name(name_out, 100))
eq(current_username, ffi.string(name_out))
@@ -56,14 +57,14 @@ describe('users function', function()
end)
describe('os_get_uname', function()
- it('should write the username into the buffer and return OK', function()
+ itp('should write the username into the buffer and return OK', function()
local name_out = ffi.new('char[100]')
local user_id = lib.getuid()
eq(OK, users.os_get_uname(user_id, name_out, 100))
eq(current_username, ffi.string(name_out))
end)
- it('should FAIL if the userid is not found', function()
+ itp('should FAIL if the userid is not found', function()
local name_out = ffi.new('char[100]')
-- hoping nobody has this uid
local user_id = 2342
@@ -73,16 +74,16 @@ describe('users function', function()
end)
describe('os_get_user_directory', function()
- it('should return NULL if called with NULL', function()
+ itp('should return NULL if called with NULL', function()
eq(NULL, users.os_get_user_directory(NULL))
end)
- it('should return $HOME for the current user', function()
+ itp('should return $HOME for the current user', function()
local home = os.getenv('HOME')
eq(home, ffi.string((users.os_get_user_directory(current_username))))
end)
- it('should return NULL if the user is not found', function()
+ itp('should return NULL if the user is not found', function()
eq(NULL, users.os_get_user_directory('neovim_user_not_found_test'))
end)
end)
diff --git a/test/unit/path_spec.lua b/test/unit/path_spec.lua
index ccaf0228ab..470f971e68 100644
--- a/test/unit/path_spec.lua
+++ b/test/unit/path_spec.lua
@@ -1,5 +1,6 @@
local lfs = require('lfs')
-local helpers = require('test.unit.helpers')
+local helpers = require('test.unit.helpers')(after_each)
+local itp = helpers.gen_itp(it)
local cimport = helpers.cimport
local eq = helpers.eq
@@ -14,13 +15,6 @@ local FAIL = helpers.FAIL
cimport('string.h')
local path = cimport('./src/nvim/path.h')
--- import constants parsed by ffi
-local kEqualFiles = path.kEqualFiles
-local kDifferentFiles = path.kDifferentFiles
-local kBothFilesMissing = path.kBothFilesMissing
-local kOneFileMissing = path.kOneFileMissing
-local kEqualFileNames = path.kEqualFileNames
-
local length = 0
local buffer = nil
@@ -45,7 +39,7 @@ describe('path function', function()
buffer = cstr(length, '')
end)
- it('returns the absolute directory name of a given relative one', function()
+ itp('returns the absolute directory name of a given relative one', function()
local result = path_full_dir_name('..', buffer, length)
eq(OK, result)
local old_dir = lfs.currentdir()
@@ -55,16 +49,16 @@ describe('path function', function()
eq(expected, (ffi.string(buffer)))
end)
- it('returns the current directory name if the given string is empty', function()
+ itp('returns the current directory name if the given string is empty', function()
eq(OK, (path_full_dir_name('', buffer, length)))
eq(lfs.currentdir(), (ffi.string(buffer)))
end)
- it('fails if the given directory does not exist', function()
+ itp('fails if the given directory does not exist', function()
eq(FAIL, path_full_dir_name('does_not_exist', buffer, length))
end)
- it('works with a normal relative dir', function()
+ itp('works with a normal relative dir', function()
local result = path_full_dir_name('unit-test-directory', buffer, length)
eq(lfs.currentdir() .. '/unit-test-directory', (ffi.string(buffer)))
eq(OK, result)
@@ -91,26 +85,26 @@ describe('path function', function()
os.remove(f2)
end)
- it('returns kEqualFiles when passed the same file', function()
- eq(kEqualFiles, (path_full_compare(f1, f1)))
+ itp('returns kEqualFiles when passed the same file', function()
+ eq(path.kEqualFiles, (path_full_compare(f1, f1)))
end)
- it('returns kEqualFileNames when files that dont exist and have same name', function()
- eq(kEqualFileNames, (path_full_compare('null.txt', 'null.txt', true)))
+ itp('returns kEqualFileNames when files that dont exist and have same name', function()
+ eq(path.kEqualFileNames, (path_full_compare('null.txt', 'null.txt', true)))
end)
- it('returns kBothFilesMissing when files that dont exist', function()
- eq(kBothFilesMissing, (path_full_compare('null.txt', 'null.txt')))
+ itp('returns kBothFilesMissing when files that dont exist', function()
+ eq(path.kBothFilesMissing, (path_full_compare('null.txt', 'null.txt')))
end)
- it('returns kDifferentFiles when passed different files', function()
- eq(kDifferentFiles, (path_full_compare(f1, f2)))
- eq(kDifferentFiles, (path_full_compare(f2, f1)))
+ itp('returns kDifferentFiles when passed different files', function()
+ eq(path.kDifferentFiles, (path_full_compare(f1, f2)))
+ eq(path.kDifferentFiles, (path_full_compare(f2, f1)))
end)
- it('returns kOneFileMissing if only one does not exist', function()
- eq(kOneFileMissing, (path_full_compare(f1, 'null.txt')))
- eq(kOneFileMissing, (path_full_compare('null.txt', f1)))
+ itp('returns kOneFileMissing if only one does not exist', function()
+ eq(path.kOneFileMissing, (path_full_compare(f1, 'null.txt')))
+ eq(path.kOneFileMissing, (path_full_compare('null.txt', f1)))
end)
end)
@@ -121,11 +115,11 @@ describe('path function', function()
return ffi.string(res)
end
- it('returns the tail of a given file path', function()
+ itp('returns the tail of a given file path', function()
eq('file.txt', path_tail('directory/file.txt'))
end)
- it('returns an empty string if file ends in a slash', function()
+ itp('returns an empty string if file ends in a slash', function()
eq('', path_tail('directory/'))
end)
end)
@@ -137,24 +131,24 @@ describe('path function', function()
return ffi.string(res)
end
- it('returns the tail of a file together with its separator', function()
+ itp('returns the tail of a file together with its separator', function()
eq('///file.txt', path_tail_with_sep('directory///file.txt'))
end)
- it('returns an empty string when given an empty file name', function()
+ itp('returns an empty string when given an empty file name', function()
eq('', path_tail_with_sep(''))
end)
- it('returns only the separator if there is a trailing separator', function()
+ itp('returns only the separator if there is a trailing separator', function()
eq('/', path_tail_with_sep('some/directory/'))
end)
- it('cuts a leading separator', function()
+ itp('cuts a leading separator', function()
eq('file.txt', path_tail_with_sep('/file.txt'))
eq('', path_tail_with_sep('/'))
end)
- it('returns the whole file name if there is no separator', function()
+ itp('returns the whole file name if there is no separator', function()
eq('file.txt', path_tail_with_sep('file.txt'))
end)
end)
@@ -180,13 +174,13 @@ describe('path function', function()
return eq(0, (ffi.C.strncmp((to_cstr(base)), pinvk, len)))
end
- it('returns the executable name of an invocation given a relative invocation', function()
+ itp('returns the executable name of an invocation given a relative invocation', function()
local invk, len = invocation_path_tail('directory/exe a b c')
compare("exe a b c", invk, len)
eq(3, len)
end)
- it('returns the executable name of an invocation given an absolute invocation', function()
+ itp('returns the executable name of an invocation given an absolute invocation', function()
if ffi.os == 'Windows' then
local invk, len = invocation_path_tail('C:\\Users\\anyone\\Program Files\\z a b')
compare('z a b', invk, len)
@@ -198,18 +192,18 @@ describe('path function', function()
end
end)
- it('does not count arguments to the executable as part of its path', function()
+ itp('does not count arguments to the executable as part of its path', function()
local invk, len = invocation_path_tail('exe a/b\\c')
compare("exe a/b\\c", invk, len)
eq(3, len)
end)
- it('only accepts whitespace as a terminator for the executable name', function()
+ itp('only accepts whitespace as a terminator for the executable name', function()
local invk, _ = invocation_path_tail('exe-a+b_c[]()|#!@$%^&*')
eq('exe-a+b_c[]()|#!@$%^&*', (ffi.string(invk)))
end)
- it('is equivalent to path_tail when args do not contain a path separator', function()
+ itp('is equivalent to path_tail when args do not contain a path separator', function()
local ptail = path.path_tail(to_cstr("a/b/c x y z"))
neq(NULL, ptail)
local tail = ffi.string(ptail)
@@ -217,7 +211,7 @@ describe('path function', function()
eq(tail, ffi.string(invk))
end)
- it('is not equivalent to path_tail when args contain a path separator', function()
+ itp('is not equivalent to path_tail when args contain a path separator', function()
local ptail = path.path_tail(to_cstr("a/b/c x y/z"))
neq(NULL, ptail)
local invk, _ = invocation_path_tail("a/b/c x y/z")
@@ -232,34 +226,34 @@ describe('path function', function()
return ffi.string(res)
end
- it('returns', function()
+ itp('returns', function()
eq('directory/file.txt', path_next_component('some/directory/file.txt'))
end)
- it('returns empty string if given file contains no separator', function()
+ itp('returns empty string if given file contains no separator', function()
eq('', path_next_component('file.txt'))
end)
end)
describe('path_shorten_fname', function()
- it('returns NULL if `full_path` is NULL', function()
+ itp('returns NULL if `full_path` is NULL', function()
local dir = to_cstr('some/directory/file.txt')
eq(NULL, (path.path_shorten_fname(NULL, dir)))
end)
- it('returns NULL if the path and dir does not match', function()
+ itp('returns NULL if the path and dir does not match', function()
local dir = to_cstr('not/the/same')
local full = to_cstr('as/this.txt')
eq(NULL, (path.path_shorten_fname(full, dir)))
end)
- it('returns NULL if the path is not separated properly', function()
+ itp('returns NULL if the path is not separated properly', function()
local dir = to_cstr('some/very/long/')
local full = to_cstr('some/very/long/directory/file.txt')
eq(NULL, (path.path_shorten_fname(full, dir)))
end)
- it('shortens the filename if `dir_name` is the start of `full_path`', function()
+ itp('shortens the filename if `dir_name` is the start of `full_path`', function()
local full = to_cstr('some/very/long/directory/file.txt')
local dir = to_cstr('some/very/long')
eq('directory/file.txt', (ffi.string(path.path_shorten_fname(full, dir))))
@@ -280,20 +274,20 @@ describe('path_shorten_fname_if_possible', function()
end)
describe('path_shorten_fname_if_possible', function()
- it('returns shortened path if possible', function()
+ itp('returns shortened path if possible', function()
lfs.chdir('ut_directory')
local full = to_cstr(lfs.currentdir() .. '/subdir/file.txt')
eq('subdir/file.txt', (ffi.string(path.path_shorten_fname_if_possible(full))))
end)
- it('returns `full_path` if a shorter version is not possible', function()
+ itp('returns `full_path` if a shorter version is not possible', function()
local old = lfs.currentdir()
lfs.chdir('ut_directory')
local full = old .. '/subdir/file.txt'
eq(full, (ffi.string(path.path_shorten_fname_if_possible(to_cstr(full)))))
end)
- it('returns NULL if `full_path` is NULL', function()
+ itp('returns NULL if `full_path` is NULL', function()
eq(NULL, (path.path_shorten_fname_if_possible(NULL)))
end)
end)
@@ -330,13 +324,13 @@ describe('more path function', function()
buffer = cstr(length, '')
end)
- it('fails if given filename is NULL', function()
+ itp('fails if given filename is NULL', function()
local force_expansion = 1
local result = path.vim_FullName(NULL, buffer, length, force_expansion)
eq(FAIL, result)
end)
- it('fails safely if given length is wrong #5737', function()
+ itp('fails safely if given length is wrong #5737', function()
local force_expansion = 1
local filename = 'foo/bar/bazzzzzzz/buz/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/a'
local too_short_len = 8
@@ -347,7 +341,7 @@ describe('more path function', function()
eq(FAIL, result)
end)
- it('uses the filename if the filename is a URL', function()
+ itp('uses the filename if the filename is a URL', function()
local force_expansion = 1
local filename = 'http://www.neovim.org'
local result = vim_FullName(filename, buffer, length, force_expansion)
@@ -355,7 +349,7 @@ describe('more path function', function()
eq(OK, result)
end)
- it('fails and uses filename if given filename contains non-existing directory', function()
+ itp('fails and uses filename if given filename contains non-existing directory', function()
local force_expansion = 1
local filename = 'non_existing_dir/test.file'
local result = vim_FullName(filename, buffer, length, force_expansion)
@@ -363,7 +357,7 @@ describe('more path function', function()
eq(FAIL, result)
end)
- it('concatenates given filename if it does not contain a slash', function()
+ itp('concatenates given filename if it does not contain a slash', function()
local force_expansion = 1
local result = vim_FullName('test.file', buffer, length, force_expansion)
local expected = lfs.currentdir() .. '/test.file'
@@ -371,7 +365,7 @@ describe('more path function', function()
eq(OK, result)
end)
- it('concatenates given filename if it is a directory but does not contain a\n slash', function()
+ itp('concatenates given filename if it is a directory but does not contain a\n slash', function()
local force_expansion = 1
local result = vim_FullName('..', buffer, length, force_expansion)
local expected = lfs.currentdir() .. '/..'
@@ -381,7 +375,7 @@ describe('more path function', function()
-- Is it possible for every developer to enter '..' directory while running
-- the unit tests? Which other directory would be better?
- it('enters given directory (instead of just concatenating the strings) if possible and if path contains a slash', function()
+ itp('enters given directory (instead of just concatenating the strings) if possible and if path contains a slash', function()
local force_expansion = 1
local result = vim_FullName('../test.file', buffer, length, force_expansion)
local old_dir = lfs.currentdir()
@@ -392,7 +386,7 @@ describe('more path function', function()
eq(OK, result)
end)
- it('just copies the path if it is already absolute and force=0', function()
+ itp('just copies the path if it is already absolute and force=0', function()
local force_expansion = 0
local absolute_path = '/absolute/path'
local result = vim_FullName(absolute_path, buffer, length, force_expansion)
@@ -400,7 +394,7 @@ describe('more path function', function()
eq(OK, result)
end)
- it('fails and uses filename when the path is relative to HOME', function()
+ itp('fails and uses filename when the path is relative to HOME', function()
local force_expansion = 1
local absolute_path = '~/home.file'
local result = vim_FullName(absolute_path, buffer, length, force_expansion)
@@ -408,14 +402,14 @@ describe('more path function', function()
eq(FAIL, result)
end)
- it('works with some "normal" relative path with directories', function()
+ itp('works with some "normal" relative path with directories', function()
local force_expansion = 1
local result = vim_FullName('unit-test-directory/test.file', buffer, length, force_expansion)
eq(OK, result)
eq(lfs.currentdir() .. '/unit-test-directory/test.file', (ffi.string(buffer)))
end)
- it('does not modify the given filename', function()
+ itp('does not modify the given filename', function()
local force_expansion = 1
local filename = to_cstr('unit-test-directory/test.file')
-- Don't use the wrapper here but pass a cstring directly to the c
@@ -426,7 +420,7 @@ describe('more path function', function()
eq(OK, result)
end)
- it('works with directories that have one path component', function()
+ itp('works with directories that have one path component', function()
local force_expansion = 1
local filename = to_cstr('/tmp')
local result = path.vim_FullName(filename, buffer, length, force_expansion)
@@ -446,12 +440,12 @@ describe('more path function', function()
after_each(function() lfs.rmdir('CamelCase') end)
if ffi.os == 'Windows' or ffi.os == 'OSX' then
- it('Corrects the case of file names in Mac and Windows', function()
+ itp('Corrects the case of file names in Mac and Windows', function()
eq('CamelCase', fix_case('camelcase'))
eq('CamelCase', fix_case('cAMELcASE'))
end)
else
- it('does nothing on Linux', function()
+ itp('does nothing on Linux', function()
eq('camelcase', fix_case('camelcase'))
eq('cAMELcASE', fix_case('cAMELcASE'))
end)
@@ -459,41 +453,41 @@ describe('more path function', function()
end)
describe('append_path', function()
- it('joins given paths with a slash', function()
+ itp('joins given paths with a slash', function()
local path1 = cstr(100, 'path1')
local to_append = to_cstr('path2')
eq(OK, (path.append_path(path1, to_append, 100)))
eq("path1/path2", (ffi.string(path1)))
end)
- it('joins given paths without adding an unnecessary slash', function()
+ itp('joins given paths without adding an unnecessary slash', function()
local path1 = cstr(100, 'path1/')
local to_append = to_cstr('path2')
eq(OK, path.append_path(path1, to_append, 100))
eq("path1/path2", (ffi.string(path1)))
end)
- it('fails and uses filename if there is not enough space left for to_append', function()
+ itp('fails and uses filename if there is not enough space left for to_append', function()
local path1 = cstr(11, 'path1/')
local to_append = to_cstr('path2')
eq(FAIL, (path.append_path(path1, to_append, 11)))
end)
- it('does not append a slash if to_append is empty', function()
+ itp('does not append a slash if to_append is empty', function()
local path1 = cstr(6, 'path1')
local to_append = to_cstr('')
eq(OK, (path.append_path(path1, to_append, 6)))
eq('path1', (ffi.string(path1)))
end)
- it('does not append unnecessary dots', function()
+ itp('does not append unnecessary dots', function()
local path1 = cstr(6, 'path1')
local to_append = to_cstr('.')
eq(OK, (path.append_path(path1, to_append, 6)))
eq('path1', (ffi.string(path1)))
end)
- it('copies to_append to path, if path is empty', function()
+ itp('copies to_append to path, if path is empty', function()
local path1 = cstr(7, '')
local to_append = to_cstr('/path2')
eq(OK, (path.append_path(path1, to_append, 7)))
@@ -507,15 +501,15 @@ describe('more path function', function()
return path.path_is_absolute_path(filename)
end
- it('returns true if filename starts with a slash', function()
+ itp('returns true if filename starts with a slash', function()
eq(OK, path_is_absolute_path('/some/directory/'))
end)
- it('returns true if filename starts with a tilde', function()
+ itp('returns true if filename starts with a tilde', function()
eq(OK, path_is_absolute_path('~/in/my/home~/directory'))
end)
- it('returns false if filename starts not with slash nor tilde', function()
+ itp('returns false if filename starts not with slash nor tilde', function()
eq(FAIL, path_is_absolute_path('not/in/my/home~/directory'))
end)
end)
diff --git a/test/unit/preload.lua b/test/unit/preload.lua
index d8ec2c3943..841e19b878 100644
--- a/test/unit/preload.lua
+++ b/test/unit/preload.lua
@@ -2,6 +2,6 @@
-- Busted started doing this to help provide more isolation. See issue #62
-- for more information about this.
local ffi = require('ffi')
-local helpers = require('test.unit.helpers')
+local helpers = require('test.unit.helpers')(nil)
local lfs = require('lfs')
local preprocess = require('test.unit.preprocess')
diff --git a/test/unit/profile_spec.lua b/test/unit/profile_spec.lua
index 852475fe2c..08e5cedbab 100644
--- a/test/unit/profile_spec.lua
+++ b/test/unit/profile_spec.lua
@@ -1,10 +1,13 @@
-local helpers = require 'test.unit.helpers'
+local helpers = require('test.unit.helpers')(after_each)
+local itp = helpers.gen_itp(it)
-local prof = helpers.cimport './src/nvim/profile.h'
+local cimport = helpers.cimport
local ffi = helpers.ffi
local eq = helpers.eq
local neq = helpers.neq
+local prof = cimport('./src/nvim/profile.h')
+
local function split(inputstr, sep)
if sep == nil then
sep = "%s"
@@ -78,7 +81,7 @@ describe('profiling related functions', function()
end
describe('profile_equal', function()
- it('times are equal to themselves', function()
+ itp('times are equal to themselves', function()
local start = profile_start()
assert.is_true(profile_equal(start, start))
@@ -86,7 +89,7 @@ describe('profiling related functions', function()
assert.is_true(profile_equal(e, e))
end)
- it('times are unequal to others', function()
+ itp('times are unequal to others', function()
assert.is_false(profile_equal(profile_start(), profile_start()))
end)
end)
@@ -95,24 +98,24 @@ describe('profiling related functions', function()
-- the profiling package. Those functions in turn will probably be tested
-- using profile_cmp... circular reasoning.
describe('profile_cmp', function()
- it('can compare subsequent starts', function()
+ itp('can compare subsequent starts', function()
local s1, s2 = profile_start(), profile_start()
assert.is_true(profile_cmp(s1, s2) > 0)
assert.is_true(profile_cmp(s2, s1) < 0)
end)
- it('can compare the zero element', function()
+ itp('can compare the zero element', function()
assert.is_true(profile_cmp(profile_zero(), profile_zero()) == 0)
end)
- it('correctly orders divisions', function()
+ itp('correctly orders divisions', function()
local start = profile_start()
assert.is_true(profile_cmp(start, profile_divide(start, 10)) <= 0)
end)
end)
describe('profile_divide', function()
- it('actually performs division', function()
+ itp('actually performs division', function()
-- note: the routine actually performs floating-point division to get
-- better rounding behaviour, we have to take that into account when
-- checking. (check range, not exact number).
@@ -134,14 +137,14 @@ describe('profiling related functions', function()
end)
describe('profile_zero', function()
- it('returns the same value on each call', function()
+ itp('returns the same value on each call', function()
eq(0, profile_zero())
assert.is_true(profile_equal(profile_zero(), profile_zero()))
end)
end)
describe('profile_start', function()
- it('increases', function()
+ itp('increases', function()
local last = profile_start()
for _ = 1, 100 do
local curr = profile_start()
@@ -152,11 +155,11 @@ describe('profiling related functions', function()
end)
describe('profile_end', function()
- it('the elapsed time cannot be zero', function()
+ itp('the elapsed time cannot be zero', function()
neq(profile_zero(), profile_end(profile_start()))
end)
- it('outer elapsed >= inner elapsed', function()
+ itp('outer elapsed >= inner elapsed', function()
for _ = 1, 100 do
local start_outer = profile_start()
local start_inner = profile_start()
@@ -169,11 +172,11 @@ describe('profiling related functions', function()
end)
describe('profile_setlimit', function()
- it('sets no limit when 0 is passed', function()
+ itp('sets no limit when 0 is passed', function()
eq(true, profile_equal(profile_setlimit(0), profile_zero()))
end)
- it('sets a limit in the future otherwise', function()
+ itp('sets a limit in the future otherwise', function()
local future = profile_setlimit(1000)
local now = profile_start()
assert.is_true(profile_cmp(future, now) < 0)
@@ -181,12 +184,12 @@ describe('profiling related functions', function()
end)
describe('profile_passed_limit', function()
- it('start is in the past', function()
+ itp('start is in the past', function()
local start = profile_start()
eq(true, profile_passed_limit(start))
end)
- it('start + start is in the future', function()
+ itp('start + start is in the future', function()
local start = profile_start()
local future = profile_add(start, start)
eq(false, profile_passed_limit(future))
@@ -194,12 +197,12 @@ describe('profiling related functions', function()
end)
describe('profile_msg', function()
- it('prints the zero time as 0.00000', function()
+ itp('prints the zero time as 0.00000', function()
local str = trim(profile_msg(profile_zero()))
eq(str, "0.000000")
end)
- it('prints the time passed, in seconds.microsends', function()
+ itp('prints the time passed, in seconds.microsends', function()
local start = profile_start()
local endt = profile_end(start)
local str = trim(profile_msg(endt))
@@ -221,14 +224,14 @@ describe('profiling related functions', function()
end)
describe('profile_add', function()
- it('adds profiling times', function()
+ itp('adds profiling times', function()
local start = profile_start()
assert.equals(start, profile_add(profile_zero(), start))
end)
end)
describe('profile_sub', function()
- it('subtracts profiling times', function()
+ itp('subtracts profiling times', function()
-- subtracting zero does nothing
local start = profile_start()
assert.equals(start, profile_sub(start, profile_zero()))
diff --git a/test/unit/rbuffer_spec.lua b/test/unit/rbuffer_spec.lua
index 89136410d3..e9104dd5c4 100644
--- a/test/unit/rbuffer_spec.lua
+++ b/test/unit/rbuffer_spec.lua
@@ -1,9 +1,11 @@
-local helpers = require("test.unit.helpers")
+local helpers = require("test.unit.helpers")(after_each)
+local itp = helpers.gen_itp(it)
-local ffi = helpers.ffi
-local eq = helpers.eq
-local cstr = helpers.cstr
+local eq = helpers.eq
+local ffi = helpers.ffi
+local cstr = helpers.cstr
local to_cstr = helpers.to_cstr
+local child_call_once = helpers.child_call_once
local rbuffer = helpers.cimport("./test/unit/fixtures/rbuffer.h")
@@ -31,9 +33,11 @@ describe('rbuffer functions', function()
end
before_each(function()
- rbuf = ffi.gc(rbuffer.rbuffer_new(capacity), rbuffer.rbuffer_free)
- -- fill the internal buffer with the character '0' to simplify inspecting
- ffi.C.memset(rbuf.start_ptr, string.byte('0'), capacity)
+ child_call_once(function()
+ rbuf = ffi.gc(rbuffer.rbuffer_new(capacity), rbuffer.rbuffer_free)
+ -- fill the internal buffer with the character '0' to simplify inspecting
+ ffi.C.memset(rbuf.start_ptr, string.byte('0'), capacity)
+ end)
end)
describe('RBUFFER_UNTIL_FULL', function()
@@ -50,66 +54,51 @@ describe('rbuffer functions', function()
end)
describe('with empty buffer in one contiguous chunk', function()
- it('is called once with the empty chunk', function()
+ itp('is called once with the empty chunk', function()
collect_write_chunks()
eq({'0000000000000000'}, chunks)
end)
end)
describe('with partially empty buffer in one contiguous chunk', function()
- before_each(function()
+ itp('is called once with the empty chunk', function()
write('string')
- end)
-
- it('is called once with the empty chunk', function()
collect_write_chunks()
eq({'0000000000'}, chunks)
end)
end)
describe('with filled buffer in one contiguous chunk', function()
- before_each(function()
+ itp('is not called', function()
write('abcdefghijklmnopq')
- end)
-
- it('is not called', function()
collect_write_chunks()
eq({}, chunks)
end)
end)
describe('with buffer partially empty in two contiguous chunks', function()
- before_each(function()
+ itp('is called twice with each filled chunk', function()
write('1234567890')
read(8)
- end)
-
- it('is called twice with each filled chunk', function()
collect_write_chunks()
eq({'000000', '12345678'}, chunks)
end)
end)
describe('with buffer empty in two contiguous chunks', function()
- before_each(function()
+ itp('is called twice with each filled chunk', function()
write('12345678')
read(8)
- end)
-
- it('is called twice with each filled chunk', function()
collect_write_chunks()
eq({'00000000', '12345678'}, chunks)
end)
end)
describe('with buffer filled in two contiguous chunks', function()
- before_each(function()
+ itp('is not called', function()
write('12345678')
read(8)
write('abcdefghijklmnopq')
- end)
-
- it('is not called', function()
collect_write_chunks()
eq({}, chunks)
end)
@@ -130,55 +119,43 @@ describe('rbuffer functions', function()
end)
describe('with empty buffer', function()
- it('is not called', function()
+ itp('is not called', function()
collect_read_chunks()
eq({}, chunks)
end)
end)
describe('with partially filled buffer in one contiguous chunk', function()
- before_each(function()
+ itp('is called once with the filled chunk', function()
write('string')
- end)
-
- it('is called once with the filled chunk', function()
collect_read_chunks()
eq({'string'}, chunks)
end)
end)
describe('with filled buffer in one contiguous chunk', function()
- before_each(function()
+ itp('is called once with the filled chunk', function()
write('abcdefghijklmnopq')
- end)
-
- it('is called once with the filled chunk', function()
collect_read_chunks()
eq({'abcdefghijklmnop'}, chunks)
end)
end)
describe('with buffer partially filled in two contiguous chunks', function()
- before_each(function()
+ itp('is called twice with each filled chunk', function()
write('1234567890')
read(10)
write('long string')
- end)
-
- it('is called twice with each filled chunk', function()
collect_read_chunks()
eq({'long s', 'tring'}, chunks)
end)
end)
describe('with buffer filled in two contiguous chunks', function()
- before_each(function()
+ itp('is called twice with each filled chunk', function()
write('12345678')
read(8)
write('abcdefghijklmnopq')
- end)
-
- it('is called twice with each filled chunk', function()
collect_read_chunks()
eq({'abcdefgh', 'ijklmnop'}, chunks)
end)
@@ -198,20 +175,17 @@ describe('rbuffer functions', function()
end)
describe('with empty buffer', function()
- it('is not called', function()
+ itp('is not called', function()
collect_chars()
eq({}, chars)
end)
end)
describe('with buffer filled in two contiguous chunks', function()
- before_each(function()
+ itp('collects each character and index', function()
write('1234567890')
read(10)
write('long string')
- end)
-
- it('collects each character and index', function()
collect_chars()
eq({{'l', 0}, {'o', 1}, {'n', 2}, {'g', 3}, {' ', 4}, {'s', 5},
{'t', 6}, {'r', 7}, {'i', 8}, {'n', 9}, {'g', 10}}, chars)
@@ -232,20 +206,17 @@ describe('rbuffer functions', function()
end)
describe('with empty buffer', function()
- it('is not called', function()
+ itp('is not called', function()
collect_chars()
eq({}, chars)
end)
end)
describe('with buffer filled in two contiguous chunks', function()
- before_each(function()
+ itp('collects each character and index', function()
write('1234567890')
read(10)
write('long string')
- end)
-
- it('collects each character and index', function()
collect_chars()
eq({{'g', 10}, {'n', 9}, {'i', 8}, {'r', 7}, {'t', 6}, {'s', 5},
{' ', 4}, {'g', 3}, {'n', 2}, {'o', 1}, {'l', 0}}, chars)
@@ -264,13 +235,10 @@ describe('rbuffer functions', function()
end
describe('with buffer filled in two contiguous chunks', function()
- before_each(function()
+ itp('compares the common longest sequence', function()
write('1234567890')
read(10)
write('long string')
- end)
-
- it('compares the common longest sequence', function()
eq(0, cmp('long string'))
eq(0, cmp('long strin'))
eq(-1, cmp('long striM'))
@@ -282,31 +250,31 @@ describe('rbuffer functions', function()
end)
describe('with empty buffer', function()
- it('returns 0 since no characters are compared', function()
+ itp('returns 0 since no characters are compared', function()
eq(0, cmp(''))
end)
end)
end)
describe('rbuffer_write', function()
- it('fills the internal buffer and returns the write count', function()
+ itp('fills the internal buffer and returns the write count', function()
eq(12, write('short string'))
eq('short string0000', inspect())
end)
- it('wont write beyond capacity', function()
+ itp('wont write beyond capacity', function()
eq(16, write('very very long string'))
eq('very very long s', inspect())
end)
end)
describe('rbuffer_read', function()
- it('reads what was previously written', function()
+ itp('reads what was previously written', function()
write('to read')
eq('to read', read(20))
end)
- it('reads nothing if the buffer is empty', function()
+ itp('reads nothing if the buffer is empty', function()
eq('', read(20))
write('empty')
eq('empty', read(20))
@@ -315,7 +283,7 @@ describe('rbuffer functions', function()
end)
describe('rbuffer_get', function()
- it('fetch the pointer at offset, wrapping if required', function()
+ itp('fetch the pointer at offset, wrapping if required', function()
write('1234567890')
read(10)
write('long string')
@@ -334,7 +302,7 @@ describe('rbuffer functions', function()
end)
describe('wrapping behavior', function()
- it('writing/reading wraps across the end of the internal buffer', function()
+ itp('writing/reading wraps across the end of the internal buffer', function()
write('1234567890')
eq('1234', read(4))
eq('5678', read(4))
diff --git a/test/unit/set.lua b/test/unit/set.lua
index 4e66546f32..f3d68c3042 100644
--- a/test/unit/set.lua
+++ b/test/unit/set.lua
@@ -26,6 +26,22 @@ function Set:new(items)
return obj
end
+function Set:copy()
+ local obj = {}
+ obj.nelem = self.nelem
+ obj.tbl = {}
+ obj.items = {}
+ for k, v in pairs(self.tbl) do
+ obj.tbl[k] = v
+ end
+ for k, v in pairs(self.items) do
+ obj.items[k] = v
+ end
+ setmetatable(obj, Set)
+ obj.__index = Set
+ return obj
+end
+
-- adds the argument Set to this Set
function Set:union(other)
for e in other:iterator() do
diff --git a/test/unit/strings_spec.lua b/test/unit/strings_spec.lua
index 072701ea78..3bc3dc7130 100644
--- a/test/unit/strings_spec.lua
+++ b/test/unit/strings_spec.lua
@@ -1,4 +1,5 @@
-local helpers = require("test.unit.helpers")
+local helpers = require("test.unit.helpers")(after_each)
+local itp = helpers.gen_itp(it)
local cimport = helpers.cimport
local eq = helpers.eq
@@ -19,23 +20,23 @@ describe('vim_strsave_escaped()', function()
return ret
end
- it('precedes by a backslash all chars from second argument', function()
+ itp('precedes by a backslash all chars from second argument', function()
eq([[\a\b\c\d]], vim_strsave_escaped('abcd','abcd'))
end)
- it('precedes by a backslash chars only from second argument', function()
+ itp('precedes by a backslash chars only from second argument', function()
eq([[\a\bcd]], vim_strsave_escaped('abcd','ab'))
end)
- it('returns a copy of passed string if second argument is empty', function()
+ itp('returns a copy of passed string if second argument is empty', function()
eq('text \n text', vim_strsave_escaped('text \n text',''))
end)
- it('returns an empty string if first argument is empty string', function()
+ itp('returns an empty string if first argument is empty string', function()
eq('', vim_strsave_escaped('','\r'))
end)
- it('returns a copy of passed string if it does not contain chars from 2nd argument', function()
+ 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)
@@ -50,51 +51,51 @@ describe('vim_strnsave_unquoted()', function()
return ret
end
- it('copies unquoted strings as-is', function()
+ itp('copies unquoted strings as-is', function()
eq('-c', vim_strnsave_unquoted('-c'))
eq('', vim_strnsave_unquoted(''))
end)
- it('respects length argument', function()
+ itp('respects length argument', function()
eq('', vim_strnsave_unquoted('-c', 0))
eq('-', vim_strnsave_unquoted('-c', 1))
eq('-', vim_strnsave_unquoted('"-c', 2))
end)
- it('unquotes fully quoted word', function()
+ itp('unquotes fully quoted word', function()
eq('/bin/sh', vim_strnsave_unquoted('"/bin/sh"'))
end)
- it('unquotes partially quoted word', function()
+ itp('unquotes partially quoted word', function()
eq('/Program Files/sh', vim_strnsave_unquoted('/Program" "Files/sh'))
end)
- it('removes ""', function()
+ itp('removes ""', function()
eq('/Program Files/sh', vim_strnsave_unquoted('/""Program" "Files/sh'))
end)
- it('performs unescaping of "', function()
+ itp('performs unescaping of "', function()
eq('/"Program Files"/sh', vim_strnsave_unquoted('/"\\""Program Files"\\""/sh'))
end)
- it('performs unescaping of \\', function()
+ itp('performs unescaping of \\', function()
eq('/\\Program Files\\foo/sh', vim_strnsave_unquoted('/"\\\\"Program Files"\\\\foo"/sh'))
end)
- it('strips quote when there is no pair to it', function()
+ 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)
- it('allows string to end with one backslash unescaped', function()
+ itp('allows string to end with one backslash unescaped', function()
eq('/Program Files/sh\\', vim_strnsave_unquoted('/Program" Files/sh\\'))
end)
- it('does not perform unescaping out of quotes', function()
+ itp('does not perform unescaping out of quotes', function()
eq('/Program\\ Files/sh\\', vim_strnsave_unquoted('/Program\\ Files/sh\\'))
end)
- it('does not unescape \\n', function()
+ itp('does not unescape \\n', function()
eq('/Program\\nFiles/sh', vim_strnsave_unquoted('/Program"\\n"Files/sh'))
end)
end)
diff --git a/test/unit/tempfile_spec.lua b/test/unit/tempfile_spec.lua
index cf0d78b7a7..210518fe1f 100644
--- a/test/unit/tempfile_spec.lua
+++ b/test/unit/tempfile_spec.lua
@@ -1,58 +1,65 @@
-local lfs = require 'lfs'
-local helpers = require 'test.unit.helpers'
+local lfs = require('lfs')
+local helpers = require('test.unit.helpers')(after_each)
+local itp = helpers.gen_itp(it)
-local os = helpers.cimport './src/nvim/os/os.h'
-local tempfile = helpers.cimport './src/nvim/fileio.h'
+local eq = helpers.eq
+local neq = helpers.neq
+local cimport = helpers.cimport
+local child_call_once = helpers.child_call_once
+local child_cleanup_once = helpers.child_cleanup_once
+
+local lib = cimport('./src/nvim/os/os.h', './src/nvim/fileio.h')
describe('tempfile related functions', function()
before_each(function()
- tempfile.vim_deltempdir()
- end)
- after_each(function()
- tempfile.vim_deltempdir()
+ local function vim_deltempdir()
+ lib.vim_deltempdir()
+ end
+ child_call_once(vim_deltempdir)
+ child_cleanup_once(vim_deltempdir)
end)
local vim_gettempdir = function()
- return helpers.ffi.string(tempfile.vim_gettempdir())
+ return helpers.ffi.string(lib.vim_gettempdir())
end
describe('vim_gettempdir', function()
- it('returns path to Neovim own temp directory', function()
+ itp('returns path to Neovim own temp directory', function()
local dir = vim_gettempdir()
assert.True(dir ~= nil and dir:len() > 0)
-- os_file_is_writable returns 2 for a directory which we have rights
-- to write into.
- assert.equals(os.os_file_is_writable(helpers.to_cstr(dir)), 2)
+ eq(lib.os_file_is_writable(helpers.to_cstr(dir)), 2)
for entry in lfs.dir(dir) do
assert.True(entry == '.' or entry == '..')
end
end)
- it('returns the same directory on each call', function()
+ itp('returns the same directory on each call', function()
local dir1 = vim_gettempdir()
local dir2 = vim_gettempdir()
- assert.equals(dir1, dir2)
+ eq(dir1, dir2)
end)
end)
describe('vim_tempname', function()
local vim_tempname = function()
- return helpers.ffi.string(tempfile.vim_tempname())
+ return helpers.ffi.string(lib.vim_tempname())
end
- it('generate name of non-existing file', function()
+ itp('generate name of non-existing file', function()
local file = vim_tempname()
assert.truthy(file)
- assert.False(os.os_path_exists(file))
+ assert.False(lib.os_path_exists(file))
end)
- it('generate different names on each call', function()
+ itp('generate different names on each call', function()
local fst = vim_tempname()
local snd = vim_tempname()
- assert.not_equals(fst, snd)
+ neq(fst, snd)
end)
- it('generate file name in Neovim own temp directory', function()
+ itp('generate file name in Neovim own temp directory', function()
local dir = vim_gettempdir()
local file = vim_tempname()
assert.truthy(file:find('^' .. dir .. '[^/]*$'))