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

Unified Diff: resources/webgl-test-harness.js

Issue 8342021: Add webgl conformance tests r15841. (Closed) Base URL: svn://chrome-svn/chrome/trunk/deps/third_party/webgl/sdk/tests/
Patch Set: Created 9 years, 2 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « resources/js-test-style.css ('k') | webgl-conformance-tests.html » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: resources/webgl-test-harness.js
===================================================================
--- resources/webgl-test-harness.js (revision 0)
+++ resources/webgl-test-harness.js (revision 0)
@@ -0,0 +1,344 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This is a test harness for running javascript tests in the browser.
+// The only identifier exposed by this harness is WebGLTestHarnessModule.
+//
+// To use it make an HTML page with an iframe. Then call the harness like this
+//
+// function reportResults(type, msg, success) {
+// ...
+// return true;
+// }
+//
+// var fileListURL = '00_test_list.txt';
+// var testHarness = new WebGLTestHarnessModule.TestHarness(
+// iframe,
+// fileListURL,
+// reportResults);
+//
+// The harness will load the fileListURL and parse it for the URLs, one URL
+// per line. URLs should be on the same domain and at the same folder level
+// or below the main html file. If any URL ends in .txt it will be parsed
+// as well so you can nest .txt files. URLs inside a .txt file should be
+// relative to that text file.
+//
+// During startup, for each page found the reportFunction will be called with
+// WebGLTestHarnessModule.TestHarness.reportType.ADD_PAGE and msg will be
+// the URL of the test.
+//
+// Each test is required to call testHarness.reportResults. This is most easily
+// accomplished by storing that value on the main window with
+//
+// window.webglTestHarness = testHarness
+//
+// and then adding these to functions to your tests.
+//
+// function reportTestResultsToHarness(success, msg) {
+// if (window.parent.webglTestHarness) {
+// window.parent.webglTestHarness.reportResults(success, msg);
+// }
+// }
+//
+// function notifyFinishedToHarness() {
+// if (window.parent.webglTestHarness) {
+// window.parent.webglTestHarness.notifyFinished();
+// }
+// }
+//
+// This way your tests will still run without the harness and you can use
+// any testing framework you want.
+//
+// Each test should call reportTestResultsToHarness with true for success if it
+// succeeded and false if it fail followed and any message it wants to
+// associate with the test. If your testing framework supports checking for
+// timeout you can call it with success equal to undefined in that case.
+//
+// To run the tests, call testHarness.runTests();
+//
+// For each test run, before the page is loaded the reportFunction will be
+// called with WebGLTestHarnessModule.TestHarness.reportType.START_PAGE and msg
+// will be the URL of the test. You may return false if you want the test to be
+// skipped.
+//
+// For each test completed the reportFunction will be called with
+// with WebGLTestHarnessModule.TestHarness.reportType.TEST_RESULT,
+// success = true on success, false on failure, undefined on timeout
+// and msg is any message the test choose to pass on.
+//
+// When all the tests on the page have finished your page must call
+// notifyFinishedToHarness. If notifyFinishedToHarness is not called
+// the harness will assume the test timed out.
+//
+// When all the tests on a page have finished OR the page as timed out the
+// reportFunction will be called with
+// WebGLTestHarnessModule.TestHarness.reportType.FINISH_PAGE
+// where success = true if the page has completed or undefined if the page timed
+// out.
+//
+// Finally, when all the tests have completed the reportFunction will be called
+// with WebGLTestHarnessModule.TestHarness.reportType.FINISHED_ALL_TESTS.
+//
+
+WebGLTestHarnessModule = function() {
+
+/**
+ * Wrapped logging function.
+ */
+var log = function(msg) {
+ if (window.console && window.console.log) {
+ window.console.log(msg);
+ }
+};
+
+/**
+ * Loads text from an external file. This function is synchronous.
+ * @param {string} url The url of the external file.
+ * @param {!function(bool, string): void} callback that is sent a bool for
+ * success and the string.
+ */
+var loadTextFileAsynchronous = function(url, callback) {
+ log ("loading: " + url);
+ var error = 'loadTextFileSynchronous failed to load url "' + url + '"';
+ var request;
+ if (window.XMLHttpRequest) {
+ request = new XMLHttpRequest();
+ if (request.overrideMimeType) {
+ request.overrideMimeType('text/plain');
+ }
+ } else {
+ throw 'XMLHttpRequest is disabled';
+ }
+ try {
+ request.open('GET', url, true);
+ request.onreadystatechange = function() {
+ if (request.readyState == 4) {
+ var text = '';
+ // HTTP reports success with a 200 status. The file protocol reports
+ // success with zero. HTTP does not use zero as a status code (they
+ // start at 100).
+ // https://developer.mozilla.org/En/Using_XMLHttpRequest
+ var success = request.status == 200 || request.status == 0;
+ if (success) {
+ text = request.responseText;
+ }
+ log("loaded: " + url);
+ callback(success, text);
+ }
+ };
+ request.send(null);
+ } catch (e) {
+ log("failed to load: " + url);
+ callback(false, '');
+ }
+};
+
+var getFileList = function(url, callback) {
+ var files = [];
+
+ var getFileListImpl = function(url, callback) {
+ var files = [];
+ if (url.substr(url.length - 4) == '.txt') {
+ loadTextFileAsynchronous(url, function() {
+ return function(success, text) {
+ if (!success) {
+ callback(false, '');
+ return;
+ }
+ var lines = text.split('\n');
+ var prefix = '';
+ var lastSlash = url.lastIndexOf('/');
+ if (lastSlash >= 0) {
+ prefix = url.substr(0, lastSlash + 1);
+ }
+ var fail = false;
+ var count = 1;
+ var index = 0;
+ for (var ii = 0; ii < lines.length; ++ii) {
+ var str = lines[ii].replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+ if (str.length > 4 &&
+ str[0] != '#' &&
+ str[0] != ";" &&
+ str.substr(0, 2) != "//") {
+ new_url = prefix + str;
+ ++count;
+ getFileListImpl(new_url, function(index) {
+ return function(success, new_files) {
+ log("got files: " + new_files.length);
+ if (success) {
+ files[index] = new_files;
+ }
+ finish(success);
+ };
+ }(index++));
+ }
+ }
+ finish(true);
+
+ function finish(success) {
+ if (!success) {
+ fail = true;
+ }
+ --count;
+ log("count: " + count);
+ if (!count) {
+ callback(!fail, files);
+ }
+ }
+ }
+ }());
+
+ } else {
+ files.push(url);
+ callback(true, files);
+ }
+ };
+
+ getFileListImpl(url, function(success, files) {
+ // flatten
+ var flat = [];
+ flatten(files);
+ function flatten(files) {
+ for (var ii = 0; ii < files.length; ++ii) {
+ var value = files[ii];
+ if (typeof(value) == "string") {
+ flat.push(value);
+ } else {
+ flatten(value);
+ }
+ }
+ }
+ callback(success, flat);
+ });
+};
+
+var TestFile = function(url) {
+ this.url = url;
+};
+
+var TestHarness = function(iframe, filelistUrl, reportFunc) {
+ this.window = window;
+ this.iframe = iframe;
+ this.reportFunc = reportFunc;
+ this.timeoutDelay = 20000;
+ this.files = [];
+
+ var that = this;
+ getFileList(filelistUrl, function() {
+ return function(success, files) {
+ that.addFiles_(success, files);
+ };
+ }());
+
+};
+
+TestHarness.reportType = {
+ ADD_PAGE: 1,
+ READY: 2,
+ START_PAGE: 3,
+ TEST_RESULT: 4,
+ FINISH_PAGE: 5,
+ FINISHED_ALL_TESTS: 6
+};
+
+TestHarness.prototype.addFiles_ = function(success, files) {
+ if (!success) {
+ this.reportFunc(
+ TestHarness.reportType.FINISHED_ALL_TESTS,
+ 'Unable to load tests. Are you running locally?\n' +
+ 'You need to run from a server or configure your\n' +
+ 'browser to allow access to local files (not recommended).\n\n' +
+ 'Note: An easy way to run from a server:\n\n' +
+ '\tcd path_to_tests\n' +
+ '\tpython -m SimpleHTTPServer\n\n' +
+ 'then point your browser to ' +
+ '<a href="http://localhost:8000/webgl-conformance-tests.html">' +
+ 'http://localhost:8000/webgl-conformance-tests.html</a>',
+ false)
+ return;
+ }
+ log("total files: " + files.length);
+ for (var ii = 0; ii < files.length; ++ii) {
+ log("" + ii + ": " + files[ii]);
+ this.files.push(new TestFile(files[ii]));
+ this.reportFunc(TestHarness.reportType.ADD_PAGE, files[ii], undefined);
+ }
+ this.reportFunc(TestHarness.reportType.READY, undefined, undefined);
+ this.nextFileIndex = files.length;
+ this.lastFileIndex = files.length;
+}
+
+TestHarness.prototype.runTests = function(opt_start, opt_count) {
+ var count = opt_count || this.files.length;
+ this.nextFileIndex = opt_start || 0;
+ this.lastFileIndex = this.nextFileIndex + count;
+ this.startNextFile();
+};
+
+TestHarness.prototype.setTimeout = function() {
+ var that = this;
+ this.timeoutId = this.window.setTimeout(function() {
+ that.timeout();
+ }, this.timeoutDelay);
+};
+
+TestHarness.prototype.clearTimeout = function() {
+ this.window.clearTimeout(this.timeoutId);
+};
+
+TestHarness.prototype.startNextFile = function() {
+ if (this.nextFileIndex >= this.lastFileIndex) {
+ log("done");
+ this.reportFunc(TestHarness.reportType.FINISHED_ALL_TESTS,
+ '', true);
+ } else {
+ this.currentFile = this.files[this.nextFileIndex++];
+ log("loading: " + this.currentFile.url);
+ if (this.reportFunc(TestHarness.reportType.START_PAGE,
+ this.currentFile.url, undefined)) {
+ this.iframe.src = this.currentFile.url;
+ this.setTimeout();
+ } else {
+ this.reportResults(false, "skipped");
+ this.notifyFinished();
+ }
+ }
+};
+
+TestHarness.prototype.reportResults = function (success, msg) {
+ this.clearTimeout();
+ log(success ? "PASS" : "FAIL", msg);
+ this.reportFunc(TestHarness.reportType.TEST_RESULT, msg, success);
+ // For each result we get, reset the timeout
+ this.setTimeout();
+};
+
+TestHarness.prototype.notifyFinished = function () {
+ this.clearTimeout();
+ var url = this.currentFile ? this.currentFile.url : 'unknown';
+ log(url + ": finished");
+ this.reportFunc(TestHarness.reportType.FINISH_PAGE, url, true);
+ this.startNextFile();
+};
+
+TestHarness.prototype.timeout = function() {
+ this.clearTimeout();
+ var url = this.currentFile ? this.currentFile.url : 'unknown';
+ log(url + ": timeout");
+ this.reportFunc(TestHarness.reportType.FINISH_PAGE, url, undefined);
+ this.startNextFile();
+};
+
+TestHarness.prototype.setTimeoutDelay = function(x) {
+ this.timeoutDelay = x;
+};
+
+return {
+ 'TestHarness': TestHarness
+ };
+
+}();
+
+
+
Property changes on: resources/webgl-test-harness.js
___________________________________________________________________
Added: svn:eol-style
+ LF
« no previous file with comments | « resources/js-test-style.css ('k') | webgl-conformance-tests.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698