コード例 #1
0
def test_jedi_rename(tmp_workspace, config):  # pylint: disable=redefined-outer-name
    # rename the `Test1` class
    position = {'line': 0, 'character': 6}
    DOC_URI = uris.from_fs_path(os.path.join(tmp_workspace.root_path,
                                             DOC_NAME))
    doc = Document(DOC_URI, tmp_workspace)

    result = pyls_rename(config, tmp_workspace, doc, position,
                         'ShouldBeRenamed')
    assert len(result.keys()) == 1

    changes = result.get('documentChanges')
    assert len(changes) == 1
    changes = changes[0]

    assert changes.get('edits') == [{
        'range': {
            'start': {
                'line': 0,
                'character': 0
            },
            'end': {
                'line': 5,
                'character': 0
            },
        },
        'newText':
        'class ShouldBeRenamed():\n    pass\n\nclass Test2(ShouldBeRenamed):\n    pass\n',
    }]
コード例 #2
0
def test_numpy_hover(workspace):
    # Over the blank line
    no_hov_position = {'line': 1, 'character': 0}
    # Over 'numpy' in import numpy as np
    numpy_hov_position_1 = {'line': 2, 'character': 8}
    # Over 'np' in import numpy as np
    numpy_hov_position_2 = {'line': 2, 'character': 17}
    # Over 'np' in np.sin
    numpy_hov_position_3 = {'line': 3, 'character': 1}
    # Over 'sin' in np.sin
    numpy_sin_hov_position = {'line': 3, 'character': 4}

    doc = Document(DOC_URI, workspace, NUMPY_DOC)

    contents = ''
    assert contents in pyls_hover(doc, no_hov_position)['contents']

    contents = 'NumPy\n=====\n\nProvides\n'
    assert contents in pyls_hover(doc, numpy_hov_position_1)['contents'][0]

    contents = 'NumPy\n=====\n\nProvides\n'
    assert contents in pyls_hover(doc, numpy_hov_position_2)['contents'][0]

    contents = 'NumPy\n=====\n\nProvides\n'
    assert contents in pyls_hover(doc, numpy_hov_position_3)['contents'][0]

    contents = 'Trigonometric sine, element-wise.\n\n'
    assert contents in pyls_hover(
        doc, numpy_sin_hov_position)['contents'][0]
コード例 #3
0
def test_per_file_caching():
    # Ensure that diagnostics are cached per-file.
    with temp_document(DOC) as doc:
        assert pylint_lint.pyls_lint(doc, True)

    assert not pylint_lint.pyls_lint(Document(uris.from_fs_path(__file__)),
                                     False)
コード例 #4
0
def test_per_file_caching(config, workspace):
    # Ensure that diagnostics are cached per-file.
    with temp_document(DOC, workspace) as doc:
        assert pylint_lint.pyls_lint(config, doc, True)

    assert not pylint_lint.pyls_lint(
        config, Document(uris.from_fs_path(__file__), workspace), False)
コード例 #5
0
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 not pyls_definitions(config, doc, cursor_pos)
コード例 #6
0
def test_flake8_no_checked_file(config):
    # A bad uri or a non-saved file may cause the flake8 linter to do nothing.
    # In this situtation, the linter will return an empty list.

    doc = Document('', DOC)
    diags = flake8_lint.pyls_lint(config, doc)
    assert diags == []
コード例 #7
0
ファイル: test_rope_rename.py プロジェクト: zhoufan766/spyder
def test_rope_rename(tmp_workspace, config):  # pylint: disable=redefined-outer-name
    position = {"line": 0, "character": 6}
    DOC_URI = uris.from_fs_path(os.path.join(tmp_workspace.root_path,
                                             DOC_NAME))
    doc = Document(DOC_URI, tmp_workspace)

    result = pyls_rename(config, tmp_workspace, doc, position,
                         "ShouldBeRenamed")
    assert len(result.keys()) == 1

    changes = result.get("documentChanges")
    assert len(changes) == 1
    changes = changes[0]

    # Note that this test differs from test_jedi_rename, because rope does not
    # seem to modify files that haven't been opened with textDocument/didOpen.
    assert changes.get("edits") == [{
        "range": {
            "start": {
                "line": 0,
                "character": 0
            },
            "end": {
                "line": 5,
                "character": 0
            },
        },
        "newText":
        "class ShouldBeRenamed():\n    pass\n\nclass Test2(ShouldBeRenamed):\n    pass\n",
    }]
コード例 #8
0
ファイル: test_completion.py プロジェクト: zhoufan766/spyder
def test_completion_with_class_objects(config, workspace):
    doc_text = 'class FOOBAR(Object): pass\nFOOB'
    com_position = {'line': 1, 'character': 4}
    doc = Document(DOC_URI, workspace, doc_text)
    config.capabilities['textDocument'] = {
        'completion': {
            'completionItem': {
                'snippetSupport': True
            }
        }
    }
    config.update({
        'plugins': {
            'jedi_completion': {
                'include_params': True,
                'include_class_objects': True,
            }
        }
    })
    completions = pyls_jedi_completions(config, doc, com_position)
    assert len(completions) == 2

    assert completions[0]['label'] == 'FOOBAR'
    assert completions[0]['kind'] == lsp.CompletionItemKind.Class

    assert completions[1]['label'] == 'FOOBAR object'
    assert completions[1]['kind'] == lsp.CompletionItemKind.TypeParameter
コード例 #9
0
def test_pycodestyle(config):
    doc = Document(DOC_URI, DOC)
    diags = pycodestyle_lint.pyls_lint(config, doc)

    assert all([d['source'] == 'pycodestyle' for d in diags])

    # One we're expecting is:
    msg = 'W191 indentation contains tabs'
    mod_import = [d for d in diags if d['message'] == msg][0]

    assert mod_import['code'] == 'W191'
    assert mod_import['severity'] == lsp.DiagnosticSeverity.Warning
    assert mod_import['range']['start'] == {'line': 3, 'character': 0}
    assert mod_import['range']['end'] == {'line': 3, 'character': 6}

    msg = 'W391 blank line at end of file'
    mod_import = [d for d in diags if d['message'] == msg][0]

    assert mod_import['code'] == 'W391'
    assert mod_import['severity'] == lsp.DiagnosticSeverity.Warning
    assert mod_import['range']['start'] == {'line': 7, 'character': 0}
    assert mod_import['range']['end'] == {'line': 7, 'character': 1}

    msg = "E201 whitespace after '('"
    mod_import = [d for d in diags if d['message'] == msg][0]

    assert mod_import['code'] == 'E201'
    assert mod_import['severity'] == lsp.DiagnosticSeverity.Warning
    assert mod_import['range']['start'] == {'line': 2, 'character': 10}
    assert mod_import['range']['end'] == {'line': 2, 'character': 14}
コード例 #10
0
def test_numpy_hover():
    # Over the blank line
    no_hov_position = {'line': 1, 'character': 0}
    # Over 'numpy' in import numpy as np
    numpy_hov_position_1 = {'line': 2, 'character': 8}
    # Over 'np' in import numpy as np
    numpy_hov_position_2 = {'line': 2, 'character': 17}
    # Over 'np' in np.sin
    numpy_hov_position_3 = {'line': 3, 'character': 1}
    # Over 'sin' in np.sin
    numpy_sin_hov_position = {'line': 3, 'character': 4}

    doc = Document(DOC_URI, NUMPY_DOC)

    if LooseVersion(_utils.JEDI_VERSION) >= LooseVersion('0.15.0'):
        contents = ''
        assert contents in pyls_hover(doc, no_hov_position)['contents']

        contents = 'NumPy\n=====\n\nProvides\n'
        assert contents in pyls_hover(doc, numpy_hov_position_1)['contents'][0]

        contents = 'NumPy\n=====\n\nProvides\n'
        assert contents in pyls_hover(doc, numpy_hov_position_2)['contents'][0]

        contents = 'NumPy\n=====\n\nProvides\n'
        assert contents in pyls_hover(doc, numpy_hov_position_3)['contents'][0]

        contents = 'Trigonometric sine, element-wise.\n\n'
        assert contents in pyls_hover(
            doc, numpy_sin_hov_position)['contents'][0]
コード例 #11
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
コード例 #12
0
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
コード例 #13
0
def test_folding():
    doc = Document(DOC_URI, DOC)
    ranges = pyls_folding_range(doc)
    expected = [{'startLine': 1, 'endLine': 6},
                {'startLine': 2, 'endLine': 3},
                {'startLine': 5, 'endLine': 6},
                {'startLine': 8, 'endLine': 11},
                {'startLine': 12, 'endLine': 20},
                {'startLine': 13, 'endLine': 14},
                {'startLine': 15, 'endLine': 16},
                {'startLine': 17, 'endLine': 18},
                {'startLine': 19, 'endLine': 20},
                {'startLine': 22, 'endLine': 35},
                {'startLine': 23, 'endLine': 35},
                {'startLine': 24, 'endLine': 25},
                {'startLine': 27, 'endLine': 29},
                {'startLine': 28, 'endLine': 29},
                {'startLine': 30, 'endLine': 31},
                {'startLine': 32, 'endLine': 34},
                {'startLine': 33, 'endLine': 34},
                {'startLine': 38, 'endLine': 39},
                {'startLine': 41, 'endLine': 43},
                {'startLine': 42, 'endLine': 43},
                {'startLine': 45, 'endLine': 54},
                {'startLine': 47, 'endLine': 51},
                {'startLine': 49, 'endLine': 51},
                {'startLine': 50, 'endLine': 51},
                {'startLine': 52, 'endLine': 54},
                {'startLine': 53, 'endLine': 54},
                {'startLine': 56, 'endLine': 57},
                {'startLine': 59, 'endLine': 65},
                {'startLine': 60, 'endLine': 61},
                {'startLine': 62, 'endLine': 63},
                {'startLine': 64, 'endLine': 65}]
    assert ranges == expected
コード例 #14
0
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
        }
    ]
コード例 #15
0
ファイル: test_signature.py プロジェクト: zhoufan766/spyder
def test_no_signature(workspace):
    # Over blank line
    sig_position = {'line': 9, 'character': 0}
    doc = Document(DOC_URI, workspace, DOC)

    sigs = signature.pyls_signature_help(doc, sig_position)['signatures']
    assert not sigs
コード例 #16
0
ファイル: test_completion.py プロジェクト: zhoufan766/spyder
def test_jedi_method_completion(config, workspace):
    # Over the 'y' in 'print Hello().every'
    com_position = {'line': 20, 'character': 19}
    doc = Document(DOC_URI, workspace, DOC)

    config.capabilities['textDocument'] = {
        'completion': {
            'completionItem': {
                'snippetSupport': True
            }
        }
    }
    config.update({'plugins': {'jedi_completion': {'include_params': True}}})

    completions = pyls_jedi_completions(config, doc, com_position)
    everyone_method = [
        completion for completion in completions
        if completion['label'] == 'everyone(a, b, c, d)'
    ][0]

    # Ensure we only generate snippets for positional args
    assert everyone_method['insertTextFormat'] == lsp.InsertTextFormat.Snippet
    assert everyone_method['insertText'] == 'everyone(${1:a}, ${2:b})$0'

    # Disable param snippets
    config.update({'plugins': {'jedi_completion': {'include_params': False}}})

    completions = pyls_jedi_completions(config, doc, com_position)
    everyone_method = [
        completion for completion in completions
        if completion['label'] == 'everyone(a, b, c, d)'
    ][0]

    assert 'insertTextFormat' not in everyone_method
    assert everyone_method['insertText'] == 'everyone'
コード例 #17
0
def test_option_prepend(tmpdir, monkeypatch):
    import sys
    from textwrap import dedent

    sentinel = tmpdir / 'ran'

    source = dedent("""\
        #!/bin/sh
        touch {}
        exec {} "$@"
        """).format(sentinel, sys.executable)

    wrapper = tmpdir / 'bin/wrapper'
    wrapper.write(source, ensure=True)
    wrapper.chmod(0o700)

    monkeypatch.setattr(
        FakeConfig, 'plugin_settings',
        lambda *_: {'prepend': ['--python-executable', wrapper.strpath]})

    assert not sentinel.exists()
    diags = plugin.pyls_lint(
        config=FakeConfig(),
        workspace=None,
        document=Document(DOC_URI, DOC_TYPE_ERR),
        is_saved=False,
    )
    assert len(diags) == 1
    assert sentinel.exists()
    assert sentinel.exists()
コード例 #18
0
ファイル: test_references.py プロジェクト: wpfeder/spyder
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': 3, 'character': 4}
    assert doc2_usage_ref['range']['end'] == {'line': 3, 'character': 9}
コード例 #19
0
def test_parse_line_with_context(monkeypatch, word, bounds, workspace):
    doc = Document(DOC_URI, workspace)
    monkeypatch.setattr(Document, 'word_at_position', lambda *args: word)
    diag = plugin.parse_line(TEST_LINE, doc)
    assert diag['message'] == '"Request" has no attribute "id"'
    assert diag['range']['start'] == {'line': 278, 'character': bounds[0]}
    assert diag['range']['end'] == {'line': 278, 'character': bounds[1]}
コード例 #20
0
def test_symbols(config, workspace):
    doc = Document(DOC_URI, workspace, DOC)
    config.update({'plugins': {'jedi_symbols': {'all_scopes': False}}})
    symbols = pyls_document_symbols(config, doc)

    # All four symbols (import sys, a, B, main)
    # y is not in the root scope, it shouldn't be returned
    assert len(symbols) == 4

    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
    }
コード例 #21
0
def test_jedi_method_completion(config):
    # Over the 'y' in 'print Hello().every'
    com_position = {'line': 20, 'character': 19}
    doc = Document(DOC_URI, DOC)

    completions = pyls_jedi_completions(config, doc, com_position)
    everyone_method = [
        completion for completion in completions
        if completion['label'] == 'everyone(a, b, c, d)'
    ][0]

    assert everyone_method['insertTextFormat'] == lsp.InsertTextFormat.Snippet
    assert everyone_method[
        'insertText'] == 'everyone(${1:a}, ${2:b}, ${3:c}, ${4:d})$0'

    # Disable param snippets
    config.update({'plugins': {'jedi_completion': {'include_params': False}}})

    completions = pyls_jedi_completions(config, doc, com_position)
    everyone_method = [
        completion for completion in completions
        if completion['label'] == 'everyone(a, b, c, d)'
    ][0]

    assert 'insertTextFormat' not in everyone_method
    assert everyone_method['insertText'] == 'everyone'
コード例 #22
0
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 len(sigs) == 0
コード例 #23
0
def test_flake8_no_checked_file(config, workspace):
    # A bad uri or a non-saved file may cause the flake8 linter to do nothing.
    # In this situtation, the linter will return an empty list.

    doc = Document('', workspace, DOC)
    diags = flake8_lint.pyls_lint(config, doc)
    assert 'Error' in diags[0]['message']
コード例 #24
0
def test_jedi_completion_environment(config):
    # Content of doc to test completion
    doc_content = '''import logh
'''
    doc = Document(DOC_URI, MockWorkspace(), doc_content)

    # After 'import logh' with default environment
    com_position = {'line': 0, 'character': 11}

    assert os.path.isdir('/tmp/pyenv/')

    config.update({'plugins': {'jedi': {'environment': None}}})
    doc.update_config(config)
    completions = pyls_jedi_completions(config, doc, com_position)
    assert completions is None

    # Update config extra environment
    env_path = '/tmp/pyenv/bin/python'
    config.update({'plugins': {'jedi': {'environment': env_path}}})
    doc.update_config(config)

    # After 'import logh' with new environment
    completions = pyls_jedi_completions(config, doc, com_position)
    assert completions[0]['label'] == 'loghub'
    assert 'changelog generator' in completions[0]['documentation'].lower()
コード例 #25
0
def test_jedi_completion_extra_paths(config, tmpdir, workspace):
    # Create a tempfile with some content and pass to extra_paths
    temp_doc_content = '''
def spam():
    pass
'''
    p = tmpdir.mkdir("extra_path")
    extra_paths = [str(p)]
    p = p.join("foo.py")
    p.write(temp_doc_content)

    # Content of doc to test completion
    doc_content = """import foo
foo.s"""
    doc = Document(DOC_URI, workspace, doc_content)

    # After 'foo.s' without extra paths
    com_position = {'line': 1, 'character': 5}
    completions = pyls_jedi_completions(config, doc, com_position)
    assert completions is None

    # Update config extra paths
    config.update({'plugins': {'jedi': {'extra_paths': extra_paths}}})
    doc.update_config(config)

    # After 'foo.s' with extra paths
    com_position = {'line': 1, 'character': 5}
    completions = pyls_jedi_completions(config, doc, com_position)
    assert completions[0]['label'] == 'spam()'
コード例 #26
0
def test_multistatement_snippet(config, workspace):
    config.capabilities['textDocument'] = {
        'completion': {'completionItem': {'snippetSupport': True}}}
    config.update({'plugins': {'jedi_completion': {'include_params': True}}})

    document = 'a = 1; from datetime import date'
    doc = Document(DOC_URI, workspace, document)
    position = {'line': 0, 'character': len(document)}
    completions = pyls_jedi_completions(config, doc, position)
    assert completions[0]['insertText'] == 'date'

    document = 'from datetime import date; a = date'
    doc = Document(DOC_URI, workspace, document)
    position = {'line': 0, 'character': len(document)}
    completions = pyls_jedi_completions(config, doc, position)
    assert completions[0]['insertText'] == 'date(${1:year}, ${2:month}, ${3:day})$0'
コード例 #27
0
def temp_document(doc_text):
    temp_file = tempfile.NamedTemporaryFile(mode='w', delete=False)
    name = temp_file.name
    temp_file.write(doc_text)
    temp_file.close()
    doc = Document(uris.from_fs_path(name), MockWorkspace())

    return name, doc
コード例 #28
0
def test_completion():
    # Over 'r' in sys.stdin.read()
    com_position = {'line': 1, 'character': 17}
    doc = Document(DOC_URI, DOC)
    items = pyls_completions(doc, com_position)

    assert len(items) > 0
    assert items[0]['label'] == 'read'
コード例 #29
0
def test_matplotlib_completions(config, workspace):
    doc_mpl = "import matplotlib.pyplot as plt; plt."
    com_position = {'line': 0, 'character': len(doc_mpl)}
    doc = Document(DOC_URI, workspace, doc_mpl)
    items = pyls_jedi_completions(config, doc, com_position)

    assert items
    assert any(['plot' in i['label'] for i in items])
コード例 #30
0
def test_pandas_completions(config, workspace):
    doc_pandas = "import pandas as pd; pd."
    com_position = {'line': 0, 'character': len(doc_pandas)}
    doc = Document(DOC_URI, workspace, doc_pandas)
    items = pyls_jedi_completions(config, doc, com_position)

    assert items
    assert any(['DataFrame' in i['label'] for i in items])