Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: tools/testing/frogpad/frogpad.py

Issue 9454004: frogpad now invokes DumpRenderTree (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 2
3 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 3 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
4 # for details. All rights reserved. Use of this source code is governed by a 4 # for details. All rights reserved. Use of this source code is governed by a
5 # BSD-style license that can be found in the LICENSE file. 5 # BSD-style license that can be found in the LICENSE file.
6 # 6 #
7 7
8 """ 8 """
9 Generates an html file (frogpad.html) that can be used to execute the frog 9 Generates an html file (frogpad.html) that can be used to execute the frog
10 compiler in a web browser or DumpRenderTree, 10 compiler in a web browser or DumpRenderTree,
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 <body> 84 <body>
85 <h1>Frogpad</h1> 85 <h1>Frogpad</h1>
86 <div class="label">Input:</div> 86 <div class="label">Input:</div>
87 <textarea id="input"></textarea> 87 <textarea id="input"></textarea>
88 <div class="label">Compiler Messages:</div> 88 <div class="label">Compiler Messages:</div>
89 <pre id="warnings"></pre> 89 <pre id="warnings"></pre>
90 <div class="label">Timing:</div> 90 <div class="label">Timing:</div>
91 <pre id="timing"></pre> 91 <pre id="timing"></pre>
92 <div class="label">Output:</div> 92 <div class="label">Output:</div>
93 <pre id="output"></pre> 93 <pre id="output"></pre>
94 <script type="text/javascript" src={{FROGPAD_JS}} ></script> 94 <script type="text/javascript">
95 {{FROGPAD_JS}}
Siggi Cherem (dart-lang) 2012/02/23 16:43:26 note that this approach works ok on any code that
96 </script>
95 </body> 97 </body>
96 </html> 98 </html>
97 """ 99 """
98 100
99 # We use "application/inert" here to make the browser ignore the 101 # We use "application/inert" here to make the browser ignore the
100 # these script tags. (frogpad.dart will fish out the contents as needed.) 102 # these script tags. (frogpad.dart will fish out the contents as needed.)
101 # 103 #
102 SCRIPT_TAG = """<script type="application/inert" id="{{id}}"> 104 SCRIPT_TAG = """<script type="application/inert" id="{{id}}">
103 {{contents}} 105 {{contents}}
104 </script> 106 </script>
(...skipping 21 matching lines...) Expand all
126 class Pad(object): 128 class Pad(object):
127 """ 129 """
128 Accumulates all source files that are needed to compile a dart program, 130 Accumulates all source files that are needed to compile a dart program,
129 and places them in <script> tags on an html page. 131 and places them in <script> tags on an html page.
130 """ 132 """
131 133
132 def __init__(self, argv): 134 def __init__(self, argv):
133 parser = optparse.OptionParser() 135 parser = optparse.OptionParser()
134 parser.add_option("-r", "--rebuild", action="store_true", 136 parser.add_option("-r", "--rebuild", action="store_true",
135 help="forces rebuild of frogpad_js") 137 help="forces rebuild of frogpad_js")
138 parser.add_option("-o", "--out",
139 help="name of javascript output file")
136 (options, args) = parser.parse_args(argv) 140 (options, args) = parser.parse_args(argv)
137 141
138 if len(args) < 2: 142 if len(args) < 2:
139 usage() 143 usage()
140 144
141 self.main_file = os.path.abspath(args[1]) 145 self.main_file = os.path.abspath(args[1])
142 146
143 # directory of this script 147 # directory of this script
144 self.frogpad_dir = os.path.abspath(os.path.dirname(argv[0])) 148 self.frogpad_dir = os.path.abspath(os.path.dirname(argv[0]))
145 149
146 # root of dart source repo 150 # root of dart source repo
147 self.dart_dir = os.path.dirname(os.path.dirname(os.path.dirname( 151 self.dart_dir = os.path.dirname(os.path.dirname(os.path.dirname(
148 self.frogpad_dir))) 152 self.frogpad_dir)))
149 153
150 # directory of frog compiler source code 154 # directory of frog compiler source code
151 self.frog_dir = os.path.join(self.dart_dir, "frog") 155 self.frog_dir = os.path.join(self.dart_dir, "frog")
152 156
153 logging.debug("dartdir_dir: '%s'" % self.dart_dir) 157 logging.debug("dartdir_dir: '%s'" % self.dart_dir)
154 logging.debug("frog_dir: '%s'" % self.frog_dir) 158 logging.debug("frog_dir: '%s'" % self.frog_dir)
155 logging.debug("frogpad_dir: '%s'" % self.frogpad_dir) 159 logging.debug("frogpad_dir: '%s'" % self.frogpad_dir)
156 160
157 # name of frogpad_js file 161 # name of frogpad_js file
158 self.frogpad_js = os.path.join(self.frogpad_dir, FROGPAD_JS) 162 self.frogpad_js = os.path.join(self.frogpad_dir, FROGPAD_JS)
159 163
160 html_file = self.main_file + ".frogpad.html" 164 if options.out:
165 # user has specified an output file
166 self.js_file = os.path.abspath(options.out)
167 else:
168 # user didn't specify an output file, so base the name on the
169 # input file
170 self.js_file = self.main_file + ".frogpad.js"
171
172 logging.debug("js_file: '%s" % self.js_file)
173
174 # this is the html file that we pass to DumpRenderTree
175 self.html_file = self.js_file + ".frogpad.html"
176 logging.debug("html_file: '%s'" % self.html_file)
161 177
162 # map from file name to File object (contains entries for all corelib 178 # map from file name to File object (contains entries for all corelib
163 # and all other dart files needed to compile main_file) 179 # and all other dart files needed to compile main_file)
164 self.name_to_file = {} 180 self.name_to_file = {}
165 181
166 # map from script tag id to File object 182 # map from script tag id to File object
167 self.id_to_file = {} 183 self.id_to_file = {}
168 184
169 if not os.path.exists(self.frogpad_js): 185 if not os.path.exists(self.frogpad_js):
170 options.rebuild = True 186 options.rebuild = True
171 187
172 if options.rebuild: 188 if options.rebuild:
173 self.build_frogpad_js() 189 self.build_frogpad_js()
174 190
175 self.load_libraries() 191 self.load_libraries()
176 self.load_file(self.main_file) 192 self.load_file(self.main_file)
177 193
178 html = self.generate_html() 194 html = self.generate_html()
195 write_file(self.html_file, html)
179 196
180 with open(html_file, "w") as output: 197 js = self.generate_js()
181 output.write(html) 198 logging.debug("found javascript in drt output (%d lines)",
182 logging.info("generated '%s' (%d bytes)" % (html_file, len(html))) 199 len(js.splitlines()))
183 200 write_file(self.js_file, js)
201 logging.info("generated '%s'", self.js_file)
184 202
185 def build_frogpad_js(self): 203 def build_frogpad_js(self):
186 dart_vm = os.path.join(self.dart_dir, "out/Release_ia32/dart") 204 dart_vm = os.path.join(self.dart_dir, "out/Release_ia32/dart")
187 check_exists(dart_vm) 205 check_exists(dart_vm)
188 206
189 frogc_dart = os.path.join(self.frog_dir, "frogc.dart") 207 frogc_dart = os.path.join(self.frog_dir, "frogc.dart")
190 frogpad_dart = os.path.join(self.frogpad_dir, "frogpad.dart") 208 frogpad_dart = os.path.join(self.frogpad_dir, "frogpad.dart")
191 check_exists(frogc_dart) 209 check_exists(frogc_dart)
192 check_exists(frogpad_dart) 210 check_exists(frogpad_dart)
193 211
(...skipping 22 matching lines...) Expand all
216 234
217 run_command(args) 235 run_command(args)
218 check_exists(self.frogpad_js) 236 check_exists(self.frogpad_js)
219 237
220 def generate_html(self): 238 def generate_html(self):
221 tags = [] 239 tags = []
222 for f in self.id_to_file.values(): 240 for f in self.id_to_file.values():
223 tags.append(self._create_tag(f.id, f.contents)) 241 tags.append(self._create_tag(f.id, f.contents))
224 tags.append(self._create_tag(MAIN_ID, self.main_file)) 242 tags.append(self._create_tag(MAIN_ID, self.main_file))
225 html = HTML.replace("{{script_tags}}", "".join(tags)) 243 html = HTML.replace("{{script_tags}}", "".join(tags))
226 html = html.replace("{{FROGPAD_JS}}", FROGPAD_JS) 244 html = html.replace("{{FROGPAD_JS}}", read_file(self.frogpad_js))
227 return html 245 return html
228 246
247 def generate_js(self):
248 drt = os.path.join(self.dart_dir, "client/tests/drt/DumpRenderTree")
249 check_exists(drt)
250 args = []
Jennifer Messerly 2012/02/23 03:24:49 args = [drt, self.html_file] or just: stdout = r
mattsh 2012/02/23 04:13:03 Actually I think I kind of like it this way in cas
Siggi Cherem (dart-lang) 2012/02/23 16:43:26 a pattern I've seen so far is to use inline lists
251 args.append(drt)
252 args.append(self.html_file)
253
254 stdout = run_command(args)
255 match = re.match("(?s).*Output:(.*)#EOF", stdout)
Siggi Cherem (dart-lang) 2012/02/23 16:43:26 I think it is better to check that 'Output:' is at
Emily Fortuna 2012/02/23 21:38:50 +1
256 if not match:
257 raise Exception("can't find regex in DumpRenderTree output")
Emily Fortuna 2012/02/23 21:38:50 Possibly print the regex you were looking for in t
258 return match.group(1)
259
229 @staticmethod 260 @staticmethod
230 def _create_tag(id, contents): 261 def _create_tag(id, contents):
231 s = SCRIPT_TAG 262 s = SCRIPT_TAG
232 s = s.replace("{{id}}", id) 263 s = s.replace("{{id}}", id)
233 s = s.replace("{{contents}}", contents) 264 s = s.replace("{{contents}}", contents)
234 return s 265 return s
235 266
236 def dart_library(self, name): 267 def dart_library(self, name):
237 path = DART_LIBRARIES[name] 268 path = DART_LIBRARIES[name]
238 if not path: 269 if not path:
239 raise Exception("unrecognized 'dart:%s'", name) 270 raise Exception("unrecognized 'dart:%s'", name)
240 return os.path.join(self.frog_dir, path) 271 return os.path.join(self.frog_dir, path)
241 272
242 def load_libraries(self): 273 def load_libraries(self):
243 for name in DART_LIBRARIES: 274 for name in DART_LIBRARIES:
244 self.load_file(self.dart_library(name)) 275 self.load_file(self.dart_library(name))
245 276
246 def load_file(self, name): 277 def load_file(self, name):
247 logging.debug("load_file " + name)
248 name = os.path.abspath(name) 278 name = os.path.abspath(name)
249 if name in self.name_to_file: 279 if name in self.name_to_file:
250 logging.debug("already loaded %s, skipping" % name)
251 return 280 return
252 f = File(self, name) 281 f = File(self, name)
253 self.name_to_file[f.name] = f 282 self.name_to_file[f.name] = f
254 if f.id in self.id_to_file: 283 if f.id in self.id_to_file:
255 raise Exception("ambiguous id '%s'" % f.id) 284 raise Exception("ambiguous id '%s'" % f.id)
256 self.id_to_file[f.id] = f 285 self.id_to_file[f.id] = f
257 f.directives() 286 f.directives()
258 287
259 class File(object): 288 class File(object):
260 def __init__(self, pad, name): 289 def __init__(self, pad, name):
261 self.pad = pad 290 self.pad = pad
262 self.name = name 291 self.name = name
263 self.id = self._make_id() 292 self.id = self._make_id()
264 check_exists(name) 293 check_exists(name)
265 with open(self.name, "r") as f: 294 with open(self.name, "r") as f:
266 self.contents = f.read() 295 self.contents = f.read()
267 logging.debug("creating File '%s' (%d lines)" %
268 (self.name, len(self.contents)))
269 296
270 def _make_id(self): 297 def _make_id(self):
271 """ 298 """
272 Generates an id (based on the file name) for the <script> tag that will 299 Generates an id (based on the file name) for the <script> tag that will
273 hold the contents of this file. 300 hold the contents of this file.
274 """ 301 """
275 (dirname, name) = os.path.split(self.name) 302 (dirname, name) = os.path.split(self.name)
276 dirname = os.path.basename(dirname) 303 dirname = os.path.basename(dirname)
277 name = name.replace(".", "_") 304 name = name.replace(".", "_")
278 return dirname + "_" + name 305 return dirname + "_" + name
(...skipping 10 matching lines...) Expand all
289 match = DIRECTIVE_RE.match(line) 316 match = DIRECTIVE_RE.match(line)
290 if not match: 317 if not match:
291 return 318 return
292 url = match.group(2) 319 url = match.group(2)
293 if url.startswith("dart:"): 320 if url.startswith("dart:"):
294 path = self.pad.dart_library(url[len("dart:"):]) 321 path = self.pad.dart_library(url[len("dart:"):])
295 else: 322 else:
296 path = os.path.join(os.path.dirname(self.name), url) 323 path = os.path.join(os.path.dirname(self.name), url)
297 self.pad.load_file(path) 324 self.pad.load_file(path)
298 325
326 def read_file(file_name):
327 check_exists(file_name)
328 with open(file_name, "r") as input:
329 contents = input.read()
330 logging.debug("read_file '%s' (%d bytes)" % (file_name, len(contents)))
331 return contents
332
333 def write_file(file_name, contents):
334 with open(file_name, "w") as output:
335 output.write(contents)
336
337 check_exists(file_name)
338 logging.debug("write_file '%s' (%d bytes)" % (file_name, len(contents)))
339
299 340
300 def check_exists(file_name): 341 def check_exists(file_name):
301 if not os.path.exists(file_name): 342 if not os.path.exists(file_name):
302 raise FileNotFoundException(file_name) 343 raise FileNotFoundException(file_name)
303 344
304 345
305 def format_command(args): 346 def format_command(args):
306 return ' '.join(args) 347 return ' '.join(args)
307 348
308 349
309 def run_command(args): 350 def run_command(args):
310 """ 351 """
311 Args: 352 Args:
312 command: comamnd with arguments to exec 353 command: comamnd with arguments to exec
354 Returns:
355 all output that this command sent to stdout
313 """ 356 """
314 357
315 command = format_command(args) 358 command = format_command(args)
316 logging.info("RUNNING " + command) 359 logging.debug("RUNNING " + command)
317 proc = subprocess.Popen(args) 360 child = subprocess.Popen(args,
318 exit_code = proc.wait() 361 stdout=subprocess.PIPE,
319 362 stderr=subprocess.PIPE,
320 if exit_code: 363 close_fds=True)
364 (stdout, stderr) = child.communicate()
365 for line in stderr.splitlines():
366 logging.info(level, '%s: %s', args[0], line)
367 exitcode = child.wait()
368 if exitcode:
321 msg = "FAILURE (exit_code=%d): '%s'" % (exit_code, command) 369 msg = "FAILURE (exit_code=%d): '%s'" % (exit_code, command)
322 logging.error(msg) 370 logging.error(msg)
323 raise CommandFailedException(msg) 371 raise CommandFailedException(msg)
324 372 logging.debug("SUCCEEDED (%d bytes)" % len(stdout))
325 logging.debug("SUCCEEDED " + command) 373 return stdout
326 374
327 375
328 def usage(): 376 def usage():
329 print(""" 377 print("""
330 Usage: 378 Usage:
331 frogpad.py hello.dart 379 frogpad.py --out hello.js hello.dart
332 """) 380 """)
333 sys.exit(1) 381 sys.exit(1)
334 382
335 383
336 def main(argv): 384 def main(argv):
337 logging.basicConfig(level=logging.INFO) 385 logging.basicConfig(level=logging.INFO)
338 Pad(argv) 386 Pad(argv)
339 387
340 if __name__ == "__main__": 388 if __name__ == "__main__":
341 sys.exit(main(sys.argv)) 389 sys.exit(main(sys.argv))
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698