pr_comments_test.py 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. """Tests for pr_comments.py."""
  2. __copyright__ = """
  3. Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  4. Exceptions. See /LICENSE for license information.
  5. SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. """
  7. import os
  8. import unittest
  9. from unittest import mock
  10. import github_helpers
  11. import pr_comments
  12. class TestPRComments(unittest.TestCase):
  13. def setUp(self):
  14. # Stub out the access token.
  15. os.environ[github_helpers._ENV_TOKEN] = "unused"
  16. def test_format_comment_short(self):
  17. created_at = "2001-02-03T04:05:06Z"
  18. self.assertEqual(
  19. pr_comments._Comment("author", created_at, "brief").format(False),
  20. " author: brief",
  21. )
  22. self.assertEqual(
  23. pr_comments._Comment("author", created_at, "brief\nwrap").format(
  24. False
  25. ),
  26. " author: brief¶ wrap",
  27. )
  28. self.assertEqual(
  29. pr_comments._Comment(
  30. "author", created_at, "brief\n\n\nwrap"
  31. ).format(False),
  32. " author: brief¶¶¶ wrap",
  33. )
  34. self.assertEqual(
  35. pr_comments._Comment(
  36. "author",
  37. created_at,
  38. "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed "
  39. "do eiusmo",
  40. ).format(False),
  41. " author: Lorem ipsum dolor sit amet, consectetur adipiscing "
  42. "elit, sed do eiusmo",
  43. )
  44. self.assertEqual(
  45. pr_comments._Comment(
  46. "author",
  47. created_at,
  48. "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed "
  49. "do eiusmod",
  50. ).format(False),
  51. " author: Lorem ipsum dolor sit amet, consectetur adipiscing "
  52. "elit, sed do eiu...",
  53. )
  54. def test_format_comment_long(self):
  55. created_at = "2001-02-03T04:05:06Z"
  56. self.assertEqual(
  57. pr_comments._Comment("author", created_at, "brief").format(True),
  58. " author at 2001-02-03 04:05:\n brief",
  59. )
  60. self.assertEqual(
  61. pr_comments._Comment("author", created_at, "brief\nwrap").format(
  62. True
  63. ),
  64. " author at 2001-02-03 04:05:\n brief\n wrap",
  65. )
  66. body = (
  67. "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed "
  68. "do eiusmod tempor incididunt ut labore et dolore magna "
  69. "aliqua.\n"
  70. "Ut enim ad minim veniam,"
  71. )
  72. self.assertEqual(
  73. pr_comments._Comment("author", created_at, body).format(True),
  74. " author at 2001-02-03 04:05:\n"
  75. " Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed "
  76. "do eiusmod\n"
  77. " tempor incididunt ut labore et dolore magna aliqua.\n"
  78. " Ut enim ad minim veniam,",
  79. )
  80. @staticmethod
  81. def fake_thread(**kwargs):
  82. with mock.patch.dict(os.environ, {}):
  83. parsed_args = pr_comments._parse_args(["83"])
  84. return pr_comments._Thread(
  85. parsed_args, TestPRComments.fake_thread_dict(**kwargs)
  86. )
  87. @staticmethod
  88. def fake_thread_dict(
  89. is_resolved=False,
  90. path="foo.md",
  91. line=3,
  92. created_at="2001-02-03T04:05:06Z",
  93. ):
  94. thread_dict = {
  95. "isResolved": is_resolved,
  96. "comments": {
  97. "nodes": [
  98. {
  99. "author": {"login": "author"},
  100. "body": "comment",
  101. "createdAt": created_at,
  102. "originalCommit": {"abbreviatedOid": "abcdef"},
  103. "originalPosition": line,
  104. "path": path,
  105. "url": "http://xyz",
  106. },
  107. {
  108. "author": {"login": "other"},
  109. "body": "reply",
  110. "createdAt": "2001-02-03T04:15:16Z",
  111. },
  112. ],
  113. },
  114. }
  115. if is_resolved:
  116. thread_dict["resolvedBy"] = {
  117. "login": "resolver",
  118. "createdAt": "2001-02-03T04:25:26Z",
  119. }
  120. return thread_dict
  121. def test_thread_format(self):
  122. self.assertEqual(
  123. self.fake_thread().format(False),
  124. "https://github.com/carbon-language/carbon-lang/pull/83/"
  125. "files/abcdef#diff-d8ca3b3d314d8209367af0eea2373b6fR3\n"
  126. " - line 3; unresolved\n"
  127. " - diff: https://github.com/carbon-language/carbon-lang/pull/83/"
  128. "files/abcdef..HEAD#diff-d8ca3b3d314d8209367af0eea2373b6fL3\n"
  129. " author: comment\n"
  130. " other: reply",
  131. )
  132. self.assertEqual(
  133. self.fake_thread().format(True),
  134. "https://github.com/carbon-language/carbon-lang/pull/83/files/"
  135. "abcdef#diff-d8ca3b3d314d8209367af0eea2373b6fR3\n"
  136. " - line 3; unresolved\n"
  137. " - diff: https://github.com/carbon-language/carbon-lang/pull/83/"
  138. "files/abcdef..HEAD#diff-d8ca3b3d314d8209367af0eea2373b6fL3\n"
  139. " author at 2001-02-03 04:05:\n"
  140. " comment\n"
  141. " other at 2001-02-03 04:15:\n"
  142. " reply",
  143. )
  144. self.assertEqual(
  145. self.fake_thread(is_resolved=True).format(False),
  146. "https://github.com/carbon-language/carbon-lang/pull/83/"
  147. "files/abcdef#diff-d8ca3b3d314d8209367af0eea2373b6fR3\n"
  148. " - line 3; resolved\n"
  149. " - diff: https://github.com/carbon-language/carbon-lang/pull/83/"
  150. "files/abcdef..HEAD#diff-d8ca3b3d314d8209367af0eea2373b6fL3\n"
  151. " author: comment\n"
  152. " other: reply\n"
  153. " resolver: <resolved>",
  154. )
  155. self.assertEqual(
  156. self.fake_thread(is_resolved=True).format(True),
  157. "https://github.com/carbon-language/carbon-lang/pull/83/"
  158. "files/abcdef#diff-d8ca3b3d314d8209367af0eea2373b6fR3\n"
  159. " - line 3; resolved\n"
  160. " - diff: https://github.com/carbon-language/carbon-lang/pull/83/"
  161. "files/abcdef..HEAD#diff-d8ca3b3d314d8209367af0eea2373b6fL3\n"
  162. " author at 2001-02-03 04:05:\n"
  163. " comment\n"
  164. " other at 2001-02-03 04:15:\n"
  165. " reply\n"
  166. " resolver at 2001-02-03 04:25:\n"
  167. " <resolved>",
  168. )
  169. def test_thread_lt(self):
  170. thread1 = self.fake_thread(line=2)
  171. thread2 = self.fake_thread()
  172. thread3 = self.fake_thread(created_at="2002-02-03T04:05:06Z")
  173. self.assertTrue(thread1 < thread2)
  174. self.assertFalse(thread2 < thread1)
  175. self.assertFalse(thread2 < thread2)
  176. self.assertTrue(thread2 < thread3)
  177. self.assertFalse(thread3 < thread2)
  178. def test_accumulate_thread(self):
  179. with mock.patch.dict(os.environ, {}):
  180. parsed_args = pr_comments._parse_args(["83"])
  181. threads_by_path = {}
  182. review_threads = [
  183. self.fake_thread_dict(line=2),
  184. self.fake_thread_dict(line=4),
  185. self.fake_thread_dict(path="other.md"),
  186. self.fake_thread_dict(),
  187. ]
  188. for thread in review_threads:
  189. pr_comments._accumulate_thread(
  190. parsed_args,
  191. threads_by_path,
  192. thread,
  193. )
  194. self.assertEqual(sorted(threads_by_path.keys()), ["foo.md", "other.md"])
  195. threads = sorted(threads_by_path["foo.md"])
  196. self.assertEqual(len(threads), 3)
  197. self.assertEqual(threads[0].line, 2)
  198. self.assertEqual(threads[1].line, 3)
  199. self.assertEqual(threads[2].line, 4)
  200. self.assertEqual(len(threads_by_path["other.md"]), 1)
  201. @staticmethod
  202. def fake_pr_comment(**kwargs):
  203. return pr_comments._PRComment(
  204. TestPRComments.fake_pr_comment_dict(**kwargs)
  205. )
  206. @staticmethod
  207. def fake_pr_comment_dict(
  208. body="comment",
  209. created_at="2001-02-03T04:05:06Z",
  210. ):
  211. pr_comment_dict = {
  212. "author": {"login": "author"},
  213. "body": body,
  214. "createdAt": created_at,
  215. "url": "http://xyz",
  216. }
  217. return pr_comment_dict
  218. def test_pr_comment_format(self):
  219. self.assertEqual(
  220. self.fake_pr_comment().format(False),
  221. "http://xyz\n author: comment",
  222. )
  223. self.assertEqual(
  224. self.fake_pr_comment().format(True),
  225. "http://xyz\n author at 2001-02-03 04:05:\n comment",
  226. )
  227. def test_pr_comment_lt(self):
  228. pr_comment1 = self.fake_pr_comment()
  229. pr_comment2 = self.fake_pr_comment(created_at="2002-02-03T04:05:06Z")
  230. self.assertTrue(pr_comment1 < pr_comment2)
  231. self.assertFalse(pr_comment2 < pr_comment1)
  232. self.assertFalse(pr_comment2 < pr_comment2)
  233. def test_accumulate_pr_comment(self):
  234. with mock.patch.dict(os.environ, {}):
  235. parsed_args = pr_comments._parse_args(["83"])
  236. raw_comments = [
  237. self.fake_pr_comment_dict(body="x"),
  238. self.fake_pr_comment_dict(body=""),
  239. self.fake_pr_comment_dict(
  240. body="y", created_at="2000-02-03T04:05:06Z"
  241. ),
  242. self.fake_pr_comment_dict(
  243. body="z", created_at="2002-02-03T04:05:06Z"
  244. ),
  245. ]
  246. comments = []
  247. for raw_comment in raw_comments:
  248. pr_comments._accumulate_pr_comment(
  249. parsed_args, comments, raw_comment
  250. )
  251. comments.sort()
  252. self.assertEqual(len(comments), 3)
  253. self.assertEqual(comments[0].body, "y")
  254. self.assertEqual(comments[1].body, "x")
  255. self.assertEqual(comments[2].body, "z")
  256. if __name__ == "__main__":
  257. unittest.main()