[platform] Import the platform package (#4613)

Imports the `packages` platform from https://github.com/google/platform.dart
- As there is not much history in the package, this imports it as a copy instead of going through the process of actually merging the commit history of that repo into this one.
- The only changes relative to the current source in that repo are:
  - Adjustments for repo conventions (such as removing analysis_options.yaml and fixing the resulting issues).
  - Addressing https://github.com/google/platform.dart/pull/44

Part of https://github.com/flutter/flutter/issues/130915
This commit is contained in:
stuartmorgan
2023-08-16 10:32:04 -07:00
committed by GitHub
parent 63ba60ca7d
commit 3a183b78f2
15 changed files with 815 additions and 1 deletions

View File

@ -30,6 +30,7 @@ packages/multicast_dns/** @dnfield
packages/palette_generator/** @gspencergoog
packages/path_provider/** @stuartmorgan
packages/pigeon/** @tarrinneal
packages/platform/** @stuartmorgan
packages/plugin_platform_interface/** @stuartmorgan
packages/pointer_interceptor/** @ditman
packages/quick_actions/** @bparrishMines

View File

@ -14,7 +14,7 @@ These packages are also available on [pub](https://pub.dartlang.org/flutter/pack
## Issues
Please file any issues, bugs, or feature requests in the [main flutter
repo](https://github.com/flutter/flutter/issues/new).
repo](https://github.com/flutter/flutter/issues/new).
Issues pertaining to this repository are [labeled
"package"](https://github.com/flutter/flutter/issues?q=is%3Aopen+is%3Aissue+label%3Apackage).
@ -64,6 +64,7 @@ These are the packages hosted in this repository:
| [palette\_generator](./packages/palette_generator/) | [![pub package](https://img.shields.io/pub/v/palette_generator.svg)](https://pub.dartlang.org/packages/palette_generator) | [![pub points](https://img.shields.io/pub/points/palette_generator)](https://pub.dev/packages/palette_generator/score) | [![popularity](https://img.shields.io/pub/popularity/palette_generator)](https://pub.dev/packages/palette_generator/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p:%20palette_generator?label=)](https://github.com/flutter/flutter/labels/p%3A%20palette_generator) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p:%20palette_generator?label=)](https://github.com/flutter/packages/labels/p%3A%20palette_generator) |
| [path\_provider](./packages/path_provider/) | [![pub package](https://img.shields.io/pub/v/path_provider.svg)](https://pub.dev/packages/path_provider) | [![pub points](https://img.shields.io/pub/points/path_provider)](https://pub.dev/packages/path_provider/score) | [![popularity](https://img.shields.io/pub/popularity/path_provider)](https://pub.dev/packages/path_provider/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p:%20path_provider?label=)](https://github.com/flutter/flutter/labels/p%3A%20path_provider) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p:%20path_provider?label=)](https://github.com/flutter/packages/labels/p%3A%20path_provider) |
| [pigeon](./packages/pigeon/) | [![pub package](https://img.shields.io/pub/v/pigeon.svg)](https://pub.dev/packages/pigeon) | [![pub points](https://img.shields.io/pub/points/pigeon)](https://pub.dev/packages/pigeon/score) | [![popularity](https://img.shields.io/pub/popularity/pigeon)](https://pub.dev/packages/pigeon/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/pigeon?label=)](https://github.com/flutter/flutter/labels/pigeon) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p:%20pigeon?label=)](https://github.com/flutter/packages/labels/p%3A%20pigeon) |
| [platform](./packages/platform/) | [![pub package](https://img.shields.io/pub/v/platform.svg)](https://pub.dev/packages/platform) | [![pub points](https://img.shields.io/pub/points/platform)](https://pub.dev/packages/platform/score) | [![popularity](https://img.shields.io/pub/popularity/platform)](https://pub.dev/packages/platform/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p:%20platform?label=)](https://github.com/flutter/flutter/labels/p%3A%20platform) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p:%20platform?label=)](https://github.com/flutter/packages/labels/p%3A%20platform) |
| [pointer\_interceptor](./packages/pointer_interceptor/) | [![pub package](https://img.shields.io/pub/v/pointer_interceptor.svg)](https://pub.dev/packages/pointer_interceptor) | [![pub points](https://img.shields.io/pub/points/pointer_interceptor)](https://pub.dev/packages/pointer_interceptor/score) | [![popularity](https://img.shields.io/pub/popularity/pointer_interceptor)](https://pub.dev/packages/pointer_interceptor/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p:%20pointer_interceptor?label=)](https://github.com/flutter/flutter/labels/p%3A%20pointer_interceptor) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p:%20pointer_interceptor?label=)](https://github.com/flutter/packages/labels/p%3A%20pointer_interceptor) |
| [plugin\_platform\_interface](./packages/plugin_platform_interface/) | [![pub package](https://img.shields.io/pub/v/plugin_platform_interface.svg)](https://pub.dev/packages/plugin_platform_interface) | [![pub points](https://img.shields.io/pub/points/plugin_platform_interface)](https://pub.dev/packages/plugin_platform_interface/score) | [![popularity](https://img.shields.io/pub/popularity/plugin_platform_interface)](https://pub.dev/packages/plugin_platform_interface/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p:%20plugin_platform_interface?label=)](https://github.com/flutter/flutter/labels/p%3A%20plugin_platform_interface) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p:%20plugin_platform_interface?label=)](https://github.com/flutter/packages/labels/p%3A%20plugin_platform_interface) |
| [quick\_actions](./packages/quick_actions/) | [![pub package](https://img.shields.io/pub/v/quick_actions.svg)](https://pub.dev/packages/quick_actions) | [![pub points](https://img.shields.io/pub/points/quick_actions)](https://pub.dev/packages/quick_actions/score) | [![popularity](https://img.shields.io/pub/popularity/quick_actions)](https://pub.dev/packages/quick_actions/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p:%20quick_actions?label=)](https://github.com/flutter/flutter/labels/p%3A%20quick_actions) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p:%20quick_actions?label=)](https://github.com/flutter/packages/labels/p%3A%20quick_actions) |

17
packages/platform/.gitignore vendored Normal file
View File

@ -0,0 +1,17 @@
### Dart template
# Dont commit the following directories created by pub.
.buildlog
.dart_tool/
.pub/
build/
packages
.packages
# Include when developing application packages.
pubspec.lock
# IDE
.project
.settings
.idea
.c9

View File

@ -0,0 +1,6 @@
# Below is a list of people and organizations that have contributed
# to the Process project. Names should be added to the list like so:
#
# Name/Organization <email address>
Google Inc.

View File

@ -0,0 +1,87 @@
## 3.1.1
* Transfers the package source from https://github.com/google/platform.dart to
https://github.com/flutter/packages.
## 3.1.0
* Removed `Platform.packageRoot`, which was already marked deprecated, and which
didn't work in Dart 2.
## 3.0.2
* Added `FakePlatform.copyWith` function.
## 3.0.1
* Added string constants for each of the supported platforms for use in switch
statements.
## 3.0.0
* First stable null safe release.
## 3.0.0-nullsafety.4
* Update supported SDK range.
## 3.0.0-nullsafety.3
* Update supported SDK range.
## 3.0.0-nullsafety.2
* Update supported SDK range.
## 3.0.0-nullsafety.1
* Migrate package to null-safe dart.
## 2.2.1
* Add `operatingSystemVersion`
## 2.2.0
* Declare compatibility with Dart 2 stable
* Update dependency on `package:test` to 1.0
## 2.1.2
* Relax sdk upper bound constraint to '<2.0.0' to allow 'edge' dart sdk use.
## 2.1.1
* Bumped maximum Dart SDK version to 2.0.0-dev.infinity
## 2.1.0
* Added `localeName`
* Bumped minimum Dart SDK version to 1.24.0-dev.0.0
## 2.0.0
* Added `stdinSupportsAnsi` and `stdinSupportsAnsi`
* Removed `ansiSupported`
## 1.1.1
* Updated `LocalPlatform` to use new `dart.io` API for ansi color support queries
* Bumped minimum Dart SDK version to 1.23.0-dev.10.0
## 1.1.0
* Added `ansiSupported`
* Bumped minimum Dart SDK version to 1.23.0-dev.9.0
## 1.0.2
* Minor doc updates
## 1.0.1
* Added const constructors for `Platform` and `LocalPlatform`
## 1.0.0
* Initial version

25
packages/platform/LICENSE Normal file
View File

@ -0,0 +1,25 @@
Copyright 2013 The Flutter Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,10 @@
[![Pub](https://img.shields.io/pub/v/platform.svg)](https://pub.dartlang.org/packages/platform)
A generic platform abstraction for Dart.
Like `dart:io`, `package:platform` supplies a rich, Dart-idiomatic API for
accessing platform-specific information.
`package:platform` provides a lightweight wrapper around the static `Platform`
properties that exist in `dart:io`. However, it uses instance properties rather
than static properties, making it possible to mock out in tests.

View File

@ -0,0 +1 @@
test_on: vm

View File

@ -0,0 +1,8 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/// Core interfaces & classes.
export 'src/interface/local_platform.dart';
export 'src/interface/platform.dart';
export 'src/testing/fake_platform.dart';

View File

@ -0,0 +1,58 @@
// Copyright 2013 The Flutter Authors. 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' as io show Platform, stdin, stdout;
import 'platform.dart';
/// `Platform` implementation that delegates directly to `dart:io`.
class LocalPlatform extends Platform {
/// Creates a new [LocalPlatform].
const LocalPlatform();
@override
int get numberOfProcessors => io.Platform.numberOfProcessors;
@override
String get pathSeparator => io.Platform.pathSeparator;
@override
String get operatingSystem => io.Platform.operatingSystem;
@override
String get operatingSystemVersion => io.Platform.operatingSystemVersion;
@override
String get localHostname => io.Platform.localHostname;
@override
Map<String, String> get environment => io.Platform.environment;
@override
String get executable => io.Platform.executable;
@override
String get resolvedExecutable => io.Platform.resolvedExecutable;
@override
Uri get script => io.Platform.script;
@override
List<String> get executableArguments => io.Platform.executableArguments;
@override
String? get packageConfig => io.Platform.packageConfig;
@override
String get version => io.Platform.version;
@override
bool get stdinSupportsAnsi => io.stdin.supportsAnsiEscapes;
@override
bool get stdoutSupportsAnsi => io.stdout.supportsAnsiEscapes;
@override
String get localeName => io.Platform.localeName;
}

View File

@ -0,0 +1,205 @@
// Copyright 2013 The Flutter Authors. 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:convert';
/// Provides API parity with the `Platform` class in `dart:io`, but using
/// instance properties rather than static properties. This difference enables
/// the use of these APIs in tests, where you can provide mock implementations.
abstract class Platform {
/// Creates a new [Platform].
const Platform();
/// A string constant to compare with [operatingSystem] to see if the platform
/// is Linux.
///
/// Useful in case statements when switching on [operatingSystem].
///
/// To just check if the platform is Linux, use [isLinux].
static const String linux = 'linux';
/// A string constant to compare with [operatingSystem] to see if the platform
/// is Windows.
///
/// Useful in case statements when switching on [operatingSystem].
///
/// To just check if the platform is Windows, use [isWindows].
static const String windows = 'windows';
/// A string constant to compare with [operatingSystem] to see if the platform
/// is macOS.
///
/// Useful in case statements when switching on [operatingSystem].
///
/// To just check if the platform is macOS, use [isMacOS].
static const String macOS = 'macos';
/// A string constant to compare with [operatingSystem] to see if the platform
/// is Android.
///
/// Useful in case statements when switching on [operatingSystem].
///
/// To just check if the platform is Android, use [isAndroid].
static const String android = 'android';
/// A string constant to compare with [operatingSystem] to see if the platform
/// is iOS.
///
/// Useful in case statements when switching on [operatingSystem].
///
/// To just check if the platform is iOS, use [isIOS].
static const String iOS = 'ios';
/// A string constant to compare with [operatingSystem] to see if the platform
/// is Fuchsia.
///
/// Useful in case statements when switching on [operatingSystem].
///
/// To just check if the platform is Fuchsia, use [isFuchsia].
static const String fuchsia = 'fuchsia';
/// A list of the possible values that [operatingSystem] can return.
static const List<String> operatingSystemValues = <String>[
linux,
macOS,
windows,
android,
iOS,
fuchsia,
];
/// The number of processors of the machine.
int get numberOfProcessors;
/// The path separator used by the operating system to separate
/// components in file paths.
String get pathSeparator;
/// A string (`linux`, `macos`, `windows`, `android`, `ios`, or `fuchsia`)
/// representing the operating system.
///
/// The possible return values are available from [operatingSystemValues], and
/// there are constants for each of the platforms to use in switch statements
/// or conditionals (See [linux], [macOS], [windows], [android], [iOS], and
/// [fuchsia]).
String get operatingSystem;
/// A string representing the version of the operating system or platform.
String get operatingSystemVersion;
/// Get the local hostname for the system.
String get localHostname;
/// True if the operating system is Linux.
bool get isLinux => operatingSystem == linux;
/// True if the operating system is OS X.
bool get isMacOS => operatingSystem == macOS;
/// True if the operating system is Windows.
bool get isWindows => operatingSystem == windows;
/// True if the operating system is Android.
bool get isAndroid => operatingSystem == android;
/// True if the operating system is iOS.
bool get isIOS => operatingSystem == iOS;
/// True if the operating system is Fuchsia
bool get isFuchsia => operatingSystem == fuchsia;
/// The environment for this process.
///
/// The returned environment is an unmodifiable map whose content is
/// retrieved from the operating system on its first use.
///
/// Environment variables on Windows are case-insensitive. The map
/// returned on Windows is therefore case-insensitive and will convert
/// all keys to upper case. On other platforms the returned map is
/// a standard case-sensitive map.
Map<String, String> get environment;
/// The path of the executable used to run the script in this isolate.
///
/// The path returned is the literal path used to run the script. This
/// path might be relative or just be a name from which the executable
/// was found by searching the `PATH`.
///
/// To get the absolute path to the resolved executable use
/// [resolvedExecutable].
String get executable;
/// The path of the executable used to run the script in this
/// isolate after it has been resolved by the OS.
///
/// This is the absolute path, with all symlinks resolved, to the
/// executable used to run the script.
String get resolvedExecutable;
/// The absolute URI of the script being run in this
/// isolate.
///
/// If the script argument on the command line is relative,
/// it is resolved to an absolute URI before fetching the script, and
/// this absolute URI is returned.
///
/// URI resolution only does string manipulation on the script path, and this
/// may be different from the file system's path resolution behavior. For
/// example, a symbolic link immediately followed by '..' will not be
/// looked up.
///
/// If the executable environment does not support [script] an empty
/// [Uri] is returned.
Uri get script;
/// The flags passed to the executable used to run the script in this
/// isolate. These are the command-line flags between the executable name
/// and the script name. Each fetch of `executableArguments` returns a new
/// list containing the flags passed to the executable.
List<String> get executableArguments;
/// The value of the `--packages` flag passed to the executable
/// used to run the script in this isolate. This is the configuration which
/// specifies how Dart packages are looked up.
///
/// If there is no `--packages` flag, `null` is returned.
String? get packageConfig;
/// The version of the current Dart runtime.
///
/// The returned `String` is formatted as the [semver](http://semver.org)
/// version string of the current dart runtime, possibly followed by
/// whitespace and other version and build details.
String get version;
/// When stdin is connected to a terminal, whether ANSI codes are supported.
bool get stdinSupportsAnsi;
/// When stdout is connected to a terminal, whether ANSI codes are supported.
bool get stdoutSupportsAnsi;
/// Get the name of the current locale.
String get localeName;
/// Returns a JSON-encoded representation of this platform.
String toJson() {
return const JsonEncoder.withIndent(' ').convert(<String, dynamic>{
'numberOfProcessors': numberOfProcessors,
'pathSeparator': pathSeparator,
'operatingSystem': operatingSystem,
'operatingSystemVersion': operatingSystemVersion,
'localHostname': localHostname,
'environment': environment,
'executable': executable,
'resolvedExecutable': resolvedExecutable,
'script': script.toString(),
'executableArguments': executableArguments,
'packageConfig': packageConfig,
'version': version,
'stdinSupportsAnsi': stdinSupportsAnsi,
'stdoutSupportsAnsi': stdoutSupportsAnsi,
'localeName': localeName,
});
}
}

View File

@ -0,0 +1,199 @@
// Copyright 2013 The Flutter Authors. 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:convert';
import '../interface/platform.dart';
/// Provides a mutable implementation of the [Platform] interface.
class FakePlatform extends Platform {
/// Creates a new [FakePlatform] with the specified properties.
///
/// Unspecified properties will *not* be assigned default values (they will
/// remain `null`). If an unset non-null value is read, a [StateError] will
/// be thrown instead of returning `null`.
FakePlatform({
int? numberOfProcessors,
String? pathSeparator,
String? operatingSystem,
String? operatingSystemVersion,
String? localHostname,
Map<String, String>? environment,
String? executable,
String? resolvedExecutable,
Uri? script,
List<String>? executableArguments,
this.packageConfig,
String? version,
bool? stdinSupportsAnsi,
bool? stdoutSupportsAnsi,
String? localeName,
}) : _numberOfProcessors = numberOfProcessors,
_pathSeparator = pathSeparator,
_operatingSystem = operatingSystem,
_operatingSystemVersion = operatingSystemVersion,
_localHostname = localHostname,
_environment = environment,
_executable = executable,
_resolvedExecutable = resolvedExecutable,
_script = script,
_executableArguments = executableArguments,
_version = version,
_stdinSupportsAnsi = stdinSupportsAnsi,
_stdoutSupportsAnsi = stdoutSupportsAnsi,
_localeName = localeName;
/// Creates a new [FakePlatform] with properties whose initial values mirror
/// the specified [platform].
FakePlatform.fromPlatform(Platform platform)
: _numberOfProcessors = platform.numberOfProcessors,
_pathSeparator = platform.pathSeparator,
_operatingSystem = platform.operatingSystem,
_operatingSystemVersion = platform.operatingSystemVersion,
_localHostname = platform.localHostname,
_environment = Map<String, String>.from(platform.environment),
_executable = platform.executable,
_resolvedExecutable = platform.resolvedExecutable,
_script = platform.script,
_executableArguments = List<String>.from(platform.executableArguments),
packageConfig = platform.packageConfig,
_version = platform.version,
_stdinSupportsAnsi = platform.stdinSupportsAnsi,
_stdoutSupportsAnsi = platform.stdoutSupportsAnsi,
_localeName = platform.localeName;
/// Creates a new [FakePlatform] with properties extracted from the encoded
/// JSON string.
///
/// [json] must be a JSON string that matches the encoding produced by
/// [toJson].
factory FakePlatform.fromJson(String json) {
final Map<String, dynamic> map =
const JsonDecoder().convert(json) as Map<String, dynamic>;
return FakePlatform(
numberOfProcessors: map['numberOfProcessors'] as int?,
pathSeparator: map['pathSeparator'] as String?,
operatingSystem: map['operatingSystem'] as String?,
operatingSystemVersion: map['operatingSystemVersion'] as String?,
localHostname: map['localHostname'] as String?,
environment:
(map['environment'] as Map<Object?, Object?>).cast<String, String>(),
executable: map['executable'] as String?,
resolvedExecutable: map['resolvedExecutable'] as String?,
script: Uri.parse(map['script'] as String),
executableArguments:
(map['executableArguments'] as List<Object?>).cast<String>(),
packageConfig: map['packageConfig'] as String?,
version: map['version'] as String?,
stdinSupportsAnsi: map['stdinSupportsAnsi'] as bool?,
stdoutSupportsAnsi: map['stdoutSupportsAnsi'] as bool?,
localeName: map['localeName'] as String?,
);
}
/// Creates a new [FakePlatform] from this one, with some properties replaced by the given properties.
FakePlatform copyWith({
int? numberOfProcessors,
String? pathSeparator,
String? operatingSystem,
String? operatingSystemVersion,
String? localHostname,
Map<String, String>? environment,
String? executable,
String? resolvedExecutable,
Uri? script,
List<String>? executableArguments,
String? packageConfig,
String? version,
bool? stdinSupportsAnsi,
bool? stdoutSupportsAnsi,
String? localeName,
}) {
return FakePlatform(
numberOfProcessors: numberOfProcessors ?? this.numberOfProcessors,
pathSeparator: pathSeparator ?? this.pathSeparator,
operatingSystem: operatingSystem ?? this.operatingSystem,
operatingSystemVersion:
operatingSystemVersion ?? this.operatingSystemVersion,
localHostname: localHostname ?? this.localHostname,
environment: environment ?? this.environment,
executable: executable ?? this.executable,
resolvedExecutable: resolvedExecutable ?? this.resolvedExecutable,
script: script ?? this.script,
executableArguments: executableArguments ?? this.executableArguments,
packageConfig: packageConfig ?? this.packageConfig,
version: version ?? this.version,
stdinSupportsAnsi: stdinSupportsAnsi ?? this.stdinSupportsAnsi,
stdoutSupportsAnsi: stdoutSupportsAnsi ?? this.stdoutSupportsAnsi,
localeName: localeName ?? this.localeName,
);
}
@override
int get numberOfProcessors => _throwIfNull(_numberOfProcessors);
int? _numberOfProcessors;
@override
String get pathSeparator => _throwIfNull(_pathSeparator);
String? _pathSeparator;
@override
String get operatingSystem => _throwIfNull(_operatingSystem);
String? _operatingSystem;
@override
String get operatingSystemVersion => _throwIfNull(_operatingSystemVersion);
String? _operatingSystemVersion;
@override
String get localHostname => _throwIfNull(_localHostname);
String? _localHostname;
@override
Map<String, String> get environment => _throwIfNull(_environment);
Map<String, String>? _environment;
@override
String get executable => _throwIfNull(_executable);
String? _executable;
@override
String get resolvedExecutable => _throwIfNull(_resolvedExecutable);
String? _resolvedExecutable;
@override
Uri get script => _throwIfNull(_script);
Uri? _script;
@override
List<String> get executableArguments => _throwIfNull(_executableArguments);
List<String>? _executableArguments;
@override
String? packageConfig;
@override
String get version => _throwIfNull(_version);
String? _version;
@override
bool get stdinSupportsAnsi => _throwIfNull(_stdinSupportsAnsi);
bool? _stdinSupportsAnsi;
@override
bool get stdoutSupportsAnsi => _throwIfNull(_stdoutSupportsAnsi);
bool? _stdoutSupportsAnsi;
@override
String get localeName => _throwIfNull(_localeName);
String? _localeName;
T _throwIfNull<T>(T? value) {
if (value == null) {
throw StateError(
'Tried to read property of FakePlatform but it was unset.');
}
return value;
}
}

View File

@ -0,0 +1,11 @@
name: platform
description: A pluggable, mockable platform information abstraction for Dart.
repository: https://github.com/flutter/packages/tree/main/packages/platform
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+platform%22
version: 3.1.1
environment:
sdk: ">=2.18.0 <3.0.0"
dev_dependencies:
test: ^1.16.8

View File

@ -0,0 +1,165 @@
// Copyright 2013 The Flutter Authors. 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' as io;
import 'package:platform/platform.dart';
import 'package:test/test.dart';
void _expectPlatformsEqual(Platform actual, Platform expected) {
expect(actual.numberOfProcessors, expected.numberOfProcessors);
expect(actual.pathSeparator, expected.pathSeparator);
expect(actual.operatingSystem, expected.operatingSystem);
expect(actual.operatingSystemVersion, expected.operatingSystemVersion);
expect(actual.localHostname, expected.localHostname);
expect(actual.environment, expected.environment);
expect(actual.executable, expected.executable);
expect(actual.resolvedExecutable, expected.resolvedExecutable);
expect(actual.script, expected.script);
expect(actual.executableArguments, expected.executableArguments);
expect(actual.packageConfig, expected.packageConfig);
expect(actual.version, expected.version);
expect(actual.localeName, expected.localeName);
}
void main() {
group('FakePlatform', () {
late FakePlatform fake;
late LocalPlatform local;
setUp(() {
fake = FakePlatform();
local = const LocalPlatform();
});
group('fromPlatform', () {
setUp(() {
fake = FakePlatform.fromPlatform(local);
});
test('copiesAllProperties', () {
_expectPlatformsEqual(fake, local);
});
test('convertsPropertiesToMutable', () {
final String key = fake.environment.keys.first;
expect(fake.environment[key], local.environment[key]);
fake.environment[key] = 'FAKE';
expect(fake.environment[key], 'FAKE');
expect(
fake.executableArguments.length, local.executableArguments.length);
fake.executableArguments.add('ARG');
expect(fake.executableArguments.last, 'ARG');
});
});
group('copyWith', () {
setUp(() {
fake = FakePlatform.fromPlatform(local);
});
test('overrides a value, but leaves others intact', () {
final FakePlatform copy = fake.copyWith(
numberOfProcessors: -1,
);
expect(copy.numberOfProcessors, equals(-1));
expect(copy.pathSeparator, local.pathSeparator);
expect(copy.operatingSystem, local.operatingSystem);
expect(copy.operatingSystemVersion, local.operatingSystemVersion);
expect(copy.localHostname, local.localHostname);
expect(copy.environment, local.environment);
expect(copy.executable, local.executable);
expect(copy.resolvedExecutable, local.resolvedExecutable);
expect(copy.script, local.script);
expect(copy.executableArguments, local.executableArguments);
expect(copy.packageConfig, local.packageConfig);
expect(copy.version, local.version);
expect(copy.localeName, local.localeName);
});
test('can override all values', () {
fake = FakePlatform(
numberOfProcessors: 8,
pathSeparator: ':',
operatingSystem: 'fake',
operatingSystemVersion: '0.1.0',
localHostname: 'host',
environment: <String, String>{'PATH': '.'},
executable: 'executable',
resolvedExecutable: '/executable',
script: Uri.file('/platform/test/fake_platform_test.dart'),
executableArguments: <String>['scriptarg'],
version: '0.1.1',
stdinSupportsAnsi: false,
stdoutSupportsAnsi: true,
localeName: 'local',
);
final FakePlatform copy = fake.copyWith(
numberOfProcessors: local.numberOfProcessors,
pathSeparator: local.pathSeparator,
operatingSystem: local.operatingSystem,
operatingSystemVersion: local.operatingSystemVersion,
localHostname: local.localHostname,
environment: local.environment,
executable: local.executable,
resolvedExecutable: local.resolvedExecutable,
script: local.script,
executableArguments: local.executableArguments,
packageConfig: local.packageConfig,
version: local.version,
stdinSupportsAnsi: local.stdinSupportsAnsi,
stdoutSupportsAnsi: local.stdoutSupportsAnsi,
localeName: local.localeName,
);
_expectPlatformsEqual(copy, local);
});
});
group('json', () {
test('fromJson', () {
final String json = io.File('test/platform.json').readAsStringSync();
fake = FakePlatform.fromJson(json);
expect(fake.numberOfProcessors, 8);
expect(fake.pathSeparator, '/');
expect(fake.operatingSystem, 'macos');
expect(fake.operatingSystemVersion, '10.14.5');
expect(fake.localHostname, 'platform.test.org');
expect(fake.environment, <String, String>{
'PATH': '/bin',
'PWD': '/platform',
});
expect(fake.executable, '/bin/dart');
expect(fake.resolvedExecutable, '/bin/dart');
expect(fake.script, Uri.file('/platform/test/fake_platform_test.dart'));
expect(fake.executableArguments, <String>['--checked']);
expect(fake.packageConfig, null);
expect(fake.version, '1.22.0');
expect(fake.localeName, 'de/de');
});
test('fromJsonToJson', () {
fake = FakePlatform.fromJson(local.toJson());
_expectPlatformsEqual(fake, local);
});
});
});
test('Throws when unset non-null values are read', () {
final FakePlatform platform = FakePlatform();
expect(() => platform.numberOfProcessors, throwsA(isStateError));
expect(() => platform.pathSeparator, throwsA(isStateError));
expect(() => platform.operatingSystem, throwsA(isStateError));
expect(() => platform.operatingSystemVersion, throwsA(isStateError));
expect(() => platform.localHostname, throwsA(isStateError));
expect(() => platform.environment, throwsA(isStateError));
expect(() => platform.executable, throwsA(isStateError));
expect(() => platform.resolvedExecutable, throwsA(isStateError));
expect(() => platform.script, throwsA(isStateError));
expect(() => platform.executableArguments, throwsA(isStateError));
expect(() => platform.version, throwsA(isStateError));
expect(() => platform.localeName, throwsA(isStateError));
});
}

View File

@ -0,0 +1,20 @@
{
"numberOfProcessors": 8,
"pathSeparator": "/",
"operatingSystem": "macos",
"operatingSystemVersion": "10.14.5",
"localHostname": "platform.test.org",
"environment": {
"PATH": "/bin",
"PWD": "/platform"
},
"executable": "/bin/dart",
"resolvedExecutable": "/bin/dart",
"script": "file:///platform/test/fake_platform_test.dart",
"executableArguments": [
"--checked"
],
"packageConfig": null,
"version": "1.22.0",
"localeName": "de/de"
}