def _WaitForDiagnosticsForFile( app, filepath, contents, diags_filepath, diags_are_ready = lambda d: True, **kwargs ): diags = None try: for message in PollForMessages( app, { 'filepath': filepath, 'contents': contents, 'filetype': 'java' }, **kwargs ): if ( 'diagnostics' in message and message[ 'filepath' ] == diags_filepath ): print( 'Message {0}'.format( pformat( message ) ) ) diags = message[ 'diagnostics' ] if diags_are_ready( diags ): return diags # Eventually PollForMessages will throw a timeout exception and we'll fail # if we don't see the diagnostics go empty except PollForMessagesTimeoutException as e: raise AssertionError( '{0}. Timed out waiting for diagnostics for file {1}. '.format( e, diags_filepath ) ) return diags
def Diagnostics_Poll_test( app ): filepath = PathToTestFile( 'goto.go' ) contents = ReadFile( filepath ) # 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': 'go' } ): if 'diagnostics' in message: if message[ 'filepath' ] not in DIAG_MATCHERS_PER_FILE: continue seen[ message[ 'filepath' ] ] = True 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 PollForMessagesInAnotherThread( filepath, contents ): try: for message in PollForMessages( app, { 'filepath': filepath, 'contents': contents, 'filetype': 'java' } ): if 'filepath' in message and message[ 'filepath' ] == filepath: messages_for_filepath.append( message ) except PollForMessagesTimeoutException: pass
def FileReadyToParse_Diagnostics_FileNotOnDisk_test( app ): StartJavaCompleterServerInDirectory( app, PathToTestFile( DEFAULT_PROJECT_DIR ) ) contents = ''' package com.test; class Test { public String test } ''' filepath = ProjectPath( 'Test.java' ) event_data = BuildRequest( event_name = 'FileReadyToParse', contents = contents, filepath = filepath, filetype = 'java' ) results = app.post_json( '/event_notification', event_data ).json # This is a new file, so the diagnostics can't possibly be available when the # initial parse request is sent. We receive these asynchronously. eq_( results, {} ) diag_matcher = contains( has_entries( { 'kind': 'ERROR', 'text': 'Syntax error, insert ";" to complete ClassBodyDeclarations', 'location': LocationMatcher( filepath, 4, 21 ), 'location_extent': RangeMatcher( filepath, ( 4, 21 ), ( 4, 25 ) ), 'ranges': contains( RangeMatcher( filepath, ( 4, 21 ), ( 4, 25 ) ) ), 'fixit_available': False } ) ) # Poll until we receive the diags for message in PollForMessages( app, { 'filepath': filepath, 'contents': contents, 'filetype': 'java' } ): if 'diagnostics' in message and message[ 'filepath' ] == filepath: print( 'Message {0}'.format( pformat( message ) ) ) assert_that( message, has_entries( { 'diagnostics': diag_matcher, 'filepath': filepath } ) ) break # Now confirm that we _also_ get these from the FileReadyToParse request for tries in range( 0, 60 ): results = app.post_json( '/event_notification', event_data ).json if results: break time.sleep( 0.5 ) print( 'completer response: {0}'.format( pformat( results ) ) ) assert_that( results, diag_matcher )
def test_Diagnostics_Poll(self, app): project_dir = PathToTestFile('common') filepath = os.path.join(project_dir, 'src', 'main.rs') contents = ReadFile(filepath) with open(filepath, 'w') as f: f.write(contents) event_data = BuildRequest(event_name='FileSave', contents=contents, filepath=filepath, filetype='rust') app.post_json('/event_notification', event_data) # 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(f'Message { 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 ' f'{ message[ "filepath" ] }. Only expected { 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. ' f'Expected to see diags for { json.dumps( to_see, indent = 2 ) }, ' f'but only saw { json.dumps( sorted( seen.keys() ), indent = 2 ) }.' )
def Poll_Diagnostics_ProjectWide_Eclipse_test(app): StartJavaCompleterServerInDirectory(app, PathToTestFile(DEFAULT_PROJECT_DIR)) filepath = TestLauncher contents = ReadFile(filepath) # 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': 'java' }): print('Message {0}'.format(pformat(message))) if 'diagnostics' in message: seen[message['filepath']] = True if message['filepath'] not in DIAG_MATCHERS_PER_FILE: raise AssertionError( 'Received diagnostics for unexpected file {0}. ' 'Only expected {1}'.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 else: print('Seen diagnostics for {0}, still waiting for {1}'.format( json.dumps(sorted(seen.keys()), indent=2), json.dumps([x for x in to_see if x not in seen], indent=2))) # 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 {0}, but only saw {1}.'.format( json.dumps(to_see, indent=2), json.dumps(sorted(seen.keys()), indent=2)))
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 Diagnostics_UpdatedOnBufferVisit_test(app): with TemporaryTestDir() as tmp_dir: source_file = os.path.join(tmp_dir, 'source.cpp') source_contents = """#include "header.h" int main() {return S::h();} """ with open(source_file, 'w') as sf: sf.write(source_contents) header_file = os.path.join(tmp_dir, 'header.h') old_header_content = """#pragma once struct S{static int h();}; """ with open(header_file, 'w') as hf: hf.write(old_header_content) flags_file = os.path.join(tmp_dir, 'compile_flags.txt') flags_content = """-xc++""" with open(flags_file, 'w') as ff: ff.write(flags_content) messages_request = { 'contents': source_contents, 'filepath': source_file, 'filetype': 'cpp' } test = {'request': messages_request, 'route': '/receive_messages'} response = RunAfterInitialized(app, test) assert_that(response, contains_exactly(has_entries({'diagnostics': empty()}))) # Overwrite header.cpp new_header_content = """#pragma once static int h(); """ with open(header_file, 'w') as f: f.write(new_header_content) # Send BufferSaved notification for the header file_save_request = { "event_name": "FileSave", "filepath": header_file, "filetype": 'cpp' } app.post_json('/event_notification', BuildRequest(**file_save_request)) # Send BufferVisit notification buffer_visit_request = { "event_name": "BufferVisit", "filepath": source_file, "filetype": 'cpp' } app.post_json('/event_notification', BuildRequest(**buffer_visit_request)) # Assert diagnostics for message in PollForMessages(app, messages_request): if 'diagnostics' in message: assert_that( message, has_entries({ 'diagnostics': contains_exactly( has_entries({ 'kind': equal_to('ERROR'), 'text': "Use of undeclared identifier 'S' [undeclared_var_use]", 'ranges': contains_exactly( RangeMatcher(contains_string(source_file), (2, 20), (2, 21))), 'location': LocationMatcher(contains_string(source_file), 2, 20), 'location_extent': RangeMatcher(contains_string(source_file), (2, 20), (2, 21)) })) })) break # Restore original content with open(header_file, 'w') as f: f.write(old_header_content) # Send BufferSaved notification for the header file_save_request = { "event_name": "FileSave", "filepath": header_file, "filetype": 'cpp' } app.post_json('/event_notification', BuildRequest(**file_save_request)) # Send BufferVisit notification app.post_json('/event_notification', BuildRequest(**buffer_visit_request)) # Assert no diagnostics for message in PollForMessages(app, messages_request): print(f'Message { pformat( message ) }') if 'diagnostics' in message: assert_that(message, has_entries({'diagnostics': empty()})) break # Assert no dirty files with open(header_file, 'r') as f: assert_that(f.read(), equal_to(old_header_content))
def FileReadyToParse_ChangeFileContents_test( app ): filepath = TestFactory contents = ReadFile( filepath ) StartJavaCompleterServerInDirectory( app, ProjectPath() ) # It can take a while for the diagnostics to be ready for tries in range( 0, 60 ): event_data = BuildRequest( event_name = 'FileReadyToParse', contents = contents, filepath = filepath, filetype = 'java' ) results = app.post_json( '/event_notification', event_data ).json if results: break time.sleep( 0.5 ) # To make the test fair, we make sure there are some results prior to the # 'server not running' call assert results # Call the FileReadyToParse handler but pretend that the server isn't running contents = 'package com.test; class TestFactory {}' # It can take a while for the diagnostics to be ready event_data = BuildRequest( event_name = 'FileReadyToParse', contents = contents, filepath = filepath, filetype = 'java' ) app.post_json( '/event_notification', event_data ) diags = None try: for message in PollForMessages( app, { 'filepath': filepath, 'contents': contents, 'filetype': 'java' } ): print( 'Message {0}'.format( pformat( message ) ) ) if 'diagnostics' in message and message[ 'filepath' ] == filepath: diags = message[ 'diagnostics' ] if not diags: break # Eventually PollForMessages will throw a timeout exception and we'll fail # if we don't see the diagnostics go empty except PollForMessagesTimeoutException as e: raise AssertionError( '{0}. Timed out waiting for diagnostics to clear for updated file. ' 'Expected to see none, but diags were: {1}'.format( e, diags ) ) assert_that( diags, empty() ) # Close the file (ensuring no exception) event_data = BuildRequest( event_name = 'BufferUnload', contents = contents, filepath = filepath, filetype = 'java' ) result = app.post_json( '/event_notification', event_data ).json assert_that( result, equal_to( {} ) ) # Close the file again, someone erroneously (ensuring no exception) event_data = BuildRequest( event_name = 'BufferUnload', contents = contents, filepath = filepath, filetype = 'java' ) result = app.post_json( '/event_notification', event_data ).json assert_that( result, equal_to( {} ) )