| // Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| /// Tests that the logic to load, parse, and validate modular tests. | |
| library; | |
| import 'dart:io'; | |
| import 'package:test/test.dart'; | |
| import 'package:modular_test/src/loader.dart'; | |
| import 'package:modular_test/src/suite.dart'; | |
| import 'package:args/args.dart'; | |
| void main(List<String> args) async { | |
| var options = _Options.parse(args); | |
| var baseUri = Platform.script.resolve('./'); | |
| var baseDir = Directory.fromUri(baseUri); | |
| await for (var entry in baseDir.list(recursive: false)) { | |
| if (entry is Directory) { | |
| var dirName = entry.uri.path.substring(baseDir.path.length); | |
| test( | |
| dirName, | |
| () => _runTest(entry.uri, dirName, options), | |
| skip: options.filter != null && !dirName.contains(options.filter!), | |
| ); | |
| } | |
| } | |
| } | |
| Future<void> _runTest(Uri uri, String dirName, _Options options) async { | |
| String result; | |
| String header = | |
| "# This expectation file is generated by loader_test.dart\n\n"; | |
| try { | |
| ModularTest test = await loadTest(uri); | |
| result = '$header${_dumpAsText(test)}'; | |
| } on Error catch (e) { | |
| result = '$header$e'; | |
| } | |
| var file = File.fromUri(uri.resolve('expectation.txt')); | |
| if (!options.updateExpectations) { | |
| expect( | |
| await file.exists(), | |
| isTrue, | |
| reason: "expectation.txt file is missing", | |
| ); | |
| var expectation = await file.readAsString(); | |
| if (expectation != result) { | |
| print( | |
| "expectation.txt doesn't match the result of the test. " | |
| "To update it, run:\n" | |
| " ${Platform.executable} ${Platform.script} " | |
| "--update --show-update --filter $dirName", | |
| ); | |
| } | |
| expect(result, expectation); | |
| } else if (await file.exists() && (await file.readAsString() == result)) { | |
| print(" expectation matches result and was up to date."); | |
| } else { | |
| await file.writeAsString(result); | |
| print(" updated ${file.uri}"); | |
| if (options.showResultOnUpdate) { | |
| print(' new expectation is:\x1b[32m\n$result\x1b[0m'); | |
| } | |
| } | |
| } | |
| String _dumpAsText(ModularTest test) { | |
| var buffer = StringBuffer(); | |
| bool isFirst = true; | |
| for (var module in test.modules) { | |
| if (isFirst) { | |
| isFirst = false; | |
| } else { | |
| buffer.write('\n'); | |
| } | |
| buffer.write(module.name); | |
| if (module.isMain) { | |
| expect(test.mainModule, module); | |
| buffer.write('\n **main module**'); | |
| } | |
| buffer.write('\n is package? ${module.isPackage ? 'yes' : 'no'}'); | |
| buffer.write('\n is shared? ${module.isShared ? 'yes' : 'no'}'); | |
| buffer.write('\n is sdk? ${module.isSdk ? 'yes' : 'no'}'); | |
| if (module.dependencies.isEmpty) { | |
| buffer.write('\n (no dependencies)'); | |
| } else { | |
| buffer.write( | |
| '\n dependencies: ' | |
| '${module.dependencies.map((d) => d.name).join(", ")}', | |
| ); | |
| } | |
| if (module.sources.isEmpty) { | |
| buffer.write('\n (no sources)'); | |
| } else if (module.isSdk) { | |
| buffer.write('\n (sdk sources omitted)'); | |
| } else { | |
| for (var uri in module.sources) { | |
| buffer.write('\n $uri'); | |
| } | |
| } | |
| buffer.write('\n'); | |
| } | |
| return '$buffer'; | |
| } | |
| class _Options { | |
| bool updateExpectations = false; | |
| bool showResultOnUpdate = false; | |
| String? filter; | |
| static _Options parse(List<String> args) { | |
| var parser = ArgParser() | |
| ..addFlag( | |
| 'update', | |
| abbr: 'u', | |
| defaultsTo: false, | |
| help: "update expectation files if the result don't match", | |
| ) | |
| ..addFlag( | |
| 'show-update', | |
| defaultsTo: false, | |
| help: "print the result when updating expectation files", | |
| ) | |
| ..addFlag( | |
| 'show-skipped', | |
| defaultsTo: false, | |
| help: "print the name of the tests skipped by the filtering option", | |
| ) | |
| ..addOption( | |
| 'filter', | |
| help: "only run tests containing this filter as a substring", | |
| ); | |
| ArgResults argResults = parser.parse(args); | |
| return _Options() | |
| ..updateExpectations = argResults['update'] | |
| ..showResultOnUpdate = argResults['show-update'] | |
| ..filter = argResults['filter']; | |
| } | |
| } |