Chromium Code Reviews| Index: chrome/test/base/js2gtest.js |
| diff --git a/chrome/test/base/js2gtest.js b/chrome/test/base/js2gtest.js |
| index a13ad87c719744257b25ee3ff8c19bddb64e8888..0b402e838e7efcfb97faf5358ce65d458e5ba4f0 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|. |
| @@ -91,7 +98,7 @@ if (testType === 'unit') { |
| testF = 'TEST_F'; |
| addSetPreloadInfo = false; |
| } else { |
| - print('#include "chrome/test/base/web_ui_browsertest.h"'); |
| + print('#include "chrome/test/base/web_ui_browser_test.h"'); |
| testing.Test.prototype.typedefCppFixture = 'WebUIBrowserTest'; |
| testF = 'IN_PROC_BROWSER_TEST_F'; |
| addSetPreloadInfo = true; |
| @@ -114,6 +121,100 @@ function includeFileToPaths(includeFile) { |
| }; |
| } |
| + |
| +/** |
| + * Maps namespace/object names to the path to the file that provides them. |
|
dmazzoni
2014/05/31 06:16:49
How about just "class names" instead of namespace/
|
| + * Populated from the |depsFile| if any. |
| + * @type {Object.<string, string>} |
| + */ |
| +var dependencyProvidesToPaths = {}; |
| + |
| +/** |
| + * For each path included in the |depsFile|, if any, contains |
|
dmazzoni
2014/05/31 06:16:49
Nit: I'd word this more similarly to the one above
|
| + * 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. |
|
dmazzoni
2014/05/31 06:16:49
Objects -> Classes?
|
| + * @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 should contain namespace/object names provided |
| + * by the deps file. 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>} deps List of dependencies. |
| + * @return {Array.<string>} List of paths to load. |
| + */ |
| +function resolveClosureModuleDeps(deps) { |
| + if (!depsFile && deps.length > 0) { |
| + print('Can\'t have closure dependencies without a deps file.'); |
| + quit(-1); |
| + } |
| + 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 library's base.js if provided by deps. |
| + var basePath = dependencyProvidesToPaths['goog']; |
| + if (basePath) { |
| + addPath(basePath); |
| + } |
| + |
| + deps.forEach(function(dep) { |
| + var providingPath = dependencyProvidesToPaths[dep]; |
| + if (providingPath) { |
| + resolveAndAppend(providingPath); |
| + } else { |
| + print('Unknown dependency:', dep); |
| + quit(-1); |
| + } |
| + }); |
| + |
| + return resultPaths; |
| +} |
| + |
| /** |
| * Output |code| verbatim. |
| * @param {string} code The code to output. |
| @@ -158,7 +259,8 @@ function TEST_F(testFixture, testFunction, testBody) { |
| this[testFixture].prototype.extraLibraries.map( |
| function(includeFile) { |
| return includeFileToPaths(includeFile).base; |
| - })); |
| + }), |
| + resolveClosureModuleDeps(this[testFixture].prototype.closureModuleDeps)); |
| if (typedefCppFixture && !(testFixture in typedeffedCppFixtures)) { |
| print('typedef ' + typedefCppFixture + ' ' + testFixture + ';'); |