def test_right_click_gives_context_menu_for_plot_without_fit_enabled( self, mocked_figure_type, mocked_qmenu_cls): fig_manager = self._create_mock_fig_manager_to_accept_right_click() fig_manager.fit_browser.tool = None interactor = FigureInteraction(fig_manager) mouse_event = self._create_mock_right_click() mocked_figure_type.return_value = FigureType.Line # Expect a call to QMenu() for the outer menu followed by two more calls # for the Axes and Normalization menus qmenu_call1 = MagicMock() qmenu_call2 = MagicMock() qmenu_call3 = MagicMock() mocked_qmenu_cls.side_effect = [qmenu_call1, qmenu_call2, qmenu_call3] with patch('workbench.plotting.figureinteraction.QActionGroup', autospec=True): with patch.object(interactor.toolbar_manager, 'is_tool_active', lambda: False): with patch.object(interactor.errors_manager, 'add_error_bars_menu', MagicMock()): interactor.on_mouse_button_press(mouse_event) self.assertEqual(0, qmenu_call1.addSeparator.call_count) self.assertEqual(0, qmenu_call1.addAction.call_count) expected_qmenu_calls = [ call(), call("Axes", qmenu_call1), call("Normalization", qmenu_call1) ] self.assertEqual(expected_qmenu_calls, mocked_qmenu_cls.call_args_list) # 4 actions in Axes submenu self.assertEqual(4, qmenu_call2.addAction.call_count) # 2 actions in Normalization submenu self.assertEqual(2, qmenu_call3.addAction.call_count)
def _test_toggle_normalization(self, errorbars_on, plot_kwargs): fig = plot([self.ws], spectrum_nums=[1], errors=errorbars_on, plot_kwargs=plot_kwargs) mock_canvas = MagicMock(figure=fig) fig_manager_mock = MagicMock(canvas=mock_canvas) fig_interactor = FigureInteraction(fig_manager_mock) # Earlier versions of matplotlib do not store the data assciated with a # line with high precision and hence we need to set a lower tolerance # when making comparisons of this data if matplotlib.__version__ < "2": decimal_tol = 1 else: decimal_tol = 7 ax = fig.axes[0] fig_interactor._toggle_normalization(ax) assert_almost_equal(ax.lines[0].get_xdata(), [15, 25]) assert_almost_equal(ax.lines[0].get_ydata(), [0.2, 0.3], decimal=decimal_tol) self.assertEqual("Counts ($\\AA$)$^{-1}$", ax.get_ylabel()) fig_interactor._toggle_normalization(ax) assert_almost_equal(ax.lines[0].get_xdata(), [15, 25]) assert_almost_equal(ax.lines[0].get_ydata(), [2, 3], decimal=decimal_tol) self.assertEqual("Counts", ax.get_ylabel())
def test_motion_event_returns_if_toolbar_has_active_tools(self): self.interactor.toolbar_manager.is_tool_active = MagicMock( return_value=True) self.interactor._set_hover_cursor = MagicMock() self.interactor.motion_event(MagicMock()) self.assertEqual(0, self.interactor._set_hover_cursor.call_count)
def test_mpl_redraw_annotations_does_not_redraw_if_event_button_not_pressed( self): self.interactor.redraw_annotations = MagicMock() event = MagicMock() event.button = None self.interactor.mpl_redraw_annotations(event) self.assertEqual(0, self.interactor.redraw_annotations.call_count)
def test_disconnect_called_for_each_registered_handler(self): fig_manager = MagicMock() canvas = MagicMock() fig_manager.canvas = canvas interactor = FigureInteraction(fig_manager) interactor.disconnect() self.assertEqual(interactor.nevents, canvas.mpl_disconnect.call_count)
def test_correct_yunit_label_when_overplotting_after_normaliztion_toggle( self): # The earlier version of Matplotlib on RHEL throws an error when performing the second # plot in this test, if the lines have errorbars. The error occurred when it attempted # to draw an interactive legend. Plotting without errors still fulfills the purpose of this # test, so turn them off for old Matplotlib versions. errors = True if int(matplotlib.__version__[0]) < 2: errors = False fig = plot([self.ws], spectrum_nums=[1], errors=errors, plot_kwargs={'distribution': True}) mock_canvas = MagicMock(figure=fig) fig_manager_mock = MagicMock(canvas=mock_canvas) fig_interactor = FigureInteraction(fig_manager_mock) ax = fig.axes[0] fig_interactor._toggle_normalization(ax) self.assertEqual("Counts ($\AA$)$^{-1}$", ax.get_ylabel()) plot([self.ws1], spectrum_nums=[1], errors=errors, overplot=True, fig=fig) self.assertEqual("Counts ($\AA$)$^{-1}$", ax.get_ylabel())
def test_mpl_redraw_annotations_does_not_redraw_if_event_does_not_have_a_button_attribute( self): self.interactor.redraw_annotations = MagicMock() event = MagicMock(spec='no_button') event.no_button = MagicMock(spec='no_button') self.interactor.mpl_redraw_annotations(event.no_button) self.assertEqual(0, self.interactor.redraw_annotations.call_count)
def test_redraw_annotations_removes_and_adds_all_annotations_for_all_markers( self): markers = [MagicMock(), MagicMock(), MagicMock()] call_list = [call.remove_all_annotations(), call.add_all_annotations()] self.interactor.markers = markers self.interactor.redraw_annotations() for marker in markers: marker.assert_has_calls(call_list)
def test_plotting_check(self, calib, plot_tof, gen_tof, plot_van, van, sample, output_files, update_table): calib.return_value = [MagicMock(), MagicMock()] van.return_value = ("A", "B") self.model.create_new_calibration(VANADIUM_NUMBER, CERIUM_NUMBER, False, "ENGINX") plot_van.assert_not_called() plot_tof.assert_not_called() gen_tof.assert_not_called() self.model.create_new_calibration(VANADIUM_NUMBER, CERIUM_NUMBER, True, "ENGINX") plot_van.assert_called_once() self.assertEqual(gen_tof.call_count, 2) self.assertEqual(plot_tof.call_count, 1)
def test_context_menu_change_axis_scale_is_axis_aware(self): fig = plot([self.ws, self.ws1], spectrum_nums=[1, 1], tiled=True) mock_canvas = MagicMock(figure=fig) fig_manager_mock = MagicMock(canvas=mock_canvas) fig_interactor = FigureInteraction(fig_manager_mock) scale_types = ("log", "log") ax = fig.axes[0] ax1 = fig.axes[1] current_scale_types = (ax.get_xscale(), ax.get_yscale()) current_scale_types1 = (ax1.get_xscale(), ax1.get_yscale()) self.assertEqual(current_scale_types, current_scale_types1) fig_interactor._quick_change_axes(scale_types, ax) current_scale_types2 = (ax.get_xscale(), ax.get_yscale()) self.assertNotEqual(current_scale_types2, current_scale_types1)
def test_construction_registers_handler_for_button_press_event(self): fig_manager = MagicMock() fig_manager.canvas = MagicMock() interactor = FigureInteraction(fig_manager) expected_call = [ call('button_press_event', interactor.on_mouse_button_press), call('button_release_event', interactor.on_mouse_button_release), call('draw_event', interactor.draw_callback), call('motion_notify_event', interactor.motion_event), call('resize_event', interactor.mpl_redraw_annotations), call('figure_leave_event', interactor.on_leave), call('axis_leave_event', interactor.on_leave), ] fig_manager.canvas.mpl_connect.assert_has_calls(expected_call) self.assertEqual(len(expected_call), fig_manager.canvas.mpl_connect.call_count)
def test_calibrate_clicked_load_valid_path(self, path, update): self.presenter.calibration_notifier = MagicMock() self.view.get_new_checked.return_value = False self.view.get_load_checked.return_value = True path.return_value = True instrument, van, cer = ("test_ins", "test_van", "test_cer") self.model.load_existing_gsas_parameters.return_value = instrument, van, cer current = CalibrationInfo(vanadium_path="old/value", sample_path="old/cera", instrument="ENGINX") new = CalibrationInfo(vanadium_path=van, sample_path=cer, instrument=instrument) self.presenter.current_calibration = current self.presenter.on_calibrate_clicked() self.assertEqual(update.call_count, 1) self.assertEqual(self.presenter.current_calibration.get_vanadium(), new.get_vanadium()) self.assertEqual(self.presenter.current_calibration.get_sample(), new.get_sample()) self.assertEqual(self.presenter.current_calibration.get_instrument(), new.get_instrument()) self.assertEqual( self.presenter.calibration_notifier.notify_subscribers.call_count, 1)
def test_adding_vertical_marker_adds_correct_marker(self, mock_marker): x0, x1 = 0, 1 data = MagicMock() axis = MagicMock() self.interactor._add_vertical_marker(data, x0, x1, axis) expected_call = call(self.interactor.canvas, '#2ca02c', data, x0, x1, name='marker 0', marker_type='XSingle', line_style='dashed', axis=axis) self.assertEqual(1, mock_marker.call_count) mock_marker.assert_has_calls([expected_call])
def test_delete_marker_does_not_delete_markers_if_not_present(self): marker = MagicMock() self.interactor.markers = [] self.interactor._delete_marker(marker) self.assertEqual(0, self.interactor.canvas.draw.call_count) self.assertEqual(0, marker.marker.remove.call_count) self.assertEqual(0, marker.remove_all_annotations.call_count)
def test_correct_yunit_label_when_overplotting_after_normaliztion_toggle( self): fig = plot([self.ws], spectrum_nums=[1], errors=True, plot_kwargs={'distribution': True}) mock_canvas = MagicMock(figure=fig) fig_manager_mock = MagicMock(canvas=mock_canvas) fig_interactor = FigureInteraction(fig_manager_mock) ax = fig.axes[0] fig_interactor._toggle_normalization(ax) self.assertEqual("Counts ($\AA$)$^{-1}$", ax.get_ylabel()) plot([self.ws1], spectrum_nums=[1], errors=True, overplot=True, fig=fig) self.assertEqual("Counts ($\AA$)$^{-1}$", ax.get_ylabel())
def test_delete_marker_preforms_correct_cleanup(self): marker = MagicMock() self.interactor.markers = [marker] self.interactor._delete_marker(marker) self.assertEqual(1, marker.marker.remove.call_count) self.assertEqual(1, marker.remove_all_annotations.call_count) self.assertEqual(1, self.interactor.canvas.draw.call_count) self.assertNotIn(marker, self.interactor.markers)
def test_global_edit_marker_opens_correct_editor(self, mock_editor): marker = MagicMock() self.interactor.markers = [marker] expected_call = [ call(self.interactor.canvas, [marker], self.interactor.valid_lines, self.interactor.valid_colors) ] self.interactor._global_edit_markers() mock_editor.assert_has_calls(expected_call)
def test_edit_marker_opens_correct_editor(self, mock_qapp, mock_editor): marker = MagicMock() expected_call = [ call(self.interactor.canvas, marker, self.interactor.valid_lines, self.interactor.valid_colors, []) ] self.interactor._edit_marker(marker) self.assertEqual(1, mock_qapp.restoreOverrideCursor.call_count) mock_editor.assert_has_calls(expected_call)
def test_motion_event_changes_cursor_and_does_not_draw_canvas_if_no_marker_is_moving( self): markers = [MagicMock(), MagicMock(), MagicMock()] for marker in markers: marker.mouse_move.return_value = False event = MagicMock() event.xdata = 1 event.ydata = 2 self.interactor.markers = markers self.interactor.toolbar_manager.is_tool_active = MagicMock( return_value=False) self.interactor._set_hover_cursor = MagicMock() self.interactor.motion_event(event) self.interactor._set_hover_cursor.assert_has_calls([call(1, 2)]) self.assertEqual(0, self.interactor.canvas.draw.call_count)
def test_right_click_gives_context_menu_for_plot_without_fit_enabled( self, mocked_figure_type, mocked_qmenu_cls): fig_manager = self._create_mock_fig_manager_to_accept_right_click() fig_manager.fit_browser.tool = None interactor = FigureInteraction(fig_manager) mouse_event = self._create_mock_right_click() mocked_figure_type.return_value = FigureType.Line # Expect a call to QMenu() for the outer menu followed by a call with the first # as its parent to generate the Axes menu. qmenu_call1 = MagicMock() qmenu_call2 = MagicMock() mocked_qmenu_cls.side_effect = [qmenu_call1, qmenu_call2] with patch('workbench.plotting.figureinteraction.QActionGroup', autospec=True): interactor.on_mouse_button_press(mouse_event) self.assertEqual(0, qmenu_call1.addSeparator.call_count) self.assertEqual(0, qmenu_call1.addAction.call_count) expected_qmenu_calls = [call(), call("Axes", qmenu_call1)] self.assertEqual(expected_qmenu_calls, mocked_qmenu_cls.call_args_list) self.assertEqual(4, qmenu_call2.addAction.call_count)
def test_right_click_gives_context_menu_for_color_plot( self, mocked_figure_type, mocked_qmenu): fig_manager = self._create_mock_fig_manager_to_accept_right_click() interactor = FigureInteraction(fig_manager) mouse_event = self._create_mock_right_click() mocked_figure_type.return_value = FigureType.Image # Expect a call to QMenu() for the outer menu followed by three more calls # for the Axes, Normalization and Colorbar menus qmenu_call1 = MagicMock() qmenu_call2 = MagicMock() qmenu_call3 = MagicMock() qmenu_call4 = MagicMock() mocked_qmenu.side_effect = [ qmenu_call1, qmenu_call2, qmenu_call3, qmenu_call4 ] with patch('workbench.plotting.figureinteraction.QActionGroup', autospec=True): with patch.object(interactor.toolbar_manager, 'is_tool_active', lambda: False): interactor.on_mouse_button_press(mouse_event) self.assertEqual(0, qmenu_call1.addAction.call_count) expected_qmenu_calls = [ call(), call("Axes", qmenu_call1), call("Normalization", qmenu_call1), call("Color bar", qmenu_call1) ] self.assertEqual(expected_qmenu_calls, mocked_qmenu.call_args_list) # 4 actions in Axes submenu self.assertEqual(4, qmenu_call2.addAction.call_count) # 2 actions in Normalization submenu self.assertEqual(2, qmenu_call3.addAction.call_count) # 2 actions in Colorbar submenu self.assertEqual(2, qmenu_call4.addAction.call_count)
def test_calibrate_clicked_load_invalid_path(self, path): self.presenter.calibration_notifier = MagicMock() self.view.get_new_checked.return_value = False self.view.get_load_checked.return_value = True path.return_value = False current = CalibrationInfo(vanadium_path="old/value", sample_path="old/cera", instrument="ENGINX") self.presenter.current_calibration = current self.presenter.on_calibrate_clicked() self.assertEqual(self.presenter.current_calibration, current) self.assertEqual( self.presenter.calibration_notifier.notify_subscribers.call_count, 0)
def test_right_click_gives_marker_menu_when_hovering_over_one( self, mocked_figure_type, mocked_qmenu_cls): mouse_event = self._create_mock_right_click() mouse_event.inaxes.get_xlim.return_value = (1, 2) mouse_event.inaxes.get_ylim.return_value = (1, 2) mocked_figure_type.return_value = FigureType.Line marker1 = MagicMock() marker2 = MagicMock() marker3 = MagicMock() self.interactor.markers = [marker1, marker2, marker3] for marker in self.interactor.markers: marker.is_above.return_value = True # Expect a call to QMenu() for the outer menu followed by two more calls # for the Axes and Normalization menus qmenu_call1 = MagicMock() qmenu_call2 = MagicMock() qmenu_call3 = MagicMock() qmenu_call4 = MagicMock() mocked_qmenu_cls.side_effect = [ qmenu_call1, qmenu_call2, qmenu_call3, qmenu_call4 ] with patch('workbench.plotting.figureinteraction.QActionGroup', autospec=True): with patch.object(self.interactor.toolbar_manager, 'is_tool_active', lambda: False): with patch.object(self.interactor, 'add_error_bars_menu', MagicMock()): self.interactor.on_mouse_button_press(mouse_event) self.assertEqual(0, qmenu_call1.addSeparator.call_count) self.assertEqual(0, qmenu_call1.addAction.call_count) expected_qmenu_calls = [ call(), call(marker1.name, qmenu_call1), call(marker2.name, qmenu_call1), call(marker3.name, qmenu_call1) ] self.assertEqual(expected_qmenu_calls, mocked_qmenu_cls.call_args_list) # 2 Actions in marker menu self.assertEqual(2, qmenu_call2.addAction.call_count) self.assertEqual(2, qmenu_call3.addAction.call_count) self.assertEqual(2, qmenu_call4.addAction.call_count)
def test_headerData_vertical_header_display_for_numeric_axis_with_point_data( self): dummy_unit = 'unit' ws = MockWorkspace() mock_axis = Mock() mock_axis.isNumeric.return_value = True expected_value = 0. mock_axis.label = MagicMock(side_effect=[str(expected_value)]) mock_axis.getUnit().symbol().utf8.return_value = dummy_unit ws.getAxis.return_value = mock_axis model_type = MatrixWorkspaceTableViewModelType.y model = MatrixWorkspaceTableViewModel(ws, model_type) mock_section = 0 output = model.headerData(mock_section, Qt.Vertical, Qt.DisplayRole) expected_output = MatrixWorkspaceTableViewModel.VERTICAL_HEADER_DISPLAY_STRING_FOR_NUMERIC_AXIS.format( mock_section, expected_value, dummy_unit) self.assertEqual(expected_output, output)
def test_headerData_vertical_header_tooltip_for_numeric_axis_with_binned_data( self): dummy_unit = 'unit' ws = MockWorkspace() mock_axis = Mock() mock_axis.isNumeric.return_value = True ws.getNumberHistograms.return_value = 1 mock_axis.length.return_value = 2 mock_axis.label = MagicMock(side_effect=["0", "1"]) mock_axis.getUnit().symbol().utf8.return_value = dummy_unit ws.getAxis.return_value = mock_axis model_type = MatrixWorkspaceTableViewModelType.y model = MatrixWorkspaceTableViewModel(ws, model_type) mock_section = 0 output = model.headerData(mock_section, Qt.Vertical, Qt.ToolTipRole) expected_output = MatrixWorkspaceTableViewModel.VERTICAL_HEADER_TOOLTIP_STRING_FOR_NUMERIC_AXIS.format( mock_section, 0.5, dummy_unit) self.assertEqual(expected_output, output)
def test_set_current_calibration(self, update_sig): self.presenter.calibration_notifier = MagicMock() pending = CalibrationInfo(vanadium_path="/test/set/path", sample_path="test/set/path/2", instrument="TEST_INS") pendcpy = CalibrationInfo(vanadium_path="/test/set/path", sample_path="test/set/path/2", instrument="TEST_INS") self.presenter.pending_calibration = pending current = CalibrationInfo(vanadium_path="old/value", sample_path="old/cera", instrument="ENGINX") blank = CalibrationInfo() self.presenter.current_calibration = current self.presenter.set_current_calibration() self.check_calibration_equal(self.presenter.current_calibration, pendcpy) self.check_calibration_equal(self.presenter.pending_calibration, blank) self.assertEqual( self.presenter.calibration_notifier.notify_subscribers.call_count, 1) self.assertEqual(update_sig.call_count, 1)
def _create_widget(self, canvas=MagicMock(), toolbar_manager=Mock()): return FitPropertyBrowser(canvas, toolbar_manager)
def test_font_dialog_signals(self): presenter = GeneralSettings(None) with patch.object(presenter.view, 'create_font_dialog', MagicMock()) as font_dialog: presenter.action_main_font_button_clicked() self.assertEqual(1, font_dialog().fontSelected.connect.call_count)
def test_mpl_redraw_annotations_redraws_if_button_pressed(self): self.interactor.redraw_annotations = MagicMock() event = MagicMock() self.interactor.mpl_redraw_annotations(event) self.assertEqual(1, self.interactor.redraw_annotations.call_count)
def setUp(self): self.view = mock.create_autospec(view.CalibrationView) self.model = mock.create_autospec(model.CalibrationModel) self.view.get_cropping_widget.return_value = MagicMock() self.presenter = presenter.CalibrationPresenter(self.model, self.view) self.presenter.cropping_widget = MagicMock()