Index: chrome/test/base/js2gtest.js |
diff --git a/chrome/test/base/js2gtest.js b/chrome/test/base/js2gtest.js |
index a13ad87c719744257b25ee3ff8c19bddb64e8888..a066d549bfd6378ad942c037bedf6f7ba35ee5d4 100644 |
--- a/chrome/test/base/js2gtest.js |
+++ b/chrome/test/base/js2gtest.js |
@@ -15,9 +15,10 @@ |
// Arguments from rules in chrome_tests.gypi are passed in through |
// python script gypv8sh.py. |
-if (arguments.length < 4) { |
+if (arguments.length != 6) { |
print('usage: ' + |
- arguments[0] + ' path-to-testfile.js testfile.js output.cc test-type'); |
+ arguments[0] + |
+ ' path-to-testfile.js testfile.js path_to_deps.js output.cc test-type'); |
quit(-1); |
} |
@@ -35,16 +36,22 @@ var jsFile = arguments[1]; |
var jsFileBase = arguments[2]; |
/** |
+ * Path to Closure library style deps.js file. |
+ * @type {string?} |
+ */ |
+var depsFile = arguments[3]; |
+ |
+/** |
* Path to C++ file generation is outputting to. |
* @type {string} |
*/ |
-var outputFile = arguments[3]; |
+var outputFile = arguments[4]; |
/** |
* Type of this test. |
* @type {string} ('unit'| 'webui') |
*/ |
-var testType = arguments[4]; |
+var testType = arguments[5]; |
/** |
* C++ gtest macro to use for TEST_F depending on |testType|. |
@@ -114,6 +121,100 @@ function includeFileToPaths(includeFile) { |
}; |
} |
+ |
+/** |
+ * Maps namespace/object names to the path to the file that provides them. |
+ * Populated from the |depsFile| if any. |
+ * @type {Object.<string, string>} |
+ */ |
+var dependencyProvidesToPaths = {}; |
+ |
+/** |
+ * For each path included in the |depsFile|, if any, contains |
+ * the list of object/namespace names required by the file. |
+ * @type {Object.<string, Array.<string>>} |
+ */ |
+var dependencyPathsToRequires = {}; |
+ |
+if (depsFile) { |
+ var goog = goog || {}; |
+ /** |
+ * Called by the javascript in the deps file to add modules and their |
+ * dependencies. |
+ * @param {string} path Relative path to the file. |
+ * @param Array.<string> provides Objects provided by this file. |
+ * @param Array.<string> requires Objects required by this file. |
+ */ |
+ goog.addDependency = function(path, provides, requires) { |
+ provides.forEach(function(provide) { |
+ dependencyProvidesToPaths[provide] = path; |
+ }); |
+ dependencyPathsToRequires[path] = requires; |
+ }; |
+ |
+ // Read and eval the deps file. It should only contain goog.addDependency |
+ // calls. |
+ eval(read(depsFile)); |
+} |
+ |
+/** |
+ * Resolves a list of libraries to an ordered list of paths to load by the |
+ * generated C++. The input can contain paths relative to the test script and, |
+ * if a deps file was provided, namespace/object names provided by the |
+ * deps file. For the latter case, dependencies will be resolved and |
+ * included in the correct order, meaning that the returned array may contain |
+ * more entries than the input. |
+ * @param {Array.<string>} libraries List of libraries, either paths or |
+ * namespace/object names if a deps file was provided. |
+ * @return {Array.<string>} List of paths to load. |
+ */ |
+function resolveLibraries(libraries) { |
+ var resultPaths = []; |
+ var addedPaths = {}; |
+ |
+ function addPath(path) { |
+ addedPaths[path] = true; |
+ resultPaths.push(path); |
+ } |
+ |
+ function resolveAndAppend(path) { |
+ if (addedPaths[path]) { |
+ return; |
+ } |
+ // Set before recursing to catch cycles. |
+ addedPaths[path] = true; |
+ dependencyPathsToRequires[path].forEach(function(require) { |
+ var providingPath = dependencyProvidesToPaths[require]; |
+ if (!providingPath) { |
+ print('Unknown object', require, 'required by', path); |
+ quit(-1); |
+ } |
+ resolveAndAppend(providingPath); |
+ }); |
+ resultPaths.push(path); |
+ } |
+ |
+ // Always add closure libaries base.js if provided by deps. |
David Tseng
2014/05/30 17:08:46
libraries
|
+ var basePath = dependencyProvidesToPaths['goog']; |
+ if (basePath) { |
+ addPath(basePath); |
+ } |
+ |
+ libraries.forEach(function(library) { |
+ var providingPath = dependencyProvidesToPaths[library]; |
+ if (providingPath) { |
+ resolveAndAppend(providingPath); |
+ } else { |
+ var basePath = includeFileToPaths(library).base; |
+ if (!addedPaths[basePath]) { |
+ addPath(basePath); |
+ } |
+ } |
+ }); |
+ |
+ return resultPaths; |
+} |
+ |
/** |
* Output |code| verbatim. |
* @param {string} code The code to output. |
@@ -155,10 +256,7 @@ function TEST_F(testFixture, testFunction, testBody) { |
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; |
- })); |
+ resolveLibraries(this[testFixture].prototype.extraLibraries)); |
David Tseng
2014/05/30 17:08:46
Nice.
|
if (typedefCppFixture && !(testFixture in typedeffedCppFixtures)) { |
print('typedef ' + typedefCppFixture + ' ' + testFixture + ';'); |