@@ -29,62 +29,107 @@ final testTimeoutSeconds = 10;
2929// All contents after this separator are considered are diff comments.
3030final testDiffSeparator = '/** DIFF **/' ;
3131
32- final argParser = ArgParser ()
33- ..addFlag ('help' , abbr: 'h' , help: 'Display this message.' , negatable: false )
34- ..addOption ('runtime' ,
35- abbr: 'r' ,
36- defaultsTo: 'd8' ,
37- allowed: RuntimePlatforms .values.map ((v) => v.text),
38- help: 'runtime platform used to run tests.' )
39- ..addOption ('named-configuration' ,
40- abbr: 'n' ,
41- defaultsTo: 'no-configuration' ,
42- help: 'configuration name to use for emitting test result files.' )
43- ..addOption ('output-directory' , help: 'directory to emit test results files.' )
44- ..addOption (
45- 'filter' ,
46- abbr: 'f' ,
47- defaultsTo: r'.*' ,
48- help: 'regexp filter over tests to run.' ,
49- )
50- ..addOption ('diff' ,
51- allowed: ['check' , 'write' , 'ignore' ],
52- allowedHelp: {
53- 'check' : 'validate that reload test diffs are generated and correct.' ,
54- 'write' : 'write diffs for reload tests.' ,
55- 'ignore' : 'ignore reload diffs.' ,
32+ /// Command line options for the hot reload test suite.
33+ class Options {
34+ final bool help;
35+ final RuntimePlatforms runtime;
36+ final String namedConfiguration;
37+ final Uri ? testResultsOutputDir;
38+ final RegExp testNameFilter;
39+ final DiffMode diffMode;
40+ final bool debug;
41+ final bool verbose;
42+
43+ Options ._({
44+ required this .help,
45+ required this .runtime,
46+ required this .namedConfiguration,
47+ required this .testResultsOutputDir,
48+ required this .testNameFilter,
49+ required this .diffMode,
50+ required this .debug,
51+ required this .verbose,
52+ });
53+
54+ static final _parser = ArgParser ()
55+ ..addFlag ('help' ,
56+ abbr: 'h' ,
57+ help: 'Display this message.' ,
58+ negatable: false ,
59+ defaultsTo: false )
60+ ..addOption ('runtime' ,
61+ abbr: 'r' ,
62+ defaultsTo: 'd8' ,
63+ allowed: RuntimePlatforms .values.map ((v) => v.text),
64+ help: 'runtime platform used to run tests.' )
65+ ..addOption ('named-configuration' ,
66+ abbr: 'n' ,
67+ defaultsTo: 'no-configuration' ,
68+ help: 'configuration name to use for emitting test result files.' )
69+ ..addOption ('output-directory' ,
70+ help: 'directory to emit test results files.' )
71+ ..addOption ('filter' ,
72+ abbr: 'f' , defaultsTo: r'.*' , help: 'regexp filter over tests to run.' )
73+ ..addOption ('diff' ,
74+ allowed: ['check' , 'write' , 'ignore' ],
75+ allowedHelp: {
76+ 'check' : 'validate that reload test diffs are generated and correct.' ,
77+ 'write' : 'write diffs for reload tests.' ,
78+ 'ignore' : 'ignore reload diffs.' ,
79+ },
80+ defaultsTo: 'check' ,
81+ help: 'selects whether test diffs should be checked, written, or '
82+ 'ignored.' )
83+ ..addFlag ('debug' ,
84+ abbr: 'd' ,
85+ defaultsTo: false ,
86+ negatable: true ,
87+ help: 'enables additional debug behavior and logging.' )
88+ ..addFlag ('verbose' ,
89+ abbr: 'v' ,
90+ defaultsTo: true ,
91+ negatable: true ,
92+ help: 'enables verbose logging.' );
93+
94+ /// Usage description for these command line options.
95+ String get usage => _parser.usage;
96+
97+ factory Options .parse (List <String > args) {
98+ final results = _parser.parse (args);
99+ return Options ._(
100+ help: results.flag ('help' ),
101+ runtime: RuntimePlatforms .values.byName (results.option ('runtime' )! ),
102+ namedConfiguration: results.option ('named-configuration' )! ,
103+ testResultsOutputDir: results.wasParsed ('output-directory' )
104+ ? Uri .directory (results.option ('output-directory' )! )
105+ : null ,
106+ testNameFilter: RegExp (results.option ('filter' )! ),
107+ diffMode: switch (results.option ('diff' )! ) {
108+ 'check' => DiffMode .check,
109+ 'write' => DiffMode .write,
110+ 'ignore' => DiffMode .ignore,
111+ _ => throw Exception ('Invalid diff mode: ${results .option ('diff' )}' ),
56112 },
57- defaultsTo: 'check' ,
58- help:
59- 'selects whether test diffs should be checked, written, or ignored.' )
60- ..addFlag ('debug' ,
61- abbr: 'd' ,
62- defaultsTo: false ,
63- negatable: true ,
64- help: 'enables additional debug behavior and logging.' )
65- ..addFlag ('verbose' ,
66- abbr: 'v' ,
67- defaultsTo: true ,
68- negatable: true ,
69- help: 'enables verbose logging.' );
113+ debug: results.flag ('debug' ),
114+ verbose: results.flag ('verbose' ),
115+ );
116+ }
117+ }
70118
71- late final bool verbose;
72- late final bool debug;
119+ /// Modes for running diff check tests on the hot reload suite.
120+ enum DiffMode { check, write, ignore }
73121
122+ late final bool verbose;
74123Future <void > main (List <String > args) async {
75- final argResults = argParser .parse (args);
76- if (argResults[ ' help' ] as bool ) {
77- print (argParser .usage);
124+ final options = Options .parse (args);
125+ if (options. help) {
126+ print (options .usage);
78127 return ;
79128 }
80- final runtimePlatform =
81- RuntimePlatforms .values.byName (argResults['runtime' ] as String );
82- final testNameFilter = RegExp (argResults['filter' ] as String );
83- debug = argResults['debug' ] as bool ;
84- verbose = argResults['verbose' ] as bool ;
129+ verbose = options.verbose;
85130
86131 // Used to communicate individual test failures to our test bots.
87- final emitTestResultsJson = argResults[ 'output-directory' ] != null ;
132+ final emitTestResultsJson = options.testResultsOutputDir != null ;
88133 final buildRootUri = fe.computePlatformBinariesLocation (forceBuildDir: true );
89134 // We can use the outline instead of the full SDK dill here.
90135 final ddcPlatformDillUri = buildRootUri.resolve ('ddc_outline.dill' );
@@ -135,9 +180,9 @@ Future<void> main(List<String> args) async {
135180 '--output-incremental-dill=${outputIncrementalDillUri .toFilePath ()}' ,
136181 '--packages=${packageConfigUri .toFilePath ()}' ,
137182 '--sdk-root=${sdkRoot .toFilePath ()}' ,
138- '--verbosity=${verbose ? 'all' : 'info' }' ,
183+ '--verbosity=${options . verbose ? 'all' : 'info' }' ,
139184 ];
140- switch (runtimePlatform ) {
185+ switch (options.runtime ) {
141186 case RuntimePlatforms .d8:
142187 case RuntimePlatforms .chrome:
143188 final ddcPlatformDillFromSdkRoot = fe_shared.relativizeUri (
@@ -175,13 +220,13 @@ Future<void> main(List<String> args) async {
175220
176221 // Only allow Chrome when debugging a single test.
177222 // TODO(markzipan): Add support for full Chrome testing.
178- if (runtimePlatform == RuntimePlatforms .chrome) {
223+ if (options.runtime == RuntimePlatforms .chrome) {
179224 var matchingTests =
180225 Directory .fromUri (allTestsUri).listSync ().where ((testDir) {
181226 if (testDir is ! Directory ) return false ;
182227 final testDirParts = testDir.uri.pathSegments;
183228 final testName = testDirParts[testDirParts.length - 2 ];
184- return testNameFilter.hasMatch (testName);
229+ return options. testNameFilter.hasMatch (testName);
185230 });
186231
187232 if (matchingTests.length > 1 ) {
@@ -205,13 +250,13 @@ Future<void> main(List<String> args) async {
205250 final testName = testDirParts[testDirParts.length - 2 ];
206251
207252 // Skip tests that don't match the name filter.
208- if (! testNameFilter.hasMatch (testName)) {
253+ if (! options. testNameFilter.hasMatch (testName)) {
209254 _print ('Skipping test' , label: testName);
210255 continue ;
211256 }
212257
213258 var outcome = TestResultOutcome (
214- configuration: argResults[ 'named-configuration' ] as String ,
259+ configuration: options.namedConfiguration ,
215260 testName: testName,
216261 );
217262 var stopwatch = Stopwatch ()..start ();
@@ -235,7 +280,7 @@ Future<void> main(List<String> args) async {
235280 final filePath = fileUri.path;
236281 final relativeFilePath = p.relative (filePath, from: allTestsUri.path);
237282 var outcome = TestResultOutcome (
238- configuration: argResults[ 'named-configuration' ] as String ,
283+ configuration: options.namedConfiguration ,
239284 testName: '$relativeFilePath -diff' ,
240285 testOutput: testOutput,
241286 );
@@ -305,14 +350,14 @@ Future<void> main(List<String> args) async {
305350 '(requested: $maxGenerations , max: $globalMaxGenerations ).' );
306351 }
307352
308- var diffMode = argResults[ 'diff' ] ! ;
309- if (fe_shared.isWindows && diffMode != ' ignore' ) {
353+ var diffMode = options.diffMode ;
354+ if (fe_shared.isWindows && diffMode != DiffMode . ignore) {
310355 _print ("Diffing isn't supported on Windows. Defaulting to 'ignore'." ,
311356 label: testName);
312- diffMode = ' ignore' ;
357+ diffMode = DiffMode . ignore;
313358 }
314359 switch (diffMode) {
315- case ' check' :
360+ case DiffMode . check:
316361 _print ('Checking source file diffs.' , label: testName);
317362 filesByGeneration.forEach ((basename, filesQueue) {
318363 final files = filesQueue.toList ();
@@ -378,7 +423,7 @@ Future<void> main(List<String> args) async {
378423 });
379424 });
380425 break ;
381- case ' write' :
426+ case DiffMode . write:
382427 _print ('Generating source file diffs.' , label: testName);
383428 filesByGeneration.forEach ((basename, filesQueue) {
384429 final files = filesQueue.toList ();
@@ -416,7 +461,7 @@ Future<void> main(List<String> args) async {
416461 });
417462 });
418463 break ;
419- case ' ignore' :
464+ case DiffMode . ignore:
420465 _print ('Ignoring source file diffs.' , label: testName);
421466 filesByGeneration.forEach ((basename, filesQueue) {
422467 filesQueue.unorderedElements.forEach (((int , Uri ) element) {
@@ -428,8 +473,8 @@ Future<void> main(List<String> args) async {
428473 }
429474
430475 // Skip this test directory if this platform is excluded.
431- if (testConfig.excludedPlatforms.contains (runtimePlatform )) {
432- _print ('Skipping test on platform: ${runtimePlatform .text }' ,
476+ if (testConfig.excludedPlatforms.contains (options.runtime )) {
477+ _print ('Skipping test on platform: ${options . runtime .text }' ,
433478 label: testName);
434479 continue ;
435480 }
@@ -536,7 +581,7 @@ Future<void> main(List<String> args) async {
536581 '$outputDirectoryPath ' ,
537582 label: testName);
538583
539- if (runtimePlatform .emitsJS) {
584+ if (options.runtime .emitsJS) {
540585 // Update the memory filesystem with the newly-created JS files
541586 _print (
542587 'Loading generation $currentGeneration files '
@@ -589,7 +634,7 @@ Future<void> main(List<String> args) async {
589634 .transform (utf8.decoder)
590635 .listen (testOutputBuffer.write);
591636 var testPassed = false ;
592- switch (runtimePlatform ) {
637+ switch (options.runtime ) {
593638 case RuntimePlatforms .d8:
594639 // Run the compiled JS generations with D8.
595640 _print ('Creating D8 hot reload test suite.' , label: testName);
@@ -687,8 +732,7 @@ Future<void> main(List<String> args) async {
687732 if (emitTestResultsJson) {
688733 final testOutcomeResults = testOutcomes.map ((o) => o.toRecordJson ());
689734 final testOutcomeLogs = testOutcomes.map ((o) => o.toLogJson ());
690- final testResultsOutputDir =
691- Uri .directory (argResults['output-directory' ] as String );
735+ final testResultsOutputDir = options.testResultsOutputDir! ;
692736 _print ('Saving test results to ${testResultsOutputDir .toFilePath ()}.' );
693737
694738 // Test outputs must have one JSON blob per line and be newline-terminated.
0 commit comments