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:48409/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
|
|
|
|