test_style.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. """
  4. (c) 2017 - Copyright Red Hat Inc
  5. Authors:
  6. Pierre-Yves Chibon <pingou@pingoured.fr>
  7. Tests for flake8 compliance of the code
  8. """
  9. from __future__ import unicode_literals, absolute_import
  10. import os
  11. import subprocess
  12. import sys
  13. import unittest
  14. import six
  15. REPO_PATH = os.path.abspath(
  16. os.path.join(os.path.dirname(__file__), "..", "pagure")
  17. )
  18. TESTS_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__)))
  19. class TestStyle(unittest.TestCase):
  20. """This test class contains tests pertaining to code style."""
  21. def test_code_with_flake8(self):
  22. """Enforce PEP-8 compliance on the codebase.
  23. This test runs flake8 on the code, and will fail if it returns a
  24. non-zero exit code.
  25. If flake8 is not installed, this test auto-skips.
  26. """
  27. try:
  28. import flake8
  29. except ImportError as e:
  30. raise unittest.SkipTest(
  31. "flake8 is not installed, skipping flake8 style check..."
  32. )
  33. # We ignore E712, which disallows non-identity comparisons with True and False
  34. # We ignore W503, which disallows line break before binary operator
  35. flake8_command = [
  36. sys.executable,
  37. "-m",
  38. "flake8",
  39. "--ignore=E712,W503,E203,E902,I201,I100",
  40. "--max-line-length=80",
  41. REPO_PATH,
  42. ]
  43. # check if we have an old flake8 or not
  44. import flake8
  45. flake8_v = flake8.__version__.split(".")
  46. for idx, val in enumerate(flake8_v):
  47. try:
  48. val = int(val)
  49. except ValueError:
  50. pass
  51. flake8_v[idx] = val
  52. old_flake = tuple(flake8_v) < (3, 0)
  53. if old_flake:
  54. raise unittest.SkipTest("Flake8 version too old to be useful")
  55. proc = subprocess.Popen(
  56. flake8_command, stdout=subprocess.PIPE, cwd=REPO_PATH
  57. )
  58. print(proc.communicate())
  59. self.assertEqual(proc.returncode, 0)
  60. @unittest.skipIf(
  61. not (six.PY3 and sys.version_info.minor >= 6),
  62. "Black is only available in python 3.6+",
  63. )
  64. def test_code_with_black(self):
  65. """Enforce black compliance on the codebase.
  66. This test runs black on the code, and will fail if it returns a
  67. non-zero exit code.
  68. If black is not installed, this test auto-skips.
  69. """
  70. try:
  71. import black
  72. except ImportError as e:
  73. raise unittest.SkipTest(
  74. "black is not installed, skipping black style check..."
  75. )
  76. black_command = [
  77. sys.executable,
  78. "-m",
  79. "black",
  80. "-l",
  81. "79",
  82. "--check",
  83. "--diff",
  84. "--exclude",
  85. '"/(.eggs|.git|.hg|.mypy_cache|.nox|.tox|.venv|_build|buck-out|build|dist)/"',
  86. "--target-version",
  87. "py39",
  88. REPO_PATH,
  89. TESTS_PATH,
  90. ]
  91. proc = subprocess.Popen(
  92. black_command,
  93. stdout=subprocess.PIPE,
  94. stderr=subprocess.PIPE,
  95. cwd=REPO_PATH,
  96. )
  97. stdout, stderr = proc.communicate()
  98. print("stdout: ")
  99. print(stdout.decode("utf-8"))
  100. print("stderr: ")
  101. print(stderr.decode("utf-8"))
  102. self.assertEqual(proc.returncode, 0)
  103. def test_code_with_isort(self):
  104. """Enforce isort compliance on the codebase.
  105. This test runs isort on the code, and will fail if it returns a
  106. non-zero exit code.
  107. If isort is not installed, this test auto-skips.
  108. """
  109. try:
  110. import isort
  111. except ImportError as e:
  112. raise unittest.SkipTest(
  113. "isort is not installed, skipping isort style check..."
  114. )
  115. # We ignore the hooks files that have a bunch of symlink
  116. isort_command = [
  117. sys.executable,
  118. "-m",
  119. "isort",
  120. "-v",
  121. "--profile",
  122. "black",
  123. "-s",
  124. os.path.join(REPO_PATH, "hooks/files"),
  125. "-l",
  126. "79",
  127. REPO_PATH,
  128. ]
  129. # check if we have an old isort or not
  130. import isort
  131. print(" ".join(isort_command))
  132. proc = subprocess.Popen(
  133. isort_command, stdout=subprocess.PIPE, cwd=REPO_PATH
  134. )
  135. stdout, stderr = proc.communicate()
  136. print("stdout: ")
  137. print(stdout.decode("utf-8")) if stdout else ""
  138. print("stderr: ")
  139. print(stderr.decode("utf-8")) if stderr else ""
  140. self.assertEqual(proc.returncode, 0)
  141. if __name__ == "__main__":
  142. unittest.main(verbosity=2)