def wrapper(qtbot_module, request): # Activate pycodestyle and pydocstyle CONF.set('lsp-server', 'pycodestyle', True) CONF.set('lsp-server', 'pydocstyle', True) CONF.set('lsp-server', 'stdio', is_stdio) # Create the manager os.environ['SPY_TEST_USE_INTROSPECTION'] = 'True' manager = LanguageServerPlugin(parent=MainWindowMock()) # Wait for the client to be started editor = manager.main.editor with qtbot_module.waitSignal(editor.sig_lsp_initialized, timeout=30000): manager.start_client('python') capabilities = editor.completion_capabilities['python'] assert all( [option in SERVER_CAPABILITES for option in capabilities.keys()]) def teardown(): manager.shutdown() os.environ['SPY_TEST_USE_INTROSPECTION'] = 'False' CONF.set('lsp-server', 'pycodestyle', False) CONF.set('lsp-server', 'pydocstyle', False) request.addfinalizer(teardown) return manager
def test_document_range_formatting(formatter, completions_codeeditor, qtbot): """Validate text range autoformatting.""" code_editor, completion_plugin = completions_codeeditor text, expected = get_formatter_values(formatter, range_fmt=True) # After this call the manager needs to be reinitialized CONF.set('completions', ('provider_configuration', 'lsp', 'values','formatting'), formatter) completion_plugin.after_configuration_update([]) qtbot.wait(2000) # Set text in editor code_editor.set_text(text) # Notify changes with qtbot.waitSignal( code_editor.completions_response_signal, timeout=30000): code_editor.document_did_change() # Select region to format code_editor.go_to_line(12) cursor = code_editor.textCursor() start = code_editor.get_position_line_number(11, -1) end = code_editor.get_position_line_number(27, 0) cursor.setPosition(start) cursor.setPosition(end, QTextCursor.KeepAnchor) cursor.movePosition(QTextCursor.EndOfBlock, QTextCursor.KeepAnchor) code_editor.setTextCursor(cursor) # Perform formatting with qtbot.waitSignal( code_editor.completions_response_signal, timeout=30000): code_editor.format_document_range() # Wait to text to be formatted qtbot.wait(2000) assert code_editor.toPlainText() == expected
def test_space_cmd_in_vline(vim_bot, text, cmd_list, cursor_pos, sel_pos): """Test space command in vline.""" _, _, editor, vim, qtbot = vim_bot CONF.set(CONF_SECTION, 'leader_key', 'F1') vim.apply_plugin_settings("") editor.set_text(text) cmd_line = vim.get_focus_widget() for cmd in cmd_list: if isinstance(cmd, str): qtbot.keyClicks(cmd_line, cmd) else: qtbot.keyPress(cmd_line, cmd) sel = editor.get_extra_selections("vim_selection")[0] sel_pos_ = [sel.cursor.selectionStart(), sel.cursor.selectionEnd()] assert cmd_line.text() == "" assert editor.textCursor().position() == cursor_pos assert sel_pos_ == sel_pos
def test_ignore_warnings(qtbot, completions_codeeditor_linting): """Test that the editor is ignoring some warnings.""" editor, completion_plugin = completions_codeeditor_linting # Set text in editor editor.set_text(TEXT) CONF.set('completions', ('provider_configuration', 'lsp', 'values', 'pydocstyle/ignore'), 'D100') CONF.set('completions', ('provider_configuration', 'lsp', 'values', 'pycodestyle/ignore'), 'E261') # After this call the manager needs to be reinitialized completion_plugin.after_configuration_update([]) qtbot.wait(2000) # Notify changes with qtbot.waitSignal(editor.completions_response_signal, timeout=30000): editor.document_did_change() # Get current warnings qtbot.wait(2000) warnings = editor.get_current_warnings() expected = [['D103: Missing docstring in public function', 1], ['W293 blank line contains whitespace', 2], ["undefined name 's'", 5], ["undefined name 'undefined_function'", 7], ["W292 no newline at end of file", 7], [ """E305 expected 2 blank lines after class or """ """function definition, found 0""", 7 ]] CONF.set('completions', ('provider_configuration', 'lsp', 'values', 'pydocstyle/ignore'), '') CONF.set('completions', ('provider_configuration', 'lsp', 'values', 'pycodestyle/ignore'), '') completion_plugin.after_configuration_update([]) qtbot.wait(2000) assert warnings == expected
def test_max_line_length(formatter, completions_codeeditor, qtbot): """Validate autoformatting with a different value of max_line_length.""" code_editor, completion_plugin = completions_codeeditor text, expected = get_formatter_values( formatter, newline='\n', max_line=True) max_line_length = 20 # Set formatter and max line length options CONF.set( 'completions', ('provider_configuration', 'lsp', 'values', 'formatting'), formatter ) CONF.set( 'completions', ('provider_configuration', 'lsp', 'values', 'pycodestyle/max_line_length'), max_line_length ) completion_plugin.after_configuration_update([]) qtbot.wait(2000) # Set text in editor code_editor.set_text(text) # Notify changes with qtbot.waitSignal( code_editor.completions_response_signal, timeout=30000): code_editor.document_did_change() # Perform formatting with qtbot.waitSignal( code_editor.completions_response_signal, timeout=30000): code_editor.format_document() # Wait for text to be formatted qtbot.wait(2000) assert code_editor.get_text_with_eol() == expected
def save_figure_as(self, fig, fmt): """Save the figure to a file.""" fext, ffilt = { 'image/png': ('.png', 'PNG (*.png)'), 'image/jpeg': ('.jpg', 'JPEG (*.jpg;*.jpeg;*.jpe;*.jfif)'), 'image/svg+xml': ('.svg', 'SVG (*.svg);;PNG (*.png)') }[fmt] save_dir = CONF.get('plots', 'save_dir', getcwd_or_home()) figname = get_unique_figname(save_dir, 'Figure', fext) self.redirect_stdio.emit(False) fname, fext = getsavefilename(parent=self.parent(), caption='Save Figure', basedir=figname, filters=ffilt, selectedfilter='', options=None) self.redirect_stdio.emit(True) if fname: CONF.set('plots', 'save_dir', osp.dirname(fname)) save_figure_tofile(fig, fmt, fname)
def test_ignore_warnings(qtbot, lsp_codeeditor): """Test that the editor is ignoring some warnings.""" editor, manager = lsp_codeeditor # Set text in editor editor.set_text(TEXT) CONF.set('lsp-server', 'pydocstyle/ignore', 'D100') CONF.set('lsp-server', 'pycodestyle/ignore', 'E261') # After this call the manager needs to be reinitialized manager.update_configuration() if os.environ.get('CI', None) is None and sys.platform == 'darwin': # To be able to run local tests on mac this modification is needed editorstack = manager.main.editor with qtbot.waitSignal(editorstack.sig_lsp_initialized, timeout=30000): manager.start_client('python') with qtbot.waitSignal(editor.lsp_response_signal, timeout=30000): editor.document_did_open() else: qtbot.wait(2000) # Notify changes with qtbot.waitSignal(editor.lsp_response_signal, timeout=30000): editor.document_did_change() # Get current warnings warnings = editor.get_current_warnings() expected = [['D103: Missing docstring in public function', 1], ['W293 blank line contains whitespace', 2], ["undefined name 's'", 5], ["undefined name 'undefined_function'", 7], ["W292 no newline at end of file", 7], [ """E305 expected 2 blank lines after class or """ """function definition, found 0""", 7 ]] CONF.set('lsp-server', 'pydocstyle/ignore', '') CONF.set('lsp-server', 'pycodestyle/ignore', '') manager.update_configuration() qtbot.wait(2000) assert warnings == expected
def set_conf(self, option: ConfigurationKey, value: BasicTypes, section: Optional[str] = None, recursive_notification: bool = True): """ Set an option in the Spyder configuration system. Parameters ---------- option: ConfigurationKey Name/Tuple path of the option to set its value. value: BasicTypes Value to set on the configuration system. section: Optional[str] Section in the configuration system, e.g. `shortcuts`. If None, then the value of `CONF_SECTION` is used. recursive_notification: bool If True, all objects that observe all changes on the configuration section and objects that observe partial tuple paths are notified. For example if the option `opt` of section `sec` changes, then the observers for section `sec` are notified. Likewise, if the option `(a, b, c)` changes, then observers for `(a, b, c)`, `(a, b)` and a are notified as well. """ section = self.CONF_SECTION if section is None else section if section is None: raise AttributeError( 'A SpyderConfigurationAccessor must define a `CONF_SECTION` ' 'class attribute!' ) CONF.set( section, option, value, recursive_notification=recursive_notification )
def test_closing_document_formatting(formatter, completions_editor, qtbot, monkeypatch): """Check that auto-formatting works when closing an usaved file.""" file_path, editorstack, code_editor, completion_plugin = completions_editor text, expected = get_formatter_values(formatter, newline='\n') # Set formatter editorstack.set_format_on_save(True) CONF.set('completions', ('provider_configuration', 'lsp', 'values', 'formatting'), formatter) completion_plugin.after_configuration_update([]) qtbot.wait(2000) # Set text in editor code_editor.set_text(text) # Notify changes with qtbot.waitSignal(code_editor.completions_response_signal, timeout=30000): code_editor.document_did_change() # Perform formatting while closing the file with qtbot.waitSignal(code_editor.completions_response_signal, timeout=30000): monkeypatch.setattr(QMessageBox, 'exec_', classmethod(lambda *args: QMessageBox.Yes)) monkeypatch.setattr(editorstack, 'select_savename', lambda *args: str(file_path)) editorstack.save_dialog_on_tests = True editorstack.close_file() # Load again formatted file and check content code_editor = editorstack.load(str(file_path)).editor assert code_editor.get_text_with_eol() == expected
def test_editor_docstring_delayed_popup(qtbot, editor_auto_docstring, text, expected, key): """Test auto docstring using delayed popup.""" CONF.set('editor', 'docstring_type', 'Numpydoc') editor = editor_auto_docstring editor.set_text(text) cursor = editor.textCursor() cursor.movePosition(QTextCursor.NextBlock) cursor.setPosition(QTextCursor.EndOfLine, QTextCursor.MoveAnchor) editor.setTextCursor(cursor) qtbot.keyPress(editor, Qt.Key_Space) qtbot.keyPress(editor, Qt.Key_Space) qtbot.keyPress(editor, Qt.Key_Space) qtbot.keyPress(editor, Qt.Key_Space) qtbot.keyPress(editor, Qt.Key_QuoteDbl) qtbot.keyPress(editor, Qt.Key_QuoteDbl) qtbot.keyPress(editor, Qt.Key_QuoteDbl) qtbot.wait(1000) qtbot.keyPress(editor.menu_docstring, key) qtbot.wait(1000) assert editor.toPlainText() == expected
def test_get_credentials_from_settings(): b = get_backend() username, remember_me, remember_token = b._get_credentials_from_settings() assert username == '' assert remember_me is False assert remember_token is False CONF.set('main', 'report_error/username', 'user') CONF.set('main', 'report_error/remember_me', True) CONF.set('main', 'report_error/remember_token', True) username, remember_me, remember_token = b._get_credentials_from_settings() assert username == 'user' assert remember_me is True assert remember_token is True
def test_python_interpreter(tmpdir): """Test the validation of the python interpreter.""" # Set a non existing python interpreter interpreter = str(tmpdir.mkdir('interpreter').join('python')) CONF.set('main_interpreter', 'default', False) CONF.set('main_interpreter', 'custom', True) CONF.set('main_interpreter', 'executable', interpreter) # Create a kernel spec kernel_spec = SpyderKernelSpec() # Assert that the python interprerter is the default one assert interpreter not in kernel_spec.argv assert CONF.get('main_interpreter', 'default') assert not CONF.get('main_interpreter', 'custom')
def argv(self): """Command to start kernels""" # Python interpreter used to start kernels if CONF.get('main_interpreter', 'default'): pyexec = get_python_executable() else: # Avoid IPython adding the virtualenv on which Spyder is running # to the kernel sys.path os.environ.pop('VIRTUAL_ENV', None) pyexec = CONF.get('main_interpreter', 'executable') if not is_python_interpreter(pyexec): pyexec = get_python_executable() CONF.set('main_interpreter', 'executable', '') CONF.set('main_interpreter', 'default', True) CONF.set('main_interpreter', 'custom', False) # Part of spyder-ide/spyder#11819 is_different = is_different_interpreter(pyexec) # Fixes spyder-ide/spyder#3427. if os.name == 'nt': dir_pyexec = osp.dirname(pyexec) pyexec_w = osp.join(dir_pyexec, 'pythonw.exe') if osp.isfile(pyexec_w): pyexec = pyexec_w # Command used to start kernels if is_different and is_conda_env(pyexec=pyexec): # If this is a conda environment we need to call an intermediate # activation script to correctly activate the spyder-kernel # If changes are needed on this section make sure you also update # the activation scripts at spyder/plugins/ipythonconsole/scripts/ kernel_cmd = [ get_activation_script(), # This is bundled with Spyder get_conda_activation_script(), get_conda_env_path(pyexec), # Might be external pyexec, '{connection_file}', ] else: kernel_cmd = [ pyexec, '-m', 'spyder_kernels.console', '-f', '{connection_file}' ] logger.info('Kernel command: {}'.format(kernel_cmd)) return kernel_cmd
def test_completions_extra_paths(completions_codeeditor, qtbot, tmpdir): """Exercise code completion when adding extra paths.""" code_editor, completion_plugin = completions_codeeditor completion = code_editor.completion_widget code_editor.toggle_automatic_completions(False) code_editor.toggle_code_snippets(False) # Create a file to use as extra path temp_content = ''' def spam(): pass ''' CONF.set('main', 'spyder_pythonpath', []) completion_plugin.after_configuration_update([]) qtbot.wait(500) qtbot.keyClicks(code_editor, 'import foo') qtbot.keyPress(code_editor, Qt.Key_Enter) qtbot.keyClicks(code_editor, 'foo.s') code_editor.document_did_change() qtbot.keyPress(code_editor, Qt.Key_Tab) qtbot.wait(500) assert code_editor.toPlainText() == 'import foo\nfoo.s' p = tmpdir.mkdir("extra_path") extra_paths = [str(p)] p = p.join("foo.py") p.write(temp_content) # Set extra paths print(extra_paths) CONF.set('main', 'spyder_pythonpath', extra_paths) completion_plugin.after_configuration_update([]) code_editor.document_did_change() qtbot.wait(500) with qtbot.waitSignal(completion.sig_show_completions, timeout=10000) as sig: qtbot.keyPress(code_editor, Qt.Key_Tab) qtbot.keyPress(completion, Qt.Key_Tab) assert "spam()" in [x['label'] for x in sig.args[0]] assert code_editor.toPlainText() == 'import foo\nfoo.spam' # Reset extra paths CONF.set('main', 'spyder_pythonpath', []) completion_plugin.after_configuration_update([]) qtbot.wait(500)
def kite_codeeditor(qtbot_module, request): """ CodeEditor instance with Kite enabled. NOTE: This fixture only works if used with kite installed. If running in the CI, the installation of Kite could be accomplished by spyder/plugins/completion/kite/utils/tests/test_install.py::test_kite_install Any test running with this fixture should run after the installation test mentioned above. """ main = MainWindowWidgetMock() completions = CompletionManager(main, ['kite']) completions.start() completions.start_client('python') completions.language_status['python']['kite'] = True qtbot_module.addWidget(completions) # Create a CodeEditor instance editor = codeeditor_factory() qtbot_module.addWidget(editor) editor.show() # Redirect editor fallback requests to FallbackActor editor.sig_perform_completion_request.connect(completions.send_request) editor.filename = 'test.py' editor.language = 'Python' editor.completions_available = True qtbot_module.wait(2000) def teardown(): completions.shutdown() editor.hide() editor.completion_widget.hide() request.addfinalizer(teardown) kite = completions.get_client('kite') CONF.set('kite', 'show_installation_dialog', False) CONF.set('kite', 'show_onboarding', False) CONF.set('kite', 'call_to_action', False) kite.update_configuration() return editor, kite
def argv(self): """Command to start kernels""" # Python interpreter used to start kernels if CONF.get('main_interpreter', 'default'): pyexec = get_python_executable() else: pyexec = CONF.get('main_interpreter', 'executable') if not is_python_interpreter(pyexec): pyexec = get_python_executable() CONF.set('main_interpreter', 'executable', '') CONF.set('main_interpreter', 'default', True) CONF.set('main_interpreter', 'custom', False) # Part of spyder-ide/spyder#11819 is_different = is_different_interpreter(pyexec) # Command used to start kernels if is_different and is_conda_env(pyexec=pyexec): # If this is a conda environment we need to call an intermediate # activation script to correctly activate the spyder-kernel # If changes are needed on this section make sure you also update # the activation scripts at spyder/plugins/ipythonconsole/scripts/ kernel_cmd = [ get_activation_script(), # This is bundled with Spyder get_conda_activation_script(pyexec), get_conda_env_path(pyexec), # Might be external pyexec, '{connection_file}', ] else: kernel_cmd = [ pyexec, '-m', 'spyder_kernels.console', '-f', '{connection_file}' ] logger.info('Kernel command: {}'.format(kernel_cmd)) return kernel_cmd
def lsp_plugin(qtbot_module, request): # Activate pycodestyle and pydocstyle CONF.set('lsp-server', 'pycodestyle', True) CONF.set('lsp-server', 'pydocstyle', True) CONF.set('lsp-server', 'stdio', False) # Create the manager os.environ['SPY_TEST_USE_INTROSPECTION'] = 'True' main = MainWindowMock() completions = CompletionManager(main, ['lsp']) completions.start() with qtbot_module.waitSignal(main.editor.sig_lsp_initialized, timeout=30000): completions.start_client('python') def teardown(): completions.shutdown() os.environ['SPY_TEST_USE_INTROSPECTION'] = 'False' CONF.set('lsp-server', 'pycodestyle', False) CONF.set('lsp-server', 'pydocstyle', False) request.addfinalizer(teardown) return completions
def set_shortcut(context, name, keystr): """Set keyboard shortcut (key sequence string)""" CONF.set('shortcuts', '%s/%s' % (context, name), keystr)
def clear_all_breakpoints(): CONF.set('run', 'breakpoints', {})
def save_breakpoints(filename, breakpoints): if not osp.isfile(filename): return bp_dict = _load_all_breakpoints() bp_dict[filename] = breakpoints CONF.set('run', 'breakpoints', bp_dict)
def reset_namespace(self, warning=False, message=False): """Reset the namespace by removing all names defined by the user.""" reset_str = _("Remove all variables") warn_str = _("All user-defined variables will be removed. " "Are you sure you want to proceed?") # Don't show the warning when running our tests. if running_under_pytest(): warning = False # This is necessary to make resetting variables work in external # kernels. # See spyder-ide/spyder#9505. try: kernel_env = self.kernel_manager._kernel_spec.env except AttributeError: kernel_env = {} if warning: box = MessageCheckBox(icon=QMessageBox.Warning, parent=self) box.setWindowTitle(reset_str) box.set_checkbox_text(_("Don't show again.")) box.setStandardButtons(QMessageBox.Yes | QMessageBox.No) box.setDefaultButton(QMessageBox.Yes) box.set_checked(False) box.set_check_visible(True) box.setText(warn_str) answer = box.exec_() # Update checkbox based on user interaction CONF.set('ipython_console', 'show_reset_namespace_warning', not box.is_checked()) self.ipyclient.reset_warning = not box.is_checked() if answer != QMessageBox.Yes: return try: if self.is_waiting_pdb_input(): self.dbg_exec_magic('reset', '-f') else: if message: self.reset() self._append_html(_("<br><br>Removing all variables..." "\n<hr>"), before_prompt=False) self.silent_execute("%reset -f") if kernel_env.get('SPY_AUTOLOAD_PYLAB_O') == 'True': self.silent_execute("from pylab import *") if kernel_env.get('SPY_SYMPY_O') == 'True': sympy_init = """ from __future__ import division from sympy import * x, y, z, t = symbols('x y z t') k, m, n = symbols('k m n', integer=True) f, g, h = symbols('f g h', cls=Function) init_printing()""" self.silent_execute(dedent(sympy_init)) if kernel_env.get('SPY_RUN_CYTHON') == 'True': self.silent_execute("%reload_ext Cython") # This doesn't need to interrupt the kernel because # "%reset -f" is being executed before it. # Fixes spyder-ide/spyder#12689 self.refresh_namespacebrowser(interrupt=False) if not self.external_kernel: self.call_kernel().close_all_mpl_figures() except AttributeError: pass
def ipyconsole(qtbot, request): """IPython console fixture.""" class MainWindowMock(QMainWindow): def __getattr__(self, attr): if attr == 'consoles_menu_actions': return [] else: return Mock() # Tests assume inline backend CONF.set('ipython_console', 'pylab/backend', 0) # Start in a new working directory the console use_startup_wdir = request.node.get_closest_marker('use_startup_wdir') if use_startup_wdir: new_wdir = osp.join(os.getcwd(), NEW_DIR) if not osp.exists(new_wdir): os.mkdir(new_wdir) CONF.set('workingdir', 'console/use_fixed_directory', True) CONF.set('workingdir', 'console/fixed_directory', new_wdir) # Test the console with a non-ascii temp dir non_ascii_dir = request.node.get_closest_marker('non_ascii_dir') if non_ascii_dir: test_dir = NON_ASCII_DIR else: test_dir = None # Instruct the console to not use a stderr file no_stderr_file = request.node.get_closest_marker('no_stderr_file') if no_stderr_file: test_no_stderr = True else: test_no_stderr = False # Use the automatic backend if requested auto_backend = request.node.get_closest_marker('auto_backend') if auto_backend: CONF.set('ipython_console', 'pylab/backend', 1) # Start a Pylab client if requested pylab_client = request.node.get_closest_marker('pylab_client') is_pylab = True if pylab_client else False # Start a Sympy client if requested sympy_client = request.node.get_closest_marker('sympy_client') is_sympy = True if sympy_client else False # Start a Cython client if requested cython_client = request.node.get_closest_marker('cython_client') is_cython = True if cython_client else False # Create the console and a new client window = MainWindowMock() console = IPythonConsole(parent=window, testing=True, test_dir=test_dir, test_no_stderr=test_no_stderr) console.dockwidget = Mock() console._toggle_view_action = Mock() console.create_new_client(is_pylab=is_pylab, is_sympy=is_sympy, is_cython=is_cython) window.setCentralWidget(console) # Close callback def close_console(): console.closing_plugin() console.close() request.addfinalizer(close_console) qtbot.addWidget(window) window.show() return console
def save_breakpoints(filename, breakpoints): bp_dict = _load_all_breakpoints() bp_dict[osp.normcase(filename)] = breakpoints CONF.set('run', 'breakpoints', bp_dict)
def test_kite_code_snippets(kite_codeeditor, qtbot): """ Test kite code snippets completions without initial placeholder. See spyder-ide/spyder#10971 """ assert rtree_available code_editor, kite = kite_codeeditor completion = code_editor.completion_widget snippets = code_editor.editor_extensions.get('SnippetsExtension') CONF.set('lsp-server', 'code_snippets', True) CONF.set('kite', 'enable', True) kite.update_configuration() code_editor.toggle_automatic_completions(False) code_editor.toggle_code_snippets(True) # Set cursor to start code_editor.go_to_line(1) text = """ import numpy as np """ text = textwrap.dedent(text) code_editor.insert_text(text) qtbot.keyClicks(code_editor, 'np.sin') with qtbot.waitSignal(completion.sig_show_completions, timeout=10000) as sig: qtbot.keyPress(code_editor, Qt.Key_Tab, delay=300) assert 'sin('+u'\u2026'+')' in { x['label'] for x in sig.args[0]} expected_insert = 'sin($1)$0' insert = sig.args[0][0] assert expected_insert == insert['insertText'] # Insert completion qtbot.keyPress(completion, Qt.Key_Tab) assert snippets.is_snippet_active # Get code selected text cursor = code_editor.textCursor() arg1 = cursor.selectedText() assert '' == arg1 assert snippets.active_snippet == 1 code_editor.set_cursor_position('eol') code_editor.move_cursor(-1) with qtbot.waitSignal(completion.sig_show_completions, timeout=10000) as sig2: qtbot.keyPress(code_editor, Qt.Key_Space, modifier=Qt.ControlModifier, delay=300) assert '<x>)' in {x['label'] for x in sig2.args[0]} expected_insert = '${1:[x]})$0' insert = sig2.args[0][0] assert expected_insert == insert['textEdit']['newText'] qtbot.keyPress(completion, Qt.Key_Tab) # Snippets are disabled when there are no more left code_editor.set_cursor_position('eol') qtbot.keyPress(code_editor, Qt.Key_Enter) assert not snippets.is_snippet_active cursor = code_editor.textCursor() cursor.movePosition(QTextCursor.PreviousBlock) cursor.movePosition(QTextCursor.StartOfBlock) cursor.movePosition(QTextCursor.EndOfBlock, mode=QTextCursor.KeepAnchor) text1 = cursor.selectedText() assert text1 == 'np.sin([x])' CONF.set('lsp-server', 'code_snippets', False) CONF.set('kite', 'enable', False) kite.update_configuration() code_editor.toggle_automatic_completions(True) code_editor.toggle_code_snippets(True)
def test_code_snippets(lsp_codeeditor, qtbot): assert rtree_available code_editor, lsp = lsp_codeeditor completion = code_editor.completion_widget snippets = code_editor.editor_extensions.get('SnippetsExtension') CONF.set('lsp-server', 'code_snippets', True) lsp.update_configuration() code_editor.toggle_automatic_completions(False) code_editor.toggle_code_snippets(True) # Set cursor to start code_editor.go_to_line(1) text = """ def test_func(xlonger, y1, some_z): pass """ text = textwrap.dedent(text) code_editor.insert_text(text) with qtbot.waitSignal(code_editor.lsp_response_signal, timeout=30000): code_editor.document_did_change() qtbot.keyPress(code_editor, Qt.Key_Enter, delay=300) qtbot.keyPress(code_editor, Qt.Key_Enter, delay=300) qtbot.keyClicks(code_editor, 'test_') with qtbot.waitSignal(completion.sig_show_completions, timeout=10000) as sig: qtbot.keyPress(code_editor, Qt.Key_Tab) assert 'test_func(xlonger, y1, some_z)' in { x['label'] for x in sig.args[0]} expected_insert = 'test_func(${1:xlonger}, ${2:y1}, ${3:some_z})$0' insert = sig.args[0][0] assert expected_insert == insert['insertText'] assert snippets.is_snippet_active assert code_editor.has_selected_text() # Rotate through snippet regions cursor = code_editor.textCursor() arg1 = cursor.selectedText() assert 'xlonger' == arg1 assert snippets.active_snippet == 1 qtbot.keyPress(code_editor, Qt.Key_Tab) cursor = code_editor.textCursor() arg2 = cursor.selectedText() assert 'y1' == arg2 assert snippets.active_snippet == 2 qtbot.keyPress(code_editor, Qt.Key_Tab) cursor = code_editor.textCursor() arg2 = cursor.selectedText() assert 'some_z' == arg2 assert snippets.active_snippet == 3 qtbot.keyPress(code_editor, Qt.Key_Tab) assert not snippets.is_snippet_active qtbot.keyPress(code_editor, Qt.Key_Enter, delay=300) qtbot.keyClicks(code_editor, 'test_') with qtbot.waitSignal(completion.sig_show_completions, timeout=10000) as sig: qtbot.keyPress(code_editor, Qt.Key_Tab) # Replace selection qtbot.keyClicks(code_editor, 'arg1') qtbot.wait(5000) # Snippets are disabled when there are no more left for _ in range(0, 3): qtbot.keyPress(code_editor, Qt.Key_Tab) assert not snippets.is_snippet_active cursor = code_editor.textCursor() cursor.movePosition(QTextCursor.StartOfBlock) cursor.movePosition(QTextCursor.EndOfBlock, mode=QTextCursor.KeepAnchor) text1 = cursor.selectedText() assert text1 == 'test_func(arg1, y1, some_z)' qtbot.keyPress(code_editor, Qt.Key_Enter, delay=300) qtbot.keyClicks(code_editor, 'test_') with qtbot.waitSignal(completion.sig_show_completions, timeout=10000) as sig: qtbot.keyPress(code_editor, Qt.Key_Tab) qtbot.keyPress(code_editor, Qt.Key_Tab) assert snippets.active_snippet == 2 # Extend text from right qtbot.keyPress(code_editor, Qt.Key_Right, delay=300) qtbot.keyClicks(code_editor, '_var') qtbot.keyPress(code_editor, Qt.Key_Up, delay=300) qtbot.keyPress(code_editor, Qt.Key_Down, delay=300) cursor = code_editor.textCursor() cursor.movePosition(QTextCursor.StartOfBlock) cursor.movePosition(QTextCursor.EndOfBlock, mode=QTextCursor.KeepAnchor) text1 = cursor.selectedText() assert text1 == 'test_func(xlonger, y1_var, some_z)' cursor.movePosition(QTextCursor.EndOfBlock) code_editor.setTextCursor(cursor) qtbot.keyPress(code_editor, Qt.Key_Enter, delay=300) qtbot.keyClicks(code_editor, 'test_') with qtbot.waitSignal(completion.sig_show_completions, timeout=10000) as sig: qtbot.keyPress(code_editor, Qt.Key_Tab) for _ in range(0, 2): qtbot.keyPress(code_editor, Qt.Key_Tab) assert snippets.active_snippet == 3 # Extend text from left qtbot.keyPress(code_editor, Qt.Key_Left, delay=300) qtbot.keyClicks(code_editor, 's') qtbot.keyPress(code_editor, Qt.Key_Tab) assert not snippets.is_snippet_active cursor = code_editor.textCursor() cursor.movePosition(QTextCursor.StartOfBlock) cursor.movePosition(QTextCursor.EndOfBlock, mode=QTextCursor.KeepAnchor) text1 = cursor.selectedText() assert text1 == 'test_func(xlonger, y1, ssome_z)' qtbot.keyPress(code_editor, Qt.Key_Enter, delay=300) qtbot.keyClicks(code_editor, 'test_') with qtbot.waitSignal(completion.sig_show_completions, timeout=10000) as sig: qtbot.keyPress(code_editor, Qt.Key_Tab) assert snippets.active_snippet == 1 # Delete snippet region qtbot.keyPress(code_editor, Qt.Key_Left, delay=300) qtbot.keyPress(code_editor, Qt.Key_Backspace, delay=300) assert len(snippets.snippets_map) == 3 qtbot.keyPress(code_editor, Qt.Key_Tab) cursor = code_editor.textCursor() arg1 = cursor.selectedText() assert 'some_z' == arg1 # Undo action with qtbot.waitSignal(code_editor.sig_undo, timeout=10000) as sig: code_editor.undo() assert len(snippets.snippets_map) == 4 for _ in range(0, 2): qtbot.keyPress(code_editor, Qt.Key_Tab) cursor = code_editor.textCursor() arg1 = cursor.selectedText() assert 'some_z' == arg1 with qtbot.waitSignal(code_editor.sig_redo, timeout=10000) as sig: code_editor.redo() assert len(snippets.snippets_map) == 3 for _ in range(0, 3): qtbot.keyPress(code_editor, Qt.Key_Tab) qtbot.keyPress(code_editor, Qt.Key_Right) qtbot.keyPress(code_editor, Qt.Key_Enter) qtbot.keyPress(code_editor, Qt.Key_Backspace) qtbot.keyClicks(code_editor, 'test_') with qtbot.waitSignal(completion.sig_show_completions, timeout=10000) as sig: qtbot.keyPress(code_editor, Qt.Key_Tab) # Delete text qtbot.keyPress(code_editor, Qt.Key_Left, delay=300) qtbot.keyPress(code_editor, Qt.Key_Right, delay=300) qtbot.keyPress(code_editor, Qt.Key_Backspace) for _ in range(0, 3): qtbot.keyPress(code_editor, Qt.Key_Tab) cursor = code_editor.textCursor() cursor.movePosition(QTextCursor.StartOfBlock) cursor.movePosition(QTextCursor.EndOfBlock, mode=QTextCursor.KeepAnchor) text1 = cursor.selectedText() assert text1 == 'test_func(longer, y1, some_z)' CONF.set('lsp-server', 'code_snippets', False) lsp.update_configuration() code_editor.toggle_automatic_completions(True) code_editor.toggle_code_snippets(True)
def set_executable_config_helper(executable=None): if executable is None: CONF.set('main_interpreter', 'default', True) CONF.set('main_interpreter', 'custom', False) CONF.set('main_interpreter', 'custom_interpreter', sys.executable) CONF.set('main_interpreter', 'custom_interpreters_list', [sys.executable]) CONF.set('main_interpreter', 'executable', sys.executable) else: CONF.set('main_interpreter', 'default', False) CONF.set('main_interpreter', 'custom', True) CONF.set('main_interpreter', 'custom_interpreter', executable) CONF.set('main_interpreter', 'custom_interpreters_list', [executable]) CONF.set('main_interpreter', 'executable', executable)
def _set_option(self, option, value): """Set option in spyder.ini""" CONF.set(self.CONF_SECTION, str(option), value)
def teardown(): manager.shutdown() os.environ['SPY_TEST_USE_INTROSPECTION'] = 'False' CONF.set('lsp-server', 'pycodestyle', False) CONF.set('lsp-server', 'pydocstyle', False)
def set_option(self, option, value, section=None): section = self.CONF_SECTION if section is None else section CONF.set(section, option, value)
def set_firstrun_o(self): CONF.set('run', ALWAYS_OPEN_FIRST_RUN_OPTION, self.firstrun_cb.isChecked())