Chromium Code Reviews| Index: tools/testing/dart/test_suite.dart |
| =================================================================== |
| --- tools/testing/dart/test_suite.dart (revision 14667) |
| +++ tools/testing/dart/test_suite.dart (working copy) |
| @@ -427,7 +427,21 @@ |
| enqueueStandardTest(info, testName, expectations); |
| } else if (TestUtils.isBrowserRuntime(configuration['runtime'])) { |
| bool isWrappingRequired = configuration['compiler'] != 'dart2js'; |
| - enqueueBrowserTest(info, testName, expectations, isWrappingRequired); |
| + if (info.optionsFromFile['isMultiHtmlTest']) { |
| + // A browser multi-test has multiple expectations for one test file. |
| + // Find all the different sub-test expecations for one entire test file. |
| + List<String> subtestNames = info.optionsFromFile['subtestNames']; |
| + Map<String, Set<String>> multiHtmlTestExpectations = {}; |
| + for (String name in subtestNames) { |
| + String fullTestName = '$testName/$name'; |
| + multiHtmlTestExpectations[fullTestName] = |
| + testExpectations.expectations(fullTestName); |
| + } |
| + enqueueBrowserTest(info, testName, multiHtmlTestExpectations, |
| + isWrappingRequired); |
| + } else { |
| + enqueueBrowserTest(info, testName, expectations, isWrappingRequired); |
| + } |
| } else { |
| enqueueStandardTest(info, testName, expectations); |
| } |
| @@ -579,13 +593,15 @@ |
| * JavaScript version of the test, and copies the appropriate framework |
| * files to that directory. It creates a [BrowserTestCase], which has |
| * two sequential steps to be run by the [ProcessQueue] when the test is |
| - * executed: a compilation |
| - * step and an execution step, both with the appropriate executable and |
| - * arguments. |
| + * executed: a compilation step and an execution step, both with the |
| + * appropriate executable and arguments. The [expectations] object can be |
| + * either a Set<String> if the test is a regular test, or a Map<String |
| + * subTestName, Set<String>> if we are running a browser multi-test (one |
| + * compilation and many browser runs). |
| */ |
| void enqueueBrowserTest(TestInformation info, |
| String testName, |
| - Set<String> expectations, |
| + Object expectations, |
| bool isWrappingRequired) { |
| Map optionsFromFile = info.optionsFromFile; |
| Path filePath = info.filePath; |
| @@ -706,44 +722,79 @@ |
| } |
| } |
| + // Variables for browser multi-tests. |
| + List<String> subtestNames = info.optionsFromFile['subtestNames']; |
| + TestCase multitestParentTest; |
| + int subtestIndex = 0; |
| // Construct the command that executes the browser test |
| - List<String> args; |
| - if (TestUtils.usesWebDriver(runtime)) { |
| - args = [dartDir.append('tools/testing/run_selenium.py').toNativePath(), |
| - '--browser=$runtime', |
| - '--timeout=${configuration["timeout"] - 2}', |
| - '--out=$htmlPath']; |
| - if (runtime == 'dartium') { |
| - args.add('--executable=$dartiumFilename'); |
| + do { |
| + List<String> args = <String>[]; |
| + String fullHtmlPath = htmlPath.startsWith('http:')? htmlPath: |
|
Siggi Cherem (dart-lang)
2012/11/08 02:50:14
nit: spacing - add space between )? and before :
Bill Hesse
2012/11/08 09:09:49
Seconded: spacing before ? and :.
On 2012/11/08 02
Emily Fortuna
2012/11/08 18:33:14
Done.
|
| + 'file://$htmlPath'; |
|
Emily Fortuna
2012/11/08 02:19:09
lines 732-733 are new (adding file://)
Bill Hesse
2012/11/08 09:09:49
This is really Resolve(htmlPath, "file://"), isn't
Emily Fortuna
2012/11/08 18:33:14
We don't want to add a test that htmlPath starts w
|
| + if (info.optionsFromFile['isMultiHtmlTest'] |
| + && subtestNames.length > 0) { |
| + fullHtmlPath = '${fullHtmlPath}#${subtestNames[subtestIndex]}'; |
| } |
| - } else { |
| - args = [ |
| - dartDir.append('tools/testing/drt-trampoline.py').toNativePath(), |
| - dumpRenderTreeFilename, |
| - '--no-timeout' |
| - ]; |
| - if (runtime == 'drt' && |
| - (compiler == 'none' || compiler == 'dart2dart')) { |
| - var dartFlags = ['--ignore-unrecognized-flags']; |
| - if (configuration["checked"]) { |
| - dartFlags.add('--enable_asserts'); |
| - dartFlags.add("--enable_type_checks"); |
| + if (TestUtils.usesWebDriver(runtime)) { |
| + args = [ |
| + dartDir.append('tools/testing/run_selenium.py').toNativePath(), |
| + '--browser=$runtime', |
| + '--timeout=${configuration["timeout"] - 2}', |
| + '--out="$fullHtmlPath"']; |
| + if (runtime == 'dartium') { |
| + args.add('--executable=$dartiumFilename'); |
| } |
| - dartFlags.addAll(vmOptions); |
| - args.add('--dart-flags=${Strings.join(dartFlags, " ")}'); |
| + } else { |
| + args = [ |
| + dartDir.append('tools/testing/drt-trampoline.py').toNativePath(), |
| + dumpRenderTreeFilename, |
| + '--no-timeout' |
| + ]; |
| + if (runtime == 'drt' && |
| + (compiler == 'none' || compiler == 'dart2dart')) { |
| + var dartFlags = ['--ignore-unrecognized-flags']; |
| + if (configuration["checked"]) { |
| + dartFlags.add('--enable_asserts'); |
| + dartFlags.add("--enable_type_checks"); |
| + } |
| + dartFlags.addAll(vmOptions); |
| + args.add('--dart-flags=${Strings.join(dartFlags, " ")}'); |
| + } |
| + args.add(fullHtmlPath); |
| + if (expectedOutput != null) { |
| + args.add('--out-expectation=${expectedOutput.toNativePath()}'); |
| + } |
| } |
| - args.add(htmlPath); |
| - if (expectedOutput != null) { |
| - args.add('--out-expectation=${expectedOutput.toNativePath()}'); |
| + List<String> commandSet = new List<String>.from(commands); |
| + if (subtestIndex != 0) { |
| + commandSet = []; |
| + if(TestUtils.usesWebDriver(runtime)) args.add('--force-refresh'); |
| } |
| - } |
| - commands.add(new Command('python', args)); |
| + commandSet.add(new Command('python', args)); |
| - // Create BrowserTestCase and queue it. |
| - var testCase = new BrowserTestCase('$suiteName/$testName', |
| - commands, configuration, completeHandler, expectations, |
| - info, info.hasCompileError || info.hasRuntimeError); |
| - doTest(testCase); |
| + // Create BrowserTestCase and queue it. |
| + String testDisplayName = '$suiteName/$testName'; |
| + var testCase; |
| + if (info.optionsFromFile['isMultiHtmlTest']) { |
| + testDisplayName = '$testDisplayName/${subtestNames[subtestIndex]}'; |
| + testCase = new BrowserTestCase(testDisplayName, |
| + commandSet, configuration, completeHandler, |
| + expectations['$testName/${subtestNames[subtestIndex]}'], |
| + info, info.hasCompileError || info.hasRuntimeError, |
| + subtestIndex != 0); |
| + } else { |
| + testCase = new BrowserTestCase(testDisplayName, |
| + commandSet, configuration, completeHandler, expectations, |
| + info, info.hasCompileError || info.hasRuntimeError, false); |
| + } |
| + if (subtestIndex == 0) { |
| + multitestParentTest = testCase; |
| + } else { |
| + multitestParentTest.addObserver(testCase); |
| + } |
| + doTest(testCase); |
| + subtestIndex++; |
| + } while(subtestIndex < subtestNames.length); |
| } |
| } |
| @@ -969,6 +1020,8 @@ |
| RegExp dartOptionsRegExp = const RegExp(r"// DartOptions=(.*)"); |
| RegExp otherScriptsRegExp = const RegExp(r"// OtherScripts=(.*)"); |
| RegExp multiTestRegExp = const RegExp(r"/// [0-9][0-9]:(.*)"); |
| + RegExp multiHtmlTestRegExp = |
| + const RegExp(r"useHtmlIndividualConfiguration()"); |
| RegExp staticTypeRegExp = |
| const RegExp(r"/// ([0-9][0-9]:){0,1}\s*static type warning"); |
| RegExp compileTimeRegExp = |
| @@ -1035,6 +1088,7 @@ |
| } |
| bool isMultitest = multiTestRegExp.hasMatch(contents); |
| + bool isMultiHtmlTest = multiHtmlTestRegExp.hasMatch(contents); |
| bool containsLeadingHash = leadingHashRegExp.hasMatch(contents); |
| Match isolateMatch = isolateStubsRegExp.firstMatch(contents); |
| String isolateStubs = isolateMatch != null ? isolateMatch[1] : ''; |
| @@ -1050,6 +1104,20 @@ |
| numCompileTimeAnnotations++; |
| } |
| + // Note: This is brittle. It's the age-old problem of having a context free |
| + // language but the means to easily identify the construct is a regular |
| + // expression, aka impossible. Therefore we just make an approximation of |
| + // the number of top-level "group(...)" occurrences. This assumes you import |
| + // unittest with no prefix and always directly call "group(". It only uses |
| + // top-level "groups" so tests running nested groups will be no-ops. |
| + RegExp numTests = new RegExp(r"\s*[^/]\s*group\('[^,']*"); |
| + List<String> subtestNames = []; |
| + Iterator matchesIter = numTests.allMatches(contents).iterator(); |
| + while(matchesIter.hasNext && isMultiHtmlTest) { |
| + String fullMatch = matchesIter.next().group(0); |
| + subtestNames.add(fullMatch.substring(fullMatch.indexOf("'") + 1)); |
| + } |
| + |
| return { "vmOptions": result, |
| "dartOptions": dartOptions, |
| "hasCompileError": hasCompileError, |
| @@ -1057,6 +1125,8 @@ |
| "isStaticClean" : isStaticClean, |
| "otherScripts": otherScripts, |
| "isMultitest": isMultitest, |
| + "isMultiHtmlTest": isMultiHtmlTest, |
| + "subtestNames": subtestNames, |
| "containsLeadingHash": containsLeadingHash, |
| "isolateStubs": isolateStubs, |
| "containsDomImport": containsDomImport, |