Skip to content

Commit 7bcc83b

Browse files
carsten-kueblerjdsika
authored andcommitted
Update readme.md (#216)
* Update readme.md Link to online doxygen documentation. * Add test cases check enum names * Python2 Bugfix for test cases * Bugfix for python2 * Bugfix * Add test cases and correct short comments * Documentation Remove spaces at eol. Bugfix: Python 3 is ">= (3,0)" Improve error messages.
1 parent 5a60a8f commit 7bcc83b

File tree

4 files changed

+170
-10
lines changed

4 files changed

+170
-10
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ is available [here](https://github.com/OpenSimulationInterface/osi-sensor-model-
8686
Documentation
8787
-------------
8888

89+
The actual documentation of the GitHub master branch is [online](https://opensimulationinterface.github.io/open-simulation-interface/) available.
90+
8991
Detailed information about installation and usage of OSI can be found in the [Wiki](https://github.com/OpenSimulationInterface/open-simulation-interface/wiki)
9092

9193
In order to generate the doxygen documentation for OSI, please follow the following steps:

osi_object.proto

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,15 +185,19 @@ message StationaryObject
185185
DENSITY_SOLID = 2;
186186

187187
// Perforation max. ]0; 100] [mm]
188+
//
188189
DENSITY_SMALL_MESH = 3;
189190

190191
// Perforation max. ]100; 500] [mm]
192+
//
191193
DENSITY_MEDIAN_MESH = 4;
192194

193195
// Perforation max. ]500; 5000] [mm]
196+
//
194197
DENSITY_LARGE_MESH = 5;
195198

196199
// Perforation max. ]5000; infinity] [mm]
200+
//
197201
DENSITY_OPEN = 6;
198202
}
199203

osi_sensorviewconfiguration.proto

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ message GenericSensorViewConfiguration
281281
optional double field_of_view_vertical = 5;
282282

283283
// TBD: Generic sensor specific configuration.
284+
//
284285
}
285286

286287
//
@@ -677,6 +678,7 @@ message CameraSensorViewConfiguration
677678
}
678679

679680
// TBD: Optical (and other) effects to apply to image, etc.
681+
//
680682
}
681683

682684
//
@@ -746,4 +748,5 @@ message UltrasonicSensorViewConfiguration
746748
optional double field_of_view_vertical = 5;
747749

748750
// TBD: Ultrasonic Sensor specific configuration.
751+
//
749752
}

test_cases.py

Lines changed: 161 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,174 @@
11
import sys
2+
import unicodedata
3+
import re
24
from glob import *
35

46
state = 0
57

68
for file in glob("*.*"):
7-
if(file != "test_cases.py"):
8-
with open(file, "rt") as fin:
9-
i = 0
10-
for line in fin:
11-
i = i + 1
12-
13-
# Test case 1 is checking if there are illegal tabulators in the code
14-
if line.find("\t") != -1:
15-
print(file + " in line " + str(i) + ": not permitted tab found")
9+
with open(file, "rt") as fin:
10+
i = 0
11+
isEnum = False
12+
enumName = ""
13+
noMessage = 0
14+
noComment = 0
15+
16+
for line in fin:
17+
i = i + 1
18+
19+
# --------------------------------------------------------------
20+
# Test case 1 is checking if there are illegal tabulators in the code
21+
if line.find("\t") != -1:
22+
print(file + " in line " + str(i) + ": not permitted tab found")
23+
state = 1
24+
25+
# --------------------------------------------------------------
26+
# Test case 2 is checking if there is an "Umlaut" etc.
27+
if (sys.version_info >= (3, 0)):
28+
if line != unicodedata.normalize('NFKD', line).encode('ASCII', 'ignore').decode():
29+
print(file + " in line " + str(i) + ": a none ASCII char is present")
30+
state = 1
31+
else:
32+
if line != unicodedata.normalize('NFKD', unicode(line, 'ISO-8859-1')).encode('ASCII', 'ignore'):
33+
print(file + " in line " + str(i) + ": a none ASCII char is present")
1634
state = 1
1735

18-
# Test case 2 is checking if there are more than the two allowed '/'
36+
if file.find(".proto") != -1:
37+
# --------------------------------------------------------------
38+
# Test case 3 is checking if there are more than the two allowed '/'
1939
if line.find("///") != -1:
2040
print(file + " in line " + str(i) + ": not permitted use of '///' ")
2141
state = 1
2242

43+
# --------------------------------------------------------------
44+
# Test case 4 is checking if there is an other type of comment
45+
if line.find("/*") != -1:
46+
print(file + " in line " + str(i) + ": not permitted use of '/*' ")
47+
state = 1
48+
49+
# --------------------------------------------------------------
50+
# Test case 5 is checking if there is an other type of comment
51+
if line.find("*/") != -1:
52+
print(file + " in line " + str(i) + ": not permitted use of '*/' ")
53+
state = 1
54+
55+
# --------------------------------------------------------------
56+
57+
# Search for comment ("//") and add one more slash character ("/") to the comment
58+
# block to make Doxygen detect it.
59+
matchComment = re.search("//", line)
60+
if matchComment is not None:
61+
statement = line[:matchComment.start()]
62+
else:
63+
statement = line
64+
65+
# --------------------------------------------------------------
66+
# Test case 6-8 camelcase for enums and check enum name?
67+
68+
# .
69+
if isEnum is True:
70+
matchName = re.search(r"\b\w[\S:]+\b", statement)
71+
if matchName is not None:
72+
checkName = statement[matchName.start():matchName.end()]
73+
# Test case 6: Check correct name
74+
if checkName.find(enumName) != 0:
75+
print(file + " in line " + str(i) + ": enum type wrong. '"+checkName+"' should start with '"+enumName+"'")
76+
state = 1
77+
# Test case 7: Check upper case
78+
elif checkName != checkName.upper():
79+
print(file + " in line " + str(i) + ": enum type wrong. '"+checkName+"' should use upper case")
80+
state = 1
81+
82+
# Search for "enum".
83+
matchEnum = re.search(r"\benum\b", statement)
84+
if matchEnum is not None:
85+
isEnum = True
86+
endOfLine = statement[matchEnum.end():]
87+
matchName = re.search(r"\b\w[\S]*\b", endOfLine)
88+
if matchName is not None:
89+
# Test case 8: Check name - no special char
90+
matchNameConv = re.search(r"\b[A-Z][a-zA-Z0-9]*\b",endOfLine[matchName.start():matchName.end()])
91+
if matchNameConv is None:
92+
print(file + " in line " + str(i) + ": enum name wrong. '"+endOfLine[matchName.start():matchName.end()]+"'")
93+
state = 1
94+
enumName = convert(endOfLine[matchName.start():matchName.end()])+"_"
95+
96+
# Search for a closing brace.
97+
matchClosingBrace = re.search("}", statement)
98+
if isEnum is True and matchClosingBrace is not None:
99+
isEnum = False
100+
enumName = ""
101+
102+
def convert(name):
103+
s1 = re.sub(r'(.)([A-Z][a-z]+)', r'\1_\2', name)
104+
return re.sub(r'([a-z0-9])([A-Z])', r'\1_\2', s1).upper()
105+
106+
# --------------------------------------------------------------
107+
# Test case 9 is checking if there is '__'
108+
if line.find("__") != -1:
109+
print(file + " in line " + str(i) + ": not permitted use of '__' ")
110+
state = 1
111+
112+
# --------------------------------------------------------------
113+
# Test case 10-12 check message name, field type and field name
114+
#
115+
# Check (nested) messages
116+
117+
if isEnum is False:
118+
# Check if not inside an enum.
119+
120+
# Search for "message".
121+
matchMessage = re.search(r"\bmessage\b", statement)
122+
if matchMessage is not None:
123+
# a new message or a new nested message
124+
noMessage += 1
125+
endOfLine = statement[matchMessage.end():]
126+
matchName = re.search(r"\b\w[\S]*\b", endOfLine)
127+
if matchName is not None:
128+
# Test case 10: Check name - no special char -
129+
# start with a capital letter
130+
matchNameConv = re.search(r"\b[A-Z][a-zA-Z0-9]*\b",endOfLine[matchName.start():matchName.end()])
131+
if matchNameConv is None:
132+
print(file + " in line " + str(i) + ": message name wrong. '"+endOfLine[matchName.start():matchName.end()]+"'")
133+
state = 1
134+
else:
135+
# Check field names
136+
if noMessage > 0:
137+
matchName = re.search(r"\b\w[\S]*\b\s*=", statement)
138+
if matchName is not None:
139+
checkName = statement[matchName.start():matchName.end()-1]
140+
# Test case 11: Check lowercase letters for field names
141+
if checkName != checkName.lower():
142+
print(file + " in line " + str(i) + ": field name wrong. '"+checkName+"' should use lower case")
143+
state = 1
144+
# Check field message type (remove field name)
145+
type = statement.replace(checkName, "")
146+
matchName = re.search(r"\b\w[\S\.]*\s*=", type)
147+
if matchName is not None:
148+
checkType = " "+type[matchName.start():matchName.end()-1]+" "
149+
# Test case 12: Check nested message type
150+
matchNameConv = re.search(r"[ ][a-zA-Z][a-zA-Z0-9]*([\.][A-Z][a-zA-Z0-9]*)*[ ]",checkType)
151+
if matchNameConv is None:
152+
print(file + " in line " + str(i) + ": field message type wrong. Check: '"+checkType+"'")
153+
state = 1
154+
155+
# Search for a closing brace.
156+
matchClosingBrace = re.search("}", statement)
157+
if noMessage > 0 and matchClosingBrace is not None:
158+
noMessage -= 1
159+
160+
# --------------------------------------------------------------
161+
# Test case 13 is checking if comment is min. 2 lines
162+
if line.find("//") != -1:
163+
noComment += 1;
164+
else:
165+
if noComment == 1:
166+
print(file + " in line " + str(i-1) + ": short comment - min. 2 lines.")
167+
state = 1
168+
noComment = 0
169+
170+
# --------------------------------------------------------------
171+
172+
23173
sys.exit(state)
174+

0 commit comments

Comments
 (0)