| // 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. |
| |
| import 'package:boolean_selector/boolean_selector.dart'; |
| import 'package:source_span/source_span.dart'; |
| |
| import 'operating_system.dart'; |
| import 'runtime.dart'; |
| import 'suite_platform.dart'; |
| |
| /// The set of variable names that are valid for all platform selectors. |
| final _universalValidVariables = { |
| 'posix', |
| 'dart-vm', |
| 'browser', |
| 'js', |
| 'blink', |
| 'google', |
| for (var runtime in Runtime.builtIn) runtime.identifier, |
| for (var os in OperatingSystem.all) os.identifier, |
| }; |
| |
| /// An expression for selecting certain platforms, including operating systems |
| /// and browsers. |
| /// |
| /// This uses the [boolean selector][] syntax. |
| /// |
| /// [boolean selector]: https://pub.dev/packages/boolean_selector |
| class PlatformSelector { |
| /// A selector that declares that a test can be run on all platforms. |
| static const all = PlatformSelector._(BooleanSelector.all); |
| |
| /// The boolean selector used to implement this selector. |
| final BooleanSelector _inner; |
| |
| /// The source span from which this selector was parsed. |
| final SourceSpan? _span; |
| |
| /// Parses [selector]. |
| /// |
| /// If [span] is passed, it indicates the location of the text for [selector] |
| /// in a larger document. It's used for error reporting. |
| PlatformSelector.parse(String selector, [SourceSpan? span]) |
| : _inner = |
| _wrapFormatException(() => BooleanSelector.parse(selector), span), |
| _span = span; |
| |
| const PlatformSelector._(this._inner) : _span = null; |
| |
| /// Runs [body] and wraps any [FormatException] it throws in a |
| /// [SourceSpanFormatException] using [span]. |
| /// |
| /// If [span] is `null`, runs [body] as-is. |
| static T _wrapFormatException<T>(T Function() body, [SourceSpan? span]) { |
| if (span == null) return body(); |
| |
| try { |
| return body(); |
| } on FormatException catch (error) { |
| throw SourceSpanFormatException(error.message, span); |
| } |
| } |
| |
| /// Throws a [FormatException] if this selector uses any variables that don't |
| /// appear either in [validVariables] or in the set of variables that are |
| /// known to be valid for all selectors. |
| void validate(Set<String> validVariables) { |
| if (identical(this, all)) return; |
| |
| _wrapFormatException( |
| () => _inner.validate((name) => |
| _universalValidVariables.contains(name) || |
| validVariables.contains(name)), |
| _span); |
| } |
| |
| /// Returns whether the selector matches the given [platform]. |
| /// |
| /// [os] defaults to [OperatingSystem.none]. |
| bool evaluate(SuitePlatform platform) { |
| return _inner.evaluate((String variable) { |
| if (variable == platform.runtime.identifier) return true; |
| if (variable == platform.runtime.parent?.identifier) return true; |
| if (variable == platform.os.identifier) return true; |
| switch (variable) { |
| case 'dart-vm': |
| return platform.runtime.isDartVM; |
| case 'browser': |
| return platform.runtime.isBrowser; |
| case 'js': |
| return platform.runtime.isJS; |
| case 'blink': |
| return platform.runtime.isBlink; |
| case 'posix': |
| return platform.os.isPosix; |
| case 'google': |
| return platform.inGoogle; |
| default: |
| return false; |
| } |
| }); |
| } |
| |
| /// Returns a new [PlatformSelector] that matches only platforms matched by |
| /// both [this] and [other]. |
| PlatformSelector intersection(PlatformSelector other) { |
| if (other == PlatformSelector.all) return this; |
| return PlatformSelector._(_inner.intersection(other._inner)); |
| } |
| |
| @override |
| String toString() => _inner.toString(); |
| |
| @override |
| bool operator ==(other) => |
| other is PlatformSelector && _inner == other._inner; |
| |
| @override |
| int get hashCode => _inner.hashCode; |
| } |