def DebugInfo_NoRlsVersion_test(app, *args): StartRustCompleterServerInDirectory(app, PathToTestFile('common', 'src')) request_data = BuildRequest(filetype='rust') assert_that( app.post_json('/debug_info', request_data).json, has_entry( 'completer', has_entries({ 'name': 'Rust', 'servers': contains( has_entries({ 'name': 'Rust Language Server', 'is_running': instance_of(bool), 'executable': instance_of(str), 'pid': instance_of(int), 'address': none(), 'port': none(), 'logfiles': contains(instance_of(str)), 'extras': contains( has_entries({ 'key': 'Server State', 'value': instance_of(str) }), has_entries({ 'key': 'Project Directory', 'value': instance_of(str) }), has_entries({ 'key': 'Settings', 'value': '{}' }), has_entries({ 'key': 'Project State', 'value': instance_of(str) }), has_entries({ 'key': 'Version', 'value': none() })) })) })))
def Subcommands_Format_Range_test(app): # RLS can't execute textDocument/formatting if any file # under the project root has errors, so we need to use # a different project just for formatting. # For further details check https://github.com/rust-lang/rls/issues/1397 project_dir = PathToTestFile('formatting') StartRustCompleterServerInDirectory(app, project_dir) filepath = os.path.join(project_dir, 'src', 'main.rs') RunTest( app, { 'description': 'Formatting is applied on some part of the file', 'request': { 'command': 'Format', 'filepath': filepath, 'range': { 'start': { 'line_num': 1, 'column_num': 1, }, 'end': { 'line_num': 2, 'column_num': 18 } }, 'options': { 'tab_size': 4, 'insert_spaces': False } }, 'expect': { 'response': requests.codes.ok, 'data': has_entries({ 'fixits': contains( has_entries({ 'chunks': contains( ChunkMatcher( 'fn unformatted_function(param: bool) -> bool {\n' '\treturn param;\n' '}\n', LocationMatcher(filepath, 1, 1), LocationMatcher(filepath, 3, 1)), ) })) }) } })
def ServerManagement_CloseServer_Unclean_test(wait_until, app): StartRustCompleterServerInDirectory(app, PathToTestFile('common', 'src')) app.post_json( '/run_completer_command', BuildRequest(filetype='rust', command_arguments=['StopServer'])) request_data = BuildRequest(filetype='rust') assert_that( app.post_json('/debug_info', request_data).json, has_entry( 'completer', has_entry('servers', contains_exactly(has_entry('is_running', False)))))
def Diagnostics_Poll_test(app): project_dir = PathToTestFile('common') filepath = os.path.join(project_dir, 'src', 'main.rs') contents = ReadFile(filepath) StartRustCompleterServerInDirectory(app, project_dir) # Poll until we receive _all_ the diags asynchronously. to_see = sorted(DIAG_MATCHERS_PER_FILE.keys()) seen = {} try: for message in PollForMessages(app, { 'filepath': filepath, 'contents': contents, 'filetype': 'rust' }): print('Message {}'.format(pformat(message))) if 'diagnostics' in message: if message['diagnostics'] == []: # Sometimes we get empty diagnostics before the real ones. continue seen[message['filepath']] = True if message['filepath'] not in DIAG_MATCHERS_PER_FILE: raise AssertionError( 'Received diagnostics for unexpected file {}. ' 'Only expected {}'.format(message['filepath'], to_see)) assert_that( message, has_entries({ 'diagnostics': DIAG_MATCHERS_PER_FILE[message['filepath']], 'filepath': message['filepath'] })) if sorted(seen.keys()) == to_see: break # Eventually PollForMessages will throw a timeout exception and we'll fail # if we don't see all of the expected diags. except PollForMessagesTimeoutException as e: raise AssertionError( str(e) + 'Timed out waiting for full set of diagnostics. ' 'Expected to see diags for {}, but only saw {}.'.format( json.dumps(to_see, indent=2), json.dumps(sorted(seen.keys()), indent=2)))
def Subcommands_Format_Range_test(app): project_dir = PathToTestFile('common') StartRustCompleterServerInDirectory(app, project_dir) filepath = os.path.join(project_dir, 'src', 'main.rs') RunTest( app, { 'description': 'Formatting is applied on some part of the file', 'request': { 'command': 'Format', 'filepath': filepath, 'range': { 'start': { 'line_num': 17, 'column_num': 1, }, 'end': { 'line_num': 22, 'column_num': 2 } }, 'options': { 'tab_size': 4, 'insert_spaces': False } }, 'expect': { 'response': requests.codes.ok, 'data': has_entries({ 'fixits': contains( has_entries({ 'chunks': contains( ChunkMatcher( 'fn format_test() {\n' '\tlet a: i32 = 5;\n', LocationMatcher(filepath, 17, 1), LocationMatcher(filepath, 22, 1)), ) })) }) } })
def ServerManagement_RestartServer_test(app): filepath = PathToTestFile('common', 'src', 'main.rs') StartRustCompleterServerInDirectory(app, filepath) AssertRustCompleterServerIsRunning(app, True) app.post_json( '/run_completer_command', BuildRequest( filepath=filepath, filetype='rust', command_arguments=['RestartServer'], ), ) WaitUntilCompleterServerReady(app, 'rust') AssertRustCompleterServerIsRunning(app, True)
def Subcommands_Format_WholeFile_test(app): project_dir = PathToTestFile('common') StartRustCompleterServerInDirectory(app, project_dir) filepath = os.path.join(project_dir, 'src', 'main.rs') RunTest( app, { 'description': 'Formatting is applied on the whole file', 'request': { 'command': 'Format', 'filepath': filepath, 'options': { 'tab_size': 2, 'insert_spaces': True } }, 'expect': { 'response': requests.codes.ok, 'data': has_entries({ 'fixits': contains( has_entries({ 'chunks': contains( ChunkMatcher( ' create_universe();\n' ' let builder = Builder {};\n' ' builder.build_\n', LocationMatcher(filepath, 12, 1), LocationMatcher(filepath, 15, 1)), ChunkMatcher( 'fn format_test() {\n' ' let a: i32 = 5;\n', LocationMatcher(filepath, 17, 1), LocationMatcher(filepath, 22, 1)), ) })) }) } })
def Subcommands_FixIt_EmptyResponse_test( app ): project_dir = PathToTestFile( 'formatting' ) StartRustCompleterServerInDirectory( app, project_dir ) filepath = os.path.join( project_dir, 'src', 'main.rs' ) RunTest( app, { 'description': 'FixIt on a line with no codeAction returns empty response', 'request': { 'command': 'FixIt', 'line_num': 1, 'column_num': 1, 'filepath': filepath }, 'expect': { 'response': requests.codes.ok, 'data': has_entry( 'fixits', empty() ) } } )
def ServerManagement_StopServerTwice_test(app): StartRustCompleterServerInDirectory(app, PathToTestFile('common', 'src')) app.post_json( '/run_completer_command', BuildRequest( filetype='rust', command_arguments=['StopServer'], ), ) AssertRustCompleterServerIsRunning(app, False) # Stopping a stopped server is a no-op app.post_json( '/run_completer_command', BuildRequest( filetype='rust', command_arguments=['StopServer'], ), ) AssertRustCompleterServerIsRunning(app, False)
def GetCompletions_ProcMacro_test(app): StartRustCompleterServerInDirectory(app, PathToTestFile('macro')) filepath = PathToTestFile('macro', 'src', 'main.rs') contents = ReadFile(filepath) completion_data = BuildRequest(filepath=filepath, filetype='rust', contents=contents, line_num=33, column_num=14) results = [] expiration = time.time() + 60 while time.time() < expiration: results = app.post_json('/completions', completion_data).json['completions'] if len(results) > 0: break time.sleep(0.25) assert_that(results, has_item(CompletionEntryMatcher('checkpoint'))) # This completer does not require or support resolve assert_that(results[0], is_not(has_key('resolve'))) assert_that(results[0], is_not(has_key('item'))) # So (erroneously) resolving an item returns the item completion_data['resolve'] = 0 response = app.post_json('/resolve_completion', completion_data).json print(f"Resolve resolve: { pformat( response ) }") # We can't actually check the result because we don't know what completion # resolve ID 0 actually is (could be anything), so we just check that we get 1 # result, and that there are no errors. assert_that(response['completion'], is_not(None)) assert_that(response['errors'], empty())
def Subcommands_FixIt_ApplySuggestion_test(app): # Similarly to textDocument/formatting, if a file has errors # RLS won't respond with `rls.applySuggestions` command. project_dir = PathToTestFile('formatting') StartRustCompleterServerInDirectory(app, project_dir) filepath = os.path.join(project_dir, 'src', 'main.rs') RunTest( app, { 'description': 'Simple FixIt test', 'request': { 'command': 'FixIt', 'line_num': 8, 'column_num': 13, 'filepath': filepath }, 'expect': { 'response': requests.codes.ok, 'data': has_entries({ 'fixits': contains_exactly( has_entries({ 'chunks': contains_exactly( ChunkMatcher('_x', LocationMatcher(filepath, 8, 13), LocationMatcher(filepath, 8, 14))) })) }) }, 'run_resolve_fixit_test': True })