|
1
|
|
|
|
|
2
|
|
|
import unittest |
|
3
|
|
|
import sys |
|
4
|
|
|
import time |
|
5
|
|
|
sys.path.insert(0, "python-opcua") # necessary on travis |
|
6
|
|
|
sys.path.insert(0, ".") |
|
7
|
|
|
|
|
8
|
|
|
from opcua import ua, Server |
|
9
|
|
|
|
|
10
|
|
|
from PyQt5.QtCore import QTimer, QSettings, QModelIndex, Qt, QCoreApplication |
|
11
|
|
|
from PyQt5.QtWidgets import QApplication, QTreeView, QAbstractItemDelegate, QTableView |
|
12
|
|
|
from PyQt5.QtTest import QTest |
|
13
|
|
|
|
|
14
|
|
|
from uawidgets.attrs_widget import AttrsWidget |
|
15
|
|
|
from uawidgets.refs_widget import RefsWidget |
|
16
|
|
|
|
|
17
|
|
|
|
|
18
|
|
|
class TestRefsWidget(unittest.TestCase): |
|
19
|
|
|
def setUp(self): |
|
20
|
|
|
self.server = Server() |
|
21
|
|
|
self.server.set_endpoint("opc.tcp://0.0.0.0:4840/freeopcua/server/") |
|
22
|
|
|
self.server.start() |
|
23
|
|
|
self.widget = RefsWidget(QTableView()) |
|
24
|
|
|
|
|
25
|
|
|
def tearDown(self): |
|
26
|
|
|
self.server.stop() |
|
27
|
|
|
|
|
28
|
|
|
def test_1(self): |
|
29
|
|
|
o = self.server.nodes.objects |
|
30
|
|
|
self.widget.show_refs(o) |
|
31
|
|
|
|
|
32
|
|
|
|
|
33
|
|
|
class TestAttrsWidget(unittest.TestCase): |
|
34
|
|
|
def setUp(self): |
|
35
|
|
|
self.server = Server() |
|
36
|
|
|
self.server.set_endpoint("opc.tcp://0.0.0.0:4840/freeopcua/server/") |
|
37
|
|
|
self.server.start() |
|
38
|
|
|
self.widget = AttrsWidget(QTreeView()) |
|
39
|
|
|
|
|
40
|
|
|
def tearDown(self): |
|
41
|
|
|
self.server.stop() |
|
42
|
|
|
|
|
43
|
|
|
def find_item(self, text): |
|
44
|
|
|
idxlist = self.widget.model.match(self.widget.model.index(0, 0), Qt.DisplayRole, text, 1, Qt.MatchExactly | Qt.MatchRecursive) |
|
45
|
|
|
idx = idxlist[0] |
|
46
|
|
|
return idx |
|
47
|
|
|
|
|
48
|
|
|
def modify_item(self, text, val, match_to_use=0): |
|
49
|
|
|
""" |
|
50
|
|
|
modify the current item and set its displayed value to 'val' |
|
51
|
|
|
""" |
|
52
|
|
|
idxlist = self.widget.model.match(self.widget.model.index(0, 0), Qt.DisplayRole, text, match_to_use + 1, Qt.MatchExactly | Qt.MatchRecursive) |
|
53
|
|
|
if not idxlist: |
|
54
|
|
|
raise RuntimeError("Item with text '{}' not found".format(text)) |
|
55
|
|
|
idx = idxlist[match_to_use] |
|
56
|
|
|
self.widget.view.setCurrentIndex(idx) |
|
57
|
|
|
idx = idx.sibling(idx.row(), 1) |
|
58
|
|
|
self.widget.view.edit(idx) |
|
59
|
|
|
editor = self.widget.view.focusWidget() |
|
60
|
|
|
if not editor: |
|
61
|
|
|
print(app.focusWidget()) |
|
62
|
|
|
print("NO EDITOR WIDGET") |
|
63
|
|
|
#QTest.keyClick(self.widget.view, Qt.Key_Return) |
|
64
|
|
|
from IPython import embed |
|
65
|
|
|
embed() |
|
66
|
|
|
raise RuntimeError("Could not get editor widget!, it does not have the focus") |
|
67
|
|
|
|
|
68
|
|
|
if hasattr(editor, "current_node"): |
|
69
|
|
|
editor.current_node = val |
|
70
|
|
|
elif hasattr(editor, "setCurrentText"): |
|
71
|
|
|
editor.setCurrentText(val) |
|
72
|
|
|
else: |
|
73
|
|
|
editor.setText(val) |
|
74
|
|
|
self.widget.view.commitData(editor) |
|
75
|
|
|
self.widget.view.closeEditor(editor, QAbstractItemDelegate.NoHint) |
|
76
|
|
|
self.widget.view.reset() |
|
77
|
|
|
|
|
78
|
|
|
def modify_value(self, val): |
|
79
|
|
|
self.modify_item("Value", val, 1) |
|
80
|
|
|
|
|
81
|
|
|
def test_display_objects_node(self): |
|
82
|
|
|
objects = self.server.nodes.objects |
|
83
|
|
|
self.widget.show_attrs(objects) |
|
84
|
|
|
self.modify_item("BrowseName", "5:titi") |
|
85
|
|
|
self.assertEqual(objects.get_browse_name().to_string(), "5:titi") |
|
86
|
|
|
self.modify_item("BrowseName", "0:Objects") # restore states for other tests |
|
87
|
|
|
|
|
88
|
|
|
def test_display_var_double(self): |
|
89
|
|
|
objects = self.server.nodes.objects |
|
90
|
|
|
myvar = objects.add_variable(1, "myvar1", 9.99, ua.VariantType.Double) |
|
91
|
|
|
self.widget.show_attrs(myvar) |
|
92
|
|
|
self.modify_value("8.45") |
|
93
|
|
|
self.assertEqual(myvar.get_value(), 8.45) |
|
94
|
|
|
|
|
95
|
|
|
def test_display_var_bytes(self): |
|
96
|
|
|
objects = self.server.nodes.objects |
|
97
|
|
|
myvar = objects.add_variable(1, "myvar_bytes", b"jkl", ua.VariantType.ByteString) |
|
98
|
|
|
self.widget.show_attrs(myvar) |
|
99
|
|
|
self.modify_value("titi") |
|
100
|
|
|
self.assertEqual(myvar.get_value(), b"titi") |
|
101
|
|
|
|
|
102
|
|
|
def test_change_data_type(self): |
|
103
|
|
|
objects = self.server.nodes.objects |
|
104
|
|
|
myvar = objects.add_variable(1, "myvar1", 9.99, ua.VariantType.Double) |
|
105
|
|
|
self.widget.show_attrs(myvar) |
|
106
|
|
|
dtype = myvar.get_data_type() |
|
107
|
|
|
self.assertEqual(dtype, ua.NodeId(ua.ObjectIds.Double)) |
|
108
|
|
|
new_dtype = ua.NodeId(ua.ObjectIds.String) |
|
109
|
|
|
self.modify_item("DataType", self.server.get_node(new_dtype)) |
|
110
|
|
|
self.assertEqual(myvar.get_data_type(), new_dtype) |
|
111
|
|
|
|
|
112
|
|
|
# now try to write a value which is a string |
|
113
|
|
|
self.modify_value("mystring") |
|
114
|
|
|
self.assertEqual(myvar.get_value(), "mystring") |
|
115
|
|
|
|
|
116
|
|
|
def test_change_value_rank(self): # need to find a way to modify combo box with QTest |
|
117
|
|
|
objects = self.server.nodes.objects |
|
118
|
|
|
myvar = objects.add_variable(1, "myvar1", 9.99, ua.VariantType.Double) |
|
119
|
|
|
self.widget.show_attrs(myvar) |
|
120
|
|
|
rank = myvar.get_value_rank() |
|
121
|
|
|
self.modify_item("ValueRank", "ThreeDimensions") |
|
122
|
|
|
self.assertEqual(myvar.get_value_rank(), ua.ValueRank.ThreeDimensions) |
|
123
|
|
|
|
|
124
|
|
|
|
|
125
|
|
|
|
|
126
|
|
|
|
|
127
|
|
|
|
|
128
|
|
|
if __name__ == "__main__": |
|
129
|
|
|
app = QApplication(sys.argv) |
|
130
|
|
|
unittest.main() |
|
131
|
|
|
|
|
132
|
|
|
|
|
133
|
|
|
|