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_highlighting_non_latin(self): documents = [{ 'content': """царстве есть сад с молодильными яблоками""" }] metas = [ (StringVariable('content'), lambda doc: doc.get('content')), ] dataset_name = 'RussianDocument' corpus = Corpus.from_documents(documents, dataset_name, metas=metas) self.send_signal(self.widget.Inputs.corpus, corpus) self.widget.regexp_filter = "\\bсад\\b" 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_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 = self.widget.unconditional_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.setup_plot.assert_called_once() self.widget.commit.assert_called_once() 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 test_pending_flags(self): workflow = self.scheme sm = TestingSignalManager() sm.set_workflow(workflow) sm.start() n0, n1, n3 = workflow.nodes[:3] l0, l1 = workflow.links[:2] self.assertFalse(n3.test_state_flags(SchemeNode.Pending)) self.assertFalse(l0.runtime_state() & SchemeLink.Pending) sm.send(n0, n0.description.outputs[0], 'hello') self.assertTrue(n3.test_state_flags(SchemeNode.Pending)) self.assertTrue(l0.runtime_state() & SchemeLink.Pending) spy = QSignalSpy(sm.processingFinished) assert spy.wait() self.assertFalse(n3.test_state_flags(SchemeNode.Pending)) self.assertFalse(l0.runtime_state() & SchemeLink.Pending)
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: 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_table_view_selection_finished(self): model = QStandardItemModel() model.setRowCount(10) model.setColumnCount(4) view = TableView() view.setModel(model) view.adjustSize() spy = QSignalSpy(view.selectionFinished) rect0 = view.visualRect(model.index(0, 0)) rect4 = view.visualRect(model.index(4, 2)) QTest.mousePress( view.viewport(), Qt.LeftButton, Qt.NoModifier, rect0.center(), ) self.assertEqual(len(spy), 0) QTest.mouseRelease( view.viewport(), Qt.LeftButton, Qt.NoModifier, rect4.center(), ) self.assertEqual(len(spy), 1)
def send_signal(self, input, value, *args, widget=None, wait=-1): """ Send signal to widget by calling appropriate triggers. Parameters ---------- input : 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.") handler = getattr(widget, input.handler) # Assert sent input is of correct class assert isinstance(value, (input.type, type(None))), "{} should be {}".format( value.__class__.__mro__, input.type) handler(value, *args) widget.handleNewSignals() if wait >= 0 and widget.isBlocking(): spy = QSignalSpy(widget.blockingStateChanged) self.assertTrue(spy.wait(timeout=wait))
def main(argv=None): from AnyQt.QtWidgets import QApplication logging.basicConfig(level=logging.DEBUG) app = QApplication(list(argv) if argv else []) argv = app.arguments() if len(argv) > 1: filename = argv[1] else: filename = "zoo-with-images" data = Table(filename) widget = OWImageEmbedding() widget.show() assert QSignalSpy(widget.blockingStateChanged).wait() widget.set_data(data) widget.handleNewSignals() app.exec() widget.set_data(None) widget.handleNewSignals() widget.saveSettings() widget.onDeleteWidget() return 0
def test_slider_move(self): w = ColorGradientSelection() w.adjustSize() w.setThresholds(0.5, 0.5) changed = QSignalSpy(w.thresholdsChanged) sl, sh = w.slider_low, w.slider_high sl.triggerAction(sl.SliderToMinimum) self.assertEqual(len(changed), 1) low, high = changed[-1] self.assertLessEqual(low, high) self.assertEqual(low, 0.0) sl.triggerAction(sl.SliderToMaximum) self.assertEqual(len(changed), 2) low, high = changed[-1] self.assertLessEqual(low, high) self.assertEqual(low, 1.0) sh.triggerAction(sl.SliderToMinimum) self.assertEqual(len(changed), 3) low, high = changed[-1] self.assertLessEqual(low, high) self.assertEqual(high, 0.0)
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_rename_selected_items_action(self): w = DiscreteVariableEditor() v = Categorical("C", ("a", "b", "c"), (("A", "1"), ("B", "b")), False) w.set_data_categorical(v, []) action = w.rename_selected_items view = w.values_edit model = view.model() selmodel = view.selectionModel() # type: QItemSelectionModel selmodel.select(QItemSelection(model.index(0, 0), model.index(1, 0)), QItemSelectionModel.ClearAndSelect) # trigger the action, then find the active popup, and simulate entry spy = QSignalSpy(w.variable_changed) with patch.object(QComboBox, "setVisible", return_value=None) as m: action.trigger() m.assert_called() cb = view.findChild(QComboBox) cb.setCurrentText("BA") view.commitData(cb) self.assertEqual(model.index(0, 0).data(Qt.EditRole), "BA") self.assertEqual(model.index(1, 0).data(Qt.EditRole), "BA") self.assertSequenceEqual(list(spy), [[]], 'variable_changed should emit exactly once')
def test_discrete_editor_merge_action(self): w = DiscreteVariableEditor() v = Categorical("C", ("a", "b", "c"), (("A", "1"), ("B", "b"))) w.set_data(v) action = w.merge_items self.assertFalse(action.isEnabled()) view = w.values_edit model = view.model() selmodel = view.selectionModel() # type: QItemSelectionModel selmodel.select(QItemSelection(model.index(0, 0), model.index(1, 0)), QItemSelectionModel.ClearAndSelect) self.assertTrue(action.isEnabled()) # trigger the action, then find the active popup, and simulate entry spy = QSignalSpy(w.variable_changed) w.merge_items.trigger() cb = w.findChild(QComboBox) cb.setCurrentText("BA") cb.activated[str].emit("BA") cb.close() self.assertEqual(model.index(0, 0).data(Qt.EditRole), "BA") self.assertEqual(model.index(1, 0).data(Qt.EditRole), "BA") self.assertSequenceEqual(list(spy), [[]], 'variable_changed should emit exactly once')
def test_selection(self): self.__initialization(self.human_tax_id) panglao, _ = self.marker_genes new_selection = None for item in self.__item_iterator(): if item.hierarchy == panglao: new_selection = item tree_widget: QTreeWidget = self.component.hierarchy_tree_widget # obtain the rectangular coordinates rect = tree_widget.visualItemRect(new_selection) emitted_signals: QSignalSpy = QSignalSpy( self.component.selection_changed) # simulate click on item but not in checkbox area. # checkbox status is not changed and signal is not emitted click_item_text = QPoint(rect.x() + 100, rect.y() + 5) QTest.mouseClick(tree_widget.viewport(), Qt.LeftButton, Qt.NoModifier, click_item_text) self.assertFalse(len(emitted_signals)) self.assertEqual(self.component._get_selection(), self.default_selection) # simulate click on items checkbox. # checkbox status is changed and signal is emitted click_checkbox = QPoint(rect.x() + 10, rect.y() + 5) QTest.mouseClick(tree_widget.viewport(), Qt.LeftButton, Qt.NoModifier, click_checkbox) self.assertTrue(len(emitted_signals)) self.assertNotEqual(self.component._get_selection(), self.default_selection) self.assertEqual( set(self.component._get_selection()), set(self.default_selection + [new_selection.hierarchy]))
def wait_for_image(widget, timeout=5000): spy = QSignalSpy(widget.imageplot.image_updated) assert spy.wait(timeout), "Failed update image in the specified timeout"
def test_schemeedit(self): reg = self.reg w = self.w scheme = Scheme() w.setScheme(scheme) self.assertIs(w.scheme(), scheme) self.assertFalse(w.isModified()) scheme = Scheme() w.setScheme(scheme) self.assertIs(w.scheme(), scheme) self.assertFalse(w.isModified()) w.show() one_desc = reg.widget("one") negate_desc = reg.widget("negate") node_list = [] link_list = [] annot_list = [] scheme.node_added.connect(node_list.append) scheme.node_removed.connect(node_list.remove) scheme.link_added.connect(link_list.append) scheme.link_removed.connect(link_list.remove) scheme.annotation_added.connect(annot_list.append) scheme.annotation_removed.connect(annot_list.remove) node = SchemeNode(one_desc, title="title1", position=(100, 100)) w.addNode(node) self.assertSequenceEqual(node_list, [node]) self.assertSequenceEqual(scheme.nodes, node_list) self.assertTrue(w.isModified()) stack = w.undoStack() stack.undo() self.assertSequenceEqual(node_list, []) self.assertSequenceEqual(scheme.nodes, node_list) self.assertTrue(not w.isModified()) stack.redo() node1 = SchemeNode(negate_desc, title="title2", position=(300, 100)) w.addNode(node1) self.assertSequenceEqual(node_list, [node, node1]) self.assertSequenceEqual(scheme.nodes, node_list) self.assertTrue(w.isModified()) link = SchemeLink(node, "value", node1, "value") w.addLink(link) self.assertSequenceEqual(link_list, [link]) stack.undo() stack.undo() stack.redo() stack.redo() w.removeNode(node1) self.assertSequenceEqual(link_list, []) self.assertSequenceEqual(node_list, [node]) stack.undo() self.assertSequenceEqual(link_list, [link]) self.assertSequenceEqual(node_list, [node, node1]) spy = QSignalSpy(node.title_changed) w.renameNode(node, "foo bar") self.assertSequenceEqual(list(spy), [["foo bar"]]) self.assertTrue(w.isModified()) stack.undo() self.assertSequenceEqual(list(spy), [["foo bar"], ["title1"]]) w.removeLink(link) self.assertSequenceEqual(link_list, []) stack.undo() self.assertSequenceEqual(link_list, [link]) annotation = SchemeTextAnnotation((200, 300, 50, 20), "text") w.addAnnotation(annotation) self.assertSequenceEqual(annot_list, [annotation]) stack.undo() self.assertSequenceEqual(annot_list, []) stack.redo() self.assertSequenceEqual(annot_list, [annotation]) w.removeAnnotation(annotation) self.assertSequenceEqual(annot_list, []) stack.undo() self.assertSequenceEqual(annot_list, [annotation]) self.assertTrue(w.isModified()) self.assertFalse(stack.isClean()) w.setModified(False) self.assertFalse(w.isModified()) self.assertTrue(stack.isClean()) w.setModified(True) self.assertTrue(w.isModified())
def test_path(self): w = self.w spy = QSignalSpy(w.pathChanged) self.w.setPath("/dev/null") self.assertSequenceEqual(list(spy), [["/dev/null"]])
def delete(qobj: QObject): assert qobj.thread() is QThread.currentThread() spy = QSignalSpy(qobj.destroyed) qobj.deleteLater() QCoreApplication.sendPostedEvents(qobj, QEvent.DeferredDelete) assert len(spy) == 1
def test_set_item_signals(self): def p(*s): return [[x] for x in s] def assert_changed(startrow, stoprow, ncolumns): start, stop = changed[-1][:2] self.assertEqual(start.row(), startrow) self.assertEqual(stop.row(), stoprow) self.assertEqual(start.column(), 0) self.assertEqual(stop.column(), ncolumns) self.model.wrap(p(0, 1, 2, 3, 4, 5)) aboutinserted = QSignalSpy(self.model.rowsAboutToBeInserted) inserted = QSignalSpy(self.model.rowsInserted) aboutremoved = QSignalSpy(self.model.rowsAboutToBeRemoved) removed = QSignalSpy(self.model.rowsRemoved) changed = QSignalSpy(self.model.dataChanged) # Insert rows self.model[2:4] = p(6, 7, 8, 9, 10) + [[11, 2]] self.assertEqual(list(self.model), p(0, 1, 6, 7, 8, 9, 10) + [[11, 2]] + p(4, 5)) self.assertEqual(len(changed), 1) assert_changed(2, 3, 1) self.assertEqual(aboutinserted[-1][1:], [4, 7]) self.assertEqual(inserted[-1][1:], [4, 7]) self.assertEqual(len(aboutremoved), 0) self.assertEqual(len(removed), 0) # Remove rows self.model[2:8] = p(2, 3) self.assertEqual(list(self.model), p(0, 1, 2, 3, 4, 5)) self.assertEqual(len(changed), 2) # one is from before assert_changed(2, 3, 0) self.assertEqual(aboutremoved[-1][1:], [4, 7]) self.assertEqual(removed[-1][1:], [4, 7]) self.assertEqual(len(inserted), 1) # from before self.assertEqual(len(aboutinserted), 1) # from before # Change rows self.model[-5:-3] = p(19, 20) self.assertEqual(list(self.model), p(0, 19, 20, 3, 4, 5)) self.assertEqual(len(changed), 3) # two are from before assert_changed(1, 2, 0) self.assertEqual(len(inserted), 1) # from before self.assertEqual(len(aboutinserted), 1) # from before self.assertEqual(len(removed), 1) # from before self.assertEqual(len(aboutremoved), 1) # from before # Insert without change self.model[3:3] = p(21, 22) self.assertEqual(list(self.model), p(0, 19, 20, 21, 22, 3, 4, 5)) self.assertEqual(len(changed), 3) #from before self.assertEqual(inserted[-1][1:], [3, 4]) self.assertEqual(aboutinserted[-1][1:], [3, 4]) self.assertEqual(len(removed), 1) # from before self.assertEqual(len(aboutremoved), 1) # from before # Remove without change self.model[3:5] = [] self.assertEqual(list(self.model), p(0, 19, 20, 3, 4, 5)) self.assertEqual(len(changed), 3) #from before self.assertEqual(removed[-1][1:], [3, 4]) self.assertEqual(aboutremoved[-1][1:], [3, 4]) self.assertEqual(len(inserted), 2) # from before self.assertEqual(len(aboutinserted), 2) # from before # Remove all self.model[:] = [] self.assertEqual(list(self.model), []) self.assertEqual(len(changed), 3) #from before self.assertEqual(removed[-1][1:], [0, 5]) self.assertEqual(aboutremoved[-1][1:], [0, 5]) self.assertEqual(len(inserted), 2) # from before self.assertEqual(len(aboutinserted), 2) # from before # Add to empty self.model[:] = p(0, 1, 2, 3) self.assertEqual(list(self.model), p(0, 1, 2, 3)) self.assertEqual(len(changed), 3) #from before self.assertEqual(inserted[-1][1:], [0, 3]) self.assertEqual(inserted[-1][1:], [0, 3]) self.assertEqual(len(removed), 3) # from before self.assertEqual(len(aboutremoved), 3) # from before
def test_multi_input_filter_none(self): # Test MultiInput.filter_none model, widgets = create_workflow_2() w1, w2, list_ = widgets.w1, widgets.w2, widgets.list_ spy = QSignalSpy(widgets.list_node.state_changed) def check_inputs(expected: list): if widgets.list_node.state() & SchemeNode.Pending: self.assertTrue(spy.wait()) self.assertEqual(list_.inputs, expected) def check_events(expected: list): if widgets.list_node.state() & SchemeNode.Pending: self.assertTrue(spy.wait()) self.assertEqual(expected, list_.events) def reset_events(): list_.events.clear() w1.Outputs.out.send(None) w2.Outputs.out.send(42) check_inputs([42]) check_events([("insert", 0, 42)]) reset_events() w1.Outputs.out.send(None) w2.Outputs.out.send(-42) check_inputs([-42]) check_events([("set", 0, -42)]) reset_events() w1.Outputs.out.send(42) check_inputs([42, -42]) check_events([("insert", 0, 42)]) reset_events() w1.Outputs.out.send(None) check_inputs([-42]) check_events([("remove", 0)]) reset_events() w2.Outputs.out.send(None) check_inputs([]) check_events([("remove", 0)]) reset_events() w2.Outputs.out.send(2) check_inputs([2]) check_events([("insert", 0, 2)]) reset_events() w1.Outputs.out.send(1) check_inputs([1, 2]) check_events([("insert", 0, 1)]), reset_events() w2.Outputs.out.send(None) check_inputs([1]) check_events([("remove", 1)]) reset_events() w2.Outputs.out.send(2) check_inputs([1, 2]) check_events([("insert", 1, 2)]) reset_events() l1 = model.find_links(widgets.w1_node, None, widgets.list_node, None)[0] model.remove_link(l1) check_inputs([2]) check_events([("remove", 0)]) reset_events() model.insert_link(0, l1) check_inputs([1, 2]) check_events([("insert", 0, 1)]) reset_events() l2 = model.find_links(widgets.w2_node, None, widgets.list_node, None)[0] model.remove_link(l2) check_inputs([1]) check_events([("remove", 1)]) model.insert_link(1, l2) check_inputs([1, 2]) model.remove_link(l1) check_inputs([2]) model.insert_link(0, l1) w1.Outputs.out.send(None) check_inputs([2]) w1.Outputs.out.send(None) check_inputs([2]) model.remove_link(l1) model.insert_link(0, l1) check_inputs([2]) w1.Outputs.out.send(1) check_inputs([1, 2]) w1.Outputs.out.send(None) check_inputs([2]) model.remove_link(l1) check_inputs([2]) reset_events() model.remove_link(l2) check_inputs([]) check_events([("remove", 0)]) reset_events() w1.Outputs.out.send(None) w2.Outputs.out.send(1) model.insert_link(0, l1) model.insert_link(1, l2) check_inputs([1]) check_events([("insert", 0, 1)]) reset_events() # ensure proper index on input removal when preceding inputs are # filtered model.remove_link(l2) check_inputs([]) check_events([("remove", 0)])
def setUp(self): self.widget = MockWidget() self.component = self.widget.filter_component self.emitted_signals: QSignalSpy = QSignalSpy( self.component.options_changed)
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 wait_for_graph(widget, timeout=5000): concurrent = widget.curveplot.show_average_thread if concurrent.task is not None: spy = QSignalSpy(concurrent.average_shown) assert spy.wait( timeout), "Failed to update graph in the specified timeout"