Add support for loading a modular test folder and specifying deps in yaml
To test the loading logic, I created sample modular test folders which also
illustrate what modular tests will look like in the future.
Change-Id: Iaa8e076e5be66107391d258f5c72456c89841123
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/101780
Commit-Queue: Sigmund Cherem <sigmund@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/modular_test/lib/src/dependency_parser.dart b/pkg/modular_test/lib/src/dependency_parser.dart
new file mode 100644
index 0000000..51f2460
--- /dev/null
+++ b/pkg/modular_test/lib/src/dependency_parser.dart
@@ -0,0 +1,74 @@
+// 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.
+
+/// This library defines how to read module dependencies from a Yaml
+/// specification. We expect to find specifications written in this format:
+///
+/// dependencies:
+/// b: a
+/// main: [b, expect]
+///
+/// Where:
+/// - Each name corresponds to a module.
+/// - Module names correlate to either a file, a folder, or a package.
+/// - A map entry contains all the dependencies of a module, if any.
+/// - If a module has a single dependency, it can be written as a single
+/// value.
+///
+/// The logic in this library mostly treats these names as strings, separately
+/// `loader.dart` is responsible for validating and attaching this dependency
+/// information to a set of module definitions.
+import 'package:yaml/yaml.dart';
+
+/// Parses [contents] containing a module dependencies specification written in
+/// yaml, and returns a normalized dependency map.
+///
+/// Note: some values in the map may not have a corresponding key. That may be
+/// the case for modules that have no dependencies and modules that are not
+/// specified in [contents] (e.g. modules that are supported by default).
+Map<String, List<String>> parseDependencyMap(String contents) {
+ var spec = loadYaml(contents);
+ if (spec is! YamlMap) {
+ return _invalidSpecification("spec is not a map");
+ }
+ var dependencies = spec['dependencies'];
+ if (dependencies == null) {
+ return _invalidSpecification("no dependencies section");
+ }
+ if (dependencies is! YamlMap) {
+ return _invalidSpecification("dependencies is not a map");
+ }
+
+ Map<String, List<String>> normalizedMap = {};
+ dependencies.forEach((key, value) {
+ if (key is! String) {
+ _invalidSpecification("key: '$key' is not a string");
+ }
+ normalizedMap[key] = [];
+ if (value is String) {
+ normalizedMap[key].add(value);
+ } else if (value is List) {
+ value.forEach((entry) {
+ if (entry is! String) {
+ _invalidSpecification("entry: '$entry' is not a string");
+ }
+ normalizedMap[key].add(entry);
+ });
+ } else {
+ _invalidSpecification(
+ "entry: '$value' is not a string or a list of strings");
+ }
+ });
+ return normalizedMap;
+}
+
+_invalidSpecification(String message) {
+ throw new InvalidSpecificationError(message);
+}
+
+class InvalidSpecificationError extends Error {
+ final String message;
+ InvalidSpecificationError(this.message);
+ String toString() => "Invalid specification: $message";
+}
diff --git a/pkg/modular_test/lib/src/find_sdk_root.dart b/pkg/modular_test/lib/src/find_sdk_root.dart
new file mode 100644
index 0000000..2b36550
--- /dev/null
+++ b/pkg/modular_test/lib/src/find_sdk_root.dart
@@ -0,0 +1,28 @@
+// 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.
+
+import 'dart:io';
+
+/// Helper method to locate the root of the SDK repository.
+///
+/// The `modular_test` package is only intended to be used within the SDK at
+/// this time. We need the ability to find the sdk root in order to locate the
+/// default set of packages that are available to all modular tests.
+Future<Uri> findRoot() async {
+ Uri current = Platform.script;
+ while (true) {
+ var segments = current.pathSegments;
+ var index = segments.lastIndexOf('sdk');
+ if (index == -1) {
+ print("error: cannot find the root of the Dart SDK");
+ exitCode = 1;
+ return null;
+ }
+ current = current.resolve("../" * (segments.length - index - 1));
+ if (await File.fromUri(current.resolve("sdk/DEPS")).exists()) {
+ break;
+ }
+ }
+ return current.resolve("sdk/");
+}
diff --git a/pkg/modular_test/lib/src/loader.dart b/pkg/modular_test/lib/src/loader.dart
new file mode 100644
index 0000000..3403380
--- /dev/null
+++ b/pkg/modular_test/lib/src/loader.dart
@@ -0,0 +1,237 @@
+// 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.
+
+/// This library defines how `modular_test` converts the contents of a folder
+/// into a modular test. At this time, the logic in this library assumes this is
+/// only used within the Dart SDK repo.
+///
+/// A modular test folder contains:
+/// * individual .dart files, each file is considered a module. A
+/// `main.dart` file is required as the entry point of the test.
+/// * subfolders: each considered a module with multiple files
+/// * (optional) a .packages file:
+/// * if this is not specified, the test will use [defaultPackagesInput]
+/// instead.
+/// * if specified, it will be extended with the definitions in
+/// [defaultPackagesInput]. The list of packages provided is expected to
+/// be disjoint with those in [defaultPackagesInput].
+/// * a modules.yaml file: a specification of dependencies between modules.
+/// The format is described in `dependencies_parser.dart`.
+import 'dart:io';
+import 'dart:convert';
+import 'suite.dart';
+import 'dependency_parser.dart';
+import 'find_sdk_root.dart';
+
+import 'package:package_config/packages_file.dart' as package_config;
+
+/// Returns the [ModularTest] associated with a folder under [uri].
+///
+/// After scanning the contents of the folder, this method creates a
+/// [ModularTest] that contains only modules that are reachable from the main
+/// module. This method runs several validations including that modules don't
+/// have conflicting names, that the default packages are always visible, and
+/// that modules do not contain cycles.
+Future<ModularTest> loadTest(Uri uri) async {
+ var folder = Directory.fromUri(uri);
+ var testUri = folder.uri; // normalized in case the trailing '/' was missing.
+ Uri root = await findRoot();
+ Map<String, Uri> defaultPackages =
+ package_config.parse(_defaultPackagesInput, root);
+ Map<String, Module> modules = {};
+ String spec;
+ Module mainModule;
+ Map<String, Uri> packages = {};
+ await for (var entry in folder.list(recursive: false)) {
+ var entryUri = entry.uri;
+ if (entry is File) {
+ var fileName = entryUri.path.substring(testUri.path.length);
+ if (fileName.endsWith('.dart')) {
+ var moduleName = fileName.substring(0, fileName.indexOf('.dart'));
+ if (defaultPackages.containsKey(moduleName)) {
+ return _invalidTest("The file '$fileName' defines a module called "
+ "'$moduleName' which conflicts with a package by the same name "
+ "that is provided by default.");
+ }
+ if (modules.containsKey(moduleName)) {
+ return _moduleConflict(fileName, modules[moduleName], testUri);
+ }
+ var relativeUri = Uri.parse(fileName);
+ var isMain = moduleName == 'main';
+ var module = Module(moduleName, [], testUri, [relativeUri],
+ mainSource: isMain ? relativeUri : null);
+ if (isMain) mainModule = module;
+ modules[moduleName] = module;
+ } else if (fileName == '.packages') {
+ List<int> packagesBytes = await entry.readAsBytes();
+ packages = package_config.parse(packagesBytes, entryUri);
+ } else if (fileName == 'modules.yaml') {
+ spec = await entry.readAsString();
+ }
+ } else {
+ assert(entry is Directory);
+ var path = entryUri.path;
+ var moduleName = path.substring(testUri.path.length, path.length - 1);
+ if (defaultPackages.containsKey(moduleName)) {
+ return _invalidTest("The folder '$moduleName' defines a module "
+ "which conflicts with a package by the same name "
+ "that is provided by default.");
+ }
+ if (modules.containsKey(moduleName)) {
+ return _moduleConflict(moduleName, modules[moduleName], testUri);
+ }
+ var sources = await _listModuleSources(entryUri);
+ modules[moduleName] = Module(moduleName, [], entryUri, sources);
+ }
+ }
+ if (spec == null) {
+ return _invalidTest("modules.yaml file is missing");
+ }
+ if (mainModule == null) {
+ return _invalidTest("main module is missing");
+ }
+
+ _addDefaultPackageEntries(packages, defaultPackages);
+ await _addModulePerPackage(packages, modules);
+ _attachDependencies(parseDependencyMap(spec), modules);
+ _attachDependencies(parseDependencyMap(_defaultPackagesSpec), modules);
+ _detectCyclesAndRemoveUnreachable(modules, mainModule);
+ var sortedModules = modules.values.toList()
+ ..sort((a, b) => a.name.compareTo(b.name));
+ return new ModularTest(sortedModules, mainModule);
+}
+
+/// Returns all source files recursively found in a folder as relative URIs.
+Future<List<Uri>> _listModuleSources(Uri root) async {
+ List<Uri> sources = [];
+ Directory folder = Directory.fromUri(root);
+ await for (var file in folder.list(recursive: true)) {
+ sources.add(Uri.parse(file.uri.path.substring(root.path.length)));
+ }
+ return sources..sort((a, b) => a.path.compareTo(b.path));
+}
+
+/// Add links between modules based on the provided dependency map.
+void _attachDependencies(
+ Map<String, List<String>> dependencies, Map<String, Module> modules) {
+ dependencies.forEach((name, moduleDependencies) {
+ var module = modules[name];
+ if (module == null) {
+ _invalidTest(
+ "declared dependencies for a non existing module named '$name'");
+ }
+ if (module.dependencies.isNotEmpty) {
+ _invalidTest("Module dependencies have already been declared on $name.");
+ }
+ moduleDependencies.forEach((dependencyName) {
+ var moduleDependency = modules[dependencyName];
+ if (moduleDependency == null) {
+ _invalidTest("'$name' declares a dependency on a non existing module "
+ "named '$dependencyName'");
+ }
+ module.dependencies.add(moduleDependency);
+ });
+ });
+}
+
+void _addDefaultPackageEntries(
+ Map<String, Uri> packages, Map<String, Uri> defaultPackages) {
+ for (var name in defaultPackages.keys) {
+ var existing = packages[name];
+ if (existing != null && existing != defaultPackages[name]) {
+ _invalidTest(
+ ".packages file defines an conflicting entry for package '$name'.");
+ }
+ packages[name] = defaultPackages[name];
+ }
+}
+
+/// Create a module for each package dependency.
+Future<void> _addModulePerPackage(
+ Map<String, Uri> packages, Map<String, Module> modules) async {
+ for (var packageName in packages.keys) {
+ var module = modules[packageName];
+ if (module != null) {
+ module.isPackage = true;
+ } else {
+ var packageLibUri = packages[packageName];
+ var sources = await _listModuleSources(packageLibUri);
+ // TODO(sigmund): validate that we don't use a different alias for a
+ // module that is part of the test (package name and module name should
+ // match).
+ modules[packageName] =
+ Module(packageName, [], packageLibUri, sources, isPackage: true);
+ }
+ }
+}
+
+/// Trim the set of modules, and detect cycles while we are at it.
+_detectCyclesAndRemoveUnreachable(Map<String, Module> modules, Module main) {
+ Set<Module> visiting = {};
+ Set<Module> visited = {};
+
+ helper(Module current) {
+ if (!visiting.add(current)) {
+ _invalidTest("module '${current.name}' has a dependency cycle.");
+ }
+ if (visited.add(current)) {
+ current.dependencies.forEach(helper);
+ }
+ visiting.remove(current);
+ }
+
+ helper(main);
+ Set<String> toKeep = visited.map((m) => m.name).toSet();
+ List<String> toRemove =
+ modules.keys.where((name) => !toKeep.contains(name)).toList();
+ toRemove.forEach(modules.remove);
+}
+
+/// Default entries for a .packages file with paths relative to the SDK root.
+List<int> _defaultPackagesInput = utf8.encode('''
+expect:pkg/expect/lib
+async_helper:pkg/async_helper/lib
+meta:pkg/meta/lib
+collection:third_party/pkg/collection/lib
+''');
+
+/// Specifies the dependencies of all packages in [_defaultPackagesInput]. This
+/// string needs to be updated if dependencies between those packages changes
+/// (which is rare).
+// TODO(sigmund): consider either computing this from the pubspec files or the
+// import graph, or adding tests that validate this is always up to date.
+String _defaultPackagesSpec = '''
+dependencies:
+ expect: meta
+ meta: []
+ async_helper: []
+ collection: []
+''';
+
+/// Report an conflict error.
+_moduleConflict(String name, Module existing, Uri root) {
+ var isFile = name.endsWith('.dart');
+ var entryType = isFile ? 'file' : 'folder';
+
+ var existingIsFile = existing.rootUri == root;
+ var existingEntryType = existingIsFile ? 'file' : 'folder';
+
+ var existingName = existingIsFile
+ ? existing.sources.single.pathSegments.last
+ : existing.name;
+
+ return _invalidTest("The $entryType '$name' defines a module "
+ "which conflicts with the module defined by the $existingEntryType "
+ "'$existingName'.");
+}
+
+_invalidTest(String message) {
+ throw new InvalidTestError(message);
+}
+
+class InvalidTestError extends Error {
+ final String message;
+ InvalidTestError(this.message);
+ String toString() => "Invalid test: $message";
+}
diff --git a/pkg/modular_test/lib/src/suite.dart b/pkg/modular_test/lib/src/suite.dart
index bba158e..45ebc6a 100644
--- a/pkg/modular_test/lib/src/suite.dart
+++ b/pkg/modular_test/lib/src/suite.dart
@@ -37,10 +37,14 @@
/// [Uri] from [rootUri].
final Uri mainSource;
+ /// Whether this module is also available as a package import, where the
+ /// package name matches the module name.
+ bool isPackage;
+
Module(this.name, this.dependencies, this.rootUri, this.sources,
- this.mainSource) {
+ {this.mainSource, this.isPackage: false}) {
if (!_validModuleName.hasMatch(name)) {
- throw "invalid module name: $name";
+ throw ArgumentError("invalid module name: $name");
}
}
diff --git a/pkg/modular_test/pubspec.yaml b/pkg/modular_test/pubspec.yaml
index 94f26d8..39f65c8 100644
--- a/pkg/modular_test/pubspec.yaml
+++ b/pkg/modular_test/pubspec.yaml
@@ -8,7 +8,9 @@
sdk: ">=2.2.1 <3.0.0"
dependencies:
+ package_config: ^1.0.5
yaml: ^2.1.15
dev_dependencies:
+ args: any
test: any
diff --git a/pkg/modular_test/test/dependency_parser_test.dart b/pkg/modular_test/test/dependency_parser_test.dart
new file mode 100644
index 0000000..f536282
--- /dev/null
+++ b/pkg/modular_test/test/dependency_parser_test.dart
@@ -0,0 +1,64 @@
+// 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.
+
+import 'package:test/test.dart';
+import 'package:modular_test/src/dependency_parser.dart';
+
+main() {
+ test('require dependencies section', () {
+ expect(() => parseDependencyMap(""),
+ throwsA(TypeMatcher<InvalidSpecificationError>()));
+ });
+
+ test('dependencies is a map', () {
+ expect(() => parseDependencyMap("dependencies: []"),
+ throwsA(TypeMatcher<InvalidSpecificationError>()));
+ });
+
+ test('dependencies can be a string or list of strings', () {
+ parseDependencyMap('''
+ dependencies:
+ a: b
+ ''');
+
+ parseDependencyMap('''
+ dependencies:
+ a: [b, c]
+ ''');
+
+ expect(() => parseDependencyMap('''
+ dependencies:
+ a: 1
+ '''), throwsA(TypeMatcher<InvalidSpecificationError>()));
+
+ expect(() => parseDependencyMap('''
+ dependencies:
+ a: true
+ '''), throwsA(TypeMatcher<InvalidSpecificationError>()));
+
+ expect(() => parseDependencyMap('''
+ dependencies:
+ a: [false]
+ '''), throwsA(TypeMatcher<InvalidSpecificationError>()));
+
+ expect(() => parseDependencyMap('''
+ dependencies:
+ a:
+ c: d
+ '''), throwsA(TypeMatcher<InvalidSpecificationError>()));
+ });
+
+ test('result map is normalized', () {
+ expect(
+ parseDependencyMap('''
+ dependencies:
+ a: [b, c]
+ b: d
+ '''),
+ equals({
+ 'a': ['b', 'c'],
+ 'b': ['d'],
+ }));
+ });
+}
diff --git a/pkg/modular_test/test/find_sdk_root1_test.dart b/pkg/modular_test/test/find_sdk_root1_test.dart
new file mode 100644
index 0000000..2a5ac51
--- /dev/null
+++ b/pkg/modular_test/test/find_sdk_root1_test.dart
@@ -0,0 +1,15 @@
+// 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.
+
+import 'dart:io';
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'package:modular_test/src/find_sdk_root.dart';
+
+main() {
+ asyncTest(() async {
+ Expect.equals(Platform.script.resolve("../../../"), await findRoot());
+ });
+}
diff --git a/pkg/modular_test/test/loader/conflict_file_folder_error/expectation.txt b/pkg/modular_test/test/loader/conflict_file_folder_error/expectation.txt
new file mode 100644
index 0000000..4a83176
--- /dev/null
+++ b/pkg/modular_test/test/loader/conflict_file_folder_error/expectation.txt
@@ -0,0 +1,3 @@
+# This expectation file is generated by loader_test.dart
+
+Invalid test: The file 'm1.dart' defines a module which conflicts with the module defined by the folder 'm1'.
\ No newline at end of file
diff --git a/pkg/modular_test/test/loader/conflict_file_folder_error/m1.dart b/pkg/modular_test/test/loader/conflict_file_folder_error/m1.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/conflict_file_folder_error/m1.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/conflict_file_folder_error/m1/b.dart b/pkg/modular_test/test/loader/conflict_file_folder_error/m1/b.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/conflict_file_folder_error/m1/b.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/conflict_file_folder_error/modules.yaml b/pkg/modular_test/test/loader/conflict_file_folder_error/modules.yaml
new file mode 100644
index 0000000..c093387
--- /dev/null
+++ b/pkg/modular_test/test/loader/conflict_file_folder_error/modules.yaml
@@ -0,0 +1 @@
+dependencies: {}
diff --git a/pkg/modular_test/test/loader/conflict_file_package_error/expect.dart b/pkg/modular_test/test/loader/conflict_file_package_error/expect.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/conflict_file_package_error/expect.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/conflict_file_package_error/expectation.txt b/pkg/modular_test/test/loader/conflict_file_package_error/expectation.txt
new file mode 100644
index 0000000..cabe77c
--- /dev/null
+++ b/pkg/modular_test/test/loader/conflict_file_package_error/expectation.txt
@@ -0,0 +1,3 @@
+# This expectation file is generated by loader_test.dart
+
+Invalid test: The file 'expect.dart' defines a module called 'expect' which conflicts with a package by the same name that is provided by default.
\ No newline at end of file
diff --git a/pkg/modular_test/test/loader/conflict_file_package_error/modules.yaml b/pkg/modular_test/test/loader/conflict_file_package_error/modules.yaml
new file mode 100644
index 0000000..c093387
--- /dev/null
+++ b/pkg/modular_test/test/loader/conflict_file_package_error/modules.yaml
@@ -0,0 +1 @@
+dependencies: {}
diff --git a/pkg/modular_test/test/loader/conflict_folder_package_error/expect/a.dart b/pkg/modular_test/test/loader/conflict_folder_package_error/expect/a.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/conflict_folder_package_error/expect/a.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/conflict_folder_package_error/expectation.txt b/pkg/modular_test/test/loader/conflict_folder_package_error/expectation.txt
new file mode 100644
index 0000000..5118fc0
--- /dev/null
+++ b/pkg/modular_test/test/loader/conflict_folder_package_error/expectation.txt
@@ -0,0 +1,3 @@
+# This expectation file is generated by loader_test.dart
+
+Invalid test: The folder 'expect' defines a module which conflicts with a package by the same name that is provided by default.
\ No newline at end of file
diff --git a/pkg/modular_test/test/loader/conflict_folder_package_error/modules.yaml b/pkg/modular_test/test/loader/conflict_folder_package_error/modules.yaml
new file mode 100644
index 0000000..c093387
--- /dev/null
+++ b/pkg/modular_test/test/loader/conflict_folder_package_error/modules.yaml
@@ -0,0 +1 @@
+dependencies: {}
diff --git a/pkg/modular_test/test/loader/cycle_error/a.dart b/pkg/modular_test/test/loader/cycle_error/a.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/cycle_error/a.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/cycle_error/b.dart b/pkg/modular_test/test/loader/cycle_error/b.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/cycle_error/b.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/cycle_error/c.dart b/pkg/modular_test/test/loader/cycle_error/c.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/cycle_error/c.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/cycle_error/expectation.txt b/pkg/modular_test/test/loader/cycle_error/expectation.txt
new file mode 100644
index 0000000..3825548
--- /dev/null
+++ b/pkg/modular_test/test/loader/cycle_error/expectation.txt
@@ -0,0 +1,3 @@
+# This expectation file is generated by loader_test.dart
+
+Invalid test: module 'b' has a dependency cycle.
\ No newline at end of file
diff --git a/pkg/modular_test/test/loader/cycle_error/main.dart b/pkg/modular_test/test/loader/cycle_error/main.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/cycle_error/main.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/cycle_error/modules.yaml b/pkg/modular_test/test/loader/cycle_error/modules.yaml
new file mode 100644
index 0000000..b07465b
--- /dev/null
+++ b/pkg/modular_test/test/loader/cycle_error/modules.yaml
@@ -0,0 +1,5 @@
+dependencies:
+ a: b
+ b: c
+ c: a
+ main: b
diff --git a/pkg/modular_test/test/loader/dag/a.dart b/pkg/modular_test/test/loader/dag/a.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/dag/a.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/dag/b.dart b/pkg/modular_test/test/loader/dag/b.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/dag/b.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/dag/c.dart b/pkg/modular_test/test/loader/dag/c.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/dag/c.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/dag/d/d.dart b/pkg/modular_test/test/loader/dag/d/d.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/dag/d/d.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/dag/d/e.dart b/pkg/modular_test/test/loader/dag/d/e.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/dag/d/e.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/dag/expectation.txt b/pkg/modular_test/test/loader/dag/expectation.txt
new file mode 100644
index 0000000..ef49643
--- /dev/null
+++ b/pkg/modular_test/test/loader/dag/expectation.txt
@@ -0,0 +1,28 @@
+# This expectation file is generated by loader_test.dart
+
+a
+ is package? no
+ dependencies: b, c
+ a.dart
+
+b
+ is package? no
+ dependencies: d
+ b.dart
+
+c
+ is package? no
+ (no dependencies)
+ c.dart
+
+d
+ is package? no
+ (no dependencies)
+ d.dart
+ e.dart
+
+main
+ **main module**
+ is package? no
+ dependencies: a, b
+ main.dart
diff --git a/pkg/modular_test/test/loader/dag/main.dart b/pkg/modular_test/test/loader/dag/main.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/dag/main.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/dag/modules.yaml b/pkg/modular_test/test/loader/dag/modules.yaml
new file mode 100644
index 0000000..0a775d2
--- /dev/null
+++ b/pkg/modular_test/test/loader/dag/modules.yaml
@@ -0,0 +1,4 @@
+dependencies:
+ a: [b, c]
+ b: d
+ main: [a, b]
diff --git a/pkg/modular_test/test/loader/dag_with_packages/.packages b/pkg/modular_test/test/loader/dag_with_packages/.packages
new file mode 100644
index 0000000..5f1a721
--- /dev/null
+++ b/pkg/modular_test/test/loader/dag_with_packages/.packages
@@ -0,0 +1,2 @@
+a:a/
+c:c/
diff --git a/pkg/modular_test/test/loader/dag_with_packages/a.dart b/pkg/modular_test/test/loader/dag_with_packages/a.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/dag_with_packages/a.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/dag_with_packages/b.dart b/pkg/modular_test/test/loader/dag_with_packages/b.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/dag_with_packages/b.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/dag_with_packages/c.dart b/pkg/modular_test/test/loader/dag_with_packages/c.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/dag_with_packages/c.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/dag_with_packages/d/d.dart b/pkg/modular_test/test/loader/dag_with_packages/d/d.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/dag_with_packages/d/d.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/dag_with_packages/d/e.dart b/pkg/modular_test/test/loader/dag_with_packages/d/e.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/dag_with_packages/d/e.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/dag_with_packages/expectation.txt b/pkg/modular_test/test/loader/dag_with_packages/expectation.txt
new file mode 100644
index 0000000..ff6f03a
--- /dev/null
+++ b/pkg/modular_test/test/loader/dag_with_packages/expectation.txt
@@ -0,0 +1,28 @@
+# This expectation file is generated by loader_test.dart
+
+a
+ is package? yes
+ dependencies: b, c
+ a.dart
+
+b
+ is package? no
+ dependencies: d
+ b.dart
+
+c
+ is package? yes
+ (no dependencies)
+ c.dart
+
+d
+ is package? no
+ (no dependencies)
+ d.dart
+ e.dart
+
+main
+ **main module**
+ is package? no
+ dependencies: a, b
+ main.dart
diff --git a/pkg/modular_test/test/loader/dag_with_packages/main.dart b/pkg/modular_test/test/loader/dag_with_packages/main.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/dag_with_packages/main.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/dag_with_packages/modules.yaml b/pkg/modular_test/test/loader/dag_with_packages/modules.yaml
new file mode 100644
index 0000000..0a775d2
--- /dev/null
+++ b/pkg/modular_test/test/loader/dag_with_packages/modules.yaml
@@ -0,0 +1,4 @@
+dependencies:
+ a: [b, c]
+ b: d
+ main: [a, b]
diff --git a/pkg/modular_test/test/loader/default_package_dependency_error/expectation.txt b/pkg/modular_test/test/loader/default_package_dependency_error/expectation.txt
new file mode 100644
index 0000000..43c7dac
--- /dev/null
+++ b/pkg/modular_test/test/loader/default_package_dependency_error/expectation.txt
@@ -0,0 +1,21 @@
+# This expectation file is generated by loader_test.dart
+
+expect
+ is package? yes
+ dependencies: meta
+ async_minitest.dart
+ expect.dart
+ matchers_lite.dart
+ minitest.dart
+
+main
+ **main module**
+ is package? no
+ dependencies: expect
+ main.dart
+
+meta
+ is package? yes
+ (no dependencies)
+ dart2js.dart
+ meta.dart
diff --git a/pkg/modular_test/test/loader/default_package_dependency_error/main.dart b/pkg/modular_test/test/loader/default_package_dependency_error/main.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/default_package_dependency_error/main.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/default_package_dependency_error/modules.yaml b/pkg/modular_test/test/loader/default_package_dependency_error/modules.yaml
new file mode 100644
index 0000000..a5864d3
--- /dev/null
+++ b/pkg/modular_test/test/loader/default_package_dependency_error/modules.yaml
@@ -0,0 +1,3 @@
+dependencies:
+ main:
+ - expect
diff --git a/pkg/modular_test/test/loader/invalid_module_name_error/bad.name.dart b/pkg/modular_test/test/loader/invalid_module_name_error/bad.name.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/invalid_module_name_error/bad.name.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/invalid_module_name_error/expectation.txt b/pkg/modular_test/test/loader/invalid_module_name_error/expectation.txt
new file mode 100644
index 0000000..631afff
--- /dev/null
+++ b/pkg/modular_test/test/loader/invalid_module_name_error/expectation.txt
@@ -0,0 +1,3 @@
+# This expectation file is generated by loader_test.dart
+
+Invalid argument(s): invalid module name: bad.name
\ No newline at end of file
diff --git a/pkg/modular_test/test/loader/invalid_module_name_error/modules.yaml b/pkg/modular_test/test/loader/invalid_module_name_error/modules.yaml
new file mode 100644
index 0000000..c093387
--- /dev/null
+++ b/pkg/modular_test/test/loader/invalid_module_name_error/modules.yaml
@@ -0,0 +1 @@
+dependencies: {}
diff --git a/pkg/modular_test/test/loader/invalid_packages_error/.packages b/pkg/modular_test/test/loader/invalid_packages_error/.packages
new file mode 100644
index 0000000..d8892ce
--- /dev/null
+++ b/pkg/modular_test/test/loader/invalid_packages_error/.packages
@@ -0,0 +1 @@
+expect:.
diff --git a/pkg/modular_test/test/loader/invalid_packages_error/expectation.txt b/pkg/modular_test/test/loader/invalid_packages_error/expectation.txt
new file mode 100644
index 0000000..6931c77
--- /dev/null
+++ b/pkg/modular_test/test/loader/invalid_packages_error/expectation.txt
@@ -0,0 +1,3 @@
+# This expectation file is generated by loader_test.dart
+
+Invalid test: .packages file defines an conflicting entry for package 'expect'.
\ No newline at end of file
diff --git a/pkg/modular_test/test/loader/invalid_packages_error/main.dart b/pkg/modular_test/test/loader/invalid_packages_error/main.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/invalid_packages_error/main.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/invalid_packages_error/modules.yaml b/pkg/modular_test/test/loader/invalid_packages_error/modules.yaml
new file mode 100644
index 0000000..a5864d3
--- /dev/null
+++ b/pkg/modular_test/test/loader/invalid_packages_error/modules.yaml
@@ -0,0 +1,3 @@
+dependencies:
+ main:
+ - expect
diff --git a/pkg/modular_test/test/loader/loader_test.dart b/pkg/modular_test/test/loader/loader_test.dart
new file mode 100644
index 0000000..e40db7b
--- /dev/null
+++ b/pkg/modular_test/test/loader/loader_test.dart
@@ -0,0 +1,129 @@
+// 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.
+import 'dart:io';
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+import 'package:modular_test/src/loader.dart';
+import 'package:modular_test/src/suite.dart';
+
+import 'package:args/args.dart';
+
+main(List<String> args) {
+ var options = _Options.parse(args);
+ asyncTest(() async {
+ var baseUri = Platform.script.resolve('./');
+ var baseDir = Directory.fromUri(baseUri);
+ await for (var entry in baseDir.list(recursive: false)) {
+ if (entry is Directory) {
+ await _runTest(entry.uri, baseUri, options);
+ }
+ }
+ });
+}
+
+Future<void> _runTest(Uri uri, Uri baseDir, _Options options) async {
+ var dirName = uri.path.substring(baseDir.path.length);
+ if (options.filter != null && !dirName.contains(options.filter)) {
+ if (options.showSkipped) print("skipped: $dirName");
+ return;
+ }
+
+ print("testing: $dirName");
+ 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.isTrue(await file.exists(), "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.equals(expectation, result);
+ print(" expectation matches result.");
+ } 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 = new StringBuffer();
+ bool isFirst = true;
+ for (var module in test.modules) {
+ if (isFirst) {
+ isFirst = false;
+ } else {
+ buffer.write('\n');
+ }
+ buffer.write(module.name);
+ if (test.mainModule == module) {
+ buffer.write('\n **main module**');
+ }
+ buffer.write('\n is package? ${module.isPackage ? '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 {
+ module.sources.forEach((uri) {
+ buffer.write('\n $uri');
+ });
+ }
+
+ buffer.write('\n');
+ }
+ return '$buffer';
+}
+
+class _Options {
+ bool updateExpectations = false;
+ bool showResultOnUpdate = false;
+ bool showSkipped = false;
+ String filter = null;
+
+ static _Options parse(List<String> args) {
+ var parser = new 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']
+ ..showSkipped = argResults['show-skipped']
+ ..filter = argResults['filter'];
+ }
+}
diff --git a/pkg/modular_test/test/loader/missing_dependency_module_error/expectation.txt b/pkg/modular_test/test/loader/missing_dependency_module_error/expectation.txt
new file mode 100644
index 0000000..7fc8c8b
--- /dev/null
+++ b/pkg/modular_test/test/loader/missing_dependency_module_error/expectation.txt
@@ -0,0 +1,3 @@
+# This expectation file is generated by loader_test.dart
+
+Invalid test: 'main' declares a dependency on a non existing module named 'foo'
\ No newline at end of file
diff --git a/pkg/modular_test/test/loader/missing_dependency_module_error/main.dart b/pkg/modular_test/test/loader/missing_dependency_module_error/main.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/missing_dependency_module_error/main.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/missing_dependency_module_error/modules.yaml b/pkg/modular_test/test/loader/missing_dependency_module_error/modules.yaml
new file mode 100644
index 0000000..ffd0987
--- /dev/null
+++ b/pkg/modular_test/test/loader/missing_dependency_module_error/modules.yaml
@@ -0,0 +1,3 @@
+dependencies:
+ main:
+ - foo
diff --git a/pkg/modular_test/test/loader/missing_module_error/expectation.txt b/pkg/modular_test/test/loader/missing_module_error/expectation.txt
new file mode 100644
index 0000000..6551c46
--- /dev/null
+++ b/pkg/modular_test/test/loader/missing_module_error/expectation.txt
@@ -0,0 +1,3 @@
+# This expectation file is generated by loader_test.dart
+
+Invalid test: declared dependencies for a non existing module named 'foo'
\ No newline at end of file
diff --git a/pkg/modular_test/test/loader/missing_module_error/main.dart b/pkg/modular_test/test/loader/missing_module_error/main.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/missing_module_error/main.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/missing_module_error/modules.yaml b/pkg/modular_test/test/loader/missing_module_error/modules.yaml
new file mode 100644
index 0000000..87e50e1
--- /dev/null
+++ b/pkg/modular_test/test/loader/missing_module_error/modules.yaml
@@ -0,0 +1,3 @@
+dependencies:
+ foo:
+ - expect
diff --git a/pkg/modular_test/test/loader/missing_yaml_error/a.dart b/pkg/modular_test/test/loader/missing_yaml_error/a.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/missing_yaml_error/a.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/missing_yaml_error/expectation.txt b/pkg/modular_test/test/loader/missing_yaml_error/expectation.txt
new file mode 100644
index 0000000..9dd6322
--- /dev/null
+++ b/pkg/modular_test/test/loader/missing_yaml_error/expectation.txt
@@ -0,0 +1,3 @@
+# This expectation file is generated by loader_test.dart
+
+Invalid test: modules.yaml file is missing
\ No newline at end of file
diff --git a/pkg/modular_test/test/loader/no_dependencies/expectation.txt b/pkg/modular_test/test/loader/no_dependencies/expectation.txt
new file mode 100644
index 0000000..f19449b
--- /dev/null
+++ b/pkg/modular_test/test/loader/no_dependencies/expectation.txt
@@ -0,0 +1,7 @@
+# This expectation file is generated by loader_test.dart
+
+main
+ **main module**
+ is package? no
+ (no dependencies)
+ main.dart
diff --git a/pkg/modular_test/test/loader/no_dependencies/main.dart b/pkg/modular_test/test/loader/no_dependencies/main.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/no_dependencies/main.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/no_dependencies/modules.yaml b/pkg/modular_test/test/loader/no_dependencies/modules.yaml
new file mode 100644
index 0000000..c093387
--- /dev/null
+++ b/pkg/modular_test/test/loader/no_dependencies/modules.yaml
@@ -0,0 +1 @@
+dependencies: {}
diff --git a/pkg/modular_test/test/loader/no_main_error/a.dart b/pkg/modular_test/test/loader/no_main_error/a.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/no_main_error/a.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/no_main_error/expectation.txt b/pkg/modular_test/test/loader/no_main_error/expectation.txt
new file mode 100644
index 0000000..78e9711
--- /dev/null
+++ b/pkg/modular_test/test/loader/no_main_error/expectation.txt
@@ -0,0 +1,3 @@
+# This expectation file is generated by loader_test.dart
+
+Invalid test: main module is missing
\ No newline at end of file
diff --git a/pkg/modular_test/test/loader/no_main_error/modules.yaml b/pkg/modular_test/test/loader/no_main_error/modules.yaml
new file mode 100644
index 0000000..c093387
--- /dev/null
+++ b/pkg/modular_test/test/loader/no_main_error/modules.yaml
@@ -0,0 +1 @@
+dependencies: {}
diff --git a/pkg/modular_test/test/loader/readme.md b/pkg/modular_test/test/loader/readme.md
new file mode 100644
index 0000000..a3da9fa
--- /dev/null
+++ b/pkg/modular_test/test/loader/readme.md
@@ -0,0 +1,18 @@
+The `loader_test` folder contains a folder per test.
+
+Each test is focusing on part of the features of how tests folders are
+recognized and turned into a modular test specification by our libraries. Note
+that all `.dart` source files in these tests are empty because we ignore their
+contents.
+
+Each folder contains a file named `expectation.txt` which shows a plain text
+summary of what we expect to extract or report from the test:
+
+ * for invalid inputs it shows the error mesage produced by the modular\_test
+ loader logic
+
+ * for valid inputs it shows the test layout, highlighting what each module
+ contents and dependencies are.
+
+In the future, modular tests will be written in the style of the non-error test
+cases.
diff --git a/pkg/modular_test/test/loader/tree/a.dart b/pkg/modular_test/test/loader/tree/a.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/tree/a.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/tree/b.dart b/pkg/modular_test/test/loader/tree/b.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/tree/b.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/tree/c.dart b/pkg/modular_test/test/loader/tree/c.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/tree/c.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/tree/d/d.dart b/pkg/modular_test/test/loader/tree/d/d.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/tree/d/d.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/tree/d/e.dart b/pkg/modular_test/test/loader/tree/d/e.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/tree/d/e.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/tree/expectation.txt b/pkg/modular_test/test/loader/tree/expectation.txt
new file mode 100644
index 0000000..ffcf4b0
--- /dev/null
+++ b/pkg/modular_test/test/loader/tree/expectation.txt
@@ -0,0 +1,28 @@
+# This expectation file is generated by loader_test.dart
+
+a
+ is package? no
+ dependencies: b, c
+ a.dart
+
+b
+ is package? no
+ dependencies: d
+ b.dart
+
+c
+ is package? no
+ (no dependencies)
+ c.dart
+
+d
+ is package? no
+ (no dependencies)
+ d.dart
+ e.dart
+
+main
+ **main module**
+ is package? no
+ dependencies: a
+ main.dart
diff --git a/pkg/modular_test/test/loader/tree/main.dart b/pkg/modular_test/test/loader/tree/main.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/tree/main.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/tree/modules.yaml b/pkg/modular_test/test/loader/tree/modules.yaml
new file mode 100644
index 0000000..b1254c0
--- /dev/null
+++ b/pkg/modular_test/test/loader/tree/modules.yaml
@@ -0,0 +1,4 @@
+dependencies:
+ a: [b, c]
+ b: d
+ main: a
diff --git a/pkg/modular_test/test/loader/valid_packages/.packages b/pkg/modular_test/test/loader/valid_packages/.packages
new file mode 100644
index 0000000..d8e718b
--- /dev/null
+++ b/pkg/modular_test/test/loader/valid_packages/.packages
@@ -0,0 +1 @@
+js:../../../../js/lib
diff --git a/pkg/modular_test/test/loader/valid_packages/expectation.txt b/pkg/modular_test/test/loader/valid_packages/expectation.txt
new file mode 100644
index 0000000..a81d4ec
--- /dev/null
+++ b/pkg/modular_test/test/loader/valid_packages/expectation.txt
@@ -0,0 +1,29 @@
+# This expectation file is generated by loader_test.dart
+
+expect
+ is package? yes
+ dependencies: meta
+ async_minitest.dart
+ expect.dart
+ matchers_lite.dart
+ minitest.dart
+
+js
+ is package? yes
+ (no dependencies)
+ js.dart
+ js_util.dart
+ src/
+ src/varargs.dart
+
+main
+ **main module**
+ is package? no
+ dependencies: js, expect
+ main.dart
+
+meta
+ is package? yes
+ (no dependencies)
+ dart2js.dart
+ meta.dart
diff --git a/pkg/modular_test/test/loader/valid_packages/main.dart b/pkg/modular_test/test/loader/valid_packages/main.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/valid_packages/main.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/valid_packages/modules.yaml b/pkg/modular_test/test/loader/valid_packages/modules.yaml
new file mode 100644
index 0000000..2ad9483
--- /dev/null
+++ b/pkg/modular_test/test/loader/valid_packages/modules.yaml
@@ -0,0 +1,4 @@
+dependencies:
+ main:
+ - js
+ - expect
diff --git a/pkg/modular_test/test/pipeline_common.dart b/pkg/modular_test/test/pipeline_common.dart
index a01da5c..d99e687 100644
--- a/pkg/modular_test/test/pipeline_common.dart
+++ b/pkg/modular_test/test/pipeline_common.dart
@@ -75,9 +75,9 @@
};
var m1 = Module("a", const [], testStrategy.testRootUri,
- [Uri.parse("a1.dart"), Uri.parse("a2.dart")], null);
+ [Uri.parse("a1.dart"), Uri.parse("a2.dart")]);
var m2 = Module("b", [m1], testStrategy.testRootUri.resolve('b/'),
- [Uri.parse("b1.dart"), Uri.parse("b2.dart")], null);
+ [Uri.parse("b1.dart"), Uri.parse("b2.dart")]);
var singleModuleInput = ModularTest([m1], m1);
var multipleModulesInput = ModularTest([m1, m2], m2);
diff --git a/pkg/modular_test/test/src/find_sdk_root2_test.dart b/pkg/modular_test/test/src/find_sdk_root2_test.dart
new file mode 100644
index 0000000..0bfbeb6
--- /dev/null
+++ b/pkg/modular_test/test/src/find_sdk_root2_test.dart
@@ -0,0 +1,15 @@
+// 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.
+
+import 'dart:io';
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'package:modular_test/src/find_sdk_root.dart';
+
+main() {
+ asyncTest(() async {
+ Expect.equals(Platform.script.resolve("../../../../"), await findRoot());
+ });
+}
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 5ad6e12..881f093 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -130,7 +130,6 @@
[ $runtime != vm ]
dev_compiler/test/options/*: SkipByDesign
front_end/test/hot_reload_e2e_test: Skip
-modular_test/test/io_pipeline_test: SkipByDesign
vm/test/*: SkipByDesign # Only meant to run on vm
[ $system == linux ]
@@ -177,9 +176,13 @@
analyzer/test/*: Skip # Issue 26813
analyzer/tool/*: Skip # Issue 26813
-# Analyze dev_compiler but only run its tests on the vm
[ $compiler != dart2analyzer && $runtime != vm ]
dev_compiler/test/*: Skip
+modular_test/test/dependency_parser_test: SkipByDesign
+modular_test/test/find_sdk_root1_test: SkipByDesign
+modular_test/test/io_pipeline_test: SkipByDesign
+modular_test/test/loader/loader_test: SkipByDesign
+modular_test/test/src/find_sdk_root2_test: SkipByDesign
[ $compiler == dart2js && $runtime == chrome && $system == macos ]
third_party/di_tests/di_test: Pass, Slow # Issue 22896