mirror of
https://github.com/neovim/neovim
synced 2025-07-18 02:01:46 +00:00
Merge #8519 feat: name, test ids, sockets in stdpath(state)
This commit is contained in:
@ -6628,30 +6628,29 @@ serverlist() *serverlist()*
|
|||||||
|
|
||||||
serverstart([{address}]) *serverstart()*
|
serverstart([{address}]) *serverstart()*
|
||||||
Opens a socket or named pipe at {address} and listens for
|
Opens a socket or named pipe at {address} and listens for
|
||||||
|RPC| messages. Clients can send |API| commands to the address
|
|RPC| messages. Clients can send |API| commands to the
|
||||||
to control Nvim.
|
returned address to control Nvim.
|
||||||
|
|
||||||
Returns the address string.
|
Returns the address string (may differ from the requested
|
||||||
|
{address}).
|
||||||
|
|
||||||
|
- If {address} contains a colon ":" it is interpreted as
|
||||||
|
a TCP/IPv4/IPv6 address where the last ":" separates host
|
||||||
|
and port (empty or zero assigns a random port).
|
||||||
|
- Else it is interpreted as a named pipe or Unix domain socket
|
||||||
|
path. If there are no slashes it is treated as a name and
|
||||||
|
appended to a generated path.
|
||||||
|
- If {address} is empty it generates a path.
|
||||||
|
|
||||||
If {address} does not contain a colon ":" it is interpreted as
|
Example named pipe: >
|
||||||
a named pipe or Unix domain socket path.
|
|
||||||
|
|
||||||
Example: >
|
|
||||||
if has('win32')
|
if has('win32')
|
||||||
call serverstart('\\.\pipe\nvim-pipe-1234')
|
echo serverstart('\\.\pipe\nvim-pipe-1234')
|
||||||
else
|
else
|
||||||
call serverstart('nvim.sock')
|
echo serverstart('nvim.sock')
|
||||||
endif
|
endif
|
||||||
<
|
<
|
||||||
If {address} contains a colon ":" it is interpreted as a TCP
|
Example TCP/IP address: >
|
||||||
address where the last ":" separates the host and port.
|
echo serverstart('::1:12345')
|
||||||
Assigns a random port if it is empty or 0. Supports IPv4/IPv6.
|
|
||||||
|
|
||||||
Example: >
|
|
||||||
:call serverstart('::1:12345')
|
|
||||||
<
|
|
||||||
If no address is given, it is equivalent to: >
|
|
||||||
:call serverstart(tempname())
|
|
||||||
|
|
||||||
serverstop({address}) *serverstop()*
|
serverstop({address}) *serverstop()*
|
||||||
Closes the pipe or socket at {address}.
|
Closes the pipe or socket at {address}.
|
||||||
@ -7545,7 +7544,7 @@ stdpath({what}) *stdpath()* *E6100*
|
|||||||
data_dirs List Other data directories.
|
data_dirs List Other data directories.
|
||||||
log String Logs directory (for use by plugins too).
|
log String Logs directory (for use by plugins too).
|
||||||
state String Session state directory: storage for file
|
state String Session state directory: storage for file
|
||||||
drafts, undo history, shada, etc.
|
drafts, undo, shada, named pipes, ...
|
||||||
|
|
||||||
Example: >
|
Example: >
|
||||||
:echo stdpath("config")
|
:echo stdpath("config")
|
||||||
|
@ -1790,8 +1790,9 @@ Dictionary nvim__stats(void)
|
|||||||
{
|
{
|
||||||
Dictionary rv = ARRAY_DICT_INIT;
|
Dictionary rv = ARRAY_DICT_INIT;
|
||||||
PUT(rv, "fsync", INTEGER_OBJ(g_stats.fsync));
|
PUT(rv, "fsync", INTEGER_OBJ(g_stats.fsync));
|
||||||
PUT(rv, "redraw", INTEGER_OBJ(g_stats.redraw));
|
PUT(rv, "log_skip", INTEGER_OBJ(g_stats.log_skip));
|
||||||
PUT(rv, "lua_refcount", INTEGER_OBJ(nlua_get_global_ref_count()));
|
PUT(rv, "lua_refcount", INTEGER_OBJ(nlua_get_global_ref_count()));
|
||||||
|
PUT(rv, "redraw", INTEGER_OBJ(g_stats.redraw));
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8497,7 +8497,7 @@ static void f_serverstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
address = xstrdup(tv_get_string(argvars));
|
address = xstrdup(tv_get_string(argvars));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
address = server_address_new();
|
address = server_address_new(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int result = server_start(address);
|
int result = server_start(address);
|
||||||
|
@ -120,7 +120,7 @@ int process_spawn(Process *proc, bool in, bool out, bool err)
|
|||||||
proc->internal_close_cb = decref;
|
proc->internal_close_cb = decref;
|
||||||
proc->refcount++;
|
proc->refcount++;
|
||||||
kl_push(WatcherPtr, proc->loop->children, proc);
|
kl_push(WatcherPtr, proc->loop->children, proc);
|
||||||
DLOG("new: pid=%d argv=[%s]", proc->pid, *proc->argv);
|
DLOG("new: pid=%d argv=[%s]", proc->pid, proc->argv[0]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,15 +16,15 @@
|
|||||||
#include <uv.h>
|
#include <uv.h>
|
||||||
|
|
||||||
#include "auto/config.h"
|
#include "auto/config.h"
|
||||||
|
#include "nvim/eval.h"
|
||||||
#include "nvim/log.h"
|
#include "nvim/log.h"
|
||||||
#include "nvim/main.h"
|
#include "nvim/main.h"
|
||||||
#include "nvim/message.h"
|
#include "nvim/message.h"
|
||||||
#include "nvim/os/os.h"
|
#include "nvim/os/os.h"
|
||||||
#include "nvim/os/time.h"
|
#include "nvim/os/time.h"
|
||||||
|
#include "nvim/path.h"
|
||||||
#include "nvim/types.h"
|
#include "nvim/types.h"
|
||||||
|
|
||||||
#define LOG_FILE_ENV "NVIM_LOG_FILE"
|
|
||||||
|
|
||||||
/// Cached location of the expanded log file path decided by log_path_init().
|
/// Cached location of the expanded log file path decided by log_path_init().
|
||||||
static char log_file_path[MAXPATHL + 1] = { 0 };
|
static char log_file_path[MAXPATHL + 1] = { 0 };
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ static bool log_try_create(char *fname)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initializes path to log file. Sets $NVIM_LOG_FILE if empty.
|
/// Initializes the log file path and sets $NVIM_LOG_FILE if empty.
|
||||||
///
|
///
|
||||||
/// Tries $NVIM_LOG_FILE, or falls back to $XDG_STATE_HOME/nvim/log. Failed
|
/// Tries $NVIM_LOG_FILE, or falls back to $XDG_STATE_HOME/nvim/log. Failed
|
||||||
/// initialization indicates either a bug in expand_env() or both $NVIM_LOG_FILE
|
/// initialization indicates either a bug in expand_env() or both $NVIM_LOG_FILE
|
||||||
@ -60,9 +60,8 @@ static bool log_try_create(char *fname)
|
|||||||
static void log_path_init(void)
|
static void log_path_init(void)
|
||||||
{
|
{
|
||||||
size_t size = sizeof(log_file_path);
|
size_t size = sizeof(log_file_path);
|
||||||
expand_env((char_u *)"$" LOG_FILE_ENV, (char_u *)log_file_path,
|
expand_env((char_u *)"$" ENV_LOGFILE, (char_u *)log_file_path, (int)size - 1);
|
||||||
(int)size - 1);
|
if (strequal("$" ENV_LOGFILE, log_file_path)
|
||||||
if (strequal("$" LOG_FILE_ENV, log_file_path)
|
|
||||||
|| log_file_path[0] == '\0'
|
|| log_file_path[0] == '\0'
|
||||||
|| os_isdir((char_u *)log_file_path)
|
|| os_isdir((char_u *)log_file_path)
|
||||||
|| !log_try_create(log_file_path)) {
|
|| !log_try_create(log_file_path)) {
|
||||||
@ -87,7 +86,7 @@ static void log_path_init(void)
|
|||||||
log_file_path[0] = '\0';
|
log_file_path[0] = '\0';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
os_setenv(LOG_FILE_ENV, log_file_path, true);
|
os_setenv(ENV_LOGFILE, log_file_path, true);
|
||||||
if (log_dir_failure) {
|
if (log_dir_failure) {
|
||||||
WLOG("Failed to create directory %s for writing logs: %s",
|
WLOG("Failed to create directory %s for writing logs: %s",
|
||||||
failed_dir, os_strerror(log_dir_failure));
|
failed_dir, os_strerror(log_dir_failure));
|
||||||
@ -209,7 +208,7 @@ FILE *open_log_file(void)
|
|||||||
// - Directory does not exist
|
// - Directory does not exist
|
||||||
// - File is not writable
|
// - File is not writable
|
||||||
do_log_to_file(stderr, LOGLVL_ERR, NULL, __func__, __LINE__, true,
|
do_log_to_file(stderr, LOGLVL_ERR, NULL, __func__, __LINE__, true,
|
||||||
"failed to open $" LOG_FILE_ENV " (%s): %s",
|
"failed to open $" ENV_LOGFILE " (%s): %s",
|
||||||
strerror(errno), log_file_path);
|
strerror(errno), log_file_path);
|
||||||
return stderr;
|
return stderr;
|
||||||
}
|
}
|
||||||
@ -277,6 +276,9 @@ static bool v_do_log_to_file(FILE *log_file, int log_level, const char *context,
|
|||||||
va_list args)
|
va_list args)
|
||||||
FUNC_ATTR_PRINTF(7, 0)
|
FUNC_ATTR_PRINTF(7, 0)
|
||||||
{
|
{
|
||||||
|
// Name of the Nvim instance that produced the log.
|
||||||
|
static char name[16] = { 0 };
|
||||||
|
|
||||||
static const char *log_levels[] = {
|
static const char *log_levels[] = {
|
||||||
[LOGLVL_DBG] = "DBG",
|
[LOGLVL_DBG] = "DBG",
|
||||||
[LOGLVL_INF] = "INF",
|
[LOGLVL_INF] = "INF",
|
||||||
@ -291,8 +293,7 @@ static bool v_do_log_to_file(FILE *log_file, int log_level, const char *context,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
char date_time[20];
|
char date_time[20];
|
||||||
if (strftime(date_time, sizeof(date_time), "%Y-%m-%dT%H:%M:%S",
|
if (strftime(date_time, sizeof(date_time), "%Y-%m-%dT%H:%M:%S", &local_time) == 0) {
|
||||||
&local_time) == 0) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,14 +303,30 @@ static bool v_do_log_to_file(FILE *log_file, int log_level, const char *context,
|
|||||||
millis = (int)curtime.tv_usec / 1000;
|
millis = (int)curtime.tv_usec / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get a name for this Nvim instance.
|
||||||
|
// TODO(justinmk): expose this as v:name ?
|
||||||
|
if (starting || name[0] == '\0') {
|
||||||
|
// Parent servername.
|
||||||
|
const char *parent = path_tail(os_getenv(ENV_NVIM));
|
||||||
|
// Servername. Empty until starting=false.
|
||||||
|
const char *serv = path_tail(get_vim_var_str(VV_SEND_SERVER));
|
||||||
|
if (parent && parent[0] != NUL) {
|
||||||
|
snprintf(name, sizeof(name), "%s/c", parent); // "/c" indicates child.
|
||||||
|
} else if (serv && serv[0] != NUL) {
|
||||||
|
snprintf(name, sizeof(name), "%s", serv ? serv : "");
|
||||||
|
} else {
|
||||||
|
int64_t pid = os_get_pid();
|
||||||
|
snprintf(name, sizeof(name), "?.%-5" PRId64, pid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Print the log message.
|
// Print the log message.
|
||||||
int64_t pid = os_get_pid();
|
|
||||||
int rv = (line_num == -1 || func_name == NULL)
|
int rv = (line_num == -1 || func_name == NULL)
|
||||||
? fprintf(log_file, "%s %s.%03d %-5" PRId64 " %s",
|
? fprintf(log_file, "%s %s.%03d %-10s %s",
|
||||||
log_levels[log_level], date_time, millis, pid,
|
log_levels[log_level], date_time, millis, name,
|
||||||
(context == NULL ? "?:" : context))
|
(context == NULL ? "?:" : context))
|
||||||
: fprintf(log_file, "%s %s.%03d %-5" PRId64 " %s%s:%d: ",
|
: fprintf(log_file, "%s %s.%03d %-10s %s%s:%d: ",
|
||||||
log_levels[log_level], date_time, millis, pid,
|
log_levels[log_level], date_time, millis, name,
|
||||||
(context == NULL ? "" : context),
|
(context == NULL ? "" : context),
|
||||||
func_name, line_num);
|
func_name, line_num);
|
||||||
if (rv < 0) {
|
if (rv < 0) {
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
|
|
||||||
#define MAX_CONNECTIONS 32
|
#define MAX_CONNECTIONS 32
|
||||||
#define ENV_LISTEN "NVIM_LISTEN_ADDRESS" // deprecated
|
#define ENV_LISTEN "NVIM_LISTEN_ADDRESS" // deprecated
|
||||||
#define ENV_NVIM "NVIM"
|
|
||||||
|
|
||||||
static garray_T watchers = GA_EMPTY_INIT_VALUE;
|
static garray_T watchers = GA_EMPTY_INIT_VALUE;
|
||||||
|
|
||||||
@ -43,7 +42,7 @@ bool server_init(const char *listen_addr)
|
|||||||
|
|
||||||
int rv = listen_addr ? server_start(listen_addr) : 1;
|
int rv = listen_addr ? server_start(listen_addr) : 1;
|
||||||
if (0 != rv) {
|
if (0 != rv) {
|
||||||
listen_addr = server_address_new();
|
listen_addr = server_address_new(NULL);
|
||||||
if (!listen_addr) {
|
if (!listen_addr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -56,6 +55,11 @@ bool server_init(const char *listen_addr)
|
|||||||
os_unsetenv(ENV_LISTEN);
|
os_unsetenv(ENV_LISTEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(justinmk): this is for logging_spec. Can remove this after nvim_log #7062 is merged.
|
||||||
|
if (os_env_exists("__NVIM_TEST_LOG")) {
|
||||||
|
ELOG("test log message");
|
||||||
|
}
|
||||||
|
|
||||||
return rv == 0;
|
return rv == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,23 +87,26 @@ void server_teardown(void)
|
|||||||
|
|
||||||
/// Generates unique address for local server.
|
/// Generates unique address for local server.
|
||||||
///
|
///
|
||||||
/// In Windows this is a named pipe in the format
|
/// Named pipe format:
|
||||||
/// \\.\pipe\nvim-<PID>-<COUNTER>.
|
/// - Windows: "\\.\pipe\<name>.<pid>.<counter>"
|
||||||
///
|
/// - Other: "~/.local/state/nvim/<name>.<pid>.<counter>"
|
||||||
/// For other systems it is a path returned by vim_tempname().
|
char *server_address_new(const char *name)
|
||||||
///
|
|
||||||
/// This function is NOT thread safe
|
|
||||||
char *server_address_new(void)
|
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
|
||||||
static uint32_t count = 0;
|
static uint32_t count = 0;
|
||||||
char template[ADDRESS_MAX_SIZE];
|
char fmt[ADDRESS_MAX_SIZE];
|
||||||
snprintf(template, ADDRESS_MAX_SIZE,
|
#ifdef WIN32
|
||||||
"\\\\.\\pipe\\nvim-%" PRIu64 "-%" PRIu32, os_get_pid(), count++);
|
int r = snprintf(fmt, sizeof(fmt), "\\\\.\\pipe\\%s.%" PRIu64 ".%" PRIu32,
|
||||||
return xstrdup(template);
|
name ? name : "nvim", os_get_pid(), count++);
|
||||||
#else
|
#else
|
||||||
return (char *)vim_tempname();
|
char *dir = get_xdg_home(kXDGStateHome);
|
||||||
|
int r = snprintf(fmt, sizeof(fmt), "%s/%s.%" PRIu64 ".%" PRIu32,
|
||||||
|
dir, name ? name : "nvim", os_get_pid(), count++);
|
||||||
|
xfree(dir);
|
||||||
#endif
|
#endif
|
||||||
|
if ((size_t)r >= sizeof(fmt)) {
|
||||||
|
ELOG("truncated server address");
|
||||||
|
}
|
||||||
|
return xstrdup(fmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if this instance owns a pipe address.
|
/// Check if this instance owns a pipe address.
|
||||||
@ -114,35 +121,35 @@ bool server_owns_pipe_address(const char *path)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Starts listening for API calls.
|
/// Starts listening for RPC calls.
|
||||||
///
|
///
|
||||||
/// The socket type is determined by parsing `endpoint`: If it's a valid IPv4
|
/// Socket type is decided by the format of `addr`:
|
||||||
/// or IPv6 address in 'ip:[port]' format, then it will be a TCP socket.
|
/// - TCP socket if it looks like an IPv4/6 address ("ip:[port]").
|
||||||
/// Otherwise it will be a Unix socket or named pipe (Windows).
|
/// - If [port] is omitted, a random one is assigned.
|
||||||
|
/// - Unix socket (or named pipe on Windows) otherwise.
|
||||||
|
/// - If the name doesn't contain slashes it is appended to a generated path. #8519
|
||||||
///
|
///
|
||||||
/// If no port is given, a random one will be assigned.
|
/// @param addr Server address: a "ip:[port]" string or arbitrary name or filepath (max 256 bytes)
|
||||||
///
|
/// for the Unix socket or named pipe.
|
||||||
/// @param endpoint Address of the server. Either a 'ip:[port]' string or an
|
/// @returns 0: success, 1: validation error, 2: already listening, -errno: failed to bind/listen.
|
||||||
/// arbitrary identifier (trimmed to 256 bytes) for the Unix
|
int server_start(const char *addr)
|
||||||
/// socket or named pipe.
|
|
||||||
/// @returns 0: success, 1: validation error, 2: already listening,
|
|
||||||
/// -errno: failed to bind or listen.
|
|
||||||
int server_start(const char *endpoint)
|
|
||||||
{
|
{
|
||||||
if (endpoint == NULL || endpoint[0] == '\0') {
|
if (addr == NULL || addr[0] == '\0') {
|
||||||
WLOG("Empty or NULL endpoint");
|
WLOG("Empty or NULL address");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isname = !strstr(addr, ":") && !strstr(addr, "/") && !strstr(addr, "\\");
|
||||||
|
char *addr_gen = isname ? server_address_new(addr) : NULL;
|
||||||
SocketWatcher *watcher = xmalloc(sizeof(SocketWatcher));
|
SocketWatcher *watcher = xmalloc(sizeof(SocketWatcher));
|
||||||
|
int result = socket_watcher_init(&main_loop, watcher, isname ? addr_gen : addr);
|
||||||
int result = socket_watcher_init(&main_loop, watcher, endpoint);
|
xfree(addr_gen);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
xfree(watcher);
|
xfree(watcher);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if a watcher for the endpoint already exists
|
// Check if a watcher for the address already exists.
|
||||||
for (int i = 0; i < watchers.ga_len; i++) {
|
for (int i = 0; i < watchers.ga_len; i++) {
|
||||||
if (!strcmp(watcher->addr, ((SocketWatcher **)watchers.ga_data)[i]->addr)) {
|
if (!strcmp(watcher->addr, ((SocketWatcher **)watchers.ga_data)[i]->addr)) {
|
||||||
ELOG("Already listening on %s", watcher->addr);
|
ELOG("Already listening on %s", watcher->addr);
|
||||||
|
@ -16,4 +16,7 @@
|
|||||||
# include "os/users.h.generated.h"
|
# include "os/users.h.generated.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define ENV_LOGFILE "NVIM_LOG_FILE"
|
||||||
|
#define ENV_NVIM "NVIM"
|
||||||
|
|
||||||
#endif // NVIM_OS_OS_H
|
#endif // NVIM_OS_OS_H
|
||||||
|
@ -163,10 +163,15 @@ static struct termios termios_default;
|
|||||||
/// @param tty_fd TTY file descriptor, or -1 if not in a terminal.
|
/// @param tty_fd TTY file descriptor, or -1 if not in a terminal.
|
||||||
void pty_process_save_termios(int tty_fd)
|
void pty_process_save_termios(int tty_fd)
|
||||||
{
|
{
|
||||||
DLOG("tty_fd=%d", tty_fd);
|
if (tty_fd == -1) {
|
||||||
if (tty_fd == -1 || tcgetattr(tty_fd, &termios_default) != 0) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
int rv = tcgetattr(tty_fd, &termios_default);
|
||||||
|
if (rv != 0) {
|
||||||
|
ELOG("tcgetattr failed (tty_fd=%d): %s", tty_fd, strerror(errno));
|
||||||
|
} else {
|
||||||
|
DLOG("tty_fd=%d", tty_fd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @returns zero on success, or negative error code
|
/// @returns zero on success, or negative error code
|
||||||
|
@ -88,7 +88,12 @@ FileComparison path_full_compare(char_u *const s1, char_u *const s2, const bool
|
|||||||
return kDifferentFiles;
|
return kDifferentFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the tail (i.e., the filename segment) of a path `fname`.
|
/// Gets the tail (filename segment) of path `fname`.
|
||||||
|
///
|
||||||
|
/// Examples:
|
||||||
|
/// - "dir/file.txt" => "file.txt"
|
||||||
|
/// - "file.txt" => "file.txt"
|
||||||
|
/// - "dir/" => ""
|
||||||
///
|
///
|
||||||
/// @return pointer just past the last path separator (empty string, if fname
|
/// @return pointer just past the last path separator (empty string, if fname
|
||||||
/// ends in a slash), or empty string if fname is NULL.
|
/// ends in a slash), or empty string if fname is NULL.
|
||||||
|
@ -91,25 +91,33 @@ or:
|
|||||||
Debugging tests
|
Debugging tests
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
- Each test gets a test id which looks like "T123". This also appears in the
|
||||||
|
log file. Child processes spawned from a test appear in the logs with the
|
||||||
|
*parent* name followed by "/c". Example:
|
||||||
|
```
|
||||||
|
DBG 2022-06-15T18:37:45.226 T57.58016.0 UI: flush
|
||||||
|
DBG 2022-06-15T18:37:45.226 T57.58016.0 inbuf_poll:442: blocking... events_enabled=0 events_pending=0
|
||||||
|
DBG 2022-06-15T18:37:45.227 T57.58016.0/c UI: stop
|
||||||
|
INF 2022-06-15T18:37:45.227 T57.58016.0/c os_exit:595: Nvim exit: 0
|
||||||
|
DBG 2022-06-15T18:37:45.229 T57.58016.0 read_cb:118: closing Stream (0x7fd5d700ea18): EOF (end of file)
|
||||||
|
INF 2022-06-15T18:37:45.229 T57.58016.0 on_process_exit:400: exited: pid=58017 status=0 stoptime=0
|
||||||
|
```
|
||||||
- You can set `$GDB` to [run tests under gdbserver](https://github.com/neovim/neovim/pull/1527).
|
- You can set `$GDB` to [run tests under gdbserver](https://github.com/neovim/neovim/pull/1527).
|
||||||
And if `$VALGRIND` is set it will pass `--vgdb=yes` to valgrind instead of
|
And if `$VALGRIND` is set it will pass `--vgdb=yes` to valgrind instead of
|
||||||
starting gdbserver directly.
|
starting gdbserver directly.
|
||||||
- Hanging tests often happen due to unexpected `:h press-enter` prompts. The
|
- Hanging tests can happen due to unexpected "press-enter" prompts. The
|
||||||
default screen width is 50 columns. Commands that try to print lines longer
|
default screen width is 50 columns. Commands that try to print lines longer
|
||||||
than 50 columns in the command-line, e.g. `:edit very...long...path`, will
|
than 50 columns in the command-line, e.g. `:edit very...long...path`, will
|
||||||
trigger the prompt. In this case, a shorter path or `:silent edit` should be
|
trigger the prompt. Try using a shorter path, or `:silent edit`.
|
||||||
used.
|
|
||||||
- If you can't figure out what is going on, try to visualize the screen. Put
|
- If you can't figure out what is going on, try to visualize the screen. Put
|
||||||
this at the beginning of your test:
|
this at the beginning of your test:
|
||||||
|
```lua
|
||||||
```lua
|
local Screen = require('test.functional.ui.screen')
|
||||||
local Screen = require('test.functional.ui.screen')
|
local screen = Screen.new()
|
||||||
local screen = Screen.new()
|
screen:attach()
|
||||||
screen:attach()
|
```
|
||||||
```
|
Then put `screen:snapshot_util()` anywhere in your test. See the comments in
|
||||||
|
`test/functional/ui/screen.lua` for more info.
|
||||||
Afterwards, put `screen:snapshot_util()` at any position in your test. See the
|
|
||||||
comment at the top of `test/functional/ui/screen.lua` for more.
|
|
||||||
|
|
||||||
Filtering Tests
|
Filtering Tests
|
||||||
---------------
|
---------------
|
||||||
@ -247,12 +255,17 @@ Number; !must be defined to function properly):
|
|||||||
|
|
||||||
- `BUSTED_ARGS` (F) (U): arguments forwarded to `busted`.
|
- `BUSTED_ARGS` (F) (U): arguments forwarded to `busted`.
|
||||||
|
|
||||||
|
- `CC` (U) (S): specifies which C compiler to use to preprocess files.
|
||||||
|
Currently only compilers with gcc-compatible arguments are supported.
|
||||||
|
|
||||||
- `GDB` (F) (D): makes nvim instances to be run under `gdbserver`. It will be
|
- `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
|
accessible on `localhost:7777`: use `gdb build/bin/nvim`, type `target remote
|
||||||
:7777` inside.
|
:7777` inside.
|
||||||
|
|
||||||
- `GDBSERVER_PORT` (F) (I): overrides port used for `GDB`.
|
- `GDBSERVER_PORT` (F) (I): overrides port used for `GDB`.
|
||||||
|
|
||||||
|
- `LOG_DIR` (FU) (S!): specifies where to seek for valgrind and ASAN log files.
|
||||||
|
|
||||||
- `VALGRIND` (F) (D): makes nvim instances to be run under `valgrind`. Log
|
- `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
|
files are named `valgrind-%p.log` in this case. Note that non-empty valgrind
|
||||||
log may fail tests. Valgrind arguments may be seen in
|
log may fail tests. Valgrind arguments may be seen in
|
||||||
@ -269,11 +282,7 @@ Number; !must be defined to function properly):
|
|||||||
|
|
||||||
- `NVIM_LUA_NOTRACK` (F) (D): disable reference counting of Lua objects
|
- `NVIM_LUA_NOTRACK` (F) (D): disable reference counting of Lua objects
|
||||||
|
|
||||||
- `NVIM_PROG`, `NVIM_PRG` (F) (S): override path to Neovim executable (default
|
- `NVIM_PRG` (F) (S): path to Nvim executable (default: `build/bin/nvim`).
|
||||||
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
|
- `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
|
raises a possibility of bugs due to conflicts in header definitions, despite
|
||||||
@ -295,8 +304,6 @@ Number; !must be defined to function properly):
|
|||||||
- `NVIM_TEST_RUN_FAILING_TESTS` (U) (1): makes `itp` run tests which are known
|
- `NVIM_TEST_RUN_FAILING_TESTS` (U) (1): makes `itp` run tests which are known
|
||||||
to fail (marked by setting third argument to `true`).
|
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
|
- `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.
|
where to search for core files. Are supposed to be defined all at once.
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
local pretty = require 'pl.pretty'
|
local pretty = require 'pl.pretty'
|
||||||
|
local global_helpers = require('test.helpers')
|
||||||
|
|
||||||
-- Colors are disabled by default. #15610
|
-- Colors are disabled by default. #15610
|
||||||
local colors = setmetatable({}, {__index = function() return function(s) return s == nil and '' or tostring(s) end end})
|
local colors = setmetatable({}, {__index = function() return function(s) return s == nil and '' or tostring(s) end end})
|
||||||
@ -25,35 +26,35 @@ return function(options)
|
|||||||
|
|
||||||
local repeatSuiteString = '\nRepeating all tests (run %d of %d) . . .\n\n'
|
local repeatSuiteString = '\nRepeating all tests (run %d of %d) . . .\n\n'
|
||||||
local randomizeString = c.note('Note: Randomizing test order with a seed of %d.\n')
|
local randomizeString = c.note('Note: Randomizing test order with a seed of %d.\n')
|
||||||
local globalSetup = c.sect('[----------]') .. ' Global test environment setup.\n'
|
local globalSetup = c.sect('--------') .. ' Global test environment setup.\n'
|
||||||
local fileStartString = c.sect('[----------]') .. ' Running tests from ' .. c.file('%s') .. '\n'
|
local fileStartString = c.sect('--------') .. ' Running tests from ' .. c.file('%s') .. '\n'
|
||||||
local runString = c.sect('[ RUN ]') .. ' ' .. c.test('%s') .. ': '
|
local runString = c.sect('RUN ') .. ' ' .. c.test('%s') .. ': '
|
||||||
local successString = c.succ('OK') .. '\n'
|
local successString = c.succ('OK') .. '\n'
|
||||||
local skippedString = c.skip('SKIP') .. '\n'
|
local skippedString = c.skip('SKIP') .. '\n'
|
||||||
local failureString = c.fail('FAIL') .. '\n'
|
local failureString = c.fail('FAIL') .. '\n'
|
||||||
local errorString = c.errr('ERR') .. '\n'
|
local errorString = c.errr('ERR') .. '\n'
|
||||||
local fileEndString = c.sect('[----------]') .. ' '.. c.nmbr('%d') .. ' %s from ' .. c.file('%s') .. ' ' .. c.time('(%.2f ms total)') .. '\n\n'
|
local fileEndString = c.sect('--------') .. ' '.. c.nmbr('%d') .. ' %s from ' .. c.file('%s') .. ' ' .. c.time('(%.2f ms total)') .. '\n\n'
|
||||||
local globalTeardown = c.sect('[----------]') .. ' Global test environment teardown.\n'
|
local globalTeardown = c.sect('--------') .. ' Global test environment teardown.\n'
|
||||||
local suiteEndString = c.sect('[==========]') .. ' ' .. c.nmbr('%d') .. ' %s from ' .. c.nmbr('%d') .. ' test %s ran. ' .. c.time('(%.2f ms total)') .. '\n'
|
local suiteEndString = c.sect('========') .. ' ' .. c.nmbr('%d') .. ' %s from ' .. c.nmbr('%d') .. ' test %s ran. ' .. c.time('(%.2f ms total)') .. '\n'
|
||||||
local successStatus = c.succ('[ PASSED ]') .. ' ' .. c.nmbr('%d') .. ' %s.\n'
|
local successStatus = c.succ('PASSED ') .. ' ' .. c.nmbr('%d') .. ' %s.\n'
|
||||||
local timeString = c.time('%.2f ms')
|
local timeString = c.time('%.2f ms')
|
||||||
|
|
||||||
local summaryStrings = {
|
local summaryStrings = {
|
||||||
skipped = {
|
skipped = {
|
||||||
header = c.skip('[ SKIPPED ]') .. ' ' .. c.nmbr('%d') .. ' %s, listed below:\n',
|
header = c.skip('SKIPPED ') .. ' ' .. c.nmbr('%d') .. ' %s, listed below:\n',
|
||||||
test = c.skip('[ SKIPPED ]') .. ' %s\n',
|
test = c.skip('SKIPPED ') .. ' %s\n',
|
||||||
footer = ' ' .. c.nmbr('%d') .. ' SKIPPED %s\n',
|
footer = ' ' .. c.nmbr('%d') .. ' SKIPPED %s\n',
|
||||||
},
|
},
|
||||||
|
|
||||||
failure = {
|
failure = {
|
||||||
header = c.fail('[ FAILED ]') .. ' ' .. c.nmbr('%d') .. ' %s, listed below:\n',
|
header = c.fail('FAILED ') .. ' ' .. c.nmbr('%d') .. ' %s, listed below:\n',
|
||||||
test = c.fail('[ FAILED ]') .. ' %s\n',
|
test = c.fail('FAILED ') .. ' %s\n',
|
||||||
footer = ' ' .. c.nmbr('%d') .. ' FAILED %s\n',
|
footer = ' ' .. c.nmbr('%d') .. ' FAILED %s\n',
|
||||||
},
|
},
|
||||||
|
|
||||||
error = {
|
error = {
|
||||||
header = c.errr('[ ERROR ]') .. ' ' .. c.nmbr('%d') .. ' %s, listed below:\n',
|
header = c.errr('ERROR ') .. ' ' .. c.nmbr('%d') .. ' %s, listed below:\n',
|
||||||
test = c.errr('[ ERROR ]') .. ' %s\n',
|
test = c.errr('ERROR ') .. ' %s\n',
|
||||||
footer = ' ' .. c.nmbr('%d') .. ' %s\n',
|
footer = ' ' .. c.nmbr('%d') .. ' %s\n',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -193,6 +194,9 @@ return function(options)
|
|||||||
io.write(globalTeardown)
|
io.write(globalTeardown)
|
||||||
io.write(suiteEndString:format(testCount, tests, fileCount, files, elapsedTime_ms))
|
io.write(suiteEndString:format(testCount, tests, fileCount, files, elapsedTime_ms))
|
||||||
io.write(getSummaryString())
|
io.write(getSummaryString())
|
||||||
|
if failureCount > 0 or errorCount > 0 then
|
||||||
|
io.write(global_helpers.read_nvim_log(nil, true))
|
||||||
|
end
|
||||||
io.flush()
|
io.flush()
|
||||||
|
|
||||||
return nil, true
|
return nil, true
|
||||||
@ -215,7 +219,9 @@ return function(options)
|
|||||||
end
|
end
|
||||||
|
|
||||||
handler.testStart = function(element, _parent)
|
handler.testStart = function(element, _parent)
|
||||||
io.write(runString:format(handler.getFullName(element)))
|
local testid = _G._nvim_test_id or ''
|
||||||
|
local desc = ('%s %s'):format(testid, handler.getFullName(element))
|
||||||
|
io.write(runString:format(desc))
|
||||||
io.flush()
|
io.flush()
|
||||||
|
|
||||||
return nil, true
|
return nil, true
|
||||||
|
@ -336,7 +336,7 @@ describe('nvim_get_keymap', function()
|
|||||||
return GlobalCount
|
return GlobalCount
|
||||||
]])
|
]])
|
||||||
local mapargs = meths.get_keymap('n')
|
local mapargs = meths.get_keymap('n')
|
||||||
assert.Truthy(type(mapargs[1].callback) == 'number', 'callback is not luaref number')
|
assert(type(mapargs[1].callback) == 'number', 'callback is not luaref number')
|
||||||
mapargs[1].callback = nil
|
mapargs[1].callback = nil
|
||||||
eq({
|
eq({
|
||||||
lhs='asdf',
|
lhs='asdf',
|
||||||
@ -815,7 +815,7 @@ describe('nvim_set_keymap, nvim_del_keymap', function()
|
|||||||
assert.truthy(string.match(funcs.maparg('asdf', 'n'),
|
assert.truthy(string.match(funcs.maparg('asdf', 'n'),
|
||||||
"^<Lua function %d+>"))
|
"^<Lua function %d+>"))
|
||||||
local mapargs = funcs.maparg('asdf', 'n', false, true)
|
local mapargs = funcs.maparg('asdf', 'n', false, true)
|
||||||
assert.Truthy(type(mapargs.callback) == 'number', 'callback is not luaref number')
|
assert(type(mapargs.callback) == 'number', 'callback is not luaref number')
|
||||||
mapargs.callback = nil
|
mapargs.callback = nil
|
||||||
eq(generate_mapargs('n', 'asdf', nil, {sid=sid_lua}), mapargs)
|
eq(generate_mapargs('n', 'asdf', nil, {sid=sid_lua}), mapargs)
|
||||||
end)
|
end)
|
||||||
|
57
test/functional/core/log_spec.lua
Normal file
57
test/functional/core/log_spec.lua
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
local helpers = require('test.functional.helpers')(after_each)
|
||||||
|
local assert_log = helpers.assert_log
|
||||||
|
local clear = helpers.clear
|
||||||
|
local command = helpers.command
|
||||||
|
local eq = helpers.eq
|
||||||
|
local exec_lua = helpers.exec_lua
|
||||||
|
local expect_exit = helpers.expect_exit
|
||||||
|
local request = helpers.request
|
||||||
|
local retry = helpers.retry
|
||||||
|
|
||||||
|
describe('log', function()
|
||||||
|
local testlog = 'Xtest_logging'
|
||||||
|
|
||||||
|
after_each(function()
|
||||||
|
expect_exit(command, 'qa!')
|
||||||
|
os.remove(testlog)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('skipped before log_init', function()
|
||||||
|
-- This test is for _visibility_: adjust as needed, after checking for regression.
|
||||||
|
--
|
||||||
|
-- During startup some components may try to log before logging is setup.
|
||||||
|
-- That should be uncommon (ideally never)--and if there are MANY such
|
||||||
|
-- calls, that needs investigation.
|
||||||
|
clear()
|
||||||
|
eq(0, request('nvim__stats').log_skip)
|
||||||
|
clear{env={CDPATH='~doesnotexist'}}
|
||||||
|
assert(request('nvim__stats').log_skip <= 13)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('messages are formatted with name or test id', function()
|
||||||
|
-- Examples:
|
||||||
|
-- ERR 2022-05-29T12:30:03.800 T2 log_init:110: test log message
|
||||||
|
-- ERR 2022-05-29T12:30:03.814 T2/child log_init:110: test log message
|
||||||
|
|
||||||
|
clear({env={
|
||||||
|
NVIM_LOG_FILE=testlog,
|
||||||
|
-- TODO: remove this after nvim_log #7062 is merged.
|
||||||
|
__NVIM_TEST_LOG='1'
|
||||||
|
}})
|
||||||
|
|
||||||
|
local tid = _G._nvim_test_id
|
||||||
|
retry(nil, 1000, function()
|
||||||
|
assert_log(tid..'%.%d+%.%d +server_init:%d+: test log message', testlog, 100)
|
||||||
|
end)
|
||||||
|
|
||||||
|
exec_lua([[
|
||||||
|
local j1 = vim.fn.jobstart({ vim.v.progpath, '-es', '-V1', '+foochild', '+qa!' }, vim.empty_dict())
|
||||||
|
vim.fn.jobwait({ j1 }, 10000)
|
||||||
|
]])
|
||||||
|
|
||||||
|
-- Child Nvim spawned by jobstart() appends "/c" to parent name.
|
||||||
|
retry(nil, 1000, function()
|
||||||
|
assert_log('%.%d+%.%d/c +server_init:%d+: test log message', testlog, 100)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
end)
|
@ -580,7 +580,7 @@ describe('user config init', function()
|
|||||||
|
|
||||||
it('loads default lua config, but shows an error', function()
|
it('loads default lua config, but shows an error', function()
|
||||||
clear{ args_rm={'-u'}, env=xenv }
|
clear{ args_rm={'-u'}, env=xenv }
|
||||||
feed('<cr>') -- confirm "Conflicting config ..." message
|
feed('<cr><c-c>') -- Dismiss "Conflicting config …" message.
|
||||||
eq(1, eval('g:lua_rc'))
|
eq(1, eval('g:lua_rc'))
|
||||||
matches('^E5422: Conflicting configs', meths.exec('messages', true))
|
matches('^E5422: Conflicting configs', meths.exec('messages', true))
|
||||||
end)
|
end)
|
||||||
@ -632,13 +632,13 @@ describe('runtime:', function()
|
|||||||
eq(2, eval('g:lua_plugin'))
|
eq(2, eval('g:lua_plugin'))
|
||||||
-- Check if plugin_file_path is listed in :scriptname
|
-- Check if plugin_file_path is listed in :scriptname
|
||||||
local scripts = meths.exec(':scriptnames', true)
|
local scripts = meths.exec(':scriptnames', true)
|
||||||
assert.Truthy(scripts:find(plugin_file_path))
|
assert(scripts:find(plugin_file_path))
|
||||||
|
|
||||||
-- Check if plugin_file_path is listed in startup profile
|
-- Check if plugin_file_path is listed in startup profile
|
||||||
local profile_reader = io.open(profiler_file, 'r')
|
local profile_reader = io.open(profiler_file, 'r')
|
||||||
local profile_log = profile_reader:read('*a')
|
local profile_log = profile_reader:read('*a')
|
||||||
profile_reader:close()
|
profile_reader:close()
|
||||||
assert.Truthy(profile_log :find(plugin_file_path))
|
assert(profile_log:find(plugin_file_path))
|
||||||
|
|
||||||
os.remove(profiler_file)
|
os.remove(profiler_file)
|
||||||
rmdir(plugin_path)
|
rmdir(plugin_path)
|
||||||
|
@ -431,18 +431,25 @@ end
|
|||||||
function module.new_argv(...)
|
function module.new_argv(...)
|
||||||
local args = {unpack(module.nvim_argv)}
|
local args = {unpack(module.nvim_argv)}
|
||||||
table.insert(args, '--headless')
|
table.insert(args, '--headless')
|
||||||
|
if _G._nvim_test_id then
|
||||||
|
-- Set the server name to the test-id for logging. #8519
|
||||||
|
table.insert(args, '--listen')
|
||||||
|
table.insert(args, _G._nvim_test_id)
|
||||||
|
end
|
||||||
local new_args
|
local new_args
|
||||||
local io_extra
|
local io_extra
|
||||||
local env = nil
|
local env = nil
|
||||||
local opts = select(1, ...)
|
local opts = select(1, ...)
|
||||||
if type(opts) == 'table' then
|
if type(opts) ~= 'table' then
|
||||||
|
new_args = {...}
|
||||||
|
else
|
||||||
args = remove_args(args, opts.args_rm)
|
args = remove_args(args, opts.args_rm)
|
||||||
if opts.env then
|
if opts.env then
|
||||||
local env_tbl = {}
|
local env_opt = {}
|
||||||
for k, v in pairs(opts.env) do
|
for k, v in pairs(opts.env) do
|
||||||
assert(type(k) == 'string')
|
assert(type(k) == 'string')
|
||||||
assert(type(v) == 'string')
|
assert(type(v) == 'string')
|
||||||
env_tbl[k] = v
|
env_opt[k] = v
|
||||||
end
|
end
|
||||||
for _, k in ipairs({
|
for _, k in ipairs({
|
||||||
'HOME',
|
'HOME',
|
||||||
@ -458,19 +465,18 @@ function module.new_argv(...)
|
|||||||
'TMPDIR',
|
'TMPDIR',
|
||||||
'VIMRUNTIME',
|
'VIMRUNTIME',
|
||||||
}) do
|
}) do
|
||||||
if not env_tbl[k] then
|
-- Set these from the environment unless the caller defined them.
|
||||||
env_tbl[k] = os.getenv(k)
|
if not env_opt[k] then
|
||||||
|
env_opt[k] = os.getenv(k)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
env = {}
|
env = {}
|
||||||
for k, v in pairs(env_tbl) do
|
for k, v in pairs(env_opt) do
|
||||||
env[#env + 1] = k .. '=' .. v
|
env[#env + 1] = k .. '=' .. v
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
new_args = opts.args or {}
|
new_args = opts.args or {}
|
||||||
io_extra = opts.io_extra
|
io_extra = opts.io_extra
|
||||||
else
|
|
||||||
new_args = {...}
|
|
||||||
end
|
end
|
||||||
for _, arg in ipairs(new_args) do
|
for _, arg in ipairs(new_args) do
|
||||||
table.insert(args, arg)
|
table.insert(args, arg)
|
||||||
|
@ -266,8 +266,8 @@ describe('LSP', function()
|
|||||||
end;
|
end;
|
||||||
-- If the program timed out, then code will be nil.
|
-- If the program timed out, then code will be nil.
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(0, code, "exit code", fake_lsp_logfile)
|
eq(0, code, "exit code")
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
end;
|
end;
|
||||||
-- Note that NIL must be used here.
|
-- Note that NIL must be used here.
|
||||||
-- on_handler(err, method, result, client_id)
|
-- on_handler(err, method, result, client_id)
|
||||||
@ -288,8 +288,8 @@ describe('LSP', function()
|
|||||||
client.stop()
|
client.stop()
|
||||||
end;
|
end;
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(101, code, "exit code", fake_lsp_logfile) -- See fake-lsp-server.lua
|
eq(101, code, "exit code") -- See fake-lsp-server.lua
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
assert_log(pesc([[assert_eq failed: left == "\"shutdown\"", right == "\"test\""]]),
|
assert_log(pesc([[assert_eq failed: left == "\"shutdown\"", right == "\"test\""]]),
|
||||||
fake_lsp_logfile)
|
fake_lsp_logfile)
|
||||||
end;
|
end;
|
||||||
@ -335,8 +335,8 @@ describe('LSP', function()
|
|||||||
client.stop()
|
client.stop()
|
||||||
end;
|
end;
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(0, code, "exit code", fake_lsp_logfile)
|
eq(0, code, "exit code")
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
end;
|
end;
|
||||||
on_handler = function(...)
|
on_handler = function(...)
|
||||||
eq(table.remove(expected_handlers), {...}, "expected handler")
|
eq(table.remove(expected_handlers), {...}, "expected handler")
|
||||||
@ -367,8 +367,8 @@ describe('LSP', function()
|
|||||||
client.notify('finish')
|
client.notify('finish')
|
||||||
end;
|
end;
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(0, code, "exit code", fake_lsp_logfile)
|
eq(0, code, "exit code")
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
end;
|
end;
|
||||||
on_handler = function(err, result, ctx)
|
on_handler = function(err, result, ctx)
|
||||||
eq(table.remove(expected_handlers), {err, result, ctx}, "expected handler")
|
eq(table.remove(expected_handlers), {err, result, ctx}, "expected handler")
|
||||||
@ -436,8 +436,8 @@ describe('LSP', function()
|
|||||||
client = _client
|
client = _client
|
||||||
end;
|
end;
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(0, code, "exit code", fake_lsp_logfile)
|
eq(0, code, "exit code")
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
end;
|
end;
|
||||||
on_handler = function(err, result, ctx)
|
on_handler = function(err, result, ctx)
|
||||||
eq(table.remove(expected_handlers), {err, result, ctx}, "expected handler")
|
eq(table.remove(expected_handlers), {err, result, ctx}, "expected handler")
|
||||||
@ -496,8 +496,8 @@ describe('LSP', function()
|
|||||||
eq(false, client.server_capabilities().codeLensProvider)
|
eq(false, client.server_capabilities().codeLensProvider)
|
||||||
end;
|
end;
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(0, code, "exit code", fake_lsp_logfile)
|
eq(0, code, "exit code")
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
end;
|
end;
|
||||||
on_handler = function(...)
|
on_handler = function(...)
|
||||||
eq(table.remove(expected_handlers), {...}, "expected handler")
|
eq(table.remove(expected_handlers), {...}, "expected handler")
|
||||||
@ -517,8 +517,8 @@ describe('LSP', function()
|
|||||||
client = c
|
client = c
|
||||||
end;
|
end;
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(0, code, "exit code", fake_lsp_logfile)
|
eq(0, code, "exit code")
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
end;
|
end;
|
||||||
on_handler = function(err, result, ctx)
|
on_handler = function(err, result, ctx)
|
||||||
eq(table.remove(expected_handlers), {err, result, ctx}, "expected handler")
|
eq(table.remove(expected_handlers), {err, result, ctx}, "expected handler")
|
||||||
@ -547,8 +547,8 @@ describe('LSP', function()
|
|||||||
client = c
|
client = c
|
||||||
end;
|
end;
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(0, code, "exit code", fake_lsp_logfile)
|
eq(0, code, "exit code")
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
end;
|
end;
|
||||||
on_handler = function(err, result, ctx)
|
on_handler = function(err, result, ctx)
|
||||||
eq(table.remove(expected_handlers), {err, result, ctx}, "expected handler")
|
eq(table.remove(expected_handlers), {err, result, ctx}, "expected handler")
|
||||||
@ -596,8 +596,8 @@ describe('LSP', function()
|
|||||||
eq(true, client.supports_method("unknown-method"))
|
eq(true, client.supports_method("unknown-method"))
|
||||||
end;
|
end;
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(0, code, "exit code", fake_lsp_logfile)
|
eq(0, code, "exit code")
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
end;
|
end;
|
||||||
on_handler = function(...)
|
on_handler = function(...)
|
||||||
eq(table.remove(expected_handlers), {...}, "expected handler")
|
eq(table.remove(expected_handlers), {...}, "expected handler")
|
||||||
@ -626,8 +626,8 @@ describe('LSP', function()
|
|||||||
]]
|
]]
|
||||||
end;
|
end;
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(0, code, "exit code", fake_lsp_logfile)
|
eq(0, code, "exit code")
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
end;
|
end;
|
||||||
on_handler = function(...)
|
on_handler = function(...)
|
||||||
eq(table.remove(expected_handlers), {...}, "expected handler")
|
eq(table.remove(expected_handlers), {...}, "expected handler")
|
||||||
@ -651,8 +651,8 @@ describe('LSP', function()
|
|||||||
exec_lua("vim.lsp.buf.type_definition()")
|
exec_lua("vim.lsp.buf.type_definition()")
|
||||||
end;
|
end;
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(0, code, "exit code", fake_lsp_logfile)
|
eq(0, code, "exit code")
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
end;
|
end;
|
||||||
on_handler = function(...)
|
on_handler = function(...)
|
||||||
eq(table.remove(expected_handlers), {...}, "expected handler")
|
eq(table.remove(expected_handlers), {...}, "expected handler")
|
||||||
@ -672,8 +672,8 @@ describe('LSP', function()
|
|||||||
client = _client
|
client = _client
|
||||||
end;
|
end;
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(0, code, "exit code", fake_lsp_logfile)
|
eq(0, code, "exit code")
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
eq(0, #expected_handlers, "did not call expected handler")
|
eq(0, #expected_handlers, "did not call expected handler")
|
||||||
end;
|
end;
|
||||||
on_handler = function(err, _, ctx)
|
on_handler = function(err, _, ctx)
|
||||||
@ -696,8 +696,8 @@ describe('LSP', function()
|
|||||||
client = _client
|
client = _client
|
||||||
end;
|
end;
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(0, code, "exit code", fake_lsp_logfile)
|
eq(0, code, "exit code")
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
eq(0, #expected_handlers, "did not call expected handler")
|
eq(0, #expected_handlers, "did not call expected handler")
|
||||||
end;
|
end;
|
||||||
on_handler = function(err, _, ctx)
|
on_handler = function(err, _, ctx)
|
||||||
@ -726,8 +726,8 @@ describe('LSP', function()
|
|||||||
client.notify("release")
|
client.notify("release")
|
||||||
end;
|
end;
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(0, code, "exit code", fake_lsp_logfile)
|
eq(0, code, "exit code")
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
eq(0, #expected_handlers, "did not call expected handler")
|
eq(0, #expected_handlers, "did not call expected handler")
|
||||||
end;
|
end;
|
||||||
on_handler = function(err, _, ctx)
|
on_handler = function(err, _, ctx)
|
||||||
@ -759,8 +759,8 @@ describe('LSP', function()
|
|||||||
client.notify("release")
|
client.notify("release")
|
||||||
end;
|
end;
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(0, code, "exit code", fake_lsp_logfile)
|
eq(0, code, "exit code")
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
eq(0, #expected_handlers, "did not call expected handler")
|
eq(0, #expected_handlers, "did not call expected handler")
|
||||||
end;
|
end;
|
||||||
on_handler = function(err, _, ctx)
|
on_handler = function(err, _, ctx)
|
||||||
@ -793,8 +793,8 @@ describe('LSP', function()
|
|||||||
client.notify("release")
|
client.notify("release")
|
||||||
end;
|
end;
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(0, code, "exit code", fake_lsp_logfile)
|
eq(0, code, "exit code")
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
eq(0, #expected_handlers, "did not call expected handler")
|
eq(0, #expected_handlers, "did not call expected handler")
|
||||||
end;
|
end;
|
||||||
on_handler = function(err, _, ctx)
|
on_handler = function(err, _, ctx)
|
||||||
@ -828,8 +828,8 @@ describe('LSP', function()
|
|||||||
client.notify("release")
|
client.notify("release")
|
||||||
end;
|
end;
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(0, code, "exit code", fake_lsp_logfile)
|
eq(0, code, "exit code")
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
eq(0, #expected_handlers, "did not call expected handler")
|
eq(0, #expected_handlers, "did not call expected handler")
|
||||||
eq(3, eval('g:requests'))
|
eq(3, eval('g:requests'))
|
||||||
end;
|
end;
|
||||||
@ -874,8 +874,8 @@ describe('LSP', function()
|
|||||||
client.notify('finish')
|
client.notify('finish')
|
||||||
end;
|
end;
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(0, code, "exit code", fake_lsp_logfile)
|
eq(0, code, "exit code")
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
end;
|
end;
|
||||||
on_handler = function(err, result, ctx)
|
on_handler = function(err, result, ctx)
|
||||||
eq(table.remove(expected_handlers), {err, result, ctx}, "expected handler")
|
eq(table.remove(expected_handlers), {err, result, ctx}, "expected handler")
|
||||||
@ -917,8 +917,8 @@ describe('LSP', function()
|
|||||||
]]
|
]]
|
||||||
end;
|
end;
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(0, code, "exit code", fake_lsp_logfile)
|
eq(0, code, "exit code")
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
end;
|
end;
|
||||||
on_handler = function(err, result, ctx)
|
on_handler = function(err, result, ctx)
|
||||||
if ctx.method == 'start' then
|
if ctx.method == 'start' then
|
||||||
@ -960,8 +960,8 @@ describe('LSP', function()
|
|||||||
]]
|
]]
|
||||||
end;
|
end;
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(0, code, "exit code", fake_lsp_logfile)
|
eq(0, code, "exit code")
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
end;
|
end;
|
||||||
on_handler = function(err, result, ctx)
|
on_handler = function(err, result, ctx)
|
||||||
if ctx.method == 'start' then
|
if ctx.method == 'start' then
|
||||||
@ -1003,8 +1003,8 @@ describe('LSP', function()
|
|||||||
]]
|
]]
|
||||||
end;
|
end;
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(0, code, "exit code", fake_lsp_logfile)
|
eq(0, code, "exit code")
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
end;
|
end;
|
||||||
on_handler = function(err, result, ctx)
|
on_handler = function(err, result, ctx)
|
||||||
if ctx.method == 'start' then
|
if ctx.method == 'start' then
|
||||||
@ -1052,8 +1052,8 @@ describe('LSP', function()
|
|||||||
]]
|
]]
|
||||||
end;
|
end;
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(0, code, "exit code", fake_lsp_logfile)
|
eq(0, code, "exit code")
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
end;
|
end;
|
||||||
on_handler = function(err, result, ctx)
|
on_handler = function(err, result, ctx)
|
||||||
if ctx.method == 'start' then
|
if ctx.method == 'start' then
|
||||||
@ -1103,8 +1103,8 @@ describe('LSP', function()
|
|||||||
]]
|
]]
|
||||||
end;
|
end;
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(0, code, "exit code", fake_lsp_logfile)
|
eq(0, code, "exit code")
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
end;
|
end;
|
||||||
on_handler = function(err, result, ctx)
|
on_handler = function(err, result, ctx)
|
||||||
if ctx.method == 'start' then
|
if ctx.method == 'start' then
|
||||||
@ -1154,8 +1154,8 @@ describe('LSP', function()
|
|||||||
]]
|
]]
|
||||||
end;
|
end;
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(0, code, "exit code", fake_lsp_logfile)
|
eq(0, code, "exit code")
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
end;
|
end;
|
||||||
on_handler = function(err, result, ctx)
|
on_handler = function(err, result, ctx)
|
||||||
if ctx.method == 'start' then
|
if ctx.method == 'start' then
|
||||||
@ -1203,8 +1203,8 @@ describe('LSP', function()
|
|||||||
]]
|
]]
|
||||||
end;
|
end;
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(0, code, "exit code", fake_lsp_logfile)
|
eq(0, code, "exit code")
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
end;
|
end;
|
||||||
on_handler = function(err, result, ctx)
|
on_handler = function(err, result, ctx)
|
||||||
if ctx.method == 'start' then
|
if ctx.method == 'start' then
|
||||||
@ -1247,8 +1247,8 @@ describe('LSP', function()
|
|||||||
]]
|
]]
|
||||||
end;
|
end;
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(0, code, "exit code", fake_lsp_logfile)
|
eq(0, code, "exit code")
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
end;
|
end;
|
||||||
on_handler = function(err, result, ctx)
|
on_handler = function(err, result, ctx)
|
||||||
if ctx.method == 'start' then
|
if ctx.method == 'start' then
|
||||||
@ -1298,8 +1298,8 @@ describe('LSP', function()
|
|||||||
]]
|
]]
|
||||||
end;
|
end;
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(0, code, "exit code", fake_lsp_logfile)
|
eq(0, code, "exit code")
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
end;
|
end;
|
||||||
on_handler = function(err, result,ctx)
|
on_handler = function(err, result,ctx)
|
||||||
if ctx.method == 'start' then
|
if ctx.method == 'start' then
|
||||||
@ -1340,8 +1340,8 @@ describe('LSP', function()
|
|||||||
client.stop(true)
|
client.stop(true)
|
||||||
end;
|
end;
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(0, code, "exit code", fake_lsp_logfile)
|
eq(0, code, "exit code")
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
end;
|
end;
|
||||||
on_handler = function(err, result, ctx)
|
on_handler = function(err, result, ctx)
|
||||||
eq(table.remove(expected_handlers), {err, result, ctx}, "expected handler")
|
eq(table.remove(expected_handlers), {err, result, ctx}, "expected handler")
|
||||||
@ -1379,8 +1379,8 @@ describe('LSP', function()
|
|||||||
]]
|
]]
|
||||||
end;
|
end;
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(0, code, "exit code", fake_lsp_logfile)
|
eq(0, code, "exit code")
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
end;
|
end;
|
||||||
on_handler = function(err, result, ctx)
|
on_handler = function(err, result, ctx)
|
||||||
eq(table.remove(expected_handlers), {err, result, ctx}, "expected handler")
|
eq(table.remove(expected_handlers), {err, result, ctx}, "expected handler")
|
||||||
@ -1725,8 +1725,8 @@ describe('LSP', function()
|
|||||||
end;
|
end;
|
||||||
-- If the program timed out, then code will be nil.
|
-- If the program timed out, then code will be nil.
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(0, code, "exit code", fake_lsp_logfile)
|
eq(0, code, "exit code")
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
end;
|
end;
|
||||||
-- Note that NIL must be used here.
|
-- Note that NIL must be used here.
|
||||||
-- on_handler(err, method, result, client_id)
|
-- on_handler(err, method, result, client_id)
|
||||||
@ -2728,8 +2728,8 @@ describe('LSP', function()
|
|||||||
]=])
|
]=])
|
||||||
end;
|
end;
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(0, code, "exit code", fake_lsp_logfile)
|
eq(0, code, "exit code")
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
end;
|
end;
|
||||||
on_handler = function(err, result, ctx)
|
on_handler = function(err, result, ctx)
|
||||||
-- Don't compare & assert params, they're not relevant for the testcase
|
-- Don't compare & assert params, they're not relevant for the testcase
|
||||||
@ -2768,8 +2768,8 @@ describe('LSP', function()
|
|||||||
on_setup = function()
|
on_setup = function()
|
||||||
end,
|
end,
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(0, code, "exit code", fake_lsp_logfile)
|
eq(0, code, "exit code")
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
end,
|
end,
|
||||||
on_handler = function(err, result, ctx)
|
on_handler = function(err, result, ctx)
|
||||||
eq(table.remove(expected_handlers), {err, result, ctx})
|
eq(table.remove(expected_handlers), {err, result, ctx})
|
||||||
@ -2846,8 +2846,8 @@ describe('LSP', function()
|
|||||||
on_setup = function()
|
on_setup = function()
|
||||||
end,
|
end,
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(0, code, "exit code", fake_lsp_logfile)
|
eq(0, code, "exit code")
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
end,
|
end,
|
||||||
on_handler = function(err, result, ctx)
|
on_handler = function(err, result, ctx)
|
||||||
eq(table.remove(expected_handlers), {err, result, ctx})
|
eq(table.remove(expected_handlers), {err, result, ctx})
|
||||||
@ -2919,8 +2919,8 @@ describe('LSP', function()
|
|||||||
on_setup = function()
|
on_setup = function()
|
||||||
end,
|
end,
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(0, code, "exit code", fake_lsp_logfile)
|
eq(0, code, "exit code")
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
end,
|
end,
|
||||||
on_handler = function(err, result, ctx)
|
on_handler = function(err, result, ctx)
|
||||||
eq(table.remove(expected_handlers), {err, result, ctx})
|
eq(table.remove(expected_handlers), {err, result, ctx})
|
||||||
@ -2985,8 +2985,8 @@ describe('LSP', function()
|
|||||||
]=])
|
]=])
|
||||||
end,
|
end,
|
||||||
on_exit = function(code, signal)
|
on_exit = function(code, signal)
|
||||||
eq(0, code, "exit code", fake_lsp_logfile)
|
eq(0, code, "exit code")
|
||||||
eq(0, signal, "exit signal", fake_lsp_logfile)
|
eq(0, signal, "exit signal")
|
||||||
end,
|
end,
|
||||||
on_handler = function(err, result, ctx)
|
on_handler = function(err, result, ctx)
|
||||||
eq(table.remove(expected_handlers), {err, result, ctx})
|
eq(table.remove(expected_handlers), {err, result, ctx})
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
-- Modules loaded here will not be cleared and reloaded by Busted.
|
-- Modules loaded here will NOT be cleared and reloaded by Busted.
|
||||||
-- Busted started doing this to help provide more isolation. See issue #62
|
-- Busted started doing this to help provide more isolation. See issue #62
|
||||||
-- for more information about this.
|
-- for more information about this.
|
||||||
local helpers = require('test.functional.helpers')(nil)
|
local helpers = require('test.functional.helpers')(nil)
|
||||||
local iswin = helpers.iswin
|
local iswin = helpers.iswin
|
||||||
|
local busted = require("busted")
|
||||||
|
|
||||||
if iswin() then
|
if iswin() then
|
||||||
local ffi = require('ffi')
|
local ffi = require('ffi')
|
||||||
@ -12,3 +13,28 @@ if iswin() then
|
|||||||
]]
|
]]
|
||||||
ffi.C._set_fmode(0x8000)
|
ffi.C._set_fmode(0x8000)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local testid = (function()
|
||||||
|
local id = 0
|
||||||
|
return (function()
|
||||||
|
id = id + 1
|
||||||
|
return id
|
||||||
|
end)
|
||||||
|
end)()
|
||||||
|
|
||||||
|
-- Global before_each. https://github.com/Olivine-Labs/busted/issues/613
|
||||||
|
local function before_each(_element, _parent)
|
||||||
|
local id = ('T%d'):format(testid())
|
||||||
|
_G._nvim_test_id = id
|
||||||
|
return nil, true
|
||||||
|
end
|
||||||
|
busted.subscribe({ 'test', 'start' },
|
||||||
|
before_each,
|
||||||
|
{
|
||||||
|
-- Ensure our --helper is handled before --output (see busted/runner.lua).
|
||||||
|
priority = 1,
|
||||||
|
-- Don't generate a test-id for skipped tests. /shrug
|
||||||
|
predicate = function (element, _, status)
|
||||||
|
return not ((element.descriptor == 'pending' or status == 'pending'))
|
||||||
|
end
|
||||||
|
})
|
||||||
|
@ -6,7 +6,7 @@ if helpers.pending_win32(pending) then return end
|
|||||||
|
|
||||||
describe('api', function()
|
describe('api', function()
|
||||||
local screen
|
local screen
|
||||||
local socket_name = "Xtest_functional_api.sock"
|
local socket_name = "./Xtest_functional_api.sock"
|
||||||
|
|
||||||
before_each(function()
|
before_each(function()
|
||||||
helpers.clear()
|
helpers.clear()
|
||||||
@ -29,7 +29,7 @@ describe('api', function()
|
|||||||
{4:~ }|
|
{4:~ }|
|
||||||
{4:~ }|
|
{4:~ }|
|
||||||
{4:~ }|
|
{4:~ }|
|
||||||
]]..socket_name..[[ |
|
]]..socket_name..[[ |
|
||||||
{3:-- TERMINAL --} |
|
{3:-- TERMINAL --} |
|
||||||
]])
|
]])
|
||||||
|
|
||||||
|
@ -47,33 +47,33 @@ describe(':let', function()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
it("multibyte env var #8398 #9267", function()
|
it("multibyte env var #8398 #9267", function()
|
||||||
command("let $NVIM_TEST = 'AìaB'")
|
command("let $NVIM_TEST_LET = 'AìaB'")
|
||||||
eq('AìaB', eval('$NVIM_TEST'))
|
eq('AìaB', eval('$NVIM_TEST_LET'))
|
||||||
command("let $NVIM_TEST = 'AaあB'")
|
command("let $NVIM_TEST_LET = 'AaあB'")
|
||||||
eq('AaあB', eval('$NVIM_TEST'))
|
eq('AaあB', eval('$NVIM_TEST_LET'))
|
||||||
local mbyte = [[\p* .ม .ม .ม .ม่ .ม่ .ม่ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹֻ ֹֻ ֹֻ
|
local mbyte = [[\p* .ม .ม .ม .ม่ .ม่ .ม่ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹֻ ֹֻ ֹֻ
|
||||||
.ֹֻ .ֹֻ .ֹֻ ֹֻ ֹֻ ֹֻ .ֹֻ .ֹֻ .ֹֻ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹֻ ֹֻ
|
.ֹֻ .ֹֻ .ֹֻ ֹֻ ֹֻ ֹֻ .ֹֻ .ֹֻ .ֹֻ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹֻ ֹֻ
|
||||||
.ֹֻ .ֹֻ .ֹֻ a a a ca ca ca à à à]]
|
.ֹֻ .ֹֻ .ֹֻ a a a ca ca ca à à à]]
|
||||||
command("let $NVIM_TEST = '"..mbyte.."'")
|
command("let $NVIM_TEST_LET = '"..mbyte.."'")
|
||||||
eq(mbyte, eval('$NVIM_TEST'))
|
eq(mbyte, eval('$NVIM_TEST_LET'))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it("multibyte env var to child process #8398 #9267", function()
|
it("multibyte env var to child process #8398 #9267", function()
|
||||||
local cmd_get_child_env = "let g:env_from_child = system(['"..nvim_dir.."/printenv-test', 'NVIM_TEST'])"
|
local cmd_get_child_env = "let g:env_from_child = system(['"..nvim_dir.."/printenv-test', 'NVIM_TEST_LET'])"
|
||||||
command("let $NVIM_TEST = 'AìaB'")
|
command("let $NVIM_TEST_LET = 'AìaB'")
|
||||||
command(cmd_get_child_env)
|
command(cmd_get_child_env)
|
||||||
eq(eval('$NVIM_TEST'), eval('g:env_from_child'))
|
eq(eval('$NVIM_TEST_LET'), eval('g:env_from_child'))
|
||||||
|
|
||||||
command("let $NVIM_TEST = 'AaあB'")
|
command("let $NVIM_TEST_LET = 'AaあB'")
|
||||||
command(cmd_get_child_env)
|
command(cmd_get_child_env)
|
||||||
eq(eval('$NVIM_TEST'), eval('g:env_from_child'))
|
eq(eval('$NVIM_TEST_LET'), eval('g:env_from_child'))
|
||||||
|
|
||||||
local mbyte = [[\p* .ม .ม .ม .ม่ .ม่ .ม่ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹֻ ֹֻ ֹֻ
|
local mbyte = [[\p* .ม .ม .ม .ม่ .ม่ .ม่ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹֻ ֹֻ ֹֻ
|
||||||
.ֹֻ .ֹֻ .ֹֻ ֹֻ ֹֻ ֹֻ .ֹֻ .ֹֻ .ֹֻ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹֻ ֹֻ
|
.ֹֻ .ֹֻ .ֹֻ ֹֻ ֹֻ ֹֻ .ֹֻ .ֹֻ .ֹֻ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹֻ ֹֻ
|
||||||
.ֹֻ .ֹֻ .ֹֻ a a a ca ca ca à à à]]
|
.ֹֻ .ֹֻ .ֹֻ a a a ca ca ca à à à]]
|
||||||
command("let $NVIM_TEST = '"..mbyte.."'")
|
command("let $NVIM_TEST_LET = '"..mbyte.."'")
|
||||||
command(cmd_get_child_env)
|
command(cmd_get_child_env)
|
||||||
eq(eval('$NVIM_TEST'), eval('g:env_from_child'))
|
eq(eval('$NVIM_TEST_LET'), eval('g:env_from_child'))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it("release of list assigned to l: variable does not trigger assertion #12387, #12430", function()
|
it("release of list assigned to l: variable does not trigger assertion #12387, #12430", function()
|
||||||
|
@ -30,7 +30,7 @@ describe('server', function()
|
|||||||
eq('', eval('$NVIM_LISTEN_ADDRESS'))
|
eq('', eval('$NVIM_LISTEN_ADDRESS'))
|
||||||
local servers = funcs.serverlist()
|
local servers = funcs.serverlist()
|
||||||
eq(1, #servers)
|
eq(1, #servers)
|
||||||
ok(string.len(servers[1]) > 4) -- Like /tmp/nvim…/… or \\.\pipe\…
|
ok(string.len(servers[1]) > 4) -- "~/.local/state/nvim…/…" or "\\.\pipe\…"
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('sets v:servername at startup or if all servers were stopped', function()
|
it('sets v:servername at startup or if all servers were stopped', function()
|
||||||
@ -54,7 +54,7 @@ describe('server', function()
|
|||||||
|
|
||||||
-- v:servername and $NVIM take the next available server.
|
-- v:servername and $NVIM take the next available server.
|
||||||
local servername = (iswin() and [[\\.\pipe\Xtest-functional-server-pipe]]
|
local servername = (iswin() and [[\\.\pipe\Xtest-functional-server-pipe]]
|
||||||
or 'Xtest-functional-server-socket')
|
or './Xtest-functional-server-socket')
|
||||||
funcs.serverstart(servername)
|
funcs.serverstart(servername)
|
||||||
eq(servername, meths.get_vvar('servername'))
|
eq(servername, meths.get_vvar('servername'))
|
||||||
-- Not set in the current process, only in children.
|
-- Not set in the current process, only in children.
|
||||||
@ -66,7 +66,7 @@ describe('server', function()
|
|||||||
eq(0, eval("serverstop('bogus-socket-name')"))
|
eq(0, eval("serverstop('bogus-socket-name')"))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('parses endpoints correctly', function()
|
it('parses endpoints', function()
|
||||||
clear_serverlist()
|
clear_serverlist()
|
||||||
eq({}, funcs.serverlist())
|
eq({}, funcs.serverlist())
|
||||||
|
|
||||||
@ -101,6 +101,10 @@ describe('server', function()
|
|||||||
eq(expected, funcs.serverlist())
|
eq(expected, funcs.serverlist())
|
||||||
clear_serverlist()
|
clear_serverlist()
|
||||||
|
|
||||||
|
-- Address without slashes is a "name" which is appended to a generated path. #8519
|
||||||
|
matches([[.*[/\\]xtest1%.2%.3%.4[^/\\]*]], funcs.serverstart('xtest1.2.3.4'))
|
||||||
|
clear_serverlist()
|
||||||
|
|
||||||
eq('Vim:Failed to start server: invalid argument',
|
eq('Vim:Failed to start server: invalid argument',
|
||||||
pcall_err(funcs.serverstart, '127.0.0.1:65536')) -- invalid port
|
pcall_err(funcs.serverstart, '127.0.0.1:65536')) -- invalid port
|
||||||
eq({}, funcs.serverlist())
|
eq({}, funcs.serverlist())
|
||||||
@ -113,7 +117,7 @@ describe('server', function()
|
|||||||
-- Add some servers.
|
-- Add some servers.
|
||||||
local servs = (iswin()
|
local servs = (iswin()
|
||||||
and { [[\\.\pipe\Xtest-pipe0934]], [[\\.\pipe\Xtest-pipe4324]] }
|
and { [[\\.\pipe\Xtest-pipe0934]], [[\\.\pipe\Xtest-pipe4324]] }
|
||||||
or { [[Xtest-pipe0934]], [[Xtest-pipe4324]] })
|
or { [[./Xtest-pipe0934]], [[./Xtest-pipe4324]] })
|
||||||
for _, s in ipairs(servs) do
|
for _, s in ipairs(servs) do
|
||||||
eq(s, eval("serverstart('"..s.."')"))
|
eq(s, eval("serverstart('"..s.."')"))
|
||||||
end
|
end
|
||||||
@ -146,9 +150,13 @@ describe('startup --listen', function()
|
|||||||
|
|
||||||
it('sets v:servername, overrides $NVIM_LISTEN_ADDRESS', function()
|
it('sets v:servername, overrides $NVIM_LISTEN_ADDRESS', function()
|
||||||
local addr = (iswin() and [[\\.\pipe\Xtest-listen-pipe]]
|
local addr = (iswin() and [[\\.\pipe\Xtest-listen-pipe]]
|
||||||
or 'Xtest-listen-pipe')
|
or './Xtest-listen-pipe')
|
||||||
clear({ env={ NVIM_LISTEN_ADDRESS='Xtest-env-pipe' },
|
clear({ env={ NVIM_LISTEN_ADDRESS='./Xtest-env-pipe' },
|
||||||
args={ '--listen', addr } })
|
args={ '--listen', addr } })
|
||||||
eq(addr, meths.get_vvar('servername'))
|
eq(addr, meths.get_vvar('servername'))
|
||||||
|
|
||||||
|
-- Address without slashes is a "name" which is appended to a generated path. #8519
|
||||||
|
clear({ args={ '--listen', 'test-name' } })
|
||||||
|
matches([[.*[/\\]test%-name[^/\\]*]], meths.get_vvar('servername'))
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
@ -40,10 +40,6 @@ function module.popen_r(...)
|
|||||||
return io.popen(module.argss_to_cmd(...), 'r')
|
return io.popen(module.argss_to_cmd(...), 'r')
|
||||||
end
|
end
|
||||||
|
|
||||||
function module.popen_w(...)
|
|
||||||
return io.popen(module.argss_to_cmd(...), 'w')
|
|
||||||
end
|
|
||||||
|
|
||||||
-- sleeps the test runner (_not_ the nvim instance)
|
-- sleeps the test runner (_not_ the nvim instance)
|
||||||
function module.sleep(ms)
|
function module.sleep(ms)
|
||||||
luv.sleep(ms)
|
luv.sleep(ms)
|
||||||
@ -55,42 +51,23 @@ local check_logs_useless_lines = {
|
|||||||
['See README_MISSING_SYSCALL_OR_IOCTL for guidance']=3,
|
['See README_MISSING_SYSCALL_OR_IOCTL for guidance']=3,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Invokes `fn` and includes the tail of `logfile` in the error message if it
|
function module.eq(expected, actual, context)
|
||||||
--- fails.
|
return assert.are.same(expected, actual, context)
|
||||||
---
|
|
||||||
---@param logfile string Log file, defaults to $NVIM_LOG_FILE or '.nvimlog'
|
|
||||||
---@param fn string Function to invoke
|
|
||||||
---@param ... string Function arguments
|
|
||||||
local function dumplog(logfile, fn, ...)
|
|
||||||
-- module.validate({
|
|
||||||
-- logfile={logfile,'s',true},
|
|
||||||
-- fn={fn,'f',false},
|
|
||||||
-- })
|
|
||||||
local status, rv = pcall(fn, ...)
|
|
||||||
if status == false then
|
|
||||||
logfile = logfile or os.getenv('NVIM_LOG_FILE') or '.nvimlog'
|
|
||||||
local logtail = module.read_nvim_log(logfile)
|
|
||||||
error(string.format('%s\n%s', tostring(rv), logtail))
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
function module.eq(expected, actual, context, logfile)
|
function module.neq(expected, actual, context)
|
||||||
return dumplog(logfile, assert.are.same, expected, actual, context)
|
return assert.are_not.same(expected, actual, context)
|
||||||
end
|
end
|
||||||
function module.neq(expected, actual, context, logfile)
|
function module.ok(res, msg)
|
||||||
return dumplog(logfile, assert.are_not.same, expected, actual, context)
|
return assert.is_true(res, msg)
|
||||||
end
|
|
||||||
function module.ok(res, msg, logfile)
|
|
||||||
return dumplog(logfile, assert.is_true, res, msg)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- TODO(bfredl): this should "failure" not "error" (issue with dumplog() )
|
|
||||||
local function epicfail(state, arguments, _)
|
local function epicfail(state, arguments, _)
|
||||||
state.failure_message = arguments[1]
|
state.failure_message = arguments[1]
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
assert:register("assertion", "epicfail", epicfail)
|
assert:register("assertion", "epicfail", epicfail)
|
||||||
function module.fail(msg, logfile)
|
function module.fail(msg)
|
||||||
return dumplog(logfile, assert.epicfail, msg)
|
return assert.epicfail(msg)
|
||||||
end
|
end
|
||||||
|
|
||||||
function module.matches(pat, actual)
|
function module.matches(pat, actual)
|
||||||
@ -104,16 +81,16 @@ end
|
|||||||
---
|
---
|
||||||
---@param pat string Lua pattern to search for in the log file
|
---@param pat string Lua pattern to search for in the log file
|
||||||
---@param logfile string Full path to log file (default=$NVIM_LOG_FILE)
|
---@param logfile string Full path to log file (default=$NVIM_LOG_FILE)
|
||||||
function module.assert_log(pat, logfile)
|
---@param nrlines number Search up to this many log lines
|
||||||
|
function module.assert_log(pat, logfile, nrlines)
|
||||||
logfile = logfile or os.getenv('NVIM_LOG_FILE') or '.nvimlog'
|
logfile = logfile or os.getenv('NVIM_LOG_FILE') or '.nvimlog'
|
||||||
local nrlines = 10
|
nrlines = nrlines or 10
|
||||||
local lines = module.read_file_list(logfile, -nrlines) or {}
|
local lines = module.read_file_list(logfile, -nrlines) or {}
|
||||||
for _,line in ipairs(lines) do
|
for _,line in ipairs(lines) do
|
||||||
if line:match(pat) then return end
|
if line:match(pat) then return end
|
||||||
end
|
end
|
||||||
local logtail = module.read_nvim_log(logfile)
|
|
||||||
error(string.format('Pattern %q not found in log (last %d lines): %s:\n%s',
|
error(string.format('Pattern %q not found in log (last %d lines): %s:\n%s',
|
||||||
pat, nrlines, logfile, logtail))
|
pat, nrlines, logfile, ' '..table.concat(lines, '\n ')))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Invokes `fn` and returns the error string (with truncated paths), or raises
|
-- Invokes `fn` and returns the error string (with truncated paths), or raises
|
||||||
@ -271,7 +248,7 @@ module.uname = (function()
|
|||||||
return platform
|
return platform
|
||||||
end
|
end
|
||||||
|
|
||||||
if os.getenv("SYSTEM_NAME") then -- From CMAKE_SYSTEM_NAME.
|
if os.getenv("SYSTEM_NAME") then -- From CMAKE_HOST_SYSTEM_NAME.
|
||||||
platform = string.lower(os.getenv("SYSTEM_NAME"))
|
platform = string.lower(os.getenv("SYSTEM_NAME"))
|
||||||
return platform
|
return platform
|
||||||
end
|
end
|
||||||
@ -409,17 +386,6 @@ function module.check_cores(app, force)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function module.which(exe)
|
|
||||||
local pipe = module.popen_r('which', exe)
|
|
||||||
local ret = pipe:read('*a')
|
|
||||||
pipe:close()
|
|
||||||
if ret == '' then
|
|
||||||
return nil
|
|
||||||
else
|
|
||||||
return ret:sub(1, -2)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function module.repeated_read_cmd(...)
|
function module.repeated_read_cmd(...)
|
||||||
for _ = 1, 10 do
|
for _ = 1, 10 do
|
||||||
local stream = module.popen_r(...)
|
local stream = module.popen_r(...)
|
||||||
|
Reference in New Issue
Block a user