| Index: mojo/public/dart/third_party/test/lib/src/backend/metadata.dart
|
| diff --git a/mojo/public/dart/third_party/test/lib/src/backend/metadata.dart b/mojo/public/dart/third_party/test/lib/src/backend/metadata.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..e6be71e93b416395896c71eebe992f9dd6e9b2ba
|
| --- /dev/null
|
| +++ b/mojo/public/dart/third_party/test/lib/src/backend/metadata.dart
|
| @@ -0,0 +1,209 @@
|
| +// Copyright (c) 2015, 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.
|
| +
|
| +library test.backend.metadata;
|
| +
|
| +import 'dart:collection';
|
| +
|
| +import '../backend/operating_system.dart';
|
| +import '../backend/test_platform.dart';
|
| +import '../frontend/skip.dart';
|
| +import '../frontend/timeout.dart';
|
| +import '../utils.dart';
|
| +import 'platform_selector.dart';
|
| +
|
| +/// Metadata for a test or test suite.
|
| +///
|
| +/// This metadata comes from declarations on the test itself; it doesn't include
|
| +/// configuration from the user.
|
| +class Metadata {
|
| + /// The selector indicating which platforms the suite supports.
|
| + final PlatformSelector testOn;
|
| +
|
| + /// The modification to the timeout for the test or suite.
|
| + final Timeout timeout;
|
| +
|
| + /// Whether the test or suite should be skipped.
|
| + final bool skip;
|
| +
|
| + /// Whether to use verbose stack traces.
|
| + final bool verboseTrace;
|
| +
|
| + /// The reason the test or suite should be skipped, if given.
|
| + final String skipReason;
|
| +
|
| + /// Platform-specific metadata.
|
| + ///
|
| + /// Each key identifies a platform, and its value identifies the specific
|
| + /// metadata for that platform. These can be applied by calling [forPlatform].
|
| + final Map<PlatformSelector, Metadata> onPlatform;
|
| +
|
| + /// Parses a user-provided map into the value for [onPlatform].
|
| + static Map<PlatformSelector, Metadata> _parseOnPlatform(
|
| + Map<String, dynamic> onPlatform) {
|
| + if (onPlatform == null) return {};
|
| +
|
| + var result = {};
|
| + onPlatform.forEach((platform, metadata) {
|
| + if (metadata is Timeout || metadata is Skip) {
|
| + metadata = [metadata];
|
| + } else if (metadata is! List) {
|
| + throw new ArgumentError('Metadata for platform "$platform" must be a '
|
| + 'Timeout, Skip, or List of those; was "$metadata".');
|
| + }
|
| +
|
| + var selector = new PlatformSelector.parse(platform);
|
| +
|
| + var timeout;
|
| + var skip;
|
| + for (var metadatum in metadata) {
|
| + if (metadatum is Timeout) {
|
| + if (timeout != null) {
|
| + throw new ArgumentError('Only a single Timeout may be declared for '
|
| + '"$platform".');
|
| + }
|
| +
|
| + timeout = metadatum;
|
| + } else if (metadatum is Skip) {
|
| + if (skip != null) {
|
| + throw new ArgumentError('Only a single Skip may be declared for '
|
| + '"$platform".');
|
| + }
|
| +
|
| + skip = metadatum.reason == null ? true : metadatum.reason;
|
| + } else {
|
| + throw new ArgumentError('Metadata for platform "$platform" must be a '
|
| + 'Timeout, Skip, or List of those; was "$metadata".');
|
| + }
|
| + }
|
| +
|
| + result[selector] = new Metadata.parse(timeout: timeout, skip: skip);
|
| + });
|
| + return result;
|
| + }
|
| +
|
| + /// Creates new Metadata.
|
| + ///
|
| + /// [testOn] defaults to [PlatformSelector.all].
|
| + Metadata({PlatformSelector testOn, Timeout timeout, bool skip: false,
|
| + this.verboseTrace: false, this.skipReason,
|
| + Map<PlatformSelector, Metadata> onPlatform})
|
| + : testOn = testOn == null ? PlatformSelector.all : testOn,
|
| + timeout = timeout == null ? const Timeout.factor(1) : timeout,
|
| + skip = skip,
|
| + onPlatform = onPlatform == null
|
| + ? const {}
|
| + : new UnmodifiableMapView(onPlatform);
|
| +
|
| + /// Creates a new Metadata, but with fields parsed from caller-friendly values
|
| + /// where applicable.
|
| + ///
|
| + /// Throws a [FormatException] if any field is invalid.
|
| + Metadata.parse({String testOn, Timeout timeout, skip,
|
| + this.verboseTrace: false, Map<String, dynamic> onPlatform})
|
| + : testOn = testOn == null
|
| + ? PlatformSelector.all
|
| + : new PlatformSelector.parse(testOn),
|
| + timeout = timeout == null ? const Timeout.factor(1) : timeout,
|
| + skip = skip != null && skip != false,
|
| + skipReason = skip is String ? skip : null,
|
| + onPlatform = _parseOnPlatform(onPlatform) {
|
| + if (skip != null && skip is! String && skip is! bool) {
|
| + throw new ArgumentError(
|
| + '"skip" must be a String or a bool, was "$skip".');
|
| + }
|
| + }
|
| +
|
| + /// Dezerializes the result of [Metadata.serialize] into a new [Metadata].
|
| + Metadata.deserialize(serialized)
|
| + : testOn = serialized['testOn'] == null
|
| + ? PlatformSelector.all
|
| + : new PlatformSelector.parse(serialized['testOn']),
|
| + timeout = _deserializeTimeout(serialized['timeout']),
|
| + skip = serialized['skip'],
|
| + skipReason = serialized['skipReason'],
|
| + verboseTrace = serialized['verboseTrace'],
|
| + onPlatform = new Map.fromIterable(serialized['onPlatform'],
|
| + key: (pair) => new PlatformSelector.parse(pair.first),
|
| + value: (pair) => new Metadata.deserialize(pair.last));
|
| +
|
| + /// Deserializes timeout from the format returned by [_serializeTimeout].
|
| + static _deserializeTimeout(serialized) {
|
| + if (serialized == 'none') return Timeout.none;
|
| + var scaleFactor = serialized['scaleFactor'];
|
| + if (scaleFactor != null) return new Timeout.factor(scaleFactor);
|
| + return new Timeout(
|
| + new Duration(microseconds: serialized['duration']));
|
| + }
|
| +
|
| + /// Return a new [Metadata] that merges [this] with [other].
|
| + ///
|
| + /// If the two [Metadata]s have conflicting properties, [other] wins.
|
| + Metadata merge(Metadata other) =>
|
| + new Metadata(
|
| + testOn: testOn.intersect(other.testOn),
|
| + timeout: timeout.merge(other.timeout),
|
| + skip: skip || other.skip,
|
| + verboseTrace: verboseTrace || other.verboseTrace,
|
| + skipReason: other.skipReason == null ? skipReason : other.skipReason,
|
| + onPlatform: mergeMaps(onPlatform, other.onPlatform));
|
| +
|
| + /// Returns a copy of [this] with the given fields changed.
|
| + Metadata change({PlatformSelector testOn, Timeout timeout, bool skip,
|
| + bool verboseTrace, String skipReason,
|
| + Map<PlatformSelector, Metadata> onPlatform}) {
|
| + if (testOn == null) testOn = this.testOn;
|
| + if (timeout == null) timeout = this.timeout;
|
| + if (skip == null) skip = this.skip;
|
| + if (verboseTrace == null) verboseTrace = this.verboseTrace;
|
| + if (skipReason == null) skipReason = this.skipReason;
|
| + if (onPlatform == null) onPlatform = this.onPlatform;
|
| + return new Metadata(testOn: testOn, timeout: timeout, skip: skip,
|
| + verboseTrace: verboseTrace, skipReason: skipReason,
|
| + onPlatform: onPlatform);
|
| + }
|
| +
|
| + /// Returns a copy of [this] with all platform-specific metadata from
|
| + /// [onPlatform] resolved.
|
| + Metadata forPlatform(TestPlatform platform, {OperatingSystem os}) {
|
| + if (onPlatform.isEmpty) return this;
|
| +
|
| + var metadata = this;
|
| + onPlatform.forEach((platformSelector, platformMetadata) {
|
| + if (!platformSelector.evaluate(platform, os: os)) return;
|
| + metadata = metadata.merge(platformMetadata);
|
| + });
|
| + return metadata.change(onPlatform: {});
|
| + }
|
| +
|
| + /// Serializes [this] into a JSON-safe object that can be deserialized using
|
| + /// [new Metadata.deserialize].
|
| + serialize() {
|
| + // Make this a list to guarantee that the order is preserved.
|
| + var serializedOnPlatform = [];
|
| + onPlatform.forEach((key, value) {
|
| + serializedOnPlatform.add([key.toString(), value.serialize()]);
|
| + });
|
| +
|
| + return {
|
| + 'testOn': testOn == PlatformSelector.all ? null : testOn.toString(),
|
| + 'timeout': _serializeTimeout(timeout),
|
| + 'skip': skip,
|
| + 'skipReason': skipReason,
|
| + 'verboseTrace': verboseTrace,
|
| + 'onPlatform': serializedOnPlatform
|
| + };
|
| + }
|
| +
|
| + /// Serializes timeout into a JSON-safe object.
|
| + _serializeTimeout(Timeout timeout) {
|
| + if (timeout == Timeout.none) return 'none';
|
| + return {
|
| + 'duration': timeout.duration == null
|
| + ? null
|
| + : timeout.duration.inMicroseconds,
|
| + 'scaleFactor': timeout.scaleFactor
|
| + };
|
| + }
|
| +}
|
|
|