Index: chrome/test/base/js2gtest.js |
diff --git a/chrome/test/base/js2gtest.js b/chrome/test/base/js2gtest.js |
index 995a2576c566d02a9c28e8f864873943babf997b..bfabc070045d418adcc9cacda07e57dbbc550319 100644 |
--- a/chrome/test/base/js2gtest.js |
+++ b/chrome/test/base/js2gtest.js |
@@ -1,24 +1,82 @@ |
// Copyright (c) 2011 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. |
+ |
+/** |
+ * @fileoverview Generator script for creating gtest-style JavaScript |
+ * tests for WebUI and unit tests. Generates C++ gtest wrappers |
+ * which will invoke the appropriate JavaScript for each test. |
+ * @author scr@chromium.org (Sheridan Rawlins) |
+ * @see WebUI testing: http://goo.gl/ZWFXF |
+ * @see gtest documentation: http://goo.gl/Ujj3H |
+ * @see chrome/chrome_tests.gypi |
+ * @see tools/gypv8sh.py |
+ */ |
+ |
+// Arguments from rules in chrome_tests.gypi are passed in through |
+// python script gypv8sh.py. |
if (arguments.length < 4) { |
print('usage: ' + |
arguments[0] + ' path-to-testfile.js testfile.js output.cc test-type'); |
quit(-1); |
} |
+ |
+/** |
+ * Full path to the test input file. |
+ * @type {string} |
+ */ |
var jsFile = arguments[1]; |
+ |
+/** |
+ * Relative path to the test input file appropriate for use in the |
+ * C++ TestFixture's addLibrary method. |
+ * @type {string} |
+ */ |
var jsFileBase = arguments[2]; |
+ |
+/** |
+ * Path to C++ file generation is outputting to. |
+ * @type {string} |
+ */ |
var outputFile = arguments[3]; |
+ |
+/** |
+ * Type of this test. |
+ * @type {string} ('unit'| 'webui') |
+ */ |
var testType = arguments[4]; |
+/** |
+ * C++ gtest macro to use for TEST_F depending on |testType|. |
+ * @type {string} ('TEST_F'|'IN_PROC_BROWSER_TEST_F') |
+ */ |
+var testF; |
+ |
+/** |
+ * Keeps track of whether a typedef has been generated for each test |
+ * fixture. |
+ * @type {Object.<string, string>} |
+ */ |
+var typedeffedCppFixtures = {}; |
+ |
+/** |
+ * Maintains a list of relative file paths to add to each gtest body |
+ * for inclusion at runtime before running each JavaScript test. |
+ * @type {Array.<string>} |
+ */ |
+var genIncludes = []; |
+ |
// Generate the file to stdout. |
print('// GENERATED FILE'); |
print('// ' + arguments.join(' ')); |
print('// PLEASE DO NOT HAND EDIT!'); |
print(); |
-var testF; |
- |
+// Output some C++ headers based upon the |testType|. |
+// |
+// Currently supports: |
+// 'unit' - unit_tests harness, js2unit rule, V8UnitTest superclass. |
+// 'webui' - browser_tests harness, js2webui rule, WebUIBrowserTest superclass. |
if (testType === 'unit') { |
print('#include "chrome/test/base/v8_unit_test.h"'); |
testing.Test.prototype.typedefCppFixture = 'V8UnitTest'; |
@@ -32,12 +90,50 @@ print('#include "googleurl/src/gurl.h"'); |
print('#include "testing/gtest/include/gtest/gtest.h"'); |
print(); |
+/** |
+ * Convert the |includeFile| to paths appropriate for immediate |
+ * inclusion (path) and runtime inclusion (base). |
+ * @param {string} includeFile The file to include. |
+ * @return {{path: string, base: string}} Object describing the paths |
+ * for |includeFile|. |
+ */ |
+function includeFileToPaths(includeFile) { |
+ return { |
+ path: jsFile.replace(/[^\/]+$/, includeFile), |
+ base: jsFileBase.replace(/[^\/]+$/, includeFile), |
+ }; |
+} |
+ |
+/** |
+ * Output |code| verbatim. |
+ * @param {string} code The code to output. |
+ */ |
function GEN(code) { |
print(code); |
} |
-var typedeffedCppFixtures = {}; |
+/** |
+ * Generate includes for the current |jsFile| by including them |
+ * immediately and at runtime. |
+ * @param {Array.<string>} includes Paths to JavaScript files to |
+ * include immediately and at runtime. |
+ */ |
+function GEN_INCLUDE(includes) { |
+ for (var i = 0; i < includes.length; i++) { |
+ var includePaths = includeFileToPaths(includes[i]); |
+ var js = read(includePaths.path); |
+ ('global', eval)(js); |
+ genIncludes.push(includePaths.base); |
+ } |
+} |
+/** |
+ * Generate gtest-style TEST_F definitions for C++ with a body that |
+ * will invoke the |testBody| for |testFixture|.|testFunction|. |
+ * @param {string} testFixture The name of this test's fixture. |
+ * @param {string} testFunction The name of this test's function. |
+ * @param {Function} testBody The function body to execute for this test. |
+ */ |
function TEST_F(testFixture, testFunction, testBody) { |
var browsePreload = this[testFixture].prototype.browsePreload; |
var browsePrintPreload = this[testFixture].prototype.browsePrintPreload; |
@@ -48,6 +144,11 @@ function TEST_F(testFixture, testFunction, testBody) { |
this[testFixture].prototype.isAsync + ', '; |
var testShouldFail = this[testFixture].prototype.testShouldFail; |
var testPredicate = testShouldFail ? 'ASSERT_FALSE' : 'ASSERT_TRUE'; |
+ var extraLibraries = genIncludes.concat( |
+ this[testFixture].prototype.extraLibraries.map( |
+ function(includeFile) { |
+ return includeFileToPaths(includeFile).base; |
+ })); |
if (typedefCppFixture && !(testFixture in typedeffedCppFixtures)) { |
print('typedef ' + typedefCppFixture + ' ' + testFixture + ';'); |
@@ -57,6 +158,10 @@ function TEST_F(testFixture, testFunction, testBody) { |
print(testF + '(' + testFixture + ', ' + testFunction + ') {'); |
if (testGenPreamble) |
testGenPreamble(testFixture, testFunction); |
+ for (var i = 0; i < extraLibraries.length; i++) { |
+ print(' AddLibrary(FilePath(FILE_PATH_LITERAL("' + |
+ extraLibraries[i].replace(/\\/g, '/') + '")));'); |
+ } |
print(' AddLibrary(FilePath(FILE_PATH_LITERAL("' + |
jsFileBase.replace(/\\/g, '/') + '")));'); |
if (browsePreload) { |
@@ -77,5 +182,6 @@ function TEST_F(testFixture, testFunction, testBody) { |
print(); |
} |
+// Now that generation functions are defined, load in |jsFile|. |
var js = read(jsFile); |
eval(js); |