def test_references(tmp_workspace): # pylint: disable=redefined-outer-name # Over 'Test1' in class Test1(): position = {'line': 0, 'character': 8} DOC1_URI = uris.from_fs_path( os.path.join(tmp_workspace.root_path, DOC1_NAME)) doc1 = Document(DOC1_URI) refs = pyls_references(doc1, position) # Definition, the import and the instantiation assert len(refs) == 3 # Briefly check excluding the definitions (also excludes imports, only counts uses) no_def_refs = pyls_references(doc1, position, exclude_declaration=True) assert len(no_def_refs) == 1 # Make sure our definition is correctly located doc1_ref = [u for u in refs if u['uri'] == DOC1_URI][0] assert doc1_ref['range']['start'] == {'line': 0, 'character': 6} assert doc1_ref['range']['end'] == {'line': 0, 'character': 11} # Make sure our import is correctly located doc2_import_ref = [u for u in refs if u['uri'] != DOC1_URI][0] assert doc2_import_ref['range']['start'] == {'line': 0, 'character': 18} assert doc2_import_ref['range']['end'] == {'line': 0, 'character': 23} doc2_usage_ref = [u for u in refs if u['uri'] != DOC1_URI][1] assert doc2_usage_ref['range']['start'] == {'line': 2, 'character': 0} assert doc2_usage_ref['range']['end'] == {'line': 2, 'character': 5}
def test_syntax_error_pyflakes(): doc = Document(DOC_URI, DOC_SYNTAX_ERR) diag = pyflakes_lint.pyls_lint(doc)[0] assert diag['message'] == 'invalid syntax' assert diag['range']['start'] == {'line': 0, 'character': 12} assert diag['severity'] == lsp.DiagnosticSeverity.Error
def test_builtin_definition(config): # Over 'i' in dict cursor_pos = {'line': 8, 'character': 24} # No go-to def for builtins doc = Document(DOC_URI, DOC) assert [] == pyls_definitions(config, doc, cursor_pos)
def test_document_empty_edit(): doc = Document('file:///uri', u'') doc.apply_change({ 'range': { 'start': { 'line': 0, 'character': 0 }, 'end': { 'line': 0, 'character': 0 } }, 'text': u'f' }) assert doc.source == u'f'
def test_document_line_edit(): doc = Document('file:///uri', u'itshelloworld') doc.apply_change({ 'text': u'goodbye', 'range': { 'start': { 'line': 0, 'character': 3 }, 'end': { 'line': 0, 'character': 8 } } }) assert doc.source == u'itsgoodbyeworld'
def test_no_signature(): # Over blank line sig_position = {'line': 9, 'character': 0} doc = Document(DOC_URI, DOC) sigs = signature.pyls_signature_help(doc, sig_position)['signatures'] assert not sigs
def test_symbols(config): doc = Document(DOC_URI, DOC) config.update({'plugins': {'jedi_symbols': {'all_scopes': False}}}) symbols = pyls_document_symbols(config, doc) # All four symbols (import sys, a, B, main, y) assert len(symbols) == 5 def sym(name): return [s for s in symbols if s['name'] == name][0] # Check we have some sane mappings to VSCode constants assert sym('a')['kind'] == SymbolKind.Variable assert sym('B')['kind'] == SymbolKind.Class assert sym('main')['kind'] == SymbolKind.Function # Not going to get too in-depth here else we're just testing Jedi assert sym('a')['location']['range']['start'] == { 'line': 2, 'character': 0 } # Ensure that the symbol range spans the whole definition assert sym('main')['location']['range']['start'] == { 'line': 9, 'character': 0 } assert sym('main')['location']['range']['end'] == { 'line': 12, 'character': 0 }
def test_undefined_name_pyflakes(): doc = Document(DOC_URI, DOC_UNDEFINED_NAME_ERR) diag = pyflakes_lint.pyls_lint(doc)[0] assert diag['message'] == 'undefined name \'b\'' assert diag['range']['start'] == {'line': 0, 'character': 4} assert diag['severity'] == lsp.DiagnosticSeverity.Error
def test_document_multiline_edit(): old = ["def hello(a, b):\n", " print a\n", " print b\n"] doc = Document('file:///uri', u''.join(old)) doc.apply_change({ 'text': u'print a, b', 'range': { 'start': { 'line': 1, 'character': 4 }, 'end': { 'line': 2, 'character': 11 } } }) assert doc.lines == ["def hello(a, b):\n", " print a, b\n"]
def test_pyflakes(): doc = Document(DOC_URI, DOC) diags = pyflakes_lint.pyls_lint(doc) # One we're expecting is: msg = '\'sys\' imported but unused' unused_import = [d for d in diags if d['message'] == msg][0] assert unused_import['range']['start'] == {'line': 0, 'character': 0} assert unused_import['severity'] == lsp.DiagnosticSeverity.Warning
def test_document_end_of_file_edit(): old = ["print 'a'\n", "print 'b'\n"] doc = Document('file:///uri', u''.join(old)) doc.apply_change({ 'text': u'o', 'range': { 'start': { 'line': 2, 'character': 0 }, 'end': { 'line': 2, 'character': 0 } } }) assert doc.lines == [ "print 'a'\n", "print 'b'\n", "o", ]
def test_hover(): # Over 'main' in def main(): hov_position = {'line': 2, 'character': 6} # Over the blank second line no_hov_position = {'line': 1, 'character': 0} doc = Document(DOC_URI, DOC) assert { 'contents': 'main()\n\nhello world' } == pyls_hover(doc, hov_position) assert {'contents': ''} == pyls_hover(doc, no_hov_position)
def test_signature(): # Over '( ' in main( sig_position = {'line': 10, 'character': 5} doc = Document(DOC_URI, DOC) sig_info = signature.pyls_signature_help(doc, sig_position) sigs = sig_info['signatures'] assert len(sigs) == 1 assert sigs[0]['label'] == 'main(param1, param2)' assert sigs[0]['parameters'][0]['label'] == 'param1' assert sigs[0]['parameters'][0]['documentation'] == 'Docs for param1' assert sig_info['activeParameter'] == 0
def test_multi_line_signature(): # Over '( ' in main( sig_position = {'line': 17, 'character': 5} doc = Document(DOC_URI, MULTI_LINE_DOC) sig_info = signature.pyls_signature_help(doc, sig_position) sigs = sig_info['signatures'] assert len(sigs) == 1 assert sigs[0]['label'] == ( 'main(param1=None, param2=None, param3=None, param4=None, ' 'param5=None, param6=None, param7=None, param8=None)') assert sigs[0]['parameters'][0]['label'] == 'param1' assert sigs[0]['parameters'][0]['documentation'] == 'Docs for param1' assert sig_info['activeParameter'] == 0
def test_sys_highlight(): cursor_pos = {'line': 0, 'character': 8} doc = Document(DOC_URI, SYS_DOC) assert pyls_document_highlight(doc, cursor_pos) == [{ 'range': { 'start': {'line': 0, 'character': 7}, 'end': {'line': 0, 'character': 10} }, 'kind': lsp.DocumentHighlightKind.Write }, { 'range': { 'start': {'line': 1, 'character': 6}, 'end': {'line': 1, 'character': 9} }, 'kind': lsp.DocumentHighlightKind.Read }]
def test_mccabe(config): old_settings = config.settings try: config.update({'plugins': {'mccabe': {'threshold': 1}}}) doc = Document(DOC_URI, DOC) diags = mccabe_lint.pyls_lint(config, doc) assert all([d['source'] == 'mccabe' for d in diags]) # One we're expecting is: msg = 'Cyclomatic complexity too high: 1 (threshold 1)' mod_import = [d for d in diags if d['message'] == msg][0] assert mod_import['severity'] == lsp.DiagnosticSeverity.Warning assert mod_import['range']['start'] == {'line': 1, 'character': 0} assert mod_import['range']['end'] == {'line': 1, 'character': 6} finally: config._settings = old_settings
def test_range_format(config): doc = Document(DOC_URI, DOC) def_range = { 'start': { 'line': 0, 'character': 0 }, 'end': { 'line': 2, 'character': 0 } } res = pyls_format_range(config, doc, def_range) assert len(res) == 1 # Make sure the func is still badly formatted assert res[0]['newText'] == "a = 123\n\n\n\n\ndef func():\n pass\n"
def test_highlight(): # Over 'a' in a.startswith cursor_pos = {'line': 1, 'character': 0} doc = Document(DOC_URI, DOC) assert pyls_document_highlight(doc, cursor_pos) == [{ 'range': { 'start': {'line': 0, 'character': 0}, 'end': {'line': 0, 'character': 1}, }, # The first usage is Write 'kind': lsp.DocumentHighlightKind.Write }, { 'range': { 'start': {'line': 1, 'character': 0}, 'end': {'line': 1, 'character': 1}, }, # The second usage is Read 'kind': lsp.DocumentHighlightKind.Read }]
def test_symbols_all_scopes(config): doc = Document(DOC_URI, DOC) symbols = pyls_document_symbols(config, doc) # All eight symbols (import sys, a, B, __init__, x, y, main, y) assert len(symbols) == 8 def sym(name): return [s for s in symbols if s['name'] == name][0] # Check we have some sane mappings to VSCode constants assert sym('a')['kind'] == SymbolKind.Variable assert sym('B')['kind'] == SymbolKind.Class assert sym('__init__')['kind'] == SymbolKind.Function assert sym('main')['kind'] == SymbolKind.Function # Not going to get too in-depth here else we're just testing Jedi assert sym('a')['location']['range']['start'] == { 'line': 2, 'character': 0 }
def test_assignment(config): # Over 's' in self.members[id] cursor_pos = {'line': 11, 'character': 19} # The assignment of 'self.members' def_range = { 'start': { 'line': 8, 'character': 13 }, 'end': { 'line': 8, 'character': 20 } } doc = Document(DOC_URI, DOC) assert [{ 'uri': DOC_URI, 'range': def_range }] == pyls_definitions(config, doc, cursor_pos)
def test_definitions(config): # Over 'a' in print a cursor_pos = {'line': 3, 'character': 6} # The definition of 'a' def_range = { 'start': { 'line': 0, 'character': 4 }, 'end': { 'line': 0, 'character': 5 } } doc = Document(DOC_URI, DOC) assert [{ 'uri': DOC_URI, 'range': def_range }] == pyls_definitions(config, doc, cursor_pos)
def test_pydocstyle(config): doc = Document(DOC_URI, DOC) diags = pydocstyle_lint.pyls_lint(config, doc) assert all([d['source'] == 'pydocstyle' for d in diags]) # One we're expecting is: assert diags[0] == { 'code': 'D100', 'message': 'D100: Missing docstring in public module', 'severity': lsp.DiagnosticSeverity.Warning, 'range': { 'start': { 'line': 0, 'character': 0 }, 'end': { 'line': 0, 'character': 11 }, }, 'source': 'pydocstyle' }
def test_document_source_unicode(): document_mem = Document(DOC_URI, u'my source') document_disk = Document(DOC_URI) assert isinstance(document_mem.source, type(document_disk.source))
def test_format(config): doc = Document(DOC_URI, DOC) res = pyls_format_document(config, doc) assert len(res) == 1 assert res[0]['newText'] == "a = 123\n\n\ndef func():\n pass\n"
def test_mccabe_syntax_error(config): doc = Document(DOC_URI, DOC_SYNTAX_ERR) assert mccabe_lint.pyls_lint(config, doc) is None
def test_pydocstyle_invalid_source(config): doc = Document(DOC_URI, "bad syntax") diags = pydocstyle_lint.pyls_lint(config, doc) # We're unable to parse the file, so can't get any pydocstyle diagnostics assert not diags
def test_pydocstyle_empty_source(config): doc = Document(DOC_URI, "") diags = pydocstyle_lint.pyls_lint(config, doc) assert diags[0]['message'] == 'D100: Missing docstring in public module' assert len(diags) == 1
def test_pydocstyle_test_document(config): # The default --match argument excludes test_* documents. doc = Document(TEST_DOC_URI, "") diags = pydocstyle_lint.pyls_lint(config, doc) assert not diags
def test_unicode_encoding(): doc = Document(DOC_URI, DOC_ENCODING) diags = pyflakes_lint.pyls_lint(doc) assert len(diags) == 1 assert diags[0]['message'] == '\'sys\' imported but unused'
def test_no_change(config): doc = Document(DOC_URI, GOOD_DOC) assert not pyls_format_document(config, doc)