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