From ca119f7634ea4ec6565d9c953dce66c6d4ed2848 Mon Sep 17 00:00:00 2001 From: Princeton Ferro Date: Fri, 16 Apr 2021 13:44:53 -0400 Subject: [PATCH] DON'T MERGE: adding tests (#26) Issues covered: - vala-language-server#57 - vala-language-server#106 - vala-language-server#138 - vala-language-server#153 Unit tests: - diagnostics --- .gitignore | 1 + meson.build | 2 +- subprojects/lstf.wrap | 6 + test/meson.build | 8 - test/testclient.vala | 200 ------------------ ...106-autocompletion-in-string-literals.lstf | 25 +++ tests/138-suggest-overridable-symbols.lstf | 35 +++ tests/153-signaturehelp-shared-prefix.lstf | 32 +++ tests/57-suggest-overridable-symbols.lstf | 49 +++++ tests/diagnostics.lstf | 17 ++ tests/meson.build | 24 +++ 11 files changed, 190 insertions(+), 209 deletions(-) create mode 100644 subprojects/lstf.wrap delete mode 100644 test/meson.build delete mode 100644 test/testclient.vala create mode 100644 tests/106-autocompletion-in-string-literals.lstf create mode 100644 tests/138-suggest-overridable-symbols.lstf create mode 100644 tests/153-signaturehelp-shared-prefix.lstf create mode 100644 tests/57-suggest-overridable-symbols.lstf create mode 100644 tests/diagnostics.lstf create mode 100644 tests/meson.build diff --git a/.gitignore b/.gitignore index 7bde8c029..2527fb440 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ build/ *.o +subprojects/lstf diff --git a/meson.build b/meson.build index b45a272f8..5687256b9 100644 --- a/meson.build +++ b/meson.build @@ -80,5 +80,5 @@ subdir('data') subdir('src') if get_option('tests') - subdir('test') + subdir('tests') endif diff --git a/subprojects/lstf.wrap b/subprojects/lstf.wrap new file mode 100644 index 000000000..d218ac8fa --- /dev/null +++ b/subprojects/lstf.wrap @@ -0,0 +1,6 @@ +[wrap-git] +url = https://github.com/Prince781/lstf +revision = head + +[provide] +program_names = lstf diff --git a/test/meson.build b/test/meson.build deleted file mode 100644 index 3b4d15030..000000000 --- a/test/meson.build +++ /dev/null @@ -1,8 +0,0 @@ -testclient_src = files([ - 'testclient.vala', -]) - -executable('vls-testclient', - dependencies: deps, - sources: [testclient_src, extra_vala_sources], - install: false) diff --git a/test/testclient.vala b/test/testclient.vala deleted file mode 100644 index f4ff9f559..000000000 --- a/test/testclient.vala +++ /dev/null @@ -1,200 +0,0 @@ -/* testclient.vala - * - * Copyright 2020 Princeton Ferro - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -using Gee; - -class Vls.TestClient : Jsonrpc.Server { - private static HashSet instances = new HashSet (); - private Jsonrpc.Client? vls_jsonrpc_client; - private Subprocess vls_subprocess; - private SubprocessLauncher launcher; - private IOStream subprocess_stream; - - public string root_path { get; private set; } - - static construct { - Posix.@signal (Posix.Signal.INT, () => { - foreach (var client in instances) - client.shutdown (); - }); - } - - ~TestClient () { - TestClient.instances.remove (this); - } - - public TestClient (string server_location, string root_path, string[] env_vars, bool unset_env) throws Error { - TestClient.instances.add (this); - - Log.set_handler (null, LogLevelFlags.LEVEL_MASK, log_handler); - Log.set_handler ("jsonrpc-server", LogLevelFlags.LEVEL_MASK, log_handler); - - this.root_path = root_path; - this.launcher = new SubprocessLauncher (SubprocessFlags.STDIN_PIPE | SubprocessFlags.STDOUT_PIPE); - - if (unset_env) - launcher.set_environ (new string[]{}); - foreach (string env in env_vars) { - int p = env.index_of_char ('='); - if (p == -1) - throw new IOError.INVALID_ARGUMENT ("`%s' not of the form VAR=STRING", env); - launcher.setenv (env[0:p], env.substring (p+1), true); - } - - vls_subprocess = launcher.spawnv ({server_location}); - - if (pause_for_debugger) { - print ("Attach debugger to PID %s and press enter.\n", vls_subprocess.get_identifier ()); - stdin.read_line (); - } - - var input_stream = vls_subprocess.get_stdout_pipe (); - var output_stream = vls_subprocess.get_stdin_pipe (); - -#if !WINDOWS - if (input_stream is UnixInputStream && output_stream is UnixOutputStream) { - // set nonblocking - if (!Unix.set_fd_nonblocking (((UnixInputStream)input_stream).fd, true) - || !Unix.set_fd_nonblocking (((UnixOutputStream)output_stream).fd, true)) - error ("could not set pipes to nonblocking.\n"); - } -#endif - - this.subprocess_stream = new SimpleIOStream (input_stream, output_stream); - accept_io_stream (subprocess_stream); - } - - private void log_handler (string? log_domain, LogLevelFlags log_levels, string message) { - stderr.printf ("%s: %s\n", log_domain == null ? "vls-testclient" : log_domain, message); - } - - // a{sv} only - public Variant buildDict (...) { - var builder = new VariantBuilder (new VariantType ("a{sv}")); - var l = va_list (); - while (true) { - string? key = l.arg (); - if (key == null) { - break; - } - Variant val = l.arg (); - builder.add ("{sv}", key, val); - } - return builder.end (); - } - - public override void client_accepted (Jsonrpc.Client client) { - if (vls_jsonrpc_client == null) { - vls_jsonrpc_client = client; - try { - initialize_server (); - } catch (Error e) { - try { - printerr ("failed to initialize server: %s", e.message); - client.close (); - } catch (Error e) {} - } - } - } - -#if WITH_JSONRPC_GLIB_3_30 - public override void client_closed (Jsonrpc.Client client) { - if (client == vls_jsonrpc_client) { - vls_jsonrpc_client = null; - } - } -#endif - - private void initialize_server () throws Error { - Variant? return_value; - vls_jsonrpc_client.call ( - "initialize", - buildDict ( - processId: new Variant.int32 ((int32) Posix.getpid ()), - rootPath: new Variant.string (root_path), - rootUri: new Variant.string (File.new_for_path (root_path).get_uri ()) - ), - null, - out return_value - ); - debug ("VLS replied with %s", Json.to_string (Json.gvariant_serialize (return_value), true)); - } - - public void wait_for_server () throws Error { - vls_subprocess.wait (); - } - - public override void notification (Jsonrpc.Client client, string method, Variant @params) { - debug ("VLS sent notification `%s': %s", method, Json.to_string (Json.gvariant_serialize (@params), true)); - } - - public void shutdown () { - try { - subprocess_stream.close (); - debug ("closed subprocess stream"); - } catch (Error e) {} - } -} - -string? server_location; -[CCode (array_length = false, array_null_terminated = true)] -string[]? env_vars; -string? root_path; -bool unset_env; -bool pause_for_debugger = false; -const OptionEntry[] options = { - { "server", 's', 0, OptionArg.FILENAME, ref server_location, "Location of server binary", "FILE" }, - { "root-path", 'r', 0, OptionArg.FILENAME, ref root_path, "Root path to initialize VLS in", "DIRECTORY" }, - { "environ", 'e', 0, OptionArg.STRING_ARRAY, ref env_vars, "List of environment variables", null }, - { "unset-environment", 'u', 0, OptionArg.NONE, ref unset_env, "Don't inherit parent environment", null }, - { "pause", 'p', 0, OptionArg.NONE, ref pause_for_debugger, "Pause before calling VLS to get a chance to attach a debugger", null }, - { null } -}; - -int main (string[] args) { - try { - var opt_context = new OptionContext ("- VLS Test Client"); - opt_context.set_help_enabled (true); - opt_context.add_main_entries (options, null); - opt_context.parse (ref args); - } catch (OptionError e) { - printerr ("error: %s\n", e.message); - printerr ("Run '%s --help'\n", args[0]); - return 1; - } - - if (server_location == null) { - printerr ("server location required\n"); - return 1; - } - - if (root_path == null) { - printerr ("root path required\n"); - return 1; - } - - try { - var client = new Vls.TestClient (server_location, root_path, env_vars, unset_env); - client.wait_for_server (); - } catch (Error e) { - printerr ("error running test client: %s\n", e.message); - return 1; - } - - return 0; -} diff --git a/tests/106-autocompletion-in-string-literals.lstf b/tests/106-autocompletion-in-string-literals.lstf new file mode 100644 index 000000000..1f38d7139 --- /dev/null +++ b/tests/106-autocompletion-in-string-literals.lstf @@ -0,0 +1,25 @@ +// issue: vala-language-server#106 +server_path = option('server-path'); + +let f = file(` +void main() { + print ("this is a string"); +} +`); + +project_files = [ f ]; + + + +await change(f, { + range: { + start: { line: 2, character: 29 }, + end: { line: 2, character: 29 } + }, + text: '.' +}); + +assert { + isIncomplete: false, + items: [] +} <=> await completion(f, 2, 29); diff --git a/tests/138-suggest-overridable-symbols.lstf b/tests/138-suggest-overridable-symbols.lstf new file mode 100644 index 000000000..aa918c2b9 --- /dev/null +++ b/tests/138-suggest-overridable-symbols.lstf @@ -0,0 +1,35 @@ +// issue: vala-language-server#138 +server_path = options('server-path'); + +let f = file(` +interface Iface { + public abstract void must_override(); +} +class Sas : Iface, Object { + +} +`); + +project_files = [ f ]; + + + +await change(f, { + range: { + start: { line: 7, character: 5 }, + end: { line: 7, character: 5 } + }, + text: '\n p' +}); + +assert { + isIncomplete: false, + completions: [ + { + label: 'public void must_override()', + kind: CompletionItemKind.Method, + insertText: 'public void must_override()$0', + insertTextFormat: InsertTextFormat.Snippet + } + ] +} <=> await completion(f, 8, 6); diff --git a/tests/153-signaturehelp-shared-prefix.lstf b/tests/153-signaturehelp-shared-prefix.lstf new file mode 100644 index 000000000..61c6b4c73 --- /dev/null +++ b/tests/153-signaturehelp-shared-prefix.lstf @@ -0,0 +1,32 @@ +// issue: vala-language-server#153 +server_path = option('server-path'); + +let f = file(` +void foo (int arg1, int arg2) { +} +void main() { + foo +} +`); + +project_files = [ f ]; + + + +await change(f, { + range: { + start: { line: 4, character: 7 }, + end: { line: 4, character: 7 } + }, + text: ' (' +}); + +assert { + signatures: [ + { + label: 'void foo(int arg1, int arg2)', + parameters: [ { label: 'int arg1' } ] + } + ], + activeParameter: 0 +} <=> await signatureHelp(f, 4, 9); diff --git a/tests/57-suggest-overridable-symbols.lstf b/tests/57-suggest-overridable-symbols.lstf new file mode 100644 index 000000000..5755546c4 --- /dev/null +++ b/tests/57-suggest-overridable-symbols.lstf @@ -0,0 +1,49 @@ +// issue: vala-language-server#57 +server_path = option('server-path'); + +let f = file(` +interface Iface { + public abstract void must_override1(); + public abstract void must_override2(int arg1); + public abstract void must_override3(int arg1, bool arg2); +} +class Sas : Iface, Object { + +} +`); + +project_files = [ f ]; + + + +await change(f, { + range: { + start: { line: 7, character: 5 }, + end: { line: 7, character: 5 } + }, + text: 'p' +}); + +assert { + isIncomplete: false, + completions: [ + { + label: 'public void must_override1()', + kind: CompletionItemKind.Method, + insertText: 'public void must_override1()$0', + insertTextFormat: InsertTextFormat.Snippet, + }, + { + label: 'public void must_override2(int arg1)', + kind: CompletionItemKind.Method, + insertText: 'public void must_override2(int ${1:arg1})$0', + insertTextFormat: InsertTextFormat.Snippet, + }, + { + label: 'public void must_override3(int arg1, bool arg2)', + kind: CompletionItemKind.Method, + insertText: 'public void must_override3(int ${1:arg1}, bool ${2:arg2})$0', + insertTextFormat: InsertTextFormat.Snippet + } + ] +} <=> await completion(f, 7, 5); diff --git a/tests/diagnostics.lstf b/tests/diagnostics.lstf new file mode 100644 index 000000000..1fe17e4b9 --- /dev/null +++ b/tests/diagnostics.lstf @@ -0,0 +1,17 @@ +server_path = option('server-path'); +let f = file(`void main(string args[]) {}`); +project_files = [ f ]; + +assert { + diagnostics: [ + ..., + { + range: { + start: { line: 3, character: 5 }, + end: { line: 3, character: 16 } + }, + severity: DiagnosticSeverity.Error + }, + ... + ] +} <=> await diagnostics(f); diff --git a/tests/meson.build b/tests/meson.build new file mode 100644 index 000000000..7fd2ae839 --- /dev/null +++ b/tests/meson.build @@ -0,0 +1,24 @@ +lstf = find_program('lstf') + +# unit tests +test('diagnostics', lstf, + workdir: meson.current_source_dir(), + args: ['diagnostics.lstf', '-e', 'server-path', vls]) + +# bugs + +test('57-suggest-overridable-symbols', lstf, + workdir: meson.current_source_dir(), + args: ['57-suggest-overridable-symbols.lstf', '-e', 'server-path', vls]) + +test('106-autocompletion-in-string-literals', lstf, + workdir: meson.current_source_dir(), + args: ['106-autocompletion-in-string-literals.lstf', '-e', 'server-path', vls]) + +test('138-suggest-overridable-symbols', lstf, + workdir: meson.current_source_dir(), + args: ['138-suggest-overridable-symbols.lstf', '-e', 'server-path', vls]) + +test('153-signaturehelp-shared-prefix', lstf, + workdir: meson.current_source_dir(), + args: ['153-signaturehelp-shared-prefix.lstf', '-e', 'server-path', vls])