def Diagnostics_Multiline_test( app ):
  contents = """
struct Foo {
  Foo(int z) {}
};

int main() {
  Foo foo("goo");
}
"""

  diag_data = BuildRequest( compilation_flags = [ '-x', 'c++' ],
                            line_num = 7,
                            contents = contents,
                            filetype = 'cpp' )

  event_data = diag_data.copy()
  event_data.update( {
    'event_name': 'FileReadyToParse',
  } )

  app.post_json( '/event_notification', event_data )
  results = app.post_json( '/detailed_diagnostic', diag_data ).json
  assert_that( results,
               has_entry( 'message', contains_string( "\n" ) ) )
def _ShouldUseNowForLine( filename_completer,
                          contents,
                          extra_data = None,
                          column_num = None ):

  # Strictly, column numbers are *byte* offsets, not character offsets. If
  # the contents of the file contain unicode characters, then we should manually
  # supply the correct byte offset.
  column_num = len( contents ) + 1 if not column_num else column_num

  request = BuildRequest( column_num = column_num,
                          filepath = PATH_TO_TEST_FILE,
                          contents = contents )
  if extra_data:
    request.update( extra_data )

  request_data = RequestWrap( request )
  return filename_completer.ShouldUseNow( request_data )
Exemple #3
0
def Diagnostics_Works_test(app):
    contents = """
struct Foo {
  int x  // semicolon missing here!
  int y;
  int c;
  int d;
};
"""

    diag_data = BuildRequest(compilation_flags=["-x", "c++"], line_num=3, contents=contents, filetype="cpp")

    event_data = diag_data.copy()
    event_data.update({"event_name": "FileReadyToParse"})

    app.post_json("/event_notification", event_data)
    results = app.post_json("/detailed_diagnostic", diag_data).json
    assert_that(results, has_entry("message", contains_string("expected ';'")))
Exemple #4
0
def Diagnostics_Multiline_test(app):
    contents = """
struct Foo {
  Foo(int z) {}
};

int main() {
  Foo foo("goo");
}
"""

    diag_data = BuildRequest(compilation_flags=["-x", "c++"], line_num=7, contents=contents, filetype="cpp")

    event_data = diag_data.copy()
    event_data.update({"event_name": "FileReadyToParse"})

    app.post_json("/event_notification", event_data)
    results = app.post_json("/detailed_diagnostic", diag_data).json
    assert_that(results, has_entry("message", contains_string("\n")))
def _CompletionResultsForLine( filename_completer,
                               contents,
                               extra_data = None,
                               column_num = None ):

  # Strictly, column numbers are *byte* offsets, not character offsets. If
  # the contents of the file contain unicode characters, then we should manually
  # supply the correct byte offset.
  column_num = len( contents ) + 1 if not column_num else column_num

  request = BuildRequest( column_num = column_num,
                          filepath = PATH_TO_TEST_FILE,
                          contents = contents )
  if extra_data:
    request.update( extra_data )

  request_data = RequestWrap( request )
  candidates = filename_completer.ComputeCandidatesInner( request_data )
  return [ ( c[ 'insertion_text' ], c[ 'extra_menu_info' ] )
          for c in candidates ]
def Diagnostics_Works_test( app ):
  contents = """
struct Foo {
  int x  // semicolon missing here!
  int y;
  int c;
  int d;
};
"""

  diag_data = BuildRequest( compilation_flags = ['-x', 'c++'],
                            line_num = 3,
                            contents = contents,
                            filetype = 'cpp' )

  event_data = diag_data.copy()
  event_data.update( {
    'event_name': 'FileReadyToParse',
  } )

  app.post_json( '/event_notification', event_data )
  results = app.post_json( '/detailed_diagnostic', diag_data ).json
  assert_that( results,
               has_entry( 'message', contains_string( "expected ';'" ) ) )
Exemple #7
0
def GetDebugInfo( app, filepath ):
  """ TODO: refactor here and in clangd test to common util """
  request_data = BuildRequest( filetype = 'cs', filepath = filepath )
  return app.post_json( '/debug_info', request_data ).json
def Poll_Diagnostics_ChangeFileContents_test(app):
    StartJavaCompleterServerInDirectory(app,
                                        PathToTestFile(DEFAULT_PROJECT_DIR))

    filepath = youcompleteme_Test
    old_contents = """package com.youcompleteme;

public class Test {
  public String test;
}"""

    messages_for_filepath = []

    with PollingThread(app, messages_for_filepath, filepath, old_contents):

        new_contents = """package com.youcompleteme;

public class Test {
  public String test;
  public String test;
}"""

        event_data = BuildRequest(event_name='FileReadyToParse',
                                  contents=new_contents,
                                  filepath=filepath,
                                  filetype='java')
        app.post_json('/event_notification', event_data).json

        expiration = time.time() + 10
        while True:
            try:
                assert_that(
                    messages_for_filepath,
                    has_item(
                        has_entries({
                            'filepath':
                            filepath,
                            'diagnostics':
                            contains_exactly(
                                has_entries({
                                    'kind':
                                    'ERROR',
                                    'text':
                                    'Duplicate field Test.test [33554772]',
                                    'location':
                                    LocationMatcher(youcompleteme_Test, 4, 17),
                                    'location_extent':
                                    RangeMatcher(youcompleteme_Test, (4, 17),
                                                 (4, 21)),
                                    'ranges':
                                    contains_exactly(
                                        RangeMatcher(youcompleteme_Test,
                                                     (4, 17), (4, 21))),
                                    'fixit_available':
                                    False
                                }),
                                has_entries({
                                    'kind':
                                    'ERROR',
                                    'text':
                                    'Duplicate field Test.test [33554772]',
                                    'location':
                                    LocationMatcher(youcompleteme_Test, 5, 17),
                                    'location_extent':
                                    RangeMatcher(youcompleteme_Test, (5, 17),
                                                 (5, 21)),
                                    'ranges':
                                    contains_exactly(
                                        RangeMatcher(youcompleteme_Test,
                                                     (5, 17), (5, 21))),
                                    'fixit_available':
                                    False
                                }))
                        })))
                break
            except AssertionError:
                if time.time() > expiration:
                    raise

                time.sleep(0.25)
Exemple #9
0
def EventNotification_OnBufferUnload_CloseFile_test(app):
    # Open main.ts file in a buffer.
    main_filepath = PathToTestFile('buffer_unload', 'main.ts')
    main_contents = ReadFile(main_filepath)

    event_data = BuildRequest(filepath=main_filepath,
                              filetype='typescript',
                              contents=main_contents,
                              event_name='BufferVisit')
    app.post_json('/event_notification', event_data)

    # Complete in main.ts buffer an object defined in imported.ts.
    completion_data = BuildRequest(filepath=main_filepath,
                                   filetype='typescript',
                                   contents=main_contents,
                                   line_num=3,
                                   column_num=10)
    response = app.post_json('/completions', completion_data)
    assert_that(
        response.json,
        has_entries(
            {'completions': contains(CompletionEntryMatcher('method'))}))

    # Open imported.ts file in another buffer.
    imported_filepath = PathToTestFile('buffer_unload', 'imported.ts')
    imported_contents = ReadFile(imported_filepath)

    event_data = BuildRequest(filepath=imported_filepath,
                              filetype='typescript',
                              contents=imported_contents,
                              event_name='BufferVisit')
    app.post_json('/event_notification', event_data)

    # Modify imported.ts buffer without writing the changes to disk.
    modified_imported_contents = imported_contents.replace(
        'method', 'modified_method')

    # FIXME: TypeScript completer should not rely on the FileReadyToParse events
    # to synchronize the contents of dirty buffers but use instead the file_data
    # field of the request.
    event_data = BuildRequest(filepath=imported_filepath,
                              filetype='typescript',
                              contents=modified_imported_contents,
                              event_name='FileReadyToParse')
    app.post_json('/event_notification', event_data)

    # Complete at same location in main.ts buffer.
    imported_data = {
        imported_filepath: {
            'filetypes': ['typescript'],
            'contents': modified_imported_contents
        }
    }
    completion_data = BuildRequest(filepath=main_filepath,
                                   filetype='typescript',
                                   contents=main_contents,
                                   line_num=3,
                                   column_num=10,
                                   file_data=imported_data)
    response = app.post_json('/completions', completion_data)
    assert_that(
        response.json,
        has_entries({
            'completions':
            contains(CompletionEntryMatcher('modified_method'))
        }))

    # Unload imported.ts buffer.
    event_data = BuildRequest(filepath=imported_filepath,
                              filetype='typescript',
                              contents=imported_contents,
                              event_name='BufferUnload')
    app.post_json('/event_notification', event_data)

    # Complete at same location in main.ts buffer.
    completion_data = BuildRequest(filepath=main_filepath,
                                   filetype='typescript',
                                   contents=main_contents,
                                   line_num=3,
                                   column_num=10)
    response = app.post_json('/completions', completion_data)
    assert_that(
        response.json,
        has_entries(
            {'completions': contains(CompletionEntryMatcher('method'))}))
Exemple #10
0
def Subcommands_RefactorRename_MultipleFiles_OnFileReadyToParse_test(app):
    StartJavaScriptCompleterServerInDirectory(app, PathToTestFile())

    file1 = PathToTestFile('file1.js')
    file2 = PathToTestFile('file2.js')
    file3 = PathToTestFile('file3.js')

    # This test is roughly the same as the previous one, except here file4.js is
    # pushed into the Tern engine via 'opening it in the editor' (i.e.
    # FileReadyToParse event). The first 3 are loaded into the tern server
    # because they are listed in the .tern-project file's loadEagerly option.
    file4 = PathToTestFile('file4.js')

    app.post_json('/event_notification',
                  BuildRequest(
                      **{
                          'filetype': 'javascript',
                          'event_name': 'FileReadyToParse',
                          'contents': ReadFile(file4),
                          'filepath': file4,
                      }),
                  expect_errors=False)

    RunTest(
        app, {
            'description': 'FileReadyToParse loads files into tern server',
            'request': {
                'command': 'RefactorRename',
                'arguments': ['a-quite-long-string'],
                'filepath': file1,
                'line_num': 3,
                'column_num': 14,
            },
            'expect': {
                'response':
                requests.codes.ok,
                'data':
                has_entries({
                    'fixits':
                    contains(
                        has_entries({
                            'chunks':
                            contains(
                                ChunkMatcher('a-quite-long-string',
                                             LocationMatcher(file1, 1, 5),
                                             LocationMatcher(file1, 1, 11)),
                                ChunkMatcher('a-quite-long-string',
                                             LocationMatcher(file1, 3, 14),
                                             LocationMatcher(file1, 3, 20)),
                                ChunkMatcher('a-quite-long-string',
                                             LocationMatcher(file2, 2, 14),
                                             LocationMatcher(file2, 2, 20)),
                                ChunkMatcher('a-quite-long-string',
                                             LocationMatcher(file3, 3, 12),
                                             LocationMatcher(file3, 3, 18)),
                                ChunkMatcher('a-quite-long-string',
                                             LocationMatcher(file4, 4, 22),
                                             LocationMatcher(file4, 4, 28))),
                            'location':
                            LocationMatcher(file1, 3, 14)
                        }))
                })
            }
        })
Exemple #11
0
 def CombineRequest(request, data):
     kw = request
     request.update(data)
     return BuildRequest(**kw)
Exemple #12
0
def WorkspaceEditToFixIt_test():
    if utils.OnWindows():
        filepath = 'C:\\test.test'
        uri = 'file:///c:/test.test'
    else:
        filepath = '/test.test'
        uri = 'file:/test.test'

    contents = 'line1\nline2\nline3'

    request_data = RequestWrap(
        BuildRequest(filetype='ycmtest', filepath=filepath, contents=contents))

    # Null response to textDocument/codeActions is valid
    assert_that(lsc.WorkspaceEditToFixIt(request_data, None), equal_to(None))
    # Empty WorkspaceEdit is not explicitly forbidden
    assert_that(lsc.WorkspaceEditToFixIt(request_data, {}), equal_to(None))
    # We don't support versioned documentChanges
    workspace_edit = {
        'documentChanges': [{
            'textDocument': {
                'version': 1,
                'uri': uri
            },
            'edits': [{
                'newText': 'blah',
                'range': {
                    'start': {
                        'line': 0,
                        'character': 5
                    },
                    'end': {
                        'line': 0,
                        'character': 5
                    },
                }
            }]
        }]
    }
    response = responses.BuildFixItResponse(
        [lsc.WorkspaceEditToFixIt(request_data, workspace_edit, 'test')])

    print('Response: {0}'.format(response))
    assert_that(
        response,
        has_entries({
            'fixits':
            contains(
                has_entries({
                    'text':
                    'test',
                    'chunks':
                    contains(
                        ChunkMatcher('blah', LocationMatcher(filepath, 1, 6),
                                     LocationMatcher(filepath, 1, 6)))
                }))
        }))

    workspace_edit = {
        'changes': {
            uri: [
                {
                    'newText': 'blah',
                    'range': {
                        'start': {
                            'line': 0,
                            'character': 5
                        },
                        'end': {
                            'line': 0,
                            'character': 5
                        },
                    }
                },
            ]
        }
    }

    response = responses.BuildFixItResponse(
        [lsc.WorkspaceEditToFixIt(request_data, workspace_edit, 'test')])

    print('Response: {0}'.format(response))
    print('Type Response: {0}'.format(type(response)))

    assert_that(
        response,
        has_entries({
            'fixits':
            contains(
                has_entries({
                    'text':
                    'test',
                    'chunks':
                    contains(
                        ChunkMatcher('blah', LocationMatcher(filepath, 1, 6),
                                     LocationMatcher(filepath, 1, 6)))
                }))
        }))
Exemple #13
0
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 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 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))
Exemple #14
0
def LanguageServerCompleter_Diagnostics_NoLimitToNumberOfDiagnostics_test():
    completer = MockCompleter({'max_diagnostics_to_display': 0})
    filepath = os.path.realpath('/foo')
    uri = lsp.FilePathToUri(filepath)
    request_data = RequestWrap(
        BuildRequest(line_num=1, column_num=1, filepath=filepath, contents=''))
    notification = {
        'jsonrpc': '2.0',
        'method': 'textDocument/publishDiagnostics',
        'params': {
            'uri':
            uri,
            'diagnostics': [{
                'range': {
                    'start': {
                        'line': 3,
                        'character': 10
                    },
                    'end': {
                        'line': 3,
                        'character': 11
                    }
                },
                'severity': 1,
                'message': 'First error'
            }, {
                'range': {
                    'start': {
                        'line': 4,
                        'character': 7
                    },
                    'end': {
                        'line': 4,
                        'character': 13
                    }
                },
                'severity': 1,
                'message': 'Second error'
            }]
        }
    }
    completer.GetConnection()._notifications.put(notification)
    completer.HandleNotificationInPollThread(notification)

    with patch.object(completer, '_ServerIsInitialized', return_value=True):
        completer.OnFileReadyToParse(request_data)
        # Simulate receipt of response and initialization complete
        initialize_response = {'result': {'capabilities': {}}}
        completer._HandleInitializeInPollThread(initialize_response)

        diagnostics = contains(
            has_entries({
                'kind':
                equal_to('ERROR'),
                'location':
                LocationMatcher(filepath, 4, 11),
                'location_extent':
                RangeMatcher(filepath, (4, 11), (4, 12)),
                'ranges':
                contains(RangeMatcher(filepath, (4, 11), (4, 12))),
                'text':
                equal_to('First error'),
                'fixit_available':
                False
            }),
            has_entries({
                'kind':
                equal_to('ERROR'),
                'location':
                LocationMatcher(filepath, 5, 8),
                'location_extent':
                RangeMatcher(filepath, (5, 8), (5, 14)),
                'ranges':
                contains(RangeMatcher(filepath, (5, 8), (5, 14))),
                'text':
                equal_to('Second error'),
                'fixit_available':
                False
            }))

        assert_that(completer.OnFileReadyToParse(request_data), diagnostics)

        assert_that(
            completer.PollForMessages(request_data),
            contains(
                has_entries({
                    'diagnostics': diagnostics,
                    'filepath': filepath
                })))
Exemple #15
0
def LanguageServerCompleter_GoTo_test():
    if utils.OnWindows():
        filepath = 'C:\\test.test'
        uri = 'file:///c:/test.test'
    else:
        filepath = '/test.test'
        uri = 'file:/test.test'

    contents = 'line1\nline2\nline3'

    completer = MockCompleter()
    # LSP server supports all code navigation features.
    completer._server_capabilities = {
        'definitionProvider': True,
        'declarationProvider': True,
        'typeDefinitionProvider': True,
        'implementationProvider': True,
        'referencesProvider': True
    }
    request_data = RequestWrap(
        BuildRequest(filetype='ycmtest',
                     filepath=filepath,
                     contents=contents,
                     line_num=2,
                     column_num=3))

    @patch.object(completer, '_ServerIsInitialized', return_value=True)
    def Test(responses, command, exception, throws, *args):
        with patch.object(completer.GetConnection(),
                          'GetResponse',
                          side_effect=responses):
            if throws:
                assert_that(
                    calling(completer.OnUserCommand).with_args([command],
                                                               request_data),
                    raises(exception))
            else:
                result = completer.OnUserCommand([command], request_data)
                print('Result: {}'.format(result))
                assert_that(result, exception)

    location = {
        'uri': uri,
        'range': {
            'start': {
                'line': 0,
                'character': 0
            },
            'end': {
                'line': 0,
                'character': 0
            },
        }
    }

    goto_response = has_entries({
        'filepath': filepath,
        'column_num': 1,
        'line_num': 1,
        'description': 'line1'
    })

    cases = [
        ([{
            'result': None
        }], 'GoToDefinition', RuntimeError, True),
        ([{
            'result': location
        }], 'GoToDeclaration', goto_response, False),
        ([{
            'result': {}
        }], 'GoToType', RuntimeError, True),
        ([{
            'result': []
        }], 'GoToImplementation', RuntimeError, True),
        ([{
            'result': [location]
        }], 'GoToReferences', goto_response, False),
        ([{
            'result': [location, location]
        }], 'GoToReferences', contains(goto_response, goto_response), False),
    ]

    for response, goto_handlers, exception, throws in cases:
        yield Test, response, goto_handlers, exception, throws

    # All requests return an invalid URI.
    with patch(
            'ycmd.completers.language_server.language_server_protocol.UriToFilePath',
            side_effect=lsp.InvalidUriException):
        yield Test, [{
            'result': {
                'uri': uri,
                'range': {
                    'start': {
                        'line': 0,
                        'character': 0
                    },
                    'end': {
                        'line': 0,
                        'character': 0
                    },
                }
            }
        }], 'GoTo', LocationMatcher('', 1, 1), False

    with patch('ycmd.completers.completer_utils.GetFileContents',
               side_effect=IOError):
        yield Test, [{
            'result': {
                'uri': uri,
                'range': {
                    'start': {
                        'line': 0,
                        'character': 0
                    },
                    'end': {
                        'line': 0,
                        'character': 0
                    },
                }
            }
        }], 'GoToDefinition', LocationMatcher(filepath, 1, 1), False

    # Both requests return the location where the cursor is.
    yield Test, [{
        'result': {
            'uri': uri,
            'range': {
                'start': {
                    'line': 1,
                    'character': 0
                },
                'end': {
                    'line': 1,
                    'character': 4
                },
            }
        }
    }, {
        'result': {
            'uri': uri,
            'range': {
                'start': {
                    'line': 1,
                    'character': 0
                },
                'end': {
                    'line': 1,
                    'character': 4
                },
            }
        }
    }], 'GoTo', LocationMatcher(filepath, 2, 1), False

    # First request returns two locations.
    yield Test, [{
        'result': [{
            'uri': uri,
            'range': {
                'start': {
                    'line': 0,
                    'character': 0
                },
                'end': {
                    'line': 0,
                    'character': 4
                },
            }
        }, {
            'uri': uri,
            'range': {
                'start': {
                    'line': 1,
                    'character': 0
                },
                'end': {
                    'line': 1,
                    'character': 4
                },
            }
        }],
    }], 'GoTo', contains(LocationMatcher(filepath, 1, 1),
                         LocationMatcher(filepath, 2, 1)), False

    # First request returns the location where the cursor is and second request
    # returns a different URI.
    if utils.OnWindows():
        other_filepath = 'C:\\another.test'
        other_uri = 'file:///c:/another.test'
    else:
        other_filepath = '/another.test'
        other_uri = 'file:/another.test'

    yield Test, [{
        'result': {
            'uri': uri,
            'range': {
                'start': {
                    'line': 1,
                    'character': 0
                },
                'end': {
                    'line': 1,
                    'character': 4
                },
            }
        }
    }, {
        'result': {
            'uri': other_uri,
            'range': {
                'start': {
                    'line': 1,
                    'character': 0
                },
                'end': {
                    'line': 1,
                    'character': 4
                },
            }
        }
    }], 'GoTo', LocationMatcher(other_filepath, 2, 1), False

    # First request returns a location before the cursor.
    yield Test, [{
        'result': {
            'uri': uri,
            'range': {
                'start': {
                    'line': 0,
                    'character': 1
                },
                'end': {
                    'line': 1,
                    'character': 1
                },
            }
        }
    }], 'GoTo', LocationMatcher(filepath, 1, 2), False

    # First request returns a location after the cursor.
    yield Test, [{
        'result': {
            'uri': uri,
            'range': {
                'start': {
                    'line': 1,
                    'character': 3
                },
                'end': {
                    'line': 2,
                    'character': 3
                },
            }
        }
    }], 'GoTo', LocationMatcher(filepath, 2, 4), False
def MiscHandlers_EventNotification_AlwaysJsonResponse_test(app):
    event_data = BuildRequest(contents='foo foogoo ba',
                              event_name='FileReadyToParse')

    assert_that(app.post_json('/event_notification', event_data).json, empty())
def MiscHandlers_SemanticCompletionAvailable_test(app):
    with PatchCompleter(DummyCompleter, filetype='dummy_filetype'):
        request_data = BuildRequest(filetype='dummy_filetype')
        assert_that(
            app.post_json('/semantic_completion_available', request_data).json,
            equal_to(True))
def _CombineRequest( request, data ):
  return BuildRequest( **_Merge( request, data ) )
Exemple #19
0
def Diagnostics_DoesWork_test(get_detailed_diag, app):
    with PatchCompleter(DummyCompleter, filetype='dummy_filetype'):
        diag_data = BuildRequest(contents='foo = 5', filetype='dummy_filetype')

        response = app.post_json('/detailed_diagnostic', diag_data)
        assert_that(response.json, MessageMatcher('detailed diagnostic'))
Exemple #20
0
def LanguageServerCompleter_GetCompletions_CompleteOnCurrentColumn_test():
    completer = MockCompleter()
    completer._resolve_completion_items = False

    a_response = {
        'result': {
            'items': [{
                'label': 'aba'
            }, {
                'label': 'aab'
            }, {
                'label': 'aaa'
            }],
            'isIncomplete': True
        }
    }
    aa_response = {
        'result': {
            'items': [{
                'label': 'aab'
            }, {
                'label': 'aaa'
            }],
            'isIncomplete': False
        }
    }
    aaa_response = {
        'result': {
            'items': [{
                'label': 'aaa'
            }],
            'isIncomplete': False
        }
    }
    ab_response = {
        'result': {
            'items': [{
                'label': 'abb'
            }, {
                'label': 'aba'
            }],
            'isIncomplete': False
        }
    }

    with patch.object(completer, '_is_completion_provider', True):
        # User starts by typing the character "a".
        request_data = RequestWrap(
            BuildRequest(column_num=2, contents='a', force_semantic=True))

        with patch.object(completer.GetConnection(),
                          'GetResponse',
                          return_value=a_response) as response:
            assert_that(
                completer.ComputeCandidates(request_data),
                contains(has_entry('insertion_text', 'aaa'),
                         has_entry('insertion_text', 'aab'),
                         has_entry('insertion_text', 'aba')))

            # Nothing cached yet.
            assert_that(response.call_count, equal_to(1))

        # User types again the character "a".
        request_data = RequestWrap(
            BuildRequest(column_num=3, contents='aa', force_semantic=True))

        with patch.object(completer.GetConnection(),
                          'GetResponse',
                          return_value=aa_response) as response:
            assert_that(
                completer.ComputeCandidates(request_data),
                contains(has_entry('insertion_text', 'aaa'),
                         has_entry('insertion_text', 'aab')))

            # The server returned an incomplete list of completions the first time so
            # a new completion request should have been sent.
            assert_that(response.call_count, equal_to(1))

        # User types the character "a" a third time.
        request_data = RequestWrap(
            BuildRequest(column_num=4, contents='aaa', force_semantic=True))

        with patch.object(completer.GetConnection(),
                          'GetResponse',
                          return_value=aaa_response) as response:

            assert_that(completer.ComputeCandidates(request_data),
                        contains(has_entry('insertion_text', 'aaa')))

            # The server returned a complete list of completions the second time and
            # the new query is a prefix of the cached one ("aa" is a prefix of "aaa")
            # so the cache should be used.
            assert_that(response.call_count, equal_to(0))

        # User deletes the third character.
        request_data = RequestWrap(
            BuildRequest(column_num=3, contents='aa', force_semantic=True))

        with patch.object(completer.GetConnection(),
                          'GetResponse',
                          return_value=aa_response) as response:

            assert_that(
                completer.ComputeCandidates(request_data),
                contains(has_entry('insertion_text', 'aaa'),
                         has_entry('insertion_text', 'aab')))

            # The new query is still a prefix of the cached one ("aa" is a prefix of
            # "aa") so the cache should again be used.
            assert_that(response.call_count, equal_to(0))

        # User deletes the second character.
        request_data = RequestWrap(
            BuildRequest(column_num=2, contents='a', force_semantic=True))

        with patch.object(completer.GetConnection(),
                          'GetResponse',
                          return_value=a_response) as response:

            assert_that(
                completer.ComputeCandidates(request_data),
                contains(has_entry('insertion_text', 'aaa'),
                         has_entry('insertion_text', 'aab'),
                         has_entry('insertion_text', 'aba')))

            # The new query is not anymore a prefix of the cached one ("aa" is not a
            # prefix of "a") so the cache is invalidated and a new request is sent.
            assert_that(response.call_count, equal_to(1))

        # Finally, user inserts the "b" character.
        request_data = RequestWrap(
            BuildRequest(column_num=3, contents='ab', force_semantic=True))

        with patch.object(completer.GetConnection(),
                          'GetResponse',
                          return_value=ab_response) as response:

            assert_that(
                completer.ComputeCandidates(request_data),
                contains(has_entry('insertion_text', 'aba'),
                         has_entry('insertion_text', 'abb')))

            # Last response was incomplete so the cache should not be used.
            assert_that(response.call_count, equal_to(1))
def LanguageServerCompleter_Diagnostics_PercentEncodeCannonical_test():
    completer = MockCompleter()
    filepath = os.path.realpath('/foo?')
    uri = lsp.FilePathToUri(filepath)
    assert_that(uri, ends_with('%3F'))
    request_data = RequestWrap(
        BuildRequest(line_num=1, column_num=1, filepath=filepath, contents=''))
    notification = {
        'jsonrpc': '2.0',
        'method': 'textDocument/publishDiagnostics',
        'params': {
            'uri':
            uri.replace('%3F', '%3f'),
            'diagnostics': [{
                'range': {
                    'start': {
                        'line': 3,
                        'character': 10
                    },
                    'end': {
                        'line': 3,
                        'character': 11
                    }
                },
                'severity': 1,
                'message': 'First error'
            }]
        }
    }
    completer.GetConnection()._notifications.put(notification)
    completer.HandleNotificationInPollThread(notification)

    with patch.object(completer, 'ServerIsReady', return_value=True):
        completer.SendInitialize(
            request_data, completer._GetSettingsFromExtraConf(request_data))
        # Simulate receipt of response and initialization complete
        initialize_response = {'result': {'capabilities': {}}}
        completer._HandleInitializeInPollThread(initialize_response)

        diagnostics = contains(
            has_entries({
                'kind':
                equal_to('ERROR'),
                'location':
                LocationMatcher(filepath, 4, 11),
                'location_extent':
                RangeMatcher(filepath, (4, 11), (4, 12)),
                'ranges':
                contains(RangeMatcher(filepath, (4, 11), (4, 12))),
                'text':
                equal_to('First error'),
                'fixit_available':
                False
            }))

        assert_that(completer.OnFileReadyToParse(request_data), diagnostics)

        assert_that(
            completer.PollForMessages(request_data),
            contains(
                has_entries({
                    'diagnostics': diagnostics,
                    'filepath': filepath
                })))
def Diagnostics_LocationExtent_MissingSemicolon_test(app):
    contents = ReadFile(PathToTestFile('location_extent.cc'))

    event_data = BuildRequest(contents=contents,
                              event_name='FileReadyToParse',
                              filetype='cpp',
                              filepath='foo',
                              compilation_flags=['-x', 'c++'])

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

    pprint(response)

    assert_that(
        response,
        contains(
            has_entries({
                'kind':
                equal_to('ERROR'),
                'location':
                has_entries({
                    'line_num': 2,
                    'column_num': 9,
                    'filepath': 'foo'
                }),
                'location_extent':
                has_entries({
                    'start':
                    has_entries({
                        'line_num': 2,
                        'column_num': 9,
                        'filepath': 'foo'
                    }),
                    'end':
                    has_entries({
                        'line_num': 2,
                        'column_num': 9,
                        'filepath': 'foo'
                    })
                }),
                'ranges':
                empty(),
                'text':
                equal_to("expected ';' at end of declaration list"),
                'fixit_available':
                True
            }),
            has_entries({
                'kind':
                equal_to('ERROR'),
                'location':
                has_entries({
                    'line_num': 5,
                    'column_num': 1,
                    'filepath': 'foo'
                }),
                'location_extent':
                has_entries({
                    'start':
                    has_entries({
                        'line_num': 5,
                        'column_num': 1,
                        'filepath': 'foo'
                    }),
                    'end':
                    has_entries({
                        'line_num': 6,
                        'column_num': 11,
                        'filepath': 'foo'
                    })
                }),
                'ranges':
                empty(),
                'text':
                equal_to("unknown type name 'multiline_identifier'"),
                'fixit_available':
                False
            }),
            has_entries({
                'kind':
                equal_to('ERROR'),
                'location':
                has_entries({
                    'line_num': 8,
                    'column_num': 7,
                    'filepath': 'foo'
                }),
                'location_extent':
                has_entries({
                    'start':
                    has_entries({
                        'line_num': 8,
                        'column_num': 7,
                        'filepath': 'foo'
                    }),
                    'end':
                    has_entries({
                        'line_num': 8,
                        'column_num': 11,
                        'filepath': 'foo'
                    })
                }),
                'ranges':
                contains(
                    # FIXME: empty ranges from libclang should be ignored.
                    has_entries({
                        'start':
                        has_entries({
                            'line_num': 0,
                            'column_num': 0,
                            'filepath': ''
                        }),
                        'end':
                        has_entries({
                            'line_num': 0,
                            'column_num': 0,
                            'filepath': ''
                        })
                    }),
                    has_entries({
                        'start':
                        has_entries({
                            'line_num': 8,
                            'column_num': 7,
                            'filepath': 'foo'
                        }),
                        'end':
                        has_entries({
                            'line_num': 8,
                            'column_num': 11,
                            'filepath': 'foo'
                        })
                    })),
                'text':
                equal_to('constructor cannot have a return type'),
                'fixit_available':
                False
            })))
Exemple #23
0
    def test_Diagnostics_FileReadyToParse(self, app):
        filepath = PathToTestFile('test.ts')
        contents = ReadFile(filepath)

        event_data = BuildRequest(filepath=filepath,
                                  filetype='typescript',
                                  contents=contents,
                                  event_name='BufferVisit')
        app.post_json('/event_notification', event_data)

        event_data = BuildRequest(filepath=filepath,
                                  filetype='typescript',
                                  contents=contents,
                                  event_name='FileReadyToParse')

        assert_that(
            app.post_json('/event_notification', event_data).json,
            contains_inanyorder(
                has_entries({
                    'kind':
                    'ERROR',
                    'text':
                    "Property 'mA' does not exist on type 'Foo'.",
                    'location':
                    LocationMatcher(filepath, 17, 5),
                    'location_extent':
                    RangeMatcher(filepath, (17, 5), (17, 7)),
                    'ranges':
                    contains_exactly(RangeMatcher(filepath, (17, 5), (17, 7))),
                    'fixit_available':
                    True
                }),
                has_entries({
                    'kind':
                    'ERROR',
                    'text':
                    "Property 'nonExistingMethod' does not exist on type 'Bar'.",
                    'location':
                    LocationMatcher(filepath, 35, 5),
                    'location_extent':
                    RangeMatcher(filepath, (35, 5), (35, 22)),
                    'ranges':
                    contains_exactly(RangeMatcher(filepath, (35, 5),
                                                  (35, 22))),
                    'fixit_available':
                    True
                }),
                has_entries({
                    'kind':
                    'ERROR',
                    'text':
                    'Expected 1-2 arguments, but got 0.',
                    'location':
                    LocationMatcher(filepath, 37, 5),
                    'location_extent':
                    RangeMatcher(filepath, (37, 5), (37, 12)),
                    'ranges':
                    contains_exactly(RangeMatcher(filepath, (37, 5),
                                                  (37, 12))),
                    'fixit_available':
                    False
                }),
                has_entries({
                    'kind':
                    'ERROR',
                    'text':
                    "Cannot find name 'Bår'.",
                    'location':
                    LocationMatcher(filepath, 39, 1),
                    'location_extent':
                    RangeMatcher(filepath, (39, 1), (39, 5)),
                    'ranges':
                    contains_exactly(RangeMatcher(filepath, (39, 1), (39, 5))),
                    'fixit_available':
                    True
                }),
            ))
def Diagnostics_Unity_test(app):
    app.post_json('/load_extra_conf_file',
                  {'filepath': PathToTestFile('.ycm_extra_conf.py')})

    for filename in ['unity.cc', 'unity.h', 'unitya.cc']:
        contents = ReadFile(PathToTestFile(filename))

        event_data = BuildRequest(filepath=PathToTestFile(filename),
                                  contents=contents,
                                  event_name='FileReadyToParse',
                                  filetype='cpp')

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

        pprint(response)

        assert_that(
            response,
            contains_inanyorder(
                has_entries({
                    'kind':
                    equal_to('ERROR'),
                    'location':
                    has_entries({
                        'line_num': 4,
                        'column_num': 3,
                        'filepath': PathToTestFile('unity.h')
                    }),
                    'location_extent':
                    has_entries({
                        'start':
                        has_entries({
                            'line_num': 4,
                            'column_num': 3,
                            'filepath': PathToTestFile('unity.h')
                        }),
                        'end':
                        has_entries({
                            'line_num': 4,
                            'column_num': 14,
                            'filepath': PathToTestFile('unity.h')
                        }),
                    }),
                    'ranges':
                    empty(),
                    'text':
                    equal_to("use of undeclared identifier 'fake_method'"),
                    'fixit_available':
                    False
                }),
                has_entries({
                    'kind':
                    equal_to('ERROR'),
                    'location':
                    has_entries({
                        'line_num': 11,
                        'column_num': 18,
                        'filepath': PathToTestFile('unitya.cc')
                    }),
                    'location_extent':
                    has_entries({
                        'start':
                        has_entries({
                            'line_num': 11,
                            'column_num': 18,
                            'filepath': PathToTestFile('unitya.cc')
                        }),
                        'end':
                        has_entries({
                            'line_num': 11,
                            'column_num': 18,
                            'filepath': PathToTestFile('unitya.cc')
                        }),
                    }),
                    'ranges':
                    empty(),
                    'text':
                    equal_to("expected ';' after expression"),
                    'fixit_available':
                    True
                }),
            ))
Exemple #25
0
def StopRacerdServer(app):
    app.post_json('/run_completer_command',
                  BuildRequest(completer_target='filetype_default',
                               command_arguments=['StopServer'],
                               filetype='rust'),
                  expect_errors=True)
def Diagnostics_CUDA_Kernel_test(app):
    filepath = PathToTestFile('cuda', 'kernel_call.cu')
    contents = ReadFile(filepath)

    event_data = BuildRequest(
        filepath=filepath,
        contents=contents,
        event_name='FileReadyToParse',
        filetype='cuda',
        compilation_flags=['-x', 'cuda', '-nocudainc', '-nocudalib'])

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

    pprint(response)

    assert_that(
        response,
        contains_inanyorder(
            has_entries({
                'kind':
                equal_to('ERROR'),
                'location':
                has_entries({
                    'line_num': 59,
                    'column_num': 5
                }),
                'location_extent':
                has_entries({
                    'start':
                    has_entries({
                        'line_num': 59,
                        'column_num': 5
                    }),
                    'end':
                    has_entries({
                        'line_num': 59,
                        'column_num': 6
                    }),
                }),
                'ranges':
                contains(
                    has_entries({
                        'start':
                        has_entries({
                            'line_num': 59,
                            'column_num': 3
                        }),
                        'end':
                        has_entries({
                            'line_num': 59,
                            'column_num': 5
                        }),
                    })),
                'text':
                equal_to('call to global function g1 not configured'),
                'fixit_available':
                False
            }),
            has_entries({
                'kind':
                equal_to('ERROR'),
                'location':
                has_entries({
                    'line_num': 60,
                    'column_num': 9
                }),
                'location_extent':
                has_entries({
                    'start':
                    has_entries({
                        'line_num': 60,
                        'column_num': 9
                    }),
                    'end':
                    has_entries({
                        'line_num': 60,
                        'column_num': 12
                    }),
                }),
                'ranges':
                contains(
                    has_entries({
                        'start':
                        has_entries({
                            'line_num': 60,
                            'column_num': 5
                        }),
                        'end':
                        has_entries({
                            'line_num': 60,
                            'column_num': 8
                        }),
                    })),
                'text':
                equal_to(
                    'too few execution configuration arguments to kernel function call,'
                    + ' expected at least 2, have 1'),
                'fixit_available':
                False
            }),
            has_entries({
                'kind':
                equal_to('ERROR'),
                'location':
                has_entries({
                    'line_num': 61,
                    'column_num': 20
                }),
                'location_extent':
                has_entries({
                    'start':
                    has_entries({
                        'line_num': 61,
                        'column_num': 20
                    }),
                    'end':
                    has_entries({
                        'line_num': 61,
                        'column_num': 21
                    }),
                }),
                'ranges':
                contains(
                    has_entries({
                        'start':
                        has_entries({
                            'line_num': 61,
                            'column_num': 5
                        }),
                        'end':
                        has_entries({
                            'line_num': 61,
                            'column_num': 8
                        }),
                    }),
                    has_entries({
                        'start':
                        has_entries({
                            'line_num': 61,
                            'column_num': 20
                        }),
                        'end':
                        has_entries({
                            'line_num': 61,
                            'column_num': 21
                        }),
                    }),
                ),
                'text':
                equal_to(
                    'too many execution configuration arguments to kernel' +
                    ' function call, expected at most 4, have 5'),
                'fixit_available':
                False
            }),
            has_entries({
                'kind':
                equal_to('ERROR'),
                'location':
                has_entries({
                    'line_num': 65,
                    'column_num': 15
                }),
                'location_extent':
                has_entries({
                    'start':
                    has_entries({
                        'line_num': 65,
                        'column_num': 15
                    }),
                    'end':
                    has_entries({
                        'line_num': 65,
                        'column_num': 16
                    }),
                }),
                'ranges':
                contains(
                    has_entries({
                        'start':
                        has_entries({
                            'line_num': 65,
                            'column_num': 3
                        }),
                        'end':
                        has_entries({
                            'line_num': 65,
                            'column_num': 5
                        }),
                    })),
                'text':
                equal_to('kernel call to non-global function h1'),
                'fixit_available':
                False
            }),
            has_entries({
                'kind':
                equal_to('ERROR'),
                'location':
                has_entries({
                    'line_num': 68,
                    'column_num': 15
                }),
                'location_extent':
                has_entries({
                    'start':
                    has_entries({
                        'line_num': 68,
                        'column_num': 15
                    }),
                    'end':
                    has_entries({
                        'line_num': 68,
                        'column_num': 16
                    }),
                }),
                'ranges':
                contains(
                    has_entries({
                        'start':
                        has_entries({
                            'line_num': 68,
                            'column_num': 3
                        }),
                        'end':
                        has_entries({
                            'line_num': 68,
                            'column_num': 5
                        }),
                    })),
                'text':
                equal_to("kernel function type 'int (*)(int)' must have " +
                         "void return type"),
                'fixit_available':
                False
            }),
            has_entries({
                'kind':
                equal_to('ERROR'),
                'location':
                has_entries({
                    'line_num': 70,
                    'column_num': 8
                }),
                'location_extent':
                has_entries({
                    'start':
                    has_entries({
                        'line_num': 70,
                        'column_num': 8
                    }),
                    'end':
                    has_entries({
                        'line_num': 70,
                        'column_num': 18
                    }),
                }),
                'ranges':
                empty(),
                'text':
                equal_to("use of undeclared identifier 'undeclared'"),
                'fixit_available':
                False
            }),
        ))
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.
    assert_that(results, empty())

    diag_matcher = contains_exactly(
        has_entries({
            'kind':
            'ERROR',
            'text':
            'Syntax error, insert ";" to complete ClassBodyDeclarations '
            '[1610612976]',
            'location':
            LocationMatcher(filepath, 4, 21),
            'location_extent':
            RangeMatcher(filepath, (4, 21), (4, 25)),
            'ranges':
            contains_exactly(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)
Exemple #28
0
def JavaCompleter_GetType_test( app ):
  completer = handlers._server_state.GetFiletypeCompleter( [ 'java' ] )

  # The LSP defines the hover response as either:
  # - a string
  # - a list of strings
  # - an object with keys language, value
  # - a list of objects with keys language, value
  # = an object with keys kind, value

  with patch.object( completer, 'GetHoverResponse', return_value = '' ):
    assert_that( calling( completer.GetType ).with_args( BuildRequest() ),
                 raises( RuntimeError, 'Unknown type' ) )

  with patch.object( completer, 'GetHoverResponse', return_value = 'string' ):
    assert_that( calling( completer.GetType ).with_args( BuildRequest() ),
                 raises( RuntimeError, 'Unknown type' ) )

  with patch.object( completer, 'GetHoverResponse', return_value = 'value' ):
    assert_that( calling( completer.GetType ).with_args( BuildRequest() ),
                 raises( RuntimeError, 'Unknown type' ) )

  with patch.object( completer, 'GetHoverResponse', return_value = [] ):
    assert_that( calling( completer.GetType ).with_args( BuildRequest() ),
                 raises( RuntimeError, 'Unknown type' ) )

  with patch.object( completer,
                     'GetHoverResponse',
                     return_value = [ 'a', 'b' ] ):
    assert_that( calling( completer.GetType ).with_args( BuildRequest() ),
                 raises( RuntimeError, 'Unknown type' ) )

  with patch.object( completer,
                     'GetHoverResponse',
                     return_value = { 'language': 'java', 'value': 'test' } ):
    assert_that( completer.GetType( BuildRequest() ),
                 has_entries( { 'message': 'test' } ) )

  with patch.object(
    completer,
    'GetHoverResponse',
    return_value = [ { 'language': 'java', 'value': 'test' } ] ):
    assert_that( completer.GetType( BuildRequest() ),
                 has_entries( { 'message': 'test' } ) )

  with patch.object(
    completer,
    'GetHoverResponse',
    return_value = [ { 'language': 'java', 'value': 'test' },
                     { 'language': 'java', 'value': 'not test' } ] ):
    assert_that( completer.GetType( BuildRequest() ),
                 has_entries( { 'message': 'test' } ) )

  with patch.object(
    completer,
    'GetHoverResponse',
    return_value = [ { 'language': 'java', 'value': 'test' },
                     'line 1',
                     'line 2' ] ):
    assert_that( completer.GetType( BuildRequest() ),
                 has_entries( { 'message': 'test' } ) )


  with patch.object( completer,
                     'GetHoverResponse',
                     return_value = { 'kind': 'plaintext', 'value': 'test' } ):
    assert_that( calling( completer.GetType ).with_args( BuildRequest() ),
                 raises( RuntimeError, 'Unknown type' ) )
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({}))
def Subcommands_ExtraConf_SettingsValid_test(app):
    StartJavaCompleterServerInDirectory(
        app, PathToTestFile('extra_confs', 'simple_extra_conf_project'))

    filepath = PathToTestFile('extra_confs', 'simple_extra_conf_project',
                              'src', 'ExtraConf.java')

    request_data = BuildRequest(filepath=filepath, filetype='java')
    assert_that(
        app.post_json('/debug_info', request_data).json,
        has_entry(
            'completer',
            has_entries({
                'name':
                'Java',
                'servers':
                contains(
                    has_entries({
                        'name':
                        'jdt.ls Java Language Server',
                        'is_running':
                        instance_of(bool),
                        'executable':
                        instance_of(str),
                        'pid':
                        instance_of(int),
                        'logfiles':
                        contains(instance_of(str), instance_of(str)),
                        'extras':
                        contains(
                            has_entries({
                                'key': 'Startup Status',
                                'value': 'Ready'
                            }),
                            has_entries({
                                'key': 'Java Path',
                                'value': instance_of(str)
                            }),
                            has_entries({
                                'key': 'Launcher Config.',
                                'value': instance_of(str)
                            }),
                            has_entries({
                                'key': 'Workspace Path',
                                'value': instance_of(str)
                            }),
                            has_entries({
                                'key': 'Extension Path',
                                'value': contains(instance_of(str))
                            }),
                            has_entries({
                                'key': 'Server State',
                                'value': 'Initialized'
                            }),
                            has_entries({
                                'key':
                                'Project Directory',
                                'value':
                                PathToTestFile('extra_confs',
                                               'simple_extra_conf_project')
                            }),
                            has_entries({
                                'key':
                                'Settings',
                                'value':
                                json.dumps(
                                    {
                                        'java.rename.enabled': False,
                                        'bundles': []
                                    },
                                    indent=2,
                                    sort_keys=True)
                            }),
                        )
                    }))
            })))
def GetCompletions_IdentifierCompleter_StartColumn_AfterWord_test( app ):
  completion_data = BuildRequest( contents = 'oo foo foogoo ba',
                                  column_num = 11 )
  response_data = app.post_json( '/completions', completion_data ).json
  eq_( 8, response_data[ 'completion_start_column' ] )
def LanguageServerCompleter_GoToDeclaration_test():
    if utils.OnWindows():
        filepath = 'C:\\test.test'
        uri = 'file:///c:/test.test'
    else:
        filepath = '/test.test'
        uri = 'file:/test.test'

    contents = 'line1\nline2\nline3'

    completer = MockCompleter()
    request_data = RequestWrap(
        BuildRequest(filetype='ycmtest', filepath=filepath, contents=contents))

    @patch.object(completer, 'ServerIsReady', return_value=True)
    def Test(response, checker, throws, *args):
        with patch.object(completer.GetConnection(),
                          'GetResponse',
                          return_value=response):
            if throws:
                assert_that(
                    calling(completer.GoToDeclaration).with_args(request_data),
                    raises(checker))
            else:
                result = completer.GoToDeclaration(request_data)
                print('Result: {0}'.format(result))
                assert_that(result, checker)

    location = {
        'uri': uri,
        'range': {
            'start': {
                'line': 0,
                'character': 0
            },
            'end': {
                'line': 0,
                'character': 0
            },
        }
    }

    goto_response = has_entries({
        'filepath': filepath,
        'column_num': 1,
        'line_num': 1,
        'description': 'line1'
    })

    cases = [
        ({
            'result': None
        }, RuntimeError, True),
        ({
            'result': location
        }, goto_response, False),
        ({
            'result': {}
        }, RuntimeError, True),
        ({
            'result': []
        }, RuntimeError, True),
        ({
            'result': [location]
        }, goto_response, False),
        ({
            'result': [location, location]
        }, contains(goto_response, goto_response), False),
    ]

    for response, checker, throws in cases:
        yield Test, response, checker, throws

    with patch(
            'ycmd.completers.language_server.language_server_protocol.UriToFilePath',
            side_effect=lsp.InvalidUriException):
        yield Test, {
            'result': {
                'uri': uri,
                'range': {
                    'start': {
                        'line': 0,
                        'character': 0
                    },
                    'end': {
                        'line': 0,
                        'character': 0
                    },
                }
            }
        }, has_entries({
            'filepath': '',
            'column_num': 1,
            'line_num': 1,
        }), False

    with patch('ycmd.completers.completer_utils.GetFileContents',
               side_effect=lsp.IOError):
        yield Test, {
            'result': {
                'uri': uri,
                'range': {
                    'start': {
                        'line': 0,
                        'character': 0
                    },
                    'end': {
                        'line': 0,
                        'character': 0
                    },
                }
            }
        }, has_entries({
            'filepath': filepath,
            'column_num': 1,
            'line_num': 1,
        }), False
Exemple #33
0
 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" ]
def GetCompletions_RejectInvalid_test():
    if utils.OnWindows():
        filepath = 'C:\\test.test'
    else:
        filepath = '/test.test'

    contents = 'line1.\nline2.\nline3.'

    request_data = RequestWrap(
        BuildRequest(filetype='ycmtest',
                     filepath=filepath,
                     contents=contents,
                     line_num=1,
                     column_num=7))

    text_edit = {
        'newText': 'blah',
        'range': {
            'start': {
                'line': 0,
                'character': 6
            },
            'end': {
                'line': 0,
                'character': 6
            },
        }
    }

    assert_that(
        lsc._GetCompletionItemStartCodepointOrReject(text_edit, request_data),
        equal_to(7))

    text_edit = {
        'newText': 'blah',
        'range': {
            'start': {
                'line': 0,
                'character': 6
            },
            'end': {
                'line': 1,
                'character': 6
            },
        }
    }

    assert_that(
        calling(lsc._GetCompletionItemStartCodepointOrReject).with_args(
            text_edit, request_data),
        raises(lsc.IncompatibleCompletionException))

    text_edit = {
        'newText': 'blah',
        'range': {
            'start': {
                'line': 0,
                'character': 20
            },
            'end': {
                'line': 0,
                'character': 20
            },
        }
    }

    assert_that(
        lsc._GetCompletionItemStartCodepointOrReject(text_edit, request_data),
        equal_to(7))

    text_edit = {
        'newText': 'blah',
        'range': {
            'start': {
                'line': 0,
                'character': 6
            },
            'end': {
                'line': 0,
                'character': 5
            },
        }
    }

    assert_that(
        lsc._GetCompletionItemStartCodepointOrReject(text_edit, request_data),
        equal_to(7))
Exemple #35
0
def BuildRequestWrap(contents, column_num, line_num=1):
    return RequestWrap(
        BuildRequest(column_num=column_num,
                     line_num=line_num,
                     contents=contents))
def DebugInfo_test(app):
    request_data = BuildRequest(filetype='java')
    assert_that(
        app.post_json('/debug_info', request_data).json,
        has_entry(
            'completer',
            has_entries({
                'name':
                'Java',
                'servers':
                contains(
                    has_entries({
                        'name':
                        'jdt.ls Java Language Server',
                        'is_running':
                        instance_of(bool),
                        'executable':
                        instance_of(str),
                        'pid':
                        instance_of(int),
                        'logfiles':
                        contains(instance_of(str), instance_of(str)),
                        'extras':
                        contains(
                            has_entries({
                                'key': 'Startup Status',
                                'value': 'Ready'
                            }),
                            has_entries({
                                'key': 'Java Path',
                                'value': instance_of(str)
                            }),
                            has_entries({
                                'key': 'Launcher Config.',
                                'value': instance_of(str)
                            }),
                            has_entries({
                                'key': 'Workspace Path',
                                'value': instance_of(str)
                            }),
                            has_entries({
                                'key': 'Extension Path',
                                'value': contains(instance_of(str))
                            }),
                            has_entries({
                                'key': 'Server State',
                                'value': 'Initialized'
                            }),
                            has_entries({
                                'key':
                                'Project Directory',
                                'value':
                                PathToTestFile(DEFAULT_PROJECT_DIR)
                            }),
                            has_entries({
                                'key':
                                'Settings',
                                'value':
                                json.dumps({'bundles': []},
                                           indent=2,
                                           sort_keys=True)
                            }))
                    }))
            })))