def send_signal(self, input, value, *args, widget=None, wait=-1): """ Send signal to widget by calling appropriate triggers. Parameters ---------- input_name : str value : Object id : int channel id, used for inputs with flag Multiple widget : Optional[OWWidget] widget to send signal to. If not set, self.widget is used wait : int The amount of time to wait for the widget to complete. """ if widget is None: widget = self.widget if isinstance(input, str): for input_signal in widget.get_signals("inputs"): if input_signal.name == input: input = input_signal break else: raise ValueError( "'{}' is not an input name for widget {}".format( input, type(widget).__name__)) if widget.isBlocking(): raise RuntimeError("'send_signal' called but the widget is in " "blocking state and does not accept inputs.") getattr(widget, input.handler)(value, *args) widget.handleNewSignals() if wait >= 0 and widget.isBlocking(): spy = QSignalSpy(widget.blockingStateChanged) self.assertTrue(spy.wait(timeout=wait))
def test(self): workflow = self.scheme sm = TestingSignalManager() sm.set_workflow(workflow) sm.set_workflow(workflow) sm.set_workflow(None) sm.set_workflow(workflow) sm.start() self.assertFalse(sm.has_pending()) sm.stop() sm.pause() sm.resume() n0, n1, n3 = workflow.nodes sm.send(n0, n0.description.outputs[0], 'hello', None) sm.send(n1, n1.description.outputs[0], 'hello', None) spy = QSignalSpy(sm.processingFinished[SchemeNode]) self.assertTrue(spy.wait()) self.assertSequenceEqual(list(spy), [[n3]]) self.assertEqual(n3.property("-input-left"), 'hello') self.assertEqual(n3.property("-input-right"), 'hello') self.assertFalse(sm.has_pending()) workflow.remove_link(workflow.links[0]) self.assertTrue(sm.has_pending()) spy = QSignalSpy(sm.processingFinished[SchemeNode]) self.assertTrue(spy.wait()) self.assertEqual(n3.property("-input-left"), None) self.assertEqual(n3.property("-input-right"), 'hello')
def get_output(self, output, widget=None, wait=5000): """Return the last output that has been sent from the widget. Parameters ---------- output_name : str widget : Optional[OWWidget] widget whose output is returned. If not set, self.widget is used wait : int The amount of time (in milliseconds) to wait for widget to complete. Returns ------- The last sent value of given output or None if nothing has been sent. """ if widget is None: widget = self.widget if widget.isBlocking() and wait >= 0: spy = QSignalSpy(widget.blockingStateChanged) self.assertTrue(spy.wait(wait), "Failed to get output in the specified timeout") if not isinstance(output, str): output = output.name return self.signal_manager.outputs.get((widget, output), None)
def send_signals(self, signals, *args, widget=None, wait=-1): """ Send signals to widget by calling appropriate triggers. After all the signals are send, widget's handleNewSignals() in invoked. Parameters ---------- signals : list of (str, Object) widget : Optional[OWBaseWidget] widget to send signals to. If not set, self.widget is used wait : int The amount of time to wait for the widget to complete. """ if widget is None: widgets = { signal.widget for signal, _ in signals if hasattr(signal, "widget") } if not widgets: widget = self.widget elif len(widgets) == 1: widget = widgets.pop() else: raise ValueError("Signals are bound to different widgets") for input, value in signals: self._send_signal(widget, input, value, *args) widget.handleNewSignals() if wait >= 0 and widget.isBlocking(): spy = QSignalSpy(widget.blockingStateChanged) self.assertTrue(spy.wait(timeout=wait))
def send_signal(self, input, value, *args, widget=None, wait=-1): """ Send signal to widget by calling appropriate triggers. Parameters ---------- input_name : str value : Object id : int channel id, used for inputs with flag Multiple widget : Optional[OWWidget] widget to send signal to. If not set, self.widget is used wait : int The amount of time to wait for the widget to complete. """ if widget is None: widget = self.widget if isinstance(input, str): for input_signal in widget.get_signals("inputs"): if input_signal.name == input: input = input_signal break else: raise ValueError("'{}' is not an input name for widget {}" .format(input, type(widget).__name__)) if widget.isBlocking(): raise RuntimeError("'send_signal' called but the widget is in " "blocking state and does not accept inputs.") getattr(widget, input.handler)(value, *args) widget.handleNewSignals() if wait >= 0 and widget.isBlocking(): spy = QSignalSpy(widget.blockingStateChanged) self.assertTrue(spy.wait(timeout=wait))
def test_datasets(self, timeout=DEFAULT_TIMEOUT): """Test widget for datasets with missing values and constant features""" for ds in datasets.datasets(): self.send_signal(self.widget.Inputs.data, ds) if self.widget.isBlocking(): spy = QSignalSpy(self.widget.blockingStateChanged) self.assertTrue(spy.wait(timeout))
def test_subset_data(self, timeout=DEFAULT_TIMEOUT): """Test widget for subset data""" self.send_signal(self.widget.Inputs.data, self.data) if self.widget.isBlocking(): spy = QSignalSpy(self.widget.blockingStateChanged) self.assertTrue(spy.wait(timeout)) self.send_signal(self.widget.Inputs.data_subset, self.data[::10])
def test_copy_paste(self): w = self.w workflow = self.setup_test_workflow() w.setRegistry(self.reg) w.setScheme(workflow) w.selectAll() nnodes, nlinks = len(workflow.nodes), len(workflow.links) ca = action_by_name(w.actions(), "copy-action") cp = action_by_name(w.actions(), "paste-action") cb = QApplication.clipboard() spy = QSignalSpy(cb.dataChanged) ca.trigger() if not len(spy): self.assertTrue(spy.wait()) self.assertEqual(len(spy), 1) cp.trigger() self.assertEqual(len(workflow.nodes), 2 * nnodes) self.assertEqual(len(workflow.links), 2 * nlinks) w1 = SchemeEditWidget() w1.setRegistry(self.reg) w1.setScheme((Scheme())) cp = action_by_name(w1.actions(), "paste-action") self.assertTrue(cp.isEnabled()) cp.trigger() wf1 = w1.scheme() self.assertEqual(len(wf1.nodes), nnodes) self.assertEqual(len(wf1.links), nlinks)
def get_output(self, output, widget=None, wait=5000): """Return the last output that has been sent from the widget. Parameters ---------- output_name : str widget : Optional[OWWidget] widget whose output is returned. If not set, self.widget is used wait : int The amount of time (in milliseconds) to wait for widget to complete. Returns ------- The last sent value of given output or None if nothing has been sent. """ if widget is None: widget = self.widget if widget.isBlocking() and wait >= 0: spy = QSignalSpy(widget.blockingStateChanged) self.assertTrue(spy.wait(wait), "Failed to get output in the specified timeout") if not isinstance(output, str): output = output.name # widget.outputs are old-style signals; if empty, use new style outputs = widget.outputs or widget.Outputs.__dict__.values() assert output in (out.name for out in outputs), \ "widget {} has no output {}".format(widget.name, output) return self.signal_manager.outputs.get((widget, output), None)
def get_output(self, output, widget=None, wait=DEFAULT_TIMEOUT): """Return the last output that has been sent from the widget. Parameters ---------- output_name : str widget : Optional[OWBaseWidget] widget whose output is returned. If not set, self.widget is used wait : int The amount of time (in milliseconds) to wait for widget to complete. Returns ------- The last sent value of given output or None if nothing has been sent. """ if widget is None: widget = self.widget if widget.isBlocking() and wait >= 0: spy = QSignalSpy(widget.blockingStateChanged) self.assertTrue(spy.wait(wait), "Failed to get output in the specified timeout") if not isinstance(output, str): output = output.name # widget.outputs are old-style signals; if empty, use new style outputs = widget.outputs or widget.Outputs.__dict__.values() assert output in (out.name for out in outputs), \ "widget {} has no output {}".format(widget.name, output) return widget.signalManager.outputs.get((widget, output), None)
def test_selection(self): w = HeatmapGridWidget() self.scene.addItem(w) w.setHeatmaps(self._Data["2-2"]) view = self.view w.resize(w.effectiveSizeHint(Qt.PreferredSize)) h = w.layout().itemAt(w.Row0, w.Col0 + 1) pos = view.mapFromScene(h.scenePos()) spy = QSignalSpy(w.selectionFinished) QTest.mouseClick( view.viewport(), Qt.LeftButton, pos=pos + QPoint(1, 1) ) self.assertSequenceEqual(list(spy), [[]]) self.assertSequenceEqual(w.selectedRows(), [0]) spy = QSignalSpy(w.selectionFinished) QTest.mouseClick( view.viewport(), Qt.LeftButton, Qt.ControlModifier, pos=pos + QPoint(1, 1) ) self.assertSequenceEqual(list(spy), [[]]) self.assertSequenceEqual(w.selectedRows(), []) spy = QSignalSpy(w.selectionFinished) QTest.mousePress(view.viewport(), Qt.LeftButton, pos=pos + QPoint(1, 1)) mouseMove(view.viewport(), Qt.LeftButton, pos=pos + QPoint(20, 20)) QTest.mouseRelease(view.viewport(), Qt.LeftButton, pos=pos + QPoint(30, 40)) self.assertSequenceEqual(list(spy), [[]]) spy_fin = QSignalSpy(w.selectionFinished) spy_chn = QSignalSpy(w.selectionChanged) w.selectRows([1]) self.assertSequenceEqual(list(spy_fin), []) self.assertSequenceEqual(list(spy_chn), [[]])
def test_options_widget(self): w = textimport.CSVOptionsWidget() schanged = QSignalSpy(w.optionsChanged) sedited = QSignalSpy(w.optionsEdited) w.setDialect(csv.excel()) self.assertEqual(len(schanged), 1) self.assertEqual(len(sedited), 0) w.setSelectedEncoding("iso8859-1") self.assertEqual(len(schanged), 2) self.assertEqual(len(sedited), 0) d = w.dialect() self.assertEqual(d.delimiter, csv.excel.delimiter) self.assertEqual(d.doublequote, csv.excel.doublequote) self.assertEqual(w.encoding(), "iso8859-1") d = textimport.Dialect("a", "b", "c", True, True) w.setDialect(d) cb = w.findChild(QComboBox, "delimiter-combo-box") self.assertEqual(cb.currentIndex(), textimport.CSVOptionsWidget.DelimiterOther) le = w.findChild(QWidget, "custom-delimiter-edit") self.assertEqual(le.text(), "a") cb = w.findChild(QWidget, "quote-edit-combo-box") self.assertEqual(cb.currentText(), "b") d1 = w.dialect() self.assertEqual(d.delimiter, d1.delimiter) self.assertEqual(d.quotechar, d1.quotechar)
def test_setup_graph(self, timeout=DEFAULT_TIMEOUT): """Plot should exist after data has been sent in order to be properly set/updated""" self.send_signal(self.widget.Inputs.data, self.data) if self.widget.isBlocking(): spy = QSignalSpy(self.widget.blockingStateChanged) self.assertTrue(spy.wait(timeout)) self.assertIsNotNone(self.widget.graph.scatterplot_item)
def _startandwait(self, widget): spy = QSignalSpy(widget.blockingStateChanged) widget.start() assert len(spy) assert spy[-1] == [True] assert spy.wait(5000) assert spy[-1] == [False] self.assertFalse(widget.isBlocking())
def wait_for_finished( self, widget: 'OWBaseWidget', timeout=DEFAULT_TIMEOUT) -> bool: monitor = _FinishedMonitor(widget) if monitor.is_finished(): return True else: spy = QSignalSpy(monitor.finished) return spy.wait(timeout)
def spies(w): return SimpleNamespace( done=QSignalSpy(w.done), finished=QSignalSpy(w.finished), result=QSignalSpy(w.resultReady), error=QSignalSpy(w.exceptionReady), cancelled=QSignalSpy(w.cancelled), )
def test_class_density(self, timeout=DEFAULT_TIMEOUT): """Check class density update""" self.send_signal(self.widget.Inputs.data, self.data) self.widget.cb_class_density.click() if self.widget.isBlocking(): spy = QSignalSpy(self.widget.blockingStateChanged) self.assertTrue(spy.wait(timeout)) self.send_signal(self.widget.Inputs.data, None) self.widget.cb_class_density.click()
def test_old_style_input(self): model, widgets = create_workflow() show_node = model.new_node(widget_description(OldStyleShow)) show = model.widget_for_node(show_node) model.new_link(widgets.w1_node, "X", show_node, "X") widgets.w1.Outputs.out.send(1) spy = QSignalSpy(show_node.state_changed) spy.wait() self.assertEqual(show.x, 1)
def test_send_report(self, timeout=DEFAULT_TIMEOUT): """Test report """ self.send_signal(self.widget.Inputs.data, self.data) self.widget.report_button.click() if self.widget.isBlocking(): spy = QSignalSpy(self.widget.blockingStateChanged) self.assertTrue(spy.wait(timeout)) self.send_signal(self.widget.Inputs.data, None) self.widget.report_button.click()
def test_overlap(self): self.send_signal(self.signal_name, self.signal_data) if self.widget.isBlocking(): spy = QSignalSpy(self.widget.blockingStateChanged) self.assertTrue(spy.wait(5000)) self.assertEqual(len(set(self.widget.graph.get_sizes())), 1) simulate.combobox_activate_item(self.widget.controls.attr_size, OWPlotGUI.SizeByOverlap) self.assertEqual(len(set(self.widget.graph.get_sizes())), 1)
def test_highlighting(self): self.send_signal(self.widget.Inputs.corpus, self.corpus) self.widget.regexp_filter = "graph" self.process_events() self.widget.doc_webview.html() spy = QSignalSpy(self.widget.doc_webview.loadFinished) spy.wait() html = self.widget.doc_webview.html() self.assertIn('<mark data-markjs="true">', html)
def test_attr_label_metas(self, timeout=DEFAULT_TIMEOUT): """Set 'Label' from string meta attribute""" data = Table("zoo") self.send_signal(self.widget.Inputs.data, data) if self.widget.isBlocking(): spy = QSignalSpy(self.widget.blockingStateChanged) self.assertTrue(spy.wait(timeout)) simulate.combobox_activate_item(self.widget.controls.attr_label, data.domain[-1].name)
def test_sparse_data(self, timeout=DEFAULT_TIMEOUT): """Test widget for sparse data""" table = Table("iris").to_sparse() self.assertTrue(sp.issparse(table.X)) self.send_signal(self.widget.Inputs.data, table) if self.widget.isBlocking(): spy = QSignalSpy(self.widget.blockingStateChanged) self.assertTrue(spy.wait(timeout)) self.send_signal(self.widget.Inputs.data_subset, table[::30]) self.assertEqual(len(self.widget.subset_data), 5)
def test_attr_label_metas(self, timeout=DEFAULT_TIMEOUT): """Set 'Label' from string meta attribute""" cont = Continuize(multinomial_treatment=Continuize.AsOrdinal) data = cont(Table("zoo")) self.send_signal(self.widget.Inputs.data, data) if self.widget.isBlocking(): spy = QSignalSpy(self.widget.blockingStateChanged) self.assertTrue(spy.wait(timeout)) simulate.combobox_activate_item(self.widget.controls.attr_label, data.domain[-1].name)
def test_qinvoke_as_decorator(self): context = QObject() @qinvoke(context=context) def f(name): context.setObjectName(name) spy = QSignalSpy(context.objectNameChanged) f("name") self.assertTrue(spy.wait(500))
def test_init(self): if self.widget.isBlocking(): spy = QSignalSpy(self.widget.blockingStateChanged) assert spy.wait(1000) self.assertFalse(self.widget.isBlocking()) model = self.widget.view.model() self.assertEqual(model.rowCount(), 3) di = self.widget.selected_dataset() self.assertEqual((di.prefix, di.filename), ("a", "c"))
def test_create_immediate(self): wm = TestingWidgetManager() wm.set_creation_policy(TestingWidgetManager.Immediate) spy = QSignalSpy(wm.widget_for_node_added) wm.set_workflow(self.scheme) nodes = self.scheme.nodes self.assertEqual(len(spy), 3) self.assertSetEqual({n for n, _ in spy}, set(nodes)) spy = QSignalSpy(wm.widget_for_node_removed) self.scheme.clear() self.assertEqual(len(spy), 3) self.assertSetEqual({n for n, _ in spy}, set(nodes))
def test_webview(self): self.send_signal(self.widget.Inputs.corpus, self.corpus) self.send_signal(self.widget.Inputs.words, self.words) self.wait_until_finished() self.process_events() spy = QSignalSpy(self.widget._web_view.loadFinished) spy.wait() html = self.widget._web_view.html() text = "Human machine interface for lab abc computer applications" self.assertIn(text, html) self.assertIn(f'<mark data-markjs="true">{text}', html)
def test_default_attrs(self, timeout=DEFAULT_TIMEOUT): """Check default values for 'Color', 'Shape', 'Size' and 'Label'""" self.send_signal(self.widget.Inputs.data, self.data) self.assertIs(self.widget.attr_color, self.data.domain.class_var) self.assertIsNone(self.widget.attr_label) self.assertIsNone(self.widget.attr_shape) self.assertIsNone(self.widget.attr_size) if self.widget.isBlocking(): spy = QSignalSpy(self.widget.blockingStateChanged) self.assertTrue(spy.wait(timeout)) self.send_signal(self.widget.Inputs.data, None) self.assertIsNone(self.widget.attr_color)
def test_insert_node_on_link(self): w = self.w workflow = self.setup_test_workflow(w.scheme()) neg = SchemeNode(self.reg.widget("negate")) target = workflow.links[0] spyrem = QSignalSpy(workflow.link_removed) spyadd = QSignalSpy(workflow.link_added) w.insertNode(neg, target) self.assertEqual(workflow.nodes[-1], neg) self.assertSequenceEqual(list(spyrem), [[target]]) self.assertEqual(len(spyadd), 2) w.undoStack().undo()
def test_hidden_effective_variables(self, timeout=DEFAULT_TIMEOUT): hidden_var1 = ContinuousVariable("c1") hidden_var1.attributes["hidden"] = True hidden_var2 = ContinuousVariable("c2") hidden_var2.attributes["hidden"] = True class_vars = [DiscreteVariable("cls", values=["a", "b"])] table = Table(Domain([hidden_var1, hidden_var2], class_vars), np.array([[0., 1.], [2., 3.]]), np.array([[0.], [1.]])) self.send_signal(self.widget.Inputs.data, table) if self.widget.isBlocking(): spy = QSignalSpy(self.widget.blockingStateChanged) self.assertTrue(spy.wait(timeout)) self.send_signal(self.widget.Inputs.data, table)
def test_saved_selection(self, timeout=DEFAULT_TIMEOUT): self.send_signal(self.widget.Inputs.data, self.data) if self.widget.isBlocking(): spy = QSignalSpy(self.widget.blockingStateChanged) self.assertTrue(spy.wait(timeout)) self.widget.graph.select_by_indices(list(range(0, len(self.data), 10))) settings = self.widget.settingsHandler.pack_data(self.widget) w = self.create_widget(self.widget.__class__, stored_settings=settings) self.send_signal(self.widget.Inputs.data, self.data, widget=w) if w.isBlocking(): spy = QSignalSpy(w.blockingStateChanged) self.assertTrue(spy.wait(timeout)) self.assertEqual(np.sum(w.graph.selection), 15) np.testing.assert_equal(self.widget.graph.selection, w.graph.selection)
def test_state_ready(self): model, widgets = create_workflow() sm = model.signal_manager widgets.w1.Outputs.out.send(42) widgets.w2.Outputs.out.send(-42) widgets.add.setReady(False) self.assertFalse(sm.is_ready(widgets.add_node)) spy = QSignalSpy(sm.processingStarted[SchemeNode]) sm.process_next() self.assertEqual(len(spy), 0) # must not have processed the node widgets.add.setReady(True) self.assertTrue(sm.is_ready(widgets.add_node)) assert spy.wait() self.assertSequenceEqual(spy, [[widgets.add_node]])
def test_sparse_data(self, timeout=DEFAULT_TIMEOUT): """Test widget for sparse data""" # scipy.sparse uses matrix; this filter can be removed when it stops warnings.filterwarnings( "ignore", ".*the matrix subclass.*", PendingDeprecationWarning) table = Table("iris").to_sparse() self.assertTrue(sp.issparse(table.X)) self.send_signal(self.widget.Inputs.data, table) if self.widget.isBlocking(): spy = QSignalSpy(self.widget.blockingStateChanged) self.assertTrue(spy.wait(timeout)) self.send_signal(self.widget.Inputs.data_subset, table[::30]) self.assertEqual(len(self.widget.subset_data), 5)
def test_subset_data_color(self, timeout=DEFAULT_TIMEOUT): self.send_signal(self.widget.Inputs.data, self.data) if self.widget.isBlocking(): spy = QSignalSpy(self.widget.blockingStateChanged) self.assertTrue(spy.wait(timeout)) self.send_signal(self.widget.Inputs.data_subset, self.data[:10]) subset = [brush.color().name() == "#46befa" for brush in self.widget.graph.scatterplot_item.data['brush'][:10]] other = [brush.color().name() == "#000000" for brush in self.widget.graph.scatterplot_item.data['brush'][10:]] self.assertTrue(all(subset)) self.assertTrue(all(other))
def test_sparse_data(self, timeout=DEFAULT_TIMEOUT): """Test widget for sparse data""" # scipy.sparse uses matrix; this filter can be removed when it stops warnings.filterwarnings("ignore", ".*the matrix subclass.*", PendingDeprecationWarning) table = Table("iris").to_sparse() self.assertTrue(sp.issparse(table.X)) self.send_signal(self.widget.Inputs.data, table) if self.widget.isBlocking(): spy = QSignalSpy(self.widget.blockingStateChanged) self.assertTrue(spy.wait(timeout)) self.send_signal(self.widget.Inputs.data_subset, table[::30]) self.assertEqual(len(self.widget.subset_data), 5)
def test_output_preprocessor(self): self.reset_tsne() self.send_signal(self.widget.Inputs.data, self.data) if self.widget.isBlocking(): spy = QSignalSpy(self.widget.blockingStateChanged) self.assertTrue(spy.wait(20000)) pp = self.get_output(self.widget.Outputs.preprocessor) self.assertIsInstance(pp, Preprocess) transformed = pp(self.data) self.assertIsInstance(transformed, Table) self.assertEqual(transformed.X.shape, (len(self.data), 2)) output = self.get_output(self.widget.Outputs.annotated_data) np.testing.assert_allclose(transformed.X, output.metas[:, :2], rtol=1, atol=1) self.assertEqual([a.name for a in transformed.domain.attributes], [m.name for m in output.domain.metas[:2]])
def test_invalidated_embedding(self): self.widget.graph.update_coordinates = unittest.mock.Mock() self.widget.graph.update_point_props = unittest.mock.Mock() self.send_signal(self.widget.Inputs.data, self.data) self.widget.graph.update_coordinates.assert_called_once() self.widget.graph.update_point_props.assert_called_once() if self.widget.isBlocking(): spy = QSignalSpy(self.widget.blockingStateChanged) self.assertTrue(spy.wait(5000)) self.widget.graph.update_coordinates.reset_mock() self.widget.graph.update_point_props.reset_mock() self.send_signal(self.widget.Inputs.data, self.data) self.widget.graph.update_coordinates.assert_not_called() self.widget.graph.update_point_props.assert_called_once()
def test_plot_once(self, timeout=DEFAULT_TIMEOUT): """Test if data is plotted only once but committed on every input change""" table = Table("heart_disease") self.widget.setup_plot = Mock() self.widget.commit = Mock() self.send_signal(self.widget.Inputs.data, table) self.widget.setup_plot.assert_called_once() self.widget.commit.assert_called_once() if self.widget.isBlocking(): spy = QSignalSpy(self.widget.blockingStateChanged) self.assertTrue(spy.wait(timeout)) self.widget.commit.reset_mock() self.send_signal(self.widget.Inputs.data_subset, table[::10]) self.widget.setup_plot.assert_called_once() self.widget.commit.assert_called_once()
def wait_until_stop_blocking(self, widget=None, wait=DEFAULT_TIMEOUT): """Wait until the widget stops blocking i.e. finishes computation. Parameters ---------- widget : Optional[OWWidget] widget to send signal to. If not set, self.widget is used wait : int The amount of time to wait for the widget to complete. """ if widget is None: widget = self.widget if widget.isBlocking(): spy = QSignalSpy(widget.blockingStateChanged) self.assertTrue(spy.wait(timeout=wait))
def test_invalidated_embedding(self, timeout=DEFAULT_TIMEOUT): """Check if graph has been replotted when sending same data""" self.widget.graph.update_coordinates = Mock() self.widget.graph.update_point_props = Mock() self.send_signal(self.widget.Inputs.data, self.data) self.widget.graph.update_coordinates.assert_called_once() self.widget.graph.update_point_props.assert_called_once() if self.widget.isBlocking(): spy = QSignalSpy(self.widget.blockingStateChanged) self.assertTrue(spy.wait(timeout)) self.widget.graph.update_coordinates.reset_mock() self.widget.graph.update_point_props.reset_mock() self.send_signal(self.widget.Inputs.data, self.data) self.widget.graph.update_coordinates.assert_not_called() self.widget.graph.update_point_props.assert_called_once()
def send_signals(self, signals, *args, widget=None, wait=-1): """ Send signals to widget by calling appropriate triggers. After all the signals are send, widget's handleNewSignals() in invoked. Parameters ---------- signals : list of (str, Object) widget : Optional[OWWidget] widget to send signals to. If not set, self.widget is used wait : int The amount of time to wait for the widget to complete. """ if widget is None: widget = self.widget for input, value in signals: self._send_signal(widget, input, value, *args) widget.handleNewSignals() if wait >= 0 and widget.isBlocking(): spy = QSignalSpy(widget.blockingStateChanged) self.assertTrue(spy.wait(timeout=wait))
def test_outputs(self, timeout=DEFAULT_TIMEOUT): self.send_signal(self.signal_name, self.signal_data) if self.widget.isBlocking(): spy = QSignalSpy(self.widget.blockingStateChanged) self.assertTrue(spy.wait(timeout)) # check selected data output self.assertIsNone(self.get_output("Selected Data")) # check annotated data output feature_name = ANNOTATED_DATA_FEATURE_NAME annotated = self.get_output(ANNOTATED_DATA_SIGNAL_NAME) self.assertEqual(0, np.sum([i[feature_name] for i in annotated])) # select data instances selected_indices = self._select_data() # check selected data output selected = self.get_output("Selected Data") n_sel, n_attr = len(selected), len(self.data.domain.attributes) self.assertGreater(n_sel, 0) self.assertEqual(selected.domain == self.data.domain, self.same_input_output_domain) np.testing.assert_array_equal(selected.X[:, :n_attr], self.data.X[selected_indices]) self.assertEqual(selected.attributes, self.data.attributes) # check annotated data output annotated = self.get_output(ANNOTATED_DATA_SIGNAL_NAME) self.assertEqual(n_sel, np.sum([i[feature_name] for i in annotated])) self.assertEqual(annotated.attributes, self.data.attributes) # compare selected and annotated data domains self._compare_selected_annotated_domains(selected, annotated) # check output when data is removed self.send_signal(self.signal_name, None) self.assertIsNone(self.get_output("Selected Data")) self.assertIsNone(self.get_output(ANNOTATED_DATA_SIGNAL_NAME))
def test_discrete_editor_add_remove_action(self): w = DiscreteVariableEditor() v = Categorical("C", ("a", "b", "c"), (("A", "1"), ("B", "b"))) w.set_data(v) action_add = w.add_new_item action_remove = w.remove_item view = w.values_edit model, selection = view.model(), view.selectionModel() selection.clear() action_add.trigger() self.assertTrue(view.state() == view.EditingState) editor = view.focusWidget() assert isinstance(editor, QLineEdit) spy = QSignalSpy(model.dataChanged) QTest.keyClick(editor, Qt.Key_D) QTest.keyClick(editor, Qt.Key_Return) self.assertTrue(model.rowCount() == 4) # The commit to model is executed via a queued invoke self.assertTrue(bool(spy) or spy.wait()) self.assertEqual(model.index(3, 0).data(Qt.EditRole), "d") # remove it spy = QSignalSpy(model.rowsRemoved) action_remove.trigger() self.assertEqual(model.rowCount(), 3) self.assertEqual(len(spy), 1) _, first, last = spy[0] self.assertEqual((first, last), (3, 3)) # remove/drop and existing value selection.select(model.index(1, 0), QItemSelectionModel.ClearAndSelect) removespy = QSignalSpy(model.rowsRemoved) changedspy = QSignalSpy(model.dataChanged) action_remove.trigger() self.assertEqual(len(removespy), 0, "Should only mark item as removed") self.assertGreaterEqual(len(changedspy), 1, "Did not change data") w.grab()
def test_size_animation(self): begin_resizing = QSignalSpy(self.graph.begin_resizing) step_resizing = QSignalSpy(self.graph.step_resizing) end_resizing = QSignalSpy(self.graph.end_resizing) self._update_sizes_for_points(5) # first end_resizing is triggered in reset, thus wait for step_resizing step_resizing.wait(200) end_resizing.wait(200) self.assertEqual(len(begin_resizing), 2) # reset and update self.assertEqual(len(step_resizing), 5) self.assertEqual(len(end_resizing), 2) # reset and update self.assertEqual(self.graph.scatterplot_item.setSize.call_count, 6) self._update_sizes_for_points(6) self.graph.scatterplot_item.setSize.assert_called_once()