404 lines
18 KiB
Python
404 lines
18 KiB
Python
import copy
|
|
|
|
from PyQt5.QtCore import QPoint, Qt, QModelIndex
|
|
from PyQt5.QtCore import QTimer
|
|
from PyQt5.QtGui import QContextMenuEvent
|
|
from PyQt5.QtTest import QTest
|
|
from PyQt5.QtWidgets import QApplication, QMenu
|
|
|
|
from tests.QtTestCase import QtTestCase
|
|
from urh.controller.CompareFrameController import CompareFrameController
|
|
from urh.controller.MainController import MainController
|
|
from urh.signalprocessing.FieldType import FieldType
|
|
from urh.ui.views.LabelValueTableView import LabelValueTableView
|
|
|
|
|
|
class TestAnalysisTabGUI(QtTestCase):
|
|
def setUp(self):
|
|
super().setUp()
|
|
self.add_signal_to_form("two_participants.complex16s")
|
|
assert isinstance(self.form, MainController)
|
|
self.cfc = self.form.compare_frame_controller # type: CompareFrameController
|
|
self.form.signal_tab_controller.signal_frames[0].ui.spinBoxCenterOffset.setValue(-0.0574)
|
|
self.form.signal_tab_controller.signal_frames[0].ui.spinBoxCenterOffset.editingFinished.emit()
|
|
self.form.signal_tab_controller.signal_frames[0].ui.spinBoxTolerance.setValue(10)
|
|
self.form.signal_tab_controller.signal_frames[0].ui.spinBoxTolerance.editingFinished.emit()
|
|
|
|
def test_analyze_button_fsk(self):
|
|
assert isinstance(self.cfc, CompareFrameController)
|
|
self.add_signal_to_form("fsk.complex")
|
|
self.cfc.assign_labels_action.setChecked(True)
|
|
self.cfc.assign_message_type_action.setChecked(True)
|
|
self.cfc.assign_participants_action.setChecked(True)
|
|
self.cfc.ui.btnAnalyze.click()
|
|
self.assertTrue(True)
|
|
|
|
def test_analyze_button_enocean(self):
|
|
self.add_signal_to_form("enocean.complex")
|
|
w = self.form.signal_tab_controller.signal_frames[1].ui.spinBoxCenterOffset
|
|
w.setValue(0)
|
|
QTest.keyClick(w, Qt.Key_Enter)
|
|
w = self.form.signal_tab_controller.signal_frames[1].ui.spinBoxNoiseTreshold
|
|
w.setValue(0.0111)
|
|
QTest.keyClick(w, Qt.Key_Enter)
|
|
self.cfc.assign_labels_action.setChecked(True)
|
|
self.cfc.assign_message_type_action.setChecked(True)
|
|
self.cfc.assign_participants_action.setChecked(True)
|
|
self.cfc.ui.btnAnalyze.click()
|
|
self.assertTrue(True)
|
|
|
|
def test_table_selection(self):
|
|
self.form.ui.tabWidget.setCurrentIndex(1)
|
|
self.cfc.ui.cbProtoView.setCurrentIndex(0)
|
|
self.cfc.ui.tblViewProtocol.selectRow(1)
|
|
QApplication.instance().processEvents()
|
|
self.assertEqual(self.cfc.ui.lBitsSelection.text(), self.cfc.proto_analyzer.messages[1].plain_bits_str)
|
|
|
|
self.cfc.ui.tblViewProtocol.clearSelection()
|
|
QApplication.instance().processEvents()
|
|
self.assertEqual("", self.cfc.ui.lBitsSelection.text())
|
|
|
|
self.cfc.ui.tblViewProtocol.select(0, 0, 0, 3)
|
|
QApplication.instance().processEvents()
|
|
self.assertEqual("1010", self.cfc.ui.lBitsSelection.text())
|
|
self.cfc.ui.cbProtoView.setCurrentIndex(1)
|
|
QApplication.instance().processEvents()
|
|
|
|
min_row, max_row, start, end = self.cfc.ui.tblViewProtocol.selection_range()
|
|
self.assertEqual(min_row, 0)
|
|
self.assertEqual(max_row, 0)
|
|
self.assertEqual(start, 0)
|
|
self.assertEqual(end, 1)
|
|
|
|
def test_search(self):
|
|
search_str = "100110001"
|
|
self.cfc.ui.cbProtoView.setCurrentIndex(0)
|
|
self.cfc.ui.tblViewProtocol.clearSelection()
|
|
self.cfc.ui.lineEditSearch.setText(search_str)
|
|
self.cfc.ui.btnSearchSelectFilter.click()
|
|
|
|
selected_now = self.cfc.ui.tblViewProtocol.selectedIndexes()
|
|
self.assertEqual(len(self.cfc.ui.tblViewProtocol.selectedIndexes()), len(search_str))
|
|
|
|
self.cfc.ui.btnNextSearch.click()
|
|
self.assertNotEqual(selected_now, self.cfc.ui.tblViewProtocol.selectedIndexes())
|
|
|
|
self.cfc.ui.btnPrevSearch.click()
|
|
self.assertEqual(selected_now, self.cfc.ui.tblViewProtocol.selectedIndexes())
|
|
|
|
self.cfc.select_action.trigger()
|
|
self.assertEqual(self.cfc.ui.btnSearchSelectFilter.text(), "Select all")
|
|
self.cfc.ui.btnSearchSelectFilter.click()
|
|
self.assertGreater(len(self.cfc.ui.tblViewProtocol.selectedIndexes()), len(selected_now))
|
|
|
|
self.cfc.filter_action.trigger()
|
|
self.assertEqual(self.cfc.ui.btnSearchSelectFilter.text(), "Filter")
|
|
self.cfc.ui.btnSearchSelectFilter.click()
|
|
hidden_rows = [i for i in range(self.cfc.protocol_model.row_count)
|
|
if self.cfc.ui.tblViewProtocol.isRowHidden(i)]
|
|
|
|
self.assertEqual(hidden_rows, [0, 5, 6, 10, 13, 14, 16, 17])
|
|
|
|
def test_search_hex(self):
|
|
search_str = "aaaaaaaa"
|
|
self.cfc.ui.cbProtoView.setCurrentIndex(1)
|
|
self.cfc.ui.tblViewProtocol.clearSelection()
|
|
self.cfc.ui.lineEditSearch.setText(search_str)
|
|
self.cfc.ui.btnSearchSelectFilter.click()
|
|
|
|
self.assertEqual(self.cfc.ui.lSearchTotal.text(), "18")
|
|
|
|
def test_search_without_results(self):
|
|
search_str = "deadbeef42"
|
|
self.cfc.ui.cbProtoView.setCurrentIndex(1)
|
|
self.cfc.ui.tblViewProtocol.clearSelection()
|
|
self.cfc.ui.lineEditSearch.setText(search_str)
|
|
|
|
self.assertEqual(self.cfc.ui.lineEditSearch.text(), search_str, msg="before search")
|
|
self.cfc.ui.btnSearchSelectFilter.click()
|
|
self.assertEqual(self.cfc.ui.lSearchTotal.text(), "-")
|
|
self.assertEqual(self.cfc.ui.lineEditSearch.text(), search_str, msg="after search")
|
|
|
|
def test_show_diff(self):
|
|
self.cfc.ui.cbProtoView.setCurrentIndex(0)
|
|
|
|
hidden_columns_before = [i for i in range(self.cfc.protocol_model.col_count)
|
|
if self.cfc.ui.tblViewProtocol.isColumnHidden(i)]
|
|
self.assertEqual(len(hidden_columns_before), 0)
|
|
|
|
self.cfc.ui.chkBoxShowOnlyDiffs.click()
|
|
self.assertTrue(self.cfc.ui.cbShowDiffs.isChecked())
|
|
|
|
hidden_columns_now = [i for i in range(self.cfc.protocol_model.col_count)
|
|
if self.cfc.ui.tblViewProtocol.isColumnHidden(i)]
|
|
|
|
self.assertNotEqual(hidden_columns_before, hidden_columns_now)
|
|
|
|
self.cfc.ui.chkBoxOnlyShowLabelsInProtocol.click()
|
|
|
|
hidden_columns_now = [i for i in range(self.cfc.protocol_model.col_count)
|
|
if self.cfc.ui.tblViewProtocol.isColumnHidden(i)]
|
|
|
|
self.assertEqual(len(hidden_columns_now), self.cfc.protocol_model.col_count)
|
|
|
|
self.cfc.ui.cbProtoView.setCurrentIndex(1)
|
|
|
|
self.assertEqual(self.cfc.protocol_model.refindex, 0)
|
|
self.assertEqual(self.cfc.protocol_model.proto_view, 1)
|
|
|
|
self.cfc.ui.cbProtoView.setCurrentIndex(2)
|
|
|
|
self.assertEqual(self.cfc.protocol_model.refindex, 0)
|
|
self.assertEqual(self.cfc.protocol_model.proto_view, 2)
|
|
|
|
def test_add_message_type(self):
|
|
self.assertEqual(len(self.cfc.proto_analyzer.message_types), 1)
|
|
self.cfc.ui.btnAddMessagetype.click()
|
|
self.assertEqual(len(self.cfc.proto_analyzer.message_types), 2)
|
|
self.cfc.message_type_table_model.delete_message_type_at(1)
|
|
self.assertEqual(len(self.cfc.proto_analyzer.message_types), 1)
|
|
|
|
def test_create_context_menu(self):
|
|
|
|
self.cfc.proto_tree_model.rootItem.child(0).show = False
|
|
QApplication.instance().processEvents()
|
|
|
|
self.assertEqual(self.cfc.protocol_model.rowCount(), 0)
|
|
self.cfc.ui.tblViewProtocol.context_menu_pos = QPoint(0, 0)
|
|
QApplication.instance().processEvents()
|
|
|
|
menu = self.cfc.ui.tblViewProtocol.create_context_menu()
|
|
texts = [a.text() for a in menu.actions()]
|
|
# Add protocol label should not be there if table is empty
|
|
self.assertFalse(any("label" in text.lower() for text in texts))
|
|
|
|
def test_show_in_interpretation(self):
|
|
self.form.ui.tabWidget.setCurrentIndex(1)
|
|
self.assertEqual(self.form.ui.tabWidget.currentIndex(), 1)
|
|
self.cfc.ui.cbProtoView.setCurrentIndex(0)
|
|
|
|
self.cfc.ui.tblViewProtocol.selectRow(1)
|
|
min_row, max_row, start, end = self.cfc.ui.tblViewProtocol.selection_range()
|
|
self.cfc.ui.tblViewProtocol.show_interpretation_clicked.emit(min_row, start, max_row, end - 1)
|
|
self.assertEqual(self.form.ui.tabWidget.currentIndex(), 0)
|
|
self.assertFalse(self.form.signal_tab_controller.signal_frames[0].ui.gvSignal.selection_area.is_empty)
|
|
|
|
def test_hide_row(self):
|
|
num_messages = len(self.cfc.proto_analyzer.messages)
|
|
self.form.ui.tabWidget.setCurrentIndex(1)
|
|
self.assertGreater(num_messages, 0)
|
|
self.assertEqual(self.cfc.protocol_model.rowCount(), num_messages)
|
|
self.cfc.ui.tblViewProtocol.hide_rows(0)
|
|
self.assertTrue(self.cfc.ui.tblViewProtocol.isRowHidden(0))
|
|
self.assertEqual(len(self.cfc.protocol_model.hidden_rows), 1)
|
|
|
|
for msg in range(1, num_messages):
|
|
self.assertFalse(self.cfc.ui.tblViewProtocol.isRowHidden(msg))
|
|
|
|
self.form.ui.tabWidget.setCurrentIndex(2)
|
|
QApplication.instance().processEvents()
|
|
self.form.ui.tabWidget.setCurrentIndex(1)
|
|
QApplication.instance().processEvents()
|
|
self.assertEqual(self.cfc.protocol_model.rowCount(), num_messages)
|
|
self.assertTrue(self.cfc.ui.tblViewProtocol.isRowHidden(0))
|
|
|
|
for msg in range(1, num_messages):
|
|
self.assertFalse(self.cfc.ui.tblViewProtocol.isRowHidden(msg))
|
|
|
|
self.assertEqual(len(self.cfc.protocol_model.hidden_rows), 1)
|
|
|
|
def test_refresh_existing_decodings(self):
|
|
self.assertEqual(self.cfc.proto_analyzer.messages[0].decoder, self.cfc.decodings[0])
|
|
decoder = copy.deepcopy(self.cfc.proto_analyzer.messages[0].decoder)
|
|
decoder.chain.append(decoder.code_invert)
|
|
self.cfc.proto_analyzer.messages[0].decoder = decoder
|
|
self.assertNotEqual(self.cfc.proto_analyzer.messages[0].decoder, self.cfc.decodings[0])
|
|
|
|
self.cfc.refresh_existing_encodings()
|
|
self.assertEqual(self.cfc.proto_analyzer.messages[0].decoder, self.cfc.decodings[0])
|
|
|
|
def test_get_labels_from_selection(self):
|
|
self.cfc.ui.tblViewProtocol.selectRow(1)
|
|
self.assertEqual(len(self.cfc.get_labels_from_selection(*self.cfc.ui.tblViewProtocol.selection_range())), 0)
|
|
|
|
def test_refresh_field_types_for_labels(self):
|
|
self.cfc.add_protocol_label(0, 10, 0, 0, edit_label_name=False)
|
|
n = len(self.cfc.field_types)
|
|
self.cfc.refresh_field_types_for_labels()
|
|
self.assertEqual(len(self.cfc.field_types), n)
|
|
|
|
def test_tree_view_selection_changed(self):
|
|
self.cfc.proto_tree_model.addGroup()
|
|
self.cfc.proto_tree_model.addGroup()
|
|
QApplication.instance().processEvents()
|
|
self.assertEqual(len(self.cfc.active_group_ids), 1)
|
|
self.cfc.ui.treeViewProtocols.selectAll()
|
|
self.cfc.ui.treeViewProtocols.selection_changed.emit()
|
|
QApplication.instance().processEvents()
|
|
self.assertEqual(len(self.cfc.active_group_ids), 1)
|
|
|
|
def test_tree_view_drop_mime_data(self):
|
|
# Drop signal to new group
|
|
self.cfc.proto_tree_model.addGroup("Test group")
|
|
self.assertEqual(len(self.cfc.groups), 2)
|
|
self.assertEqual(self.cfc.groups[0].num_protocols, 1)
|
|
self.assertEqual(self.cfc.groups[1].num_protocols, 0)
|
|
self.cfc.proto_tree_model.update()
|
|
|
|
self.cfc.show()
|
|
model = self.cfc.proto_tree_model
|
|
|
|
group_1_index = model.index(0, 0, QModelIndex())
|
|
signal_index = model.index(0, 0, group_1_index)
|
|
|
|
group_2_index = model.index(1, 0, QModelIndex())
|
|
self.assertEqual(group_2_index.internalPointer().group.name, "Test group")
|
|
mimedata = model.mimeData([signal_index])
|
|
model.dropMimeData(mimedata, Qt.MoveAction, 0, 0, group_2_index)
|
|
self.assertEqual(self.cfc.groups[0].num_protocols, 0)
|
|
self.assertEqual(self.cfc.groups[1].num_protocols, 1)
|
|
|
|
# Drop group to another position
|
|
self.assertEqual(self.cfc.groups[0].name, "New Group")
|
|
self.assertEqual(self.cfc.groups[1].name, "Test group")
|
|
mimedata = model.mimeData([group_2_index])
|
|
model.dropMimeData(mimedata, Qt.MoveAction, 0, 0, group_1_index)
|
|
self.assertEqual(self.cfc.groups[0].name, "Test group")
|
|
self.assertEqual(self.cfc.groups[0].num_protocols, 1)
|
|
self.assertEqual(self.cfc.groups[1].name, "New Group")
|
|
self.assertEqual(self.cfc.groups[1].num_protocols, 0)
|
|
|
|
def test_remove_label(self):
|
|
self.cfc.add_protocol_label(10, 20, 2, 0, edit_label_name=False)
|
|
self.assertEqual(self.cfc.label_value_model.rowCount(), 1)
|
|
self.cfc.label_value_model.delete_label_at(0)
|
|
self.assertEqual(self.cfc.label_value_model.rowCount(), 0)
|
|
|
|
def test_label_tooltip(self):
|
|
self.cfc.ui.cbProtoView.setCurrentIndex(0)
|
|
self.cfc.add_protocol_label(0, 16, 2, 0, edit_label_name=False)
|
|
model = self.cfc.label_value_model
|
|
model.setData(model.index(0, 0), "test", Qt.EditRole)
|
|
table_model = self.cfc.protocol_model
|
|
for i in range(0, 16):
|
|
self.assertEqual(table_model.data(table_model.index(2, i), Qt.ToolTipRole), "test", msg=str(i))
|
|
|
|
for i in range(17, 100):
|
|
self.assertEqual(table_model.data(table_model.index(2, i), Qt.ToolTipRole), "", msg=str(i))
|
|
|
|
self.cfc.add_protocol_label(20, 24, 2, 0, edit_label_name=False)
|
|
checksum_field_type = next(ft for ft in self.cfc.field_types if ft.function == FieldType.Function.CHECKSUM)
|
|
model.setData(model.index(1, 0), checksum_field_type.caption, Qt.EditRole)
|
|
for i in range(20, 24):
|
|
self.assertIn("Expected", table_model.data(table_model.index(2, i), Qt.ToolTipRole))
|
|
|
|
for i in range(0, 20):
|
|
self.assertNotIn("Expected", table_model.data(table_model.index(2, i), Qt.ToolTipRole))
|
|
|
|
def test_protocol_tree_context_menu(self):
|
|
self.cfc.ui.treeViewProtocols.context_menu_pos = QPoint(0, 0)
|
|
menu = self.cfc.ui.treeViewProtocols.create_context_menu()
|
|
actions = ["Create a new group", "Sort Group Elements", "Delete group"]
|
|
menu_action_names = [action.text() for action in menu.actions() if action.text()]
|
|
for action in menu_action_names:
|
|
self.assertIn(action, actions)
|
|
|
|
def test_label_value_table(self):
|
|
table = self.cfc.ui.tblLabelValues # type: LabelValueTableView
|
|
model = table.model()
|
|
self.assertEqual(model.rowCount(), 0)
|
|
self.cfc.add_protocol_label(45, 56, 0, 0, edit_label_name=False)
|
|
self.assertEqual(model.rowCount(), 1)
|
|
self.assertEqual(model.data(model.index(0, 2)), "Bit")
|
|
self.assertEqual(model.data(model.index(0, 4)), "000011001110")
|
|
|
|
model.setData(model.index(0, 2), 1, role=Qt.EditRole)
|
|
self.assertEqual(model.data(model.index(0, 2)), "Hex")
|
|
self.assertEqual(model.data(model.index(0, 4)), "0ce")
|
|
|
|
model.setData(model.index(0, 2), 2, role=Qt.EditRole)
|
|
self.assertEqual(model.data(model.index(0, 2)), "ASCII")
|
|
|
|
model.setData(model.index(0, 2), 3, role=Qt.EditRole)
|
|
self.assertEqual(model.data(model.index(0, 2)), "Decimal")
|
|
self.assertEqual(model.data(model.index(0, 4)), "206")
|
|
|
|
model.setData(model.index(0, 2), 4, role=Qt.EditRole)
|
|
self.assertEqual(model.data(model.index(0, 2)), "BCD")
|
|
self.assertEqual(model.data(model.index(0, 4)), "0??")
|
|
|
|
self.assertIn("display type", model.data(model.index(0, 2), Qt.ToolTipRole))
|
|
self.assertIn("bit order", model.data(model.index(0, 3), Qt.ToolTipRole))
|
|
|
|
lbl = self.cfc.proto_analyzer.default_message_type[0]
|
|
self.assertEqual(lbl.display_endianness, "big")
|
|
model.setData(model.index(0, 3), "MSB/LE", role=Qt.EditRole)
|
|
self.assertEqual(lbl.display_endianness, "little")
|
|
model.setData(model.index(0, 3), "LSB/BE", role=Qt.EditRole)
|
|
self.assertEqual(lbl.display_endianness, "big")
|
|
|
|
def test_label_list_view(self):
|
|
menus_before = [w for w in QApplication.topLevelWidgets() if isinstance(w, QMenu)]
|
|
|
|
global context_menu
|
|
context_menu = None # type: QMenu
|
|
|
|
def on_timeout():
|
|
global context_menu
|
|
context_menu = next(w for w in QApplication.topLevelWidgets()
|
|
if w.parent() is None and isinstance(w, QMenu) and w not in menus_before)
|
|
context_menu.close()
|
|
|
|
self.cfc.add_protocol_label(10, 20, 0, 0, False)
|
|
self.cfc.add_message_type()
|
|
self.assertEqual(self.cfc.message_type_table_model.rowCount(), 2)
|
|
|
|
self.cfc.ui.tblViewProtocol.selectRow(0)
|
|
self.assertEqual(self.cfc.ui.tblLabelValues.model().rowCount(), 1)
|
|
self.cfc.ui.tblLabelValues.selectAll()
|
|
|
|
timer = QTimer(self.cfc)
|
|
timer.setSingleShot(True)
|
|
timer.timeout.connect(on_timeout)
|
|
timer.start(1)
|
|
|
|
self.cfc.ui.tblLabelValues.contextMenuEvent(QContextMenuEvent(QContextMenuEvent.Mouse, QPoint(0, 0)))
|
|
|
|
names = [action.text() for action in context_menu.actions()]
|
|
self.assertIn("Edit...", names)
|
|
|
|
def test_create_label_dialog(self):
|
|
self.cfc.add_protocol_label(10, 20, 0, 0, False)
|
|
dialog = self.cfc.create_protocol_label_dialog()
|
|
self.assertIsNotNone(dialog)
|
|
|
|
def test_alignment(self):
|
|
assert isinstance(self.cfc, CompareFrameController)
|
|
self.form.close_all_files()
|
|
self.form.add_files([self.get_path_for_filename("misaligned.txt")])
|
|
self.assertEqual(self.cfc.protocol_model.row_count, 16)
|
|
|
|
aligned = True
|
|
pattern = "6768676"
|
|
for i in range(self.cfc.protocol_model.row_count):
|
|
for j in range(len(pattern)):
|
|
if self.cfc.protocol_model.data(self.cfc.protocol_model.index(i, j + 11)) != pattern[j]:
|
|
aligned = False
|
|
break
|
|
|
|
self.assertFalse(aligned)
|
|
|
|
self.cfc.ui.cbProtoView.setCurrentIndex(1)
|
|
self.cfc.align_action.trigger()
|
|
self.cfc.ui.lineEditSearch.setText(pattern)
|
|
self.cfc.ui.btnSearchSelectFilter.click()
|
|
|
|
aligned = True
|
|
for i in range(self.cfc.protocol_model.row_count):
|
|
for j in range(len(pattern)):
|
|
if self.cfc.protocol_model.data(self.cfc.protocol_model.index(i, j + 11)) != pattern[j]:
|
|
aligned = False
|
|
break
|
|
|
|
self.assertTrue(aligned)
|