/source/tools/tests/check_source/check_style_c_test.py

https://github.com/mgschwan/blensor · Python · 414 lines · 301 code · 54 blank · 59 comment · 9 complexity · db96553bc81e0b2dc0f110ad884e69b9 MD5 · raw file

  1. #!/usr/bin/env python3
  2. # Apache License, Version 2.0
  3. # python3 -m unittest check_style_c_test.SourceCodeTest.test_whitespace_kw_indent
  4. # ----
  5. import os
  6. import sys
  7. sys.path.append(
  8. os.path.join(
  9. os.path.dirname(__file__),
  10. "..", "..", "check_source",
  11. ))
  12. # ----
  13. import unittest
  14. warnings = []
  15. import check_style_c
  16. check_style_c.print = warnings.append
  17. # ----
  18. parser = check_style_c.create_parser()
  19. # dummy, not used at the moment
  20. args = parser.parse_args(["."])
  21. # ----
  22. # store errors we found
  23. errors = set()
  24. FUNC_BEGIN = """
  25. void func(void)
  26. {
  27. """
  28. FUNC_END = """
  29. }"""
  30. def test_code(code):
  31. warnings.clear()
  32. check_style_c.scan_source("test.c", code, args)
  33. err_found = [w.split(":", 3)[2].strip() for w in warnings]
  34. # print(warnings)
  35. return err_found
  36. class SourceCodeTest(unittest.TestCase):
  37. def assertWarning(self, err_found, *errors_test):
  38. err_set = set(err_found)
  39. errors.update(err_set)
  40. self.assertEqual(err_set, set(errors_test))
  41. def test_brace_function(self):
  42. # --------------------------------------------------------------------
  43. # brace on not on newline (function)
  44. code = """
  45. void func(void) {
  46. \t/* pass */
  47. }"""
  48. err_found = test_code(code)
  49. self.assertWarning(err_found, "E101")
  50. code = """
  51. void func(void)
  52. {
  53. \t/* pass */
  54. }"""
  55. err_found = test_code(code)
  56. self.assertWarning(err_found)
  57. def test_brace_kw_whitespace(self):
  58. # --------------------------------------------------------------------
  59. # brace has whitespace after it
  60. code = FUNC_BEGIN + """
  61. \tif (1){
  62. \t\t/* pass */
  63. \t}""" + FUNC_END
  64. err_found = test_code(code)
  65. self.assertWarning(err_found, "E107", "E150")
  66. code = FUNC_BEGIN + """
  67. \tif (1) {
  68. \t\t/* pass */
  69. \t}""" + FUNC_END
  70. err_found = test_code(code)
  71. self.assertWarning(err_found)
  72. def test_brace_kw_newline(self):
  73. # --------------------------------------------------------------------
  74. # brace on on newline (if, for... )
  75. code = FUNC_BEGIN + """
  76. \tif (1)
  77. \t{
  78. \t\t/* pass */
  79. \t}""" + FUNC_END
  80. err_found = test_code(code)
  81. self.assertWarning(err_found, "E108")
  82. code = FUNC_BEGIN + """
  83. \tif (1) {
  84. \t\t/* pass */
  85. \t}""" + FUNC_END
  86. err_found = test_code(code)
  87. self.assertWarning(err_found)
  88. # allow preprocessor splitting newlines
  89. #
  90. # #ifdef USE_FOO
  91. # if (1)
  92. # #endif
  93. # {
  94. # ...
  95. # }
  96. #
  97. code = FUNC_BEGIN + """
  98. #ifdef USE_FOO
  99. \tif (1)
  100. #endif
  101. \t{
  102. \t\t/* pass */
  103. \t}""" + FUNC_END
  104. err_found = test_code(code)
  105. self.assertWarning(err_found)
  106. def test_brace_do_while(self):
  107. # --------------------------------------------------------------------
  108. # brace on on newline do, while
  109. code = FUNC_BEGIN + """
  110. \tif (1)
  111. \t{
  112. \t\t/* pass */
  113. \t}""" + FUNC_END
  114. err_found = test_code(code)
  115. self.assertWarning(err_found, "E108")
  116. code = FUNC_BEGIN + """
  117. \tif (1) {
  118. \t\t/* pass */
  119. \t}""" + FUNC_END
  120. err_found = test_code(code)
  121. self.assertWarning(err_found)
  122. def test_brace_kw_multiline(self):
  123. # --------------------------------------------------------------------
  124. # brace-multi-line
  125. code = FUNC_BEGIN + """
  126. \tif (a &&
  127. \t b) {
  128. \t\t/* pass */
  129. \t}""" + FUNC_END
  130. err_found = test_code(code)
  131. self.assertWarning(err_found, "E103", "E104")
  132. code = FUNC_BEGIN + """
  133. \tif (a &&
  134. \t b)
  135. \t{
  136. \t\t/* pass */
  137. \t}""" + FUNC_END
  138. err_found = test_code(code)
  139. self.assertWarning(err_found)
  140. def test_brace_indent(self):
  141. # --------------------------------------------------------------------
  142. # do {} while (1);
  143. code = FUNC_BEGIN + """
  144. \tif (1) {
  145. \t\t/* pass */
  146. \t\t}""" + FUNC_END
  147. err_found = test_code(code)
  148. self.assertWarning(err_found, "E104")
  149. code = FUNC_BEGIN + """
  150. \tif (1) {
  151. \t\t/* pass */
  152. \t}""" + FUNC_END
  153. err_found = test_code(code)
  154. self.assertWarning(err_found)
  155. def test_whitespace_kw_no_parens(self):
  156. # --------------------------------------------------------------------
  157. # if MACRO {}
  158. code = FUNC_BEGIN + """
  159. \tif MACRO {
  160. \t\t/* pass */
  161. \t\t}""" + FUNC_END
  162. err_found = test_code(code)
  163. self.assertWarning(err_found, "E104", "E105")
  164. code = FUNC_BEGIN + """
  165. \tif (1) {
  166. \t\t/* pass */
  167. \t}""" + FUNC_END
  168. err_found = test_code(code)
  169. self.assertWarning(err_found)
  170. def test_whitespace_kw_missing(self):
  171. # --------------------------------------------------------------------
  172. code = FUNC_BEGIN + """
  173. \tif(1) {
  174. \t\t/* pass */
  175. \t\t}""" + FUNC_END
  176. err_found = test_code(code)
  177. self.assertWarning(err_found, "E104", "E106")
  178. code = FUNC_BEGIN + """
  179. \tif (1) {
  180. \t\t/* pass */
  181. \t}""" + FUNC_END
  182. err_found = test_code(code)
  183. self.assertWarning(err_found)
  184. def test_brace_kw_newline_missing(self):
  185. # --------------------------------------------------------------------
  186. code = FUNC_BEGIN + """
  187. \tif (1 &&
  188. \t 1) fn();
  189. \telse {}""" + FUNC_END
  190. err_found = test_code(code)
  191. self.assertWarning(err_found, "E103", "E109", "E201")
  192. code = FUNC_BEGIN + """
  193. \tif (1 &&
  194. \t 1)
  195. \t{
  196. \t\tfn();
  197. \t}
  198. \telse {}""" + FUNC_END
  199. err_found = test_code(code)
  200. self.assertWarning(err_found)
  201. def test_brace_kw_newline_split(self):
  202. # --------------------------------------------------------------------
  203. # else
  204. # if () ...
  205. code = FUNC_BEGIN + """
  206. \tif (1) {
  207. \t\tfn();
  208. \t}
  209. \telse
  210. \tif () {
  211. \t\tfn();
  212. \t}""" + FUNC_END
  213. err_found = test_code(code)
  214. self.assertWarning(err_found, "E115")
  215. # Allow an exceptional case - when we have preprocessor in-between
  216. # #ifdef USE_FOO
  217. # if (1) {
  218. # fn();
  219. # }
  220. # else
  221. # #endif
  222. # if (1) {
  223. # fn();
  224. # }
  225. code = FUNC_BEGIN + """
  226. #ifdef USE_FOO
  227. \tif (1) {
  228. \t\tfn();
  229. \t}
  230. \telse
  231. #endif
  232. \tif () {
  233. \t\tfn();
  234. \t}""" + FUNC_END
  235. err_found = test_code(code)
  236. self.assertWarning(err_found)
  237. code = FUNC_BEGIN + """
  238. \tif (1) {
  239. \t\tfn();
  240. \t}
  241. \telse if () {
  242. \t\tfn();
  243. \t}""" + FUNC_END
  244. err_found = test_code(code)
  245. self.assertWarning(err_found)
  246. def test_whitespace_kw_indent(self):
  247. # --------------------------------------------------------------------
  248. code = FUNC_BEGIN + """
  249. \tif (a &&
  250. \t\t\tb &&
  251. \t c)
  252. \t{
  253. \t\t/* pass */
  254. \t}""" + FUNC_END
  255. err_found = test_code(code)
  256. self.assertWarning(err_found, "E110")
  257. code = FUNC_BEGIN + """
  258. \tif (a &&
  259. \t b &&
  260. \t c)
  261. \t{
  262. \t\t/* pass */
  263. \t}""" + FUNC_END
  264. err_found = test_code(code)
  265. self.assertWarning(err_found)
  266. def test_switch(self):
  267. # --------------------------------------------------------------------
  268. code = FUNC_BEGIN + """
  269. \tswitch (value) {
  270. \t\tcase 0 :
  271. \t\t\tcall();
  272. \t\t\tbreak;
  273. \t}""" + FUNC_END
  274. err_found = test_code(code)
  275. self.assertWarning(err_found, "E132")
  276. code = FUNC_BEGIN + """
  277. \tswitch (value) {
  278. \t\tcase 0:
  279. \t\t\tcall();
  280. \t\t\tbreak;
  281. \t}""" + FUNC_END
  282. err_found = test_code(code)
  283. self.assertWarning(err_found)
  284. def test_whitespace_operator(self):
  285. ab_test = (
  286. ("a= 1;",
  287. "a = 1;"),
  288. ("a =A;",
  289. "a = A;"),
  290. ("a = A+0;",
  291. "a = A + 0;"),
  292. ("a+= 1;",
  293. "a += 1;"),
  294. ("a*= 1;",
  295. "a *= 1;"),
  296. ("a *=1;",
  297. "a *= 1;"),
  298. ("a/= 1;",
  299. "a /= 1;"),
  300. ("a /=1;",
  301. "a /= 1;"),
  302. ("a = a?a:0;",
  303. "a = a ? a : 0;"),
  304. ("a = a?a:0;",
  305. "a = a ? a : 0;"),
  306. ("a = a?a : 0;",
  307. "a = a ? a : 0;"),
  308. ("if (a<1) { call(); }",
  309. "if (a < 1) { call(); }"),
  310. ("if (a? c : d) { call(); }",
  311. "if (a ? c : d) { call(); }"),
  312. ("if (a ?c : d) { call(); }",
  313. "if (a ? c : d) { call(); }"),
  314. # check casts don't confuse us
  315. ("a = 1+ (size_t)-b;",
  316. "a = 1 + (size_t)-b;"),
  317. ("a = -(int)b+1;",
  318. "a = -(int)b + 1;"),
  319. ("a = 1+ (int *)*b;",
  320. "a = 1 + (int *)*b;"),
  321. )
  322. for expr_fail, expr_ok in ab_test:
  323. code = FUNC_BEGIN + expr_fail + FUNC_END
  324. err_found = test_code(code)
  325. self.assertWarning(err_found, "E130")
  326. code = FUNC_BEGIN + expr_ok + FUNC_END
  327. err_found = test_code(code)
  328. self.assertWarning(err_found)
  329. class SourceCodeTestComplete(unittest.TestCase):
  330. """ Check we ran all tests.
  331. """
  332. def _test_complete(self):
  333. # --------------------------------------------------------------------
  334. # Check we test all errors
  335. errors_uniq = set()
  336. with open(check_style_c.__file__, 'r', encoding='utf-8') as fh:
  337. import re
  338. # E100
  339. err_re_main = re.compile(r'.*\("(E\d+)"')
  340. # E100.0
  341. err_re_subv = re.compile(r'.*\("(E\d+)\.\d+"') # --> E100
  342. err_re_subv_group = re.compile(r'.*\("(E\d+\.\d+)"') # --> E100.0
  343. for l in fh:
  344. g = err_re_subv.match(l)
  345. if g is None:
  346. g = err_re_main.match(l)
  347. is_sub = False
  348. else:
  349. is_sub = True
  350. if g:
  351. err = g.group(1)
  352. self.assertIn(err, errors)
  353. # ----
  354. # now check we didn't use multiple times
  355. if is_sub:
  356. err = err_re_subv_group.match(l).group(1)
  357. self.assertNotIn(err, errors_uniq)
  358. errors_uniq.add(err)
  359. if __name__ == '__main__':
  360. unittest.main(exit=False)