baa721ba23
+ and use it in the dart2js modular tests Change-Id: I66cf29dcea7fb705135049e7a6ea4eb17052f3d9 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/103575 Commit-Queue: Sigmund Cherem <sigmund@google.com> Reviewed-by: Johnni Winther <johnniwinther@google.com>
111 lines
4.0 KiB
Dart
111 lines
4.0 KiB
Dart
// 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 a test specification from a Yaml
|
|
/// file. We expect specifications written in this format:
|
|
///
|
|
/// dependencies:
|
|
/// b: a
|
|
/// main: [b, expect]
|
|
/// flags:
|
|
/// - constant-update-2018
|
|
///
|
|
/// Where the dependencies section describe how modules depend on one another,
|
|
/// and the flags section show what flags are needed to run that specific test.
|
|
///
|
|
/// When defining dependencies:
|
|
/// - 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.
|
|
///
|
|
/// The framework is agnostic of what the flags are, but at this time we only
|
|
/// use the name of experimental language features. These are then used to
|
|
/// decide what options to pass to the tools that compile and run the tests.
|
|
import 'package:yaml/yaml.dart';
|
|
|
|
/// Parses [contents] containing a module dependencies specification written in
|
|
/// yaml, and returns a [TestSpecification].
|
|
TestSpecification parseTestSpecification(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");
|
|
}
|
|
});
|
|
|
|
List<String> normalizedFlags = [];
|
|
dynamic flags = spec['flags'];
|
|
if (flags is String) {
|
|
normalizedFlags.add(flags);
|
|
} else if (flags is List) {
|
|
normalizedFlags.addAll(flags.cast<String>());
|
|
} else if (flags != null) {
|
|
_invalidSpecification(
|
|
"flags: '$flags' expected to be string or list of strings");
|
|
}
|
|
return new TestSpecification(normalizedFlags, normalizedMap);
|
|
}
|
|
|
|
/// Data specifying details about a modular test including dependencies and
|
|
/// flags that are necessary in order to properly run a test.
|
|
///
|
|
class TestSpecification {
|
|
/// Set of flags necessary to properly run a test.
|
|
///
|
|
/// Usually this contains flags enabling language experiments.
|
|
final List<String> flags;
|
|
|
|
/// Dependencies of the modules that are expected to exist on the test.
|
|
///
|
|
/// 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 explicitly because they are added automatically by the framework
|
|
/// (for instance, the module of `package:expect` or the sdk itself).
|
|
final Map<String, List<String>> dependencies;
|
|
|
|
TestSpecification(this.flags, this.dependencies);
|
|
}
|
|
|
|
_invalidSpecification(String message) {
|
|
throw new InvalidSpecificationError(message);
|
|
}
|
|
|
|
class InvalidSpecificationError extends Error {
|
|
final String message;
|
|
InvalidSpecificationError(this.message);
|
|
String toString() => "Invalid specification: $message";
|
|
}
|