convert_to_istanbul_test.py 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. #!/usr/bin/env vpython3
  2. # Copyright 2021 The Chromium Authors. All rights reserved.
  3. # Use of this source code is governed by a BSD-style license that can be
  4. # found in the LICENSE file.
  5. import mock
  6. import os
  7. import shutil
  8. import tempfile
  9. import unittest
  10. import merge_js_lib as merger
  11. _MODULES_PATH = os.path.join(
  12. '..', '..', '..', 'third_party', 'node', 'node_modules', 'v8-to-istanbul')
  13. _COVERAGE_MODULES_EXIST = os.path.exists(_MODULES_PATH)
  14. class ConvertToIstanbulTest(unittest.TestCase):
  15. _TEST_SOURCE_A = """function add(a, b) {
  16. return a + b;
  17. }
  18. function subtract(a, b) {
  19. return a - b;
  20. }
  21. subtract(5, 2);
  22. """
  23. _TEST_COVERAGE_A = """{
  24. "result": [
  25. {
  26. "scriptId":"72",
  27. "url":"//file.js",
  28. "functions":[
  29. {
  30. "functionName":"",
  31. "ranges":[
  32. {"startOffset":0,"endOffset":101,"count":1}
  33. ],
  34. "isBlockCoverage":true
  35. },
  36. {
  37. "functionName":"add",
  38. "ranges":[
  39. {"startOffset":0,"endOffset":38,"count":0}
  40. ],
  41. "isBlockCoverage":false
  42. },
  43. {
  44. "functionName":"subtract",
  45. "ranges":[
  46. {"startOffset":40,"endOffset":83,"count":1}
  47. ],
  48. "isBlockCoverage":true
  49. }
  50. ]
  51. }
  52. ]
  53. }
  54. """
  55. _TEST_COVERAGE_INVALID = """{
  56. "scriptId":"72",
  57. "url":"//file.js",
  58. "functions":[
  59. {
  60. "functionName":"",
  61. "ranges":[
  62. {"startOffset":0,"endOffset":101,"count":1}
  63. ],
  64. "isBlockCoverage":true
  65. },
  66. {
  67. "functionName":"add",
  68. "ranges":[
  69. {"startOffset":0,"endOffset":38,"count":0}
  70. ],
  71. "isBlockCoverage":false
  72. },
  73. {
  74. "functionName":"subtract",
  75. "ranges":[
  76. {"startOffset":40,"endOffset":83,"count":1}
  77. ],
  78. "isBlockCoverage":true
  79. }
  80. ]
  81. }
  82. """
  83. _TEST_SOURCE_B = """const {subtract} = require('./test1.js');
  84. function add(a, b) {
  85. return a + b;
  86. }
  87. subtract(5, 2);
  88. """
  89. _TEST_SOURCE_C = """exports.subtract = function(a, b) {
  90. return a - b;
  91. }
  92. """
  93. _TEST_COVERAGE_B = """{
  94. "result":[
  95. {
  96. "scriptId":"72",
  97. "url":"//test.js",
  98. "functions":[
  99. {
  100. "functionName":"",
  101. "ranges":[
  102. {"startOffset":0,"endOffset":99,"count":1}
  103. ],
  104. "isBlockCoverage":true
  105. },
  106. {
  107. "functionName":"add",
  108. "ranges":[
  109. {"startOffset":43,"endOffset":81,"count":0}
  110. ],
  111. "isBlockCoverage":false
  112. }
  113. ]
  114. },
  115. {
  116. "scriptId":"73",
  117. "url":"//test1.js",
  118. "functions":[
  119. {
  120. "functionName":"",
  121. "ranges":[
  122. {"startOffset":0,"endOffset":54,"count":1}
  123. ],
  124. "isBlockCoverage":true
  125. },
  126. {
  127. "functionName":"exports.subtract",
  128. "ranges":[
  129. {"startOffset":19,"endOffset":53,"count":1}
  130. ],
  131. "isBlockCoverage":true
  132. }
  133. ]
  134. }
  135. ]
  136. }
  137. """
  138. _TEST_COVERAGE_NO_LEADING_SLASH = """{
  139. "result":[
  140. {
  141. "scriptId":"72",
  142. "url":"file:///usr/local/google/home/benreich/v8-to-istanbul/test.js",
  143. "functions":[
  144. {
  145. "functionName":"",
  146. "ranges":[
  147. {"startOffset":0,"endOffset":99,"count":1}
  148. ],
  149. "isBlockCoverage":true
  150. },
  151. {
  152. "functionName":"add",
  153. "ranges":[
  154. {"startOffset":43,"endOffset":81,"count":0}
  155. ],
  156. "isBlockCoverage":false
  157. }
  158. ]
  159. },
  160. {
  161. "scriptId":"73",
  162. "url":"//test1.js",
  163. "functions":[
  164. {
  165. "functionName":"",
  166. "ranges":[
  167. {"startOffset":0,"endOffset":54,"count":1}
  168. ],
  169. "isBlockCoverage":true
  170. },
  171. {
  172. "functionName":"exports.subtract",
  173. "ranges":[
  174. {"startOffset":19,"endOffset":53,"count":1}
  175. ],
  176. "isBlockCoverage":true
  177. }
  178. ]
  179. }
  180. ]
  181. }
  182. """
  183. _TEST_COVERAGE_DUPLICATE_SINGLE = """{
  184. "result":[
  185. {
  186. "scriptId":"73",
  187. "url":"//test1.js",
  188. "functions":[
  189. {
  190. "functionName":"",
  191. "ranges":[
  192. {"startOffset":0,"endOffset":54,"count":1}
  193. ],
  194. "isBlockCoverage":true
  195. },
  196. {
  197. "functionName":"exports.subtract",
  198. "ranges":[
  199. {"startOffset":19,"endOffset":53,"count":1}
  200. ],
  201. "isBlockCoverage":true
  202. }
  203. ]
  204. }
  205. ]
  206. }
  207. """
  208. _TEST_COVERAGE_DUPLICATE_DOUBLE = """{
  209. "result":[
  210. {
  211. "scriptId":"72",
  212. "url":"//test.js",
  213. "functions":[
  214. {
  215. "functionName":"",
  216. "ranges":[
  217. {"startOffset":0,"endOffset":99,"count":1}
  218. ],
  219. "isBlockCoverage":true
  220. },
  221. {
  222. "functionName":"add",
  223. "ranges":[
  224. {"startOffset":43,"endOffset":81,"count":0}
  225. ],
  226. "isBlockCoverage":false
  227. }
  228. ]
  229. },
  230. {
  231. "scriptId":"73",
  232. "url":"//test1.js",
  233. "functions":[
  234. {
  235. "functionName":"",
  236. "ranges":[
  237. {"startOffset":0,"endOffset":54,"count":1}
  238. ],
  239. "isBlockCoverage":true
  240. },
  241. {
  242. "functionName":"exports.subtract",
  243. "ranges":[
  244. {"startOffset":19,"endOffset":53,"count":1}
  245. ],
  246. "isBlockCoverage":true
  247. }
  248. ]
  249. }
  250. ]
  251. }
  252. """
  253. def setUp(self):
  254. self.task_output_dir = tempfile.mkdtemp()
  255. self.coverage_dir = os.path.join(self.task_output_dir, 'coverages')
  256. self.source_dir = os.path.join(self.task_output_dir, 'source')
  257. os.makedirs(self.coverage_dir)
  258. os.makedirs(self.source_dir)
  259. def tearDown(self):
  260. shutil.rmtree(self.task_output_dir)
  261. def list_files(self, absolute_path):
  262. actual_files = []
  263. for root, _, files in os.walk(absolute_path):
  264. actual_files.extend([
  265. os.path.join(root, file_name) for file_name in files
  266. ])
  267. return actual_files
  268. def _write_files(self, root_dir, *file_path_contents):
  269. for data in file_path_contents:
  270. file_path, contents = data
  271. with open(os.path.join(root_dir, file_path), 'w') as f:
  272. f.write(contents)
  273. def write_sources(self, *file_path_contents):
  274. self._write_files(self.source_dir, *file_path_contents)
  275. def write_coverages(self, *file_path_contents):
  276. self._write_files(self.coverage_dir, *file_path_contents)
  277. @unittest.skipUnless(_COVERAGE_MODULES_EXIST, 'requires JS coverage modules')
  278. def test_happy_path(self):
  279. self.write_sources(('file.js', self._TEST_SOURCE_A))
  280. self.write_coverages(('test_coverage.cov.json', self._TEST_COVERAGE_A))
  281. merger.convert_raw_coverage_to_istanbul(
  282. [self.coverage_dir], self.source_dir, self.task_output_dir)
  283. istanbul_files = self.list_files(
  284. os.path.join(self.task_output_dir, 'istanbul'))
  285. self.assertEqual(len(istanbul_files), 1)
  286. @unittest.skipUnless(_COVERAGE_MODULES_EXIST, 'requires JS coverage modules')
  287. def test_no_coverages_in_file(self):
  288. coverage_file = """{
  289. "result": []
  290. }
  291. """
  292. self.write_sources(('file.js', self._TEST_SOURCE_A))
  293. self.write_coverages(('test_coverage.cov.json', coverage_file))
  294. merger.convert_raw_coverage_to_istanbul(
  295. [self.coverage_dir], self.source_dir, self.task_output_dir)
  296. istanbul_files = self.list_files(
  297. os.path.join(self.task_output_dir, 'istanbul'))
  298. self.assertEqual(len(istanbul_files), 0)
  299. @unittest.skipUnless(_COVERAGE_MODULES_EXIST, 'requires JS coverage modules')
  300. def test_invalid_coverage_file(self):
  301. self.write_sources(('file.js', self._TEST_SOURCE_A))
  302. self.write_coverages(
  303. ('test_coverage.cov.json', self._TEST_COVERAGE_INVALID))
  304. self.assertRaises(merger.convert_raw_coverage_to_istanbul(
  305. [self.coverage_dir], self.source_dir, self.task_output_dir))
  306. @unittest.skipUnless(_COVERAGE_MODULES_EXIST, 'requires JS coverage modules')
  307. def test_multiple_coverages_single_file(self):
  308. self.write_sources(('test.js', self._TEST_SOURCE_B))
  309. self.write_sources(('test1.js', self._TEST_SOURCE_C))
  310. self.write_coverages(('test_coverage.cov.json', self._TEST_COVERAGE_B))
  311. merger.convert_raw_coverage_to_istanbul(
  312. [self.coverage_dir], self.source_dir, self.task_output_dir)
  313. istanbul_files = self.list_files(
  314. os.path.join(self.task_output_dir, 'istanbul'))
  315. self.assertEqual(len(istanbul_files), 2)
  316. @unittest.skipUnless(_COVERAGE_MODULES_EXIST, 'requires JS coverage modules')
  317. def test_multiple_coverages_no_leading_double_slash(self):
  318. self.write_sources(('test.js', self._TEST_SOURCE_B))
  319. self.write_sources(('test1.js', self._TEST_SOURCE_C))
  320. self.write_coverages(
  321. ('test_coverage.cov.json', self._TEST_COVERAGE_NO_LEADING_SLASH))
  322. merger.convert_raw_coverage_to_istanbul(
  323. [self.coverage_dir], self.source_dir, self.task_output_dir)
  324. istanbul_files = self.list_files(
  325. os.path.join(self.task_output_dir, 'istanbul'))
  326. self.assertEqual(len(istanbul_files), 1)
  327. @unittest.skipUnless(_COVERAGE_MODULES_EXIST, 'requires JS coverage modules')
  328. def test_multiple_duplicate_coverages_flattened(self):
  329. self.write_sources(('test.js', self._TEST_SOURCE_B))
  330. self.write_sources(('test1.js', self._TEST_SOURCE_C))
  331. self.write_coverages(
  332. ('test_coverage_1.cov.json', self._TEST_COVERAGE_B))
  333. self.write_coverages(
  334. ('test_coverage_2.cov.json', self._TEST_COVERAGE_DUPLICATE_DOUBLE))
  335. merger.convert_raw_coverage_to_istanbul(
  336. [self.coverage_dir], self.source_dir, self.task_output_dir)
  337. istanbul_files = self.list_files(
  338. os.path.join(self.task_output_dir, 'istanbul'))
  339. self.assertEqual(len(istanbul_files), 2)
  340. if __name__ == '__main__':
  341. unittest.main()