test_converter_unittest.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. #!/usr/bin/env python
  2. # Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
  3. #
  4. # Redistribution and use in source and binary forms, with or without
  5. # modification, are permitted provided that the following conditions
  6. # are met:
  7. #
  8. # 1. Redistributions of source code must retain the above
  9. # copyright notice, this list of conditions and the following
  10. # disclaimer.
  11. # 2. Redistributions in binary form must reproduce the above
  12. # copyright notice, this list of conditions and the following
  13. # disclaimer in the documentation and/or other materials
  14. # provided with the distribution.
  15. #
  16. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
  17. # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18. # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  19. # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
  20. # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
  21. # OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  22. # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  23. # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24. # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
  25. # TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  26. # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27. # SUCH DAMAGE.
  28. import os
  29. import re
  30. import unittest2 as unittest
  31. from webkitpy.common.system.outputcapture import OutputCapture
  32. from webkitpy.thirdparty.BeautifulSoup import BeautifulSoup
  33. from webkitpy.w3c.test_converter import W3CTestConverter
  34. class W3CTestConverterTest(unittest.TestCase):
  35. def fake_dir_path(self, converter, dirname):
  36. return converter.path_from_webkit_root("LayoutTests", "css", dirname)
  37. def test_read_prefixed_property_list(self):
  38. """ Tests that the current list of properties requiring the -webkit- prefix load correctly """
  39. # FIXME: We should be passing in a MockHost here ...
  40. converter = W3CTestConverter()
  41. prop_list = converter.prefixed_properties
  42. self.assertTrue(prop_list, 'No prefixed properties found')
  43. for prop in prop_list:
  44. self.assertTrue(prop.startswith('-webkit-'))
  45. def test_convert_for_webkit_nothing_to_convert(self):
  46. """ Tests convert_for_webkit() using a basic test that has nothing to convert """
  47. test_html = """<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  48. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  49. <html xmlns="http://www.w3.org/1999/xhtml">
  50. <head>
  51. <title>CSS Test: DESCRIPTION OF TEST</title>
  52. <link rel="author" title="NAME_OF_AUTHOR"
  53. href="mailto:EMAIL OR http://CONTACT_PAGE"/>
  54. <link rel="help" href="RELEVANT_SPEC_SECTION"/>
  55. <meta name="assert" content="TEST ASSERTION"/>
  56. <style type="text/css"><![CDATA[
  57. CSS FOR TEST
  58. ]]></style>
  59. </head>
  60. <body>
  61. CONTENT OF TEST
  62. </body>
  63. </html>
  64. """
  65. converter = W3CTestConverter()
  66. oc = OutputCapture()
  67. oc.capture_output()
  68. try:
  69. converted = converter.convert_html('/nothing/to/convert', test_html)
  70. finally:
  71. oc.restore_output()
  72. self.verify_no_conversion_happened(converted)
  73. def test_convert_for_webkit_harness_only(self):
  74. """ Tests convert_for_webkit() using a basic JS test that uses testharness.js only and has no prefixed properties """
  75. test_html = """<head>
  76. <link href="/resources/testharness.css" rel="stylesheet" type="text/css">
  77. <script src="/resources/testharness.js"></script>
  78. </head>
  79. """
  80. converter = W3CTestConverter()
  81. fake_dir_path = self.fake_dir_path(converter, "harnessonly")
  82. converted = converter.convert_html(fake_dir_path, test_html)
  83. self.verify_conversion_happened(converted)
  84. self.verify_test_harness_paths(converter, converted[1], fake_dir_path, 1, 1)
  85. self.verify_prefixed_properties(converted, [])
  86. def test_convert_for_webkit_properties_only(self):
  87. """ Tests convert_for_webkit() using a test that has 2 prefixed properties: 1 in a style block + 1 inline style """
  88. test_html = """<html>
  89. <head>
  90. <link href="/resources/testharness.css" rel="stylesheet" type="text/css">
  91. <script src="/resources/testharness.js"></script>
  92. <style type="text/css">
  93. #block1 { @test0@: propvalue; }
  94. </style>
  95. </head>
  96. <body>
  97. <div id="elem1" style="@test1@: propvalue;"></div>
  98. </body>
  99. </html>
  100. """
  101. converter = W3CTestConverter()
  102. fake_dir_path = self.fake_dir_path(converter, 'harnessandprops')
  103. test_content = self.generate_test_content(converter.prefixed_properties, 1, test_html)
  104. oc = OutputCapture()
  105. oc.capture_output()
  106. try:
  107. converted = converter.convert_html(fake_dir_path, test_content[1])
  108. finally:
  109. oc.restore_output()
  110. self.verify_conversion_happened(converted)
  111. self.verify_test_harness_paths(converter, converted[1], fake_dir_path, 1, 1)
  112. self.verify_prefixed_properties(converted, test_content[0])
  113. def test_convert_for_webkit_harness_and_properties(self):
  114. """ Tests convert_for_webkit() using a basic JS test that uses testharness.js and testharness.css and has 4 prefixed properties: 3 in a style block + 1 inline style """
  115. test_html = """<html>
  116. <head>
  117. <link href="/resources/testharness.css" rel="stylesheet" type="text/css">
  118. <script src="/resources/testharness.js"></script>
  119. <style type="text/css">
  120. #block1 { @test0@: propvalue; }
  121. #block2 { @test1@: propvalue; }
  122. #block3 { @test2@: propvalue; }
  123. </style>
  124. </head>
  125. <body>
  126. <div id="elem1" style="@test3@: propvalue;"></div>
  127. </body>
  128. </html>
  129. """
  130. converter = W3CTestConverter()
  131. fake_dir_path = self.fake_dir_path(converter, 'harnessandprops')
  132. oc = OutputCapture()
  133. oc.capture_output()
  134. try:
  135. test_content = self.generate_test_content(converter.prefixed_properties, 2, test_html)
  136. converted = converter.convert_html(fake_dir_path, test_content[1])
  137. finally:
  138. oc.restore_output()
  139. self.verify_conversion_happened(converted)
  140. self.verify_test_harness_paths(converter, converted[1], fake_dir_path, 1, 1)
  141. self.verify_prefixed_properties(converted, test_content[0])
  142. def test_convert_test_harness_paths(self):
  143. """ Tests convert_testharness_paths() with a test that uses all three testharness files """
  144. test_html = """<head>
  145. <link href="/resources/testharness.css" rel="stylesheet" type="text/css">
  146. <script src="/resources/testharness.js"></script>
  147. <script src="/resources/testharnessreport.js"></script>
  148. </head>
  149. """
  150. converter = W3CTestConverter()
  151. fake_dir_path = self.fake_dir_path(converter, 'testharnesspaths')
  152. doc = BeautifulSoup(test_html)
  153. oc = OutputCapture()
  154. oc.capture_output()
  155. try:
  156. converted = converter.convert_testharness_paths(doc, fake_dir_path)
  157. finally:
  158. oc.restore_output()
  159. self.verify_conversion_happened(converted)
  160. self.verify_test_harness_paths(converter, doc, fake_dir_path, 2, 1)
  161. def test_convert_prefixed_properties(self):
  162. """ Tests convert_prefixed_properties() file that has 20 properties requiring the -webkit- prefix:
  163. 10 in one style block + 5 in another style
  164. block + 5 inline styles, including one with multiple prefixed properties.
  165. The properties in the test content are in all sorts of wack formatting.
  166. """
  167. test_html = """<html>
  168. <style type="text/css"><![CDATA[
  169. .block1 {
  170. width: 300px;
  171. height: 300px
  172. }
  173. .block2 {
  174. @test0@: propvalue;
  175. }
  176. .block3{@test1@: propvalue;}
  177. .block4 { @test2@:propvalue; }
  178. .block5{ @test3@ :propvalue; }
  179. #block6 { @test4@ : propvalue; }
  180. #block7
  181. {
  182. @test5@: propvalue;
  183. }
  184. #block8 { @test6@: propvalue; }
  185. #block9:pseudo
  186. {
  187. @test7@: propvalue;
  188. @test8@: propvalue propvalue propvalue;;
  189. }
  190. ]]></style>
  191. </head>
  192. <body>
  193. <div id="elem1" style="@test9@: propvalue;"></div>
  194. <div id="elem2" style="propname: propvalue; @test10@ : propvalue; propname:propvalue;"></div>
  195. <div id="elem2" style="@test11@: propvalue; @test12@ : propvalue; @test13@ :propvalue;"></div>
  196. <div id="elem3" style="@test14@:propvalue"></div>
  197. </body>
  198. <style type="text/css"><![CDATA[
  199. .block10{ @test15@: propvalue; }
  200. .block11{ @test16@: propvalue; }
  201. .block12{ @test17@: propvalue; }
  202. #block13:pseudo
  203. {
  204. @test18@: propvalue;
  205. @test19@: propvalue;
  206. }
  207. ]]></style>
  208. </html>
  209. """
  210. converter = W3CTestConverter()
  211. test_content = self.generate_test_content(converter.prefixed_properties, 20, test_html)
  212. oc = OutputCapture()
  213. oc.capture_output()
  214. try:
  215. converted = converter.convert_prefixed_properties(BeautifulSoup(test_content[1]))
  216. finally:
  217. oc.restore_output()
  218. self.verify_conversion_happened(converted)
  219. self.verify_prefixed_properties(converted, test_content[0])
  220. def verify_conversion_happened(self, converted):
  221. self.assertTrue(converted, "conversion didn't happen")
  222. def verify_no_conversion_happened(self, converted):
  223. self.assertEqual(converted, None, 'test should not have been converted')
  224. def verify_test_harness_paths(self, converter, converted, test_path, num_src_paths, num_href_paths):
  225. if isinstance(converted, basestring):
  226. converted = BeautifulSoup(converted)
  227. resources_dir = converter.path_from_webkit_root("LayoutTests", "resources")
  228. # Verify the original paths are gone, and the new paths are present.
  229. orig_path_pattern = re.compile('\"/resources/testharness')
  230. self.assertEquals(len(converted.findAll(src=orig_path_pattern)), 0, 'testharness src path was not converted')
  231. self.assertEquals(len(converted.findAll(href=orig_path_pattern)), 0, 'testharness href path was not converted')
  232. new_relpath = os.path.relpath(resources_dir, test_path)
  233. relpath_pattern = re.compile(new_relpath)
  234. self.assertEquals(len(converted.findAll(src=relpath_pattern)), num_src_paths, 'testharness src relative path not correct')
  235. self.assertEquals(len(converted.findAll(href=relpath_pattern)), num_href_paths, 'testharness href relative path not correct')
  236. def verify_prefixed_properties(self, converted, test_properties):
  237. self.assertEqual(len(converted[0]), len(test_properties), 'Incorrect number of properties converted')
  238. for test_prop in test_properties:
  239. self.assertTrue((test_prop in converted[1]), 'Property ' + test_prop + ' not found in converted doc')
  240. def generate_test_content(self, full_property_list, num_test_properties, html):
  241. """Inserts properties requiring a -webkit- prefix into the content, replacing \'@testXX@\' with a property."""
  242. test_properties = []
  243. count = 0
  244. while count < num_test_properties:
  245. test_properties.append(full_property_list[count])
  246. count += 1
  247. # Replace the tokens in the testhtml with the test properties. Walk backward
  248. # through the list to replace the double-digit tokens first
  249. index = len(test_properties) - 1
  250. while index >= 0:
  251. # Use the unprefixed version
  252. test_prop = test_properties[index].replace('-webkit-', '')
  253. # Replace the token
  254. html = html.replace('@test' + str(index) + '@', test_prop)
  255. index -= 1
  256. return (test_properties, html)