diff options
author | scr@chromium.org <scr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-09 21:55:09 +0000 |
---|---|---|
committer | scr@chromium.org <scr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-09 21:55:09 +0000 |
commit | e010983a890901bb8dfdc5fc19043dd5faf7a330 (patch) | |
tree | 933cc0ba796fbec00b8f38e1af208f0cb998bfb4 | |
parent | 698415277ea798691a713c39c43af91a3d7a0dfc (diff) | |
download | chromium_src-e010983a890901bb8dfdc5fc19043dd5faf7a330.zip chromium_src-e010983a890901bb8dfdc5fc19043dd5faf7a330.tar.gz chromium_src-e010983a890901bb8dfdc5fc19043dd5faf7a330.tar.bz2 |
Make it possible to include another file and port print_preview unit test to unit_tests.
Print Preview unit_tests were good to tackle because it brought in a dependency on the need
to include another js file.
This also hilighted another need - that of being able to include non-generative js files in gyp
and have them copied to the test_data dir, while doing both generation and copy for gtest files.
I changed the "extension" of files which generate C++ with gtest-like syntax to .gtestjs and
added a copyjs rule to the chrome_tests.gypi.
FWIW, I believe this is mostly needed for unit_tests and only applied it there, although I would
be amenable to also making this change for the webui tests to make it clear that they are not
plain js files.
R=dpapad@chromium.org
BUG=101443,102222
TEST=unit_tests --gtest_filter=PrintPreviewUtilsUnitTest.*
Review URL: http://codereview.chromium.org/8438063
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@109310 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | build/cp.py | 18 | ||||
-rw-r--r-- | chrome/browser/resources/print_preview/print_preview_utils_unittest.gtestjs (renamed from chrome/browser/resources/print_preview/print_preview_utils_test.html) | 73 | ||||
-rw-r--r-- | chrome/chrome_tests.gypi | 27 | ||||
-rw-r--r-- | chrome/test/base/js2gtest.js | 112 | ||||
-rw-r--r-- | chrome/test/data/unit/framework_unittest.gtestjs | 44 | ||||
-rw-r--r-- | chrome/test/data/webui/test_api.js | 94 |
6 files changed, 285 insertions, 83 deletions
diff --git a/build/cp.py b/build/cp.py new file mode 100644 index 0000000..7dfeb38 --- /dev/null +++ b/build/cp.py @@ -0,0 +1,18 @@ +#!/usr/bin/python +# 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. + +import shutil, sys; + +""" Copy File. + +This module works much like the cp posix command - it takes 2 arguments: +(src, dst) and copies the file with path |src| to |dst|. +""" + +def Main(src, dst): + return shutil.copyfile(src, dst) + +if __name__ == '__main__': + sys.exit(Main(sys.argv[1], sys.argv[2])) diff --git a/chrome/browser/resources/print_preview/print_preview_utils_test.html b/chrome/browser/resources/print_preview/print_preview_utils_unittest.gtestjs index 58994ed..620fcfb 100644 --- a/chrome/browser/resources/print_preview/print_preview_utils_test.html +++ b/chrome/browser/resources/print_preview/print_preview_utils_unittest.gtestjs @@ -1,17 +1,24 @@ -<!DOCTYPE html> -<html> -<head> -<title>print_preview_utils.js tests</title> -<script src="http://closure-library.googlecode.com/svn/trunk/closure/goog/base.js"></script> -<script src="print_preview_utils.js"></script> -<script> -goog.require('goog.testing.jsunit'); -</script> -</head> -<body> -<script> - -function testIsInteger() { +// 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. + +/** + * Test fixture for print preview utils. + * @constructor + * @extends {testing.Test} + */ +function PrintPreviewUtilsUnitTest () {} + +PrintPreviewUtilsUnitTest.prototype = { + __proto__: testing.Test.prototype, + + /** @inheritDoc */ + extraLibraries: [ + 'print_preview_utils.js', + ], +}; + +TEST_F('PrintPreviewUtilsUnitTest', 'IsInteger', function() { assertFalse(isInteger(" abc ")); assertFalse(isInteger("-7")); assertFalse(isInteger("7.0")); @@ -20,31 +27,31 @@ function testIsInteger() { assertTrue(isInteger("0")); assertTrue(isInteger(" 100 ")); assertTrue(isInteger("0055 ")); -} +}); -function testIsPositiveInteger() { +TEST_F('PrintPreviewUtilsUnitTest', 'IsPositiveInteger', function() { assertTrue(isPositiveInteger("100")); assertTrue(isPositiveInteger("0055")); assertFalse(isPositiveInteger("0")); assertFalse(isPositiveInteger("-100")); assertFalse(isPositiveInteger("sdfs")); -} +}); -function testAreArraysEqual() { +TEST_F('PrintPreviewUtilsUnitTest', 'AreArraysEqual', function() { assertTrue(areArraysEqual([2,4,6,8,10], [2,4,6,8,10])); assertTrue(areArraysEqual([], [])); assertFalse(areArraysEqual([2,4,6,8,10,12], [2,4,6,8,10])); assertFalse(areArraysEqual([], [2,4,6,8,10])); -} +}); -function testRemoveDuplicates() { +TEST_F('PrintPreviewUtilsUnitTest', 'RemoveDuplicates', function() { var array1 = [1,2,2,3,6,6,6,7,9,10]; assertTrue(areArraysEqual(removeDuplicates(array1), [1,2,3,6,7,9,10])); -} +}); -function testIsPageRangeTextValid1() { +TEST_F('PrintPreviewUtilsUnitTest', 'IsPageRangeTextValid1', function() { var totalPageCount; assertTrue(isPageRangeTextValid("1,2, 3,56,1000000", totalPageCount)); assertTrue(isPageRangeTextValid(", ,1,2,3,,1,, 56 ,", totalPageCount)); @@ -56,9 +63,9 @@ function testIsPageRangeTextValid1() { assertFalse(isPageRangeTextValid("1,2,0,56,1000000", totalPageCount)); assertFalse(isPageRangeTextValid("-1,1,2,,56", totalPageCount)); assertFalse(isPageRangeTextValid("1,2,56-40", totalPageCount)); -} +}); -function testIsPageRangeTextValid2() { +TEST_F('PrintPreviewUtilsUnitTest', 'IsPageRangeTextValid2', function() { var totalPageCount = 100; assertTrue(isPageRangeTextValid(",,1,2,3,,1,,56,", totalPageCount)); assertTrue(isPageRangeTextValid(",1-3,,6-9,6-10,", totalPageCount)); @@ -70,9 +77,9 @@ function testIsPageRangeTextValid2() { assertFalse(isPageRangeTextValid("-1,1,2,,56", totalPageCount)); assertFalse(isPageRangeTextValid("1,2,56-40", totalPageCount)); assertFalse(isPageRangeTextValid("101-110", totalPageCount)); -} +}); -function testPageRangeTextToPageList() { +TEST_F('PrintPreviewUtilsUnitTest', 'PageRangeTextToPageList', function() { var totalPageCount = 10; assertTrue(areArraysEqual([1,2,3,4], pageRangeTextToPageList("1-4", totalPageCount))); @@ -86,15 +93,15 @@ function testPageRangeTextToPageList() { assertTrue(areArraysEqual([], pageRangeTextToPageList("1-4", undefined))); assertTrue(areArraysEqual([], pageRangeTextToPageList("1-abcd", totalPageCount))); -} +}); -function testPageListToPageSet() { +TEST_F('PrintPreviewUtilsUnitTest', 'PageListToPageSet', function() { assertTrue(areArraysEqual([1,2,3,4], pageListToPageSet([4,3,2,1,1,1]))); assertTrue(areArraysEqual([1,2,3,4], pageListToPageSet([1,2,2,3,4,1,1,1]))); assertTrue(areArraysEqual([], pageListToPageSet([]))); -} +}); -function testPageSetToPageRanges() { +TEST_F('PrintPreviewUtilsUnitTest', 'PageSetToPageRanges', function() { var pageRanges = pageSetToPageRanges([1,2,3,7,8,9,11]); assertEquals(pageRanges.length, 3); assertEquals(pageRanges[0].from, 1); @@ -103,8 +110,4 @@ function testPageSetToPageRanges() { assertEquals(pageRanges[1].to, 9); assertEquals(pageRanges[2].from, 11); assertEquals(pageRanges[2].to, 11); -} - -</script> -</body> -</html> +}); diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 615623a..b6c52df 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1531,6 +1531,8 @@ 'browser/profiles/profile_info_cache_unittest.cc', 'browser/profiles/profile_manager_unittest.cc', 'browser/renderer_host/web_cache_manager_unittest.cc', + 'browser/resources/print_preview/print_preview_utils.js', + 'browser/resources/print_preview/print_preview_utils_unittest.gtestjs', 'browser/resources_util_unittest.cc', 'browser/rlz/rlz_unittest.cc', 'browser/safe_browsing/bloom_filter_unittest.cc', @@ -1956,7 +1958,7 @@ 'test/base/v8_unit_test.cc', 'test/base/v8_unit_test.h', 'test/data/resource.rc', - 'test/data/unit/framework_unittest.js', + 'test/data/unit/framework_unittest.gtestjs', 'tools/convert_dict/convert_dict_unittest.cc', '../content/browser/renderer_host/render_widget_host_unittest.cc', '../content/browser/renderer_host/text_input_client_mac_unittest.mm', @@ -1980,10 +1982,27 @@ ], 'rules': [ { - 'rule_name': 'js2unit', + 'rule_name': 'copyjs', 'extension': 'js', 'msvs_external_rule': 1, 'inputs': [ + '../build/cp.py', + ], + 'outputs': [ + '<(PRODUCT_DIR)/test_data/chrome/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).<(_extension)', + ], + 'action': [ + 'python', + '<@(_inputs)', + '<(RULE_INPUT_PATH)', + '<@(_outputs)', + ], + }, + { + 'rule_name': 'js2unit', + 'extension': 'gtestjs', + 'msvs_external_rule': 1, + 'inputs': [ '<(gypv8sh)', '<(PRODUCT_DIR)/v8_shell<(EXECUTABLE_SUFFIX)', '<(mock_js)', @@ -1992,7 +2011,7 @@ ], 'outputs': [ '<(js2gtest_out_dir)/chrome/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).cc', - '<(PRODUCT_DIR)/test_data/chrome/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).js', + '<(PRODUCT_DIR)/test_data/chrome/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).<(_extension)', ], 'process_outputs_as_sources': 1, 'action': [ @@ -2000,7 +2019,7 @@ '<@(_inputs)', 'unit', '<(RULE_INPUT_PATH)', - 'chrome/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).js', + 'chrome/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).<(_extension)', '<@(_outputs)', ], }, diff --git a/chrome/test/base/js2gtest.js b/chrome/test/base/js2gtest.js index 995a257..bfabc07 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); diff --git a/chrome/test/data/unit/framework_unittest.gtestjs b/chrome/test/data/unit/framework_unittest.gtestjs new file mode 100644 index 0000000..874e730 --- /dev/null +++ b/chrome/test/data/unit/framework_unittest.gtestjs @@ -0,0 +1,44 @@ +// 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. + +/** + * Class for testing the unit_test framework. + * @constructor + * @extends {testing.Test} + */ +function FrameworkUnitTest() {} + +FrameworkUnitTest.prototype = { + __proto__: testing.Test.prototype, +}; + +TEST_F('FrameworkUnitTest', 'ExpectTrueOk', function() { + expectTrue(true); +}); + +TEST_F('FrameworkUnitTest', 'AssertTrueOk', function() { + assertTrue(true); +}); + +/** + * Failing version of FrameworkUnitTest. + * @constructor + * @extends {FrameworkUnitTest} + */ +function FrameworkUnitTestFail() {} + +FrameworkUnitTestFail.prototype = { + __proto__: FrameworkUnitTest.prototype, + + /** inheritDoc */ + testShouldFail: true, +}; + +TEST_F('FrameworkUnitTestFail', 'ExpectFailFails', function() { + expectNotReached(); +}); + +TEST_F('FrameworkUnitTestFail', 'AssertFailFails', function() { + assertNotReached(); +});
\ No newline at end of file diff --git a/chrome/test/data/webui/test_api.js b/chrome/test/data/webui/test_api.js index 140efe7..c9f2313 100644 --- a/chrome/test/data/webui/test_api.js +++ b/chrome/test/data/webui/test_api.js @@ -11,7 +11,7 @@ * @type {Object} */ var testing = {}; -(function(window) { +(function(exports) { /** * Hold the currentTestCase across between preLoad and run. * @type {TestCase} @@ -110,6 +110,12 @@ var testing = {}; testShouldFail: false, /** + * Extra libraries to add before loading this test file. + * @type {Array.<string>} + */ + extraLibraries: [], + + /** * Override this method to perform initialization during preload (such as * creating mocks and registering handlers). * @type {Function} @@ -829,7 +835,7 @@ var testing = {}; function preloadJavascriptLibraries(testFixture, testName) { deferGlobalOverrides = true; - window.addEventListener('DOMContentLoaded', function() { + exports.addEventListener('DOMContentLoaded', function() { var oldChrome = chrome; chrome = { __proto__: oldChrome, @@ -852,6 +858,11 @@ var testing = {}; function GEN() {} /** + * During generation phase, this outputs; do nothing at runtime. + */ + function GEN_INCLUDE() {} + + /** * At runtime, register the testName with a test fixture. Since this method * doesn't have a test fixture, create a dummy fixture to hold its |name| * and |testCaseBodies|. @@ -1268,44 +1279,45 @@ var testing = {}; // Exports. testing.Test = Test; - window.testDone = testDone; - window.assertTrue = assertTrue; - window.assertFalse = assertFalse; - window.assertGE = assertGE; - window.assertGT = assertGT; - window.assertEquals = assertEquals; - window.assertLE = assertLE; - window.assertLT = assertLT; - window.assertNotEquals = assertNotEquals; - window.assertNotReached = assertNotReached; - window.callFunction = callFunction; - window.callFunctionWithSavedArgs = callFunctionWithSavedArgs; - window.callGlobalWithSavedArgs = callGlobalWithSavedArgs; - window.expectTrue = createExpect(assertTrue); - window.expectFalse = createExpect(assertFalse); - window.expectGE = createExpect(assertGE); - window.expectGT = createExpect(assertGT); - window.expectEquals = createExpect(assertEquals); - window.expectLE = createExpect(assertLE); - window.expectLT = createExpect(assertLT); - window.expectNotEquals = createExpect(assertNotEquals); - window.expectNotReached = createExpect(assertNotReached); - window.preloadJavascriptLibraries = preloadJavascriptLibraries; - window.registerMessageCallback = registerMessageCallback; - window.registerMockGlobals = registerMockGlobals; - window.registerMockMessageCallbacks = registerMockMessageCallbacks; - window.resetTestState = resetTestState; - window.runAllActions = runAllActions; - window.runAllActionsAsync = runAllActionsAsync; - window.runTest = runTest; - window.runTestFunction = runTestFunction; - window.SaveMockArguments = SaveMockArguments; - window.DUMMY_URL = DUMMY_URL; - window.TEST = TEST; - window.TEST_F = TEST_F; - window.GEN = GEN; - window.WhenTestDone = WhenTestDone; + exports.testDone = testDone; + exports.assertTrue = assertTrue; + exports.assertFalse = assertFalse; + exports.assertGE = assertGE; + exports.assertGT = assertGT; + exports.assertEquals = assertEquals; + exports.assertLE = assertLE; + exports.assertLT = assertLT; + exports.assertNotEquals = assertNotEquals; + exports.assertNotReached = assertNotReached; + exports.callFunction = callFunction; + exports.callFunctionWithSavedArgs = callFunctionWithSavedArgs; + exports.callGlobalWithSavedArgs = callGlobalWithSavedArgs; + exports.expectTrue = createExpect(assertTrue); + exports.expectFalse = createExpect(assertFalse); + exports.expectGE = createExpect(assertGE); + exports.expectGT = createExpect(assertGT); + exports.expectEquals = createExpect(assertEquals); + exports.expectLE = createExpect(assertLE); + exports.expectLT = createExpect(assertLT); + exports.expectNotEquals = createExpect(assertNotEquals); + exports.expectNotReached = createExpect(assertNotReached); + exports.preloadJavascriptLibraries = preloadJavascriptLibraries; + exports.registerMessageCallback = registerMessageCallback; + exports.registerMockGlobals = registerMockGlobals; + exports.registerMockMessageCallbacks = registerMockMessageCallbacks; + exports.resetTestState = resetTestState; + exports.runAllActions = runAllActions; + exports.runAllActionsAsync = runAllActionsAsync; + exports.runTest = runTest; + exports.runTestFunction = runTestFunction; + exports.SaveMockArguments = SaveMockArguments; + exports.DUMMY_URL = DUMMY_URL; + exports.TEST = TEST; + exports.TEST_F = TEST_F; + exports.GEN = GEN; + exports.GEN_INCLUDE = GEN_INCLUDE; + exports.WhenTestDone = WhenTestDone; // Import the Mock4JS helpers. - Mock4JS.addMockSupport(window); -})(('window' in this) ? window : this); + Mock4JS.addMockSupport(exports); +})(this); |