コード例 #1
0
ファイル: conftest.py プロジェクト: CorinnaBuerger/dotfiles
def StartJavaCompleterServerWithFile( app, file_path ):
  app.post_json( '/event_notification',
                 BuildRequest(
                   event_name = 'FileReadyToParse',
                   filepath = file_path,
                   filetype = 'java' ) )
  WaitUntilCompleterServerReady( app, 'java', SERVER_STARTUP_TIMEOUT )
コード例 #2
0
ファイル: server_management_test.py プロジェクト: tungpd/ycmd
    def ServerManagement_WipeWorkspace_WithConfig( app ):
      StartJavaCompleterServerInDirectory(
        app, PathToTestFile( 'simple_eclipse_project', 'src' ) )

      project = PathToTestFile( 'simple_eclipse_project' )
      filepath = PathToTestFile( 'simple_eclipse_project',
                                 'src',
                                 'com',
                                 'youcompleteme',
                                 'Test.java' )

      app.post_json(
        '/run_completer_command',
        BuildRequest(
          filepath = filepath,
          filetype = 'java',
          command_arguments = [ 'WipeWorkspace', '--with-config' ],
        ),
      )

      WaitUntilCompleterServerReady( app, 'java' )

      assert_that(
        app.post_json( '/debug_info',
                       BuildRequest( filetype = 'java',
                                     filepath = filepath ) ).json,
        CompleterProjectDirectoryMatcher( project ) )
コード例 #3
0
ファイル: generic_completer_test.py プロジェクト: tungpd/ycmd
def GenericLSPCompleter_SignatureHelp_NotASigHelpProvider_test(app, *args):
    test_file = PathToTestFile('generic_server', 'foo', 'bar', 'baz',
                               'test_file')
    request = BuildRequest(filepath=test_file,
                           filetype='foo',
                           line_num=1,
                           column_num=1,
                           contents='',
                           event_name='FileReadyToParse')
    app.post_json('/event_notification', request)
    WaitUntilCompleterServerReady(app, 'foo')
    request.pop('event_name')
    response = app.post_json('/signature_help', request).json
    assert_that(
        response,
        has_entries({
            'signature_help':
            has_entries({
                'activeSignature': 0,
                'activeParameter': 0,
                'signatures': empty()
            }),
            'errors':
            empty()
        }))
コード例 #4
0
def setUpModule():
    global shared_app
    with patch('ycmd.completers.javascript.hook.'
               'ShouldEnableTernCompleter',
               return_value=False):
        shared_app = SetUpApp()
        WaitUntilCompleterServerReady(shared_app, 'javascriptreact')
コード例 #5
0
def DebugInfo_HandleNotificationInPollThread_Throw_test(app):
    filepath = PathToTestFile(DEFAULT_PROJECT_DIR, 'src', 'com',
                              'youcompleteme', 'Test.java')
    StartJavaCompleterServerInDirectory(app, filepath)

    # This mock will be called in the message pump thread, so syncronize the
    # result (thrown) using an Event
    thrown = threading.Event()

    def ThrowOnLogMessage(msg):
        thrown.set()
        raise RuntimeError("ThrowOnLogMessage")

    with patch.object(lsc.LanguageServerCompleter,
                      'HandleNotificationInPollThread',
                      side_effect=ThrowOnLogMessage):
        app.post_json(
            '/run_completer_command',
            BuildRequest(
                filepath=filepath,
                filetype='java',
                command_arguments=['RestartServer'],
            ),
        )

        # Ensure that we still process and handle messages even though a
        # message-pump-thread-handler raised an error.
        WaitUntilCompleterServerReady(app, 'java')

    # Prove that the exception was thrown.
    assert_that(thrown.is_set(), equal_to(True))
コード例 #6
0
def ServerManagement_RestartServer_test( app ):
  StartClangd( app, PathToTestFile( 'basic.cpp' ) )

  assert_that(
    GetDebugInfo( app ),
    CompleterProjectDirectoryMatcher( PathToTestFile() ) )

  app.post_json(
    '/run_completer_command',
    BuildRequest(
      filepath = PathToTestFile( 'test-include', 'main.cpp' ),
      filetype = 'cpp',
      command_arguments = [ 'RestartServer' ],
    ),
  )

  WaitUntilCompleterServerReady( app, 'cpp' )

  assert_that(
    GetDebugInfo( app ),
    has_entry( 'completer', has_entries( {
      'name': 'C-family',
      'servers': contains( has_entries( {
        'name': 'Clangd',
        'is_running': True,
        'extras': has_item( has_entries( {
          'key': 'Project Directory',
          'value': PathToTestFile( 'test-include' ),
        } ) )
      } ) )
    } ) )
  )
コード例 #7
0
ファイル: subcommands_test.py プロジェクト: tungpd/ycmd
def Subcommands_StopServer_Timeout_test( app ):
  filepath = PathToTestFile( 'testy', 'GotoTestCase.cs' )
  contents = ReadFile( filepath )
  event_data = BuildRequest( filepath = filepath,
                             filetype = 'cs',
                             contents = contents,
                             event_name = 'FileReadyToParse' )

  app.post_json( '/event_notification', event_data )
  WaitUntilCompleterServerReady( app, 'cs' )

  app.post_json(
    '/run_completer_command',
    BuildRequest(
      filetype = 'cs',
      filepath = filepath,
      command_arguments = [ 'StopServer' ]
    )
  )

  request_data = BuildRequest( filetype = 'cs', filepath = filepath )
  assert_that( app.post_json( '/debug_info', request_data ).json,
               has_entry(
                 'completer',
                 has_entry( 'servers', contains(
                   has_entry( 'is_running', False )
                 ) )
               ) )
コード例 #8
0
ファイル: subcommands_test.py プロジェクト: rootmass/dotfiles
def StopServer_KeepLogFiles(app, keeping_log_files):
    with UserOption('server_keep_logfiles', keeping_log_files):
        filepath = PathToTestFile('testy', 'GotoTestCase.cs')
        contents = ReadFile(filepath)
        event_data = BuildRequest(filepath=filepath,
                                  filetype='cs',
                                  contents=contents,
                                  event_name='FileReadyToParse')

        app.post_json('/event_notification', event_data)
        WaitUntilCompleterServerReady(app, 'cs')

        event_data = BuildRequest(filetype='cs', filepath=filepath)

        response = app.post_json('/debug_info', event_data).json

        logfiles = []
        for server in response['completer']['servers']:
            logfiles.extend(server['logfiles'])

        try:
            for logfile in logfiles:
                ok_(os.path.exists(logfile),
                    'Logfile should exist at {0}'.format(logfile))
        finally:
            StopCompleterServer(app, 'cs', filepath)

        if keeping_log_files:
            for logfile in logfiles:
                ok_(os.path.exists(logfile),
                    'Logfile should still exist at {0}'.format(logfile))
        else:
            for logfile in logfiles:
                ok_(not os.path.exists(logfile),
                    'Logfile should no longer exist at {0}'.format(logfile))
コード例 #9
0
ファイル: __init__.py プロジェクト: zouhejing0000/ycmd
def StartJavaCompleterServerInDirectory( app, directory ):
  app.post_json( '/event_notification',
                 BuildRequest(
                   filepath = os.path.join( directory, 'test.java' ),
                   event_name = 'FileReadyToParse',
                   filetype = 'java' ) )
  WaitUntilCompleterServerReady( shared_app, 'java', SERVER_STARTUP_TIMEOUT )
コード例 #10
0
ファイル: generic_completer_test.py プロジェクト: tungpd/ycmd
def GenericLSPCompleter_Diagnostics_test(app):
    request = BuildRequest(filepath=TEST_FILE,
                           filetype='foo',
                           line_num=1,
                           column_num=1,
                           contents=TEST_FILE_CONTENT,
                           event_name='FileReadyToParse')

    app.post_json('/event_notification', request)
    WaitUntilCompleterServerReady(app, 'foo')
    request.pop('event_name')
    response = app.post_json('/receive_messages', request)
    assert_that(
        response.json,
        has_items(
            has_entries({
                'diagnostics':
                has_items(
                    has_entries({
                        'kind':
                        equal_to('WARNING'),
                        'location':
                        LocationMatcher(TEST_FILE, 2, 1),
                        'location_extent':
                        RangeMatcher(TEST_FILE, (2, 1), (2, 4)),
                        'text':
                        equal_to('FOO is all uppercase.'),
                        'fixit_available':
                        False
                    }))
            })))
コード例 #11
0
def RunTest(app, test):
    """
  Method to run a simple completion test and verify the result

  Note: Compile commands are extracted from a compile_flags.txt file by clangd
  by iteratively looking at the directory containing the source file and its
  ancestors.

  test is a dictionary containing:
    'request': kwargs for BuildRequest
    'expect': {
       'response': server response code (e.g. requests.codes.ok)
       'data': matcher for the server response json
    }
  """

    request = test['request']
    filetype = request.get('filetype', 'cpp')
    if 'contents' not in request:
        contents = ReadFile(request['filepath'])
        request['contents'] = contents
        request['filetype'] = filetype

    # Because we aren't testing this command, we *always* ignore errors. This
    # is mainly because we (may) want to test scenarios where the completer
    # throws an exception and the easiest way to do that is to throw from
    # within the Settings function.
    app.post_json('/event_notification',
                  CombineRequest(request, {
                      'event_name': 'FileReadyToParse',
                      'filetype': filetype
                  }),
                  expect_errors=True)
    WaitUntilCompleterServerReady(app, filetype)

    for i in range(10):
        try:
            # We also ignore errors here, but then we check the response code ourself.
            # This is to allow testing of requests returning errors.
            response = app.post_json('/completions',
                                     BuildRequest(**request),
                                     expect_errors=True)

            assert_that(response.status_code,
                        equal_to(test['expect']['response']))

            print('Completer response: {}'.format(
                json.dumps(response.json, indent=2)))

            assert_that(response.json, test['expect']['data'])
            break
        except Exception:
            if i == 9:
                raise
            else:
                completer = handlers._server_state.GetFiletypeCompleter(
                    ['cpp'])
                completer._completions_cache.Invalidate()
                sleep(0.1)
                pass
コード例 #12
0
def GetCompletions_ChangeStartColumn_test(app):
    WaitUntilCompleterServerReady(app, 'javascript')
    RunTest(
        app, {
            'description': 'the completion_start_column is updated by tern',
            'request': {
                'filetype': 'javascript',
                'filepath': PathToTestFile('node', 'node_test.js'),
                'line_num': 1,
                'column_num': 17,
                'force_semantic': True,
            },
            'expect': {
                'response':
                requests.codes.ok,
                'data':
                has_entries({
                    'completions':
                    contains(CompletionEntryMatcher('"path"', 'path')),
                    'completion_start_column':
                    14,
                    'errors':
                    empty(),
                })
            },
        })
コード例 #13
0
ファイル: conftest.py プロジェクト: CorinnaBuerger/dotfiles
def StartJavaScriptCompleterServerInDirectory(app, directory):
    app.post_json(
        '/event_notification',
        BuildRequest(filepath=os.path.join(directory, 'test.js'),
                     event_name='FileReadyToParse',
                     filetype='javascript'))
    WaitUntilCompleterServerReady(app, 'javascript')
コード例 #14
0
ファイル: subcommands_test.py プロジェクト: dragon7-fc/vimrc
def Subcommands_FixIt_AlreadyResolved_test( app ):
  filename = PathToTestFile( 'FixIt_Clang_cpp11.cpp' )
  request = {
    'completer_target' : 'filetype_default',
    'contents'         : ReadFile( filename ),
    'filepath'         : filename,
    'command_arguments': [ 'FixIt' ],
    'line_num'         : 16,
    'column_num'       : 1,
    'filetype'         : 'cpp'
  }
  app.post_json( '/event_notification',
                 CombineRequest( request, {
                   'event_name': 'FileReadyToParse',
                 } ),
                 expect_errors = True )
  WaitUntilCompleterServerReady( app, 'cpp' )
  expected = app.post_json( '/run_completer_command',
                            BuildRequest( **request ) ).json
  print( 'expected = ' )
  print( expected )
  request[ 'fixit' ] = expected[ 'fixits' ][ 0 ]
  actual = app.post_json( '/resolve_fixit',
                          BuildRequest( **request ) ).json
  print( 'actual = ' )
  print( actual )
  assert_that( actual, equal_to( expected ) )
コード例 #15
0
def Subcommands_Format_ExtraConf_BraceOnNewLine_test( app ):
  WaitUntilCompleterServerReady( app, 'typescript' )
  filepath = PathToTestFile( 'extra_confs', 'func.ts' )
  RunTest( app, {
    'description': 'Format with an extra conf, braces on new line',
    'request': {
      'command': 'Format',
      'filepath': filepath,
      'options': {
        'tab_size': 4,
        'insert_spaces': True
      }
    },
    'expect': {
      'response': requests.codes.ok,
      'data': has_entries( {
        'fixits': contains_exactly( has_entries( {
          'chunks': contains_exactly(
            ChunkMatcher( matches_regexp( '\n?\n' ),
                          LocationMatcher( filepath,  1, 19 ),
                          LocationMatcher( filepath,  1, 20 ) ),
            ChunkMatcher( '    ',
                          LocationMatcher( filepath,  2,  1 ),
                          LocationMatcher( filepath,  2,  1 ) ),
          )
        } ) )
      } )
    }
  } )
コード例 #16
0
def WaitUntilCsCompleterIsReady( app, filepath, wait_for_diags = True ):
  WaitUntilCompleterServerReady( app, 'cs' )
  # Omnisharp isn't ready when it says it is, so wait until Omnisharp returns
  # at least one diagnostic multiple times.
  if not wait_for_diags:
    # Wait a fixed amount of time, because there's no reliable way to
    # know Roslyn is actually ready.
    time.sleep( 15 )
    return
  success_count = 0
  for reraise_error in [ False ] * 39 + [ True ]:
    try:
      if len( GetDiagnostics( app, filepath ) ) == 0:
        raise RuntimeError( "No diagnostic" )
      success_count += 1
      if success_count > 2:
        break
    except Exception:
      success_count = 0
      if reraise_error:
        raise

    time.sleep( .5 )
  else:
    raise RuntimeError( "Never was ready" )
コード例 #17
0
def DebugInfo_ServerIsRunning_test( app ):
  filepath = PathToTestFile( 'testy', 'Program.cs' )
  contents = ReadFile( filepath )
  event_data = BuildRequest( filepath = filepath,
                             filetype = 'cs',
                             contents = contents,
                             event_name = 'FileReadyToParse' )

  app.post_json( '/event_notification', event_data )
  WaitUntilCompleterServerReady( app, 'cs' )

  request_data = BuildRequest( filepath = filepath,
                               filetype = 'cs' )
  assert_that(
    app.post_json( '/debug_info', request_data ).json,
    has_entry( 'completer', has_entries( {
      'name': 'C#',
      'servers': contains_exactly( has_entries( {
        'name': 'OmniSharp',
        'is_running': True,
        'executable': instance_of( str ),
        'pid': instance_of( int ),
        'address': instance_of( str ),
        'port': instance_of( int ),
        'logfiles': contains_exactly( instance_of( str ),
                              instance_of( str ) ),
        'extras': contains_exactly( has_entries( {
          'key': 'solution',
          'value': instance_of( str )
        } ) )
      } ) ),
      'items': empty()
    } ) )
  )
コード例 #18
0
ファイル: conftest.py プロジェクト: katosun2/YouCompleteMe
def StartRustCompleterServerInDirectory(app, directory):
    app.post_json(
        '/event_notification',
        BuildRequest(filepath=os.path.join(directory, 'main.rs'),
                     event_name='FileReadyToParse',
                     filetype='rust'))
    WaitUntilCompleterServerReady(app, 'rust')
コード例 #19
0
    def test_GenericLSPCompleter_DebugInfo_CustomRoot(self, app, *args):
        test_file = PathToTestFile('generic_server', 'foo', 'bar', 'baz',
                                   'test_file')
        request = BuildRequest(filepath=test_file,
                               filetype='foo',
                               line_num=1,
                               column_num=1,
                               contents='',
                               event_name='FileReadyToParse')

        app.post_json('/event_notification', request)
        WaitUntilCompleterServerReady(app, 'foo')
        request.pop('event_name')
        response = app.post_json('/debug_info', request).json
        assert_that(
            response,
            has_entry(
                'completer',
                has_entries({
                    'name':
                    'GenericLSP',
                    'servers':
                    contains_exactly(
                        has_entries({
                            'name':
                            'fooCompleter',
                            'is_running':
                            instance_of(bool),
                            'executable':
                            contains_exactly(instance_of(str),
                                             instance_of(str),
                                             instance_of(str)),
                            'address':
                            None,
                            'port':
                            None,
                            'pid':
                            instance_of(int),
                            'logfiles':
                            contains_exactly(instance_of(str)),
                            'extras':
                            contains_exactly(
                                has_entries({
                                    'key': 'Server State',
                                    'value': instance_of(str),
                                }),
                                has_entries({
                                    'key':
                                    'Project Directory',
                                    'value':
                                    PathToTestFile('generic_server', 'foo'),
                                }),
                                has_entries({
                                    'key': 'Settings',
                                    'value': '{}'
                                }),
                            )
                        })),
                })))
コード例 #20
0
ファイル: __init__.py プロジェクト: HusterYP/VimConf
def WrapOmniSharpServer(app, filepath):
    global shared_filepaths

    if filepath not in shared_filepaths:
        StartCompleterServer(app, 'cs', filepath)
        shared_filepaths.append(filepath)
    WaitUntilCompleterServerReady(app, 'cs')
    yield
コード例 #21
0
ファイル: subcommands_test.py プロジェクト: toxeus/ycmd
def Subcommands_Format_Range_Tabs_test(app):
    WaitUntilCompleterServerReady(app, 'typescript')
    filepath = PathToTestFile('test.ts')
    RunTest(
        app, {
            'description': 'Formatting is applied on some part of the file '
            'with tabs instead of spaces',
            'request': {
                'command': 'Format',
                'filepath': filepath,
                'range': {
                    'start': {
                        'line_num': 6,
                        'column_num': 3,
                    },
                    'end': {
                        'line_num': 11,
                        'column_num': 6
                    }
                },
                'options': {
                    'tab_size': 4,
                    'insert_spaces': False
                }
            },
            'expect': {
                'response':
                requests.codes.ok,
                'data':
                has_entries({
                    'fixits':
                    contains_exactly(
                        has_entries({
                            'chunks':
                            contains_exactly(
                                ChunkMatcher('\t',
                                             LocationMatcher(filepath, 6, 1),
                                             LocationMatcher(filepath, 6, 3)),
                                ChunkMatcher('\t\t',
                                             LocationMatcher(filepath, 7, 1),
                                             LocationMatcher(filepath, 7, 5)),
                                ChunkMatcher('\t\t\t',
                                             LocationMatcher(filepath, 8, 1),
                                             LocationMatcher(filepath, 8, 7)),
                                ChunkMatcher('\t\t\t',
                                             LocationMatcher(filepath, 9, 1),
                                             LocationMatcher(filepath, 9, 7)),
                                ChunkMatcher('\t\t',
                                             LocationMatcher(filepath, 10, 1),
                                             LocationMatcher(filepath, 10, 5)),
                                ChunkMatcher('\t',
                                             LocationMatcher(filepath, 11, 1),
                                             LocationMatcher(filepath, 11, 3)),
                            )
                        }))
                })
            }
        })
コード例 #22
0
ファイル: __init__.py プロジェクト: rootmass/dotfiles
def setUpPackage():
    """Initializes the ycmd server as a WebTest application that will be shared
  by all tests using the SharedYcmd decorator in this package. Additional
  configuration that is common to these tests, like starting a semantic
  subserver, should be done here."""
    global shared_app

    shared_app = SetUpApp()
    WaitUntilCompleterServerReady(shared_app, 'rust')
コード例 #23
0
ファイル: subcommands_test.py プロジェクト: tungpd/ycmd
def Subcommands_RestartServer_PidChanges_test( app ):
  filepath = PathToTestFile( 'testy', 'GotoTestCase.cs' )
  contents = ReadFile( filepath )
  event_data = BuildRequest( filepath = filepath,
                             filetype = 'cs',
                             contents = contents,
                             event_name = 'FileReadyToParse' )

  app.post_json( '/event_notification', event_data )

  try:
    WaitUntilCompleterServerReady( app, 'cs' )

    def GetPid():
      request_data = BuildRequest( filetype = 'cs', filepath = filepath )
      debug_info = app.post_json( '/debug_info', request_data ).json
      return debug_info[ "completer" ][ "servers" ][ 0 ][ "pid" ]

    old_pid = GetPid()

    app.post_json(
      '/run_completer_command',
      BuildRequest(
        filetype = 'cs',
        filepath = filepath,
        command_arguments = [ 'RestartServer' ]
      )
    )
    WaitUntilCompleterServerReady( app, 'cs' )

    new_pid = GetPid()

    assert old_pid != new_pid, '%r == %r' % ( old_pid, new_pid )
  finally:
    app.post_json(
      '/run_completer_command',
      BuildRequest(
        filetype = 'cs',
        filepath = filepath,
        command_arguments = [ 'StopServer' ]
      )
    )
コード例 #24
0
def setUpPackage():
    """Initializes the ycmd server as a WebTest application that will be shared
  by all tests using the SharedYcmd decorator in this package. Additional
  configuration that is common to these tests, like starting a semantic
  subserver, should be done here."""
    global shared_app, shared_current_dir

    shared_app = SetUpApp()
    shared_current_dir = GetCurrentDirectory()
    os.chdir(PathToTestFile())
    WaitUntilCompleterServerReady(shared_app, 'javascript')
コード例 #25
0
def setUpPackage():
  """Initializes the ycmd server as a WebTest application that will be shared
  by all tests using the SharedYcmd decorator in this package. Additional
  configuration that is common to these tests, like starting a semantic
  subserver, should be done here."""
  global shared_app

  with patch( 'ycmd.completers.javascript.hook.'
              'ShouldEnableTernCompleter', return_value = False ):
    shared_app = SetUpApp()
    WaitUntilCompleterServerReady( shared_app, 'javascript' )
コード例 #26
0
def Signature_Help_Available_test(app):
    request = {'filepath': PathToTestFile('common', 'src', 'main.rs')}
    app.post_json('/event_notification',
                  CombineRequest(request, {
                      'event_name': 'FileReadyToParse',
                      'filetype': 'rust'
                  }),
                  expect_errors=True)
    WaitUntilCompleterServerReady(app, 'rust')

    response = app.get('/signature_help_available', {'subserver': 'rust'}).json
    assert_that(response, SignatureAvailableMatcher('YES'))
コード例 #27
0
def Signature_Help_Available_Disabled_By_User_test(app, *args):
    request = {'filepath': PathToTestFile('goto.cc')}
    app.post_json('/event_notification',
                  CombineRequest(request, {
                      'event_name': 'FileReadyToParse',
                      'filetype': 'cpp'
                  }),
                  expect_errors=True)
    WaitUntilCompleterServerReady(app, 'cpp')

    response = app.get('/signature_help_available', {'subserver': 'cpp'}).json
    assert_that(response, SignatureAvailableMatcher('NO'))
コード例 #28
0
def EventNotification_OnFileReadyToParse_ProjectFile_cwd_test(app):
    WaitUntilCompleterServerReady(app, 'javascript')

    contents = ReadFile(PathToTestFile('simple_test.js'))

    response = app.post_json('/event_notification',
                             BuildRequest(event_name='FileReadyToParse',
                                          contents=contents,
                                          filetype='javascript'),
                             expect_errors=True)

    eq_(response.status_code, requests.codes.ok)
    assert_that(response.json, empty())
コード例 #29
0
def Subcommands_StopServer_Timeout_test(app):
    WaitUntilCompleterServerReady(app, 'typescript')

    app.post_json(
        '/run_completer_command',
        BuildRequest(filetype='typescript', command_arguments=['StopServer']))

    request_data = BuildRequest(filetype='typescript')
    assert_that(
        app.post_json('/debug_info', request_data).json,
        has_entry(
            'completer',
            has_entry('servers', contains(has_entry('is_running', False)))))
コード例 #30
0
ファイル: __init__.py プロジェクト: ctomiao2/vim
def RunAfterInitialized(app, test):
    """Performs initialization of clangd server for the file contents specified in
  the |test| and optionally can run a test and check for its response.
  Since LSP servers do not start until initialization we need to send a
  FileReadyToParse request prior to any other request we will make.

  |test| consists of two parts a 'request' to be made and an optional 'expect'
  to perform a check on server's response.
  Request part must contain either a 'content' or 'filepath' element which
  either contains or points to the source code that will be sent to the server.
  In addition to that, if |test| also contain a 'route' element, then a
  follow-up request will be made to the server, with the same file contents and
  response of that request will be returned.
  Expect part, if specified, must contain two elements named 'response' and
  'data' which are used to check status code and data of the result received
  from server before returning them to the caller.

  Example usage:
    filepath = PathToTestFile( 'foo.cc' )
    request = { 'filepath': filepath,
                'filetype': 'cpp' }

    test = { 'request': request }
    RunAfterInitialized( app, test )
    ...
  """
    request = test['request']
    contents = (request['contents']
                if 'contents' in request else ReadFile(request['filepath']))
    response = app.post_json('/event_notification',
                             CombineRequest(
                                 request, {
                                     'event_name': 'FileReadyToParse',
                                     'contents': contents,
                                 }),
                             expect_errors=True)
    WaitUntilCompleterServerReady(app, 'cpp')

    if 'route' in test:
        expect_errors = 'expect' in test
        response = app.post_json(test['route'],
                                 CombineRequest(request,
                                                {'contents': contents}),
                                 expect_errors=expect_errors)

    if 'expect' in test:
        print("Completer response: {}".format(
            json.dumps(response.json, indent=2)))
        eq_(response.status_code, test['expect']['response'])
        assert_that(response.json, test['expect']['data'])
    return response.json