| Index: lib/src/backend/metadata.dart
|
| diff --git a/lib/src/backend/metadata.dart b/lib/src/backend/metadata.dart
|
| index 54eb64ed71ccb25a68620857617785a05e10cbbe..2b38c08e0fb78c588418bc2389d568b1d96e548b 100644
|
| --- a/lib/src/backend/metadata.dart
|
| +++ b/lib/src/backend/metadata.dart
|
| @@ -4,6 +4,7 @@
|
|
|
| import 'dart:collection';
|
|
|
| +import 'package:boolean_selector/boolean_selector.dart';
|
| import 'package:collection/collection.dart';
|
|
|
| import '../frontend/skip.dart';
|
| @@ -48,9 +49,9 @@ class Metadata {
|
| /// Note that unlike [onPlatform], the base metadata takes precedence over any
|
| /// tag-specific metadata.
|
| ///
|
| - /// This is guaranteed not to have any keys that appear in [tags]; those are
|
| + /// This is guaranteed not to have any keys that match [tags]; those are
|
| /// resolved when the metadata is constructed.
|
| - final Map<String, Metadata> forTag;
|
| + final Map<BooleanSelector, Metadata> forTag;
|
|
|
| /// Parses a user-provided map into the value for [onPlatform].
|
| static Map<PlatformSelector, Metadata> _parseOnPlatform(
|
| @@ -118,45 +119,39 @@ class Metadata {
|
| ///
|
| /// [testOn] defaults to [PlatformSelector.all].
|
| ///
|
| - /// If [forTag] contains metadata for any tags in [tags], that metadata is
|
| + /// If [forTag] contains metadata that applies to [tags], that metadata is
|
| /// included inline in the returned value. The values directly passed to the
|
| /// constructor take precedence over tag-specific metadata.
|
| factory Metadata({PlatformSelector testOn, Timeout timeout, bool skip: false,
|
| bool verboseTrace: false, String skipReason, Iterable<String> tags,
|
| Map<PlatformSelector, Metadata> onPlatform,
|
| - Map<String, Metadata> forTag}) {
|
| + Map<BooleanSelector, Metadata> forTag}) {
|
| + // Returns metadata without forTag resolved at all.
|
| + _unresolved() => new Metadata._(
|
| + testOn: testOn,
|
| + timeout: timeout,
|
| + skip: skip,
|
| + verboseTrace: verboseTrace,
|
| + skipReason: skipReason,
|
| + tags: tags,
|
| + onPlatform: onPlatform,
|
| + forTag: forTag);
|
| +
|
| // If there's no tag-specific metadata, or if none of it applies, just
|
| // return the metadata as-is.
|
| - if (forTag == null || tags == null || !tags.any(forTag.containsKey)) {
|
| - return new Metadata._(
|
| - testOn: testOn,
|
| - timeout: timeout,
|
| - skip: skip,
|
| - verboseTrace: verboseTrace,
|
| - skipReason: skipReason,
|
| - tags: tags,
|
| - onPlatform: onPlatform,
|
| - forTag: forTag);
|
| - }
|
| + if (forTag == null || tags == null) return _unresolved();
|
|
|
| // Otherwise, resolve the tag-specific components. Doing this eagerly means
|
| // we only have to resolve suite- or group-level tags once, rather than
|
| // doing it for every test individually.
|
| - forTag = new Map.from(forTag);
|
| - var merged = tags.fold(new Metadata._(), (merged, tag) {
|
| - var tagMetadata = forTag.remove(tag);
|
| - return tagMetadata == null ? merged : merged.merge(tagMetadata);
|
| + var empty = new Metadata._();
|
| + var merged = forTag.keys.toList().fold(empty, (merged, selector) {
|
| + if (!selector.evaluate(tags)) return merged;
|
| + return merged.merge(forTag.remove(selector));
|
| });
|
|
|
| - return merged.merge(new Metadata._(
|
| - testOn: testOn,
|
| - timeout: timeout,
|
| - skip: skip,
|
| - verboseTrace: verboseTrace,
|
| - skipReason: skipReason,
|
| - tags: tags,
|
| - onPlatform: onPlatform,
|
| - forTag: forTag));
|
| + if (merged == empty) return _unresolved();
|
| + return merged.merge(_unresolved());
|
| }
|
|
|
| /// Creates new Metadata.
|
| @@ -165,7 +160,7 @@ class Metadata {
|
| Metadata._({PlatformSelector testOn, Timeout timeout, bool skip: false,
|
| this.verboseTrace: false, this.skipReason, Iterable<String> tags,
|
| Map<PlatformSelector, Metadata> onPlatform,
|
| - Map<String, Metadata> forTag})
|
| + Map<BooleanSelector, Metadata> forTag})
|
| : testOn = testOn == null ? PlatformSelector.all : testOn,
|
| timeout = timeout == null ? const Timeout.factor(1) : timeout,
|
| skip = skip,
|
| @@ -218,6 +213,7 @@ class Metadata {
|
| key: (pair) => new PlatformSelector.parse(pair.first),
|
| value: (pair) => new Metadata.deserialize(pair.last)),
|
| forTag = mapMap(serialized['forTag'],
|
| + key: (key, _) => new BooleanSelector.parse(key),
|
| value: (_, nested) => new Metadata.deserialize(nested));
|
|
|
| /// Deserializes timeout from the format returned by [_serializeTimeout].
|
| @@ -308,7 +304,9 @@ class Metadata {
|
| 'verboseTrace': verboseTrace,
|
| 'tags': tags.toList(),
|
| 'onPlatform': serializedOnPlatform,
|
| - 'forTag': mapMap(forTag, value: (_, metadata) => metadata.serialize())
|
| + 'forTag': mapMap(forTag,
|
| + key: (selector, _) => selector.toString(),
|
| + value: (_, metadata) => metadata.serialize())
|
| };
|
| }
|
|
|
|
|