├── .github └── workflows │ └── platform.yml ├── .gitignore ├── AUTHORS ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── analysis_options.yaml ├── example ├── .gitignore ├── README.md ├── analysis_options.yaml ├── bin │ └── example.dart └── pubspec.yaml ├── lib ├── platform.dart └── src │ ├── interface │ ├── local_platform.dart │ └── platform.dart │ └── testing │ └── fake_platform.dart ├── pubspec.yaml └── test ├── fake_platform_test.dart └── platform.json /.github/workflows/platform.yml: -------------------------------------------------------------------------------- 1 | name: Platform Package 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | workflow_dispatch: 9 | 10 | jobs: 11 | correctness: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f 15 | - uses: dart-lang/setup-dart@9a04e6d73cca37bd455e0608d7e5092f881fd603 16 | with: 17 | sdk: dev 18 | - name: Install dependencies 19 | run: dart pub upgrade 20 | - name: Verify formatting 21 | run: dart format --output=none --set-exit-if-changed . 22 | - name: Analyze project source 23 | run: dart analyze --fatal-infos 24 | test: 25 | runs-on: ${{ matrix.os }} 26 | strategy: 27 | matrix: 28 | os: [ubuntu-latest, macos-latest, windows-latest] 29 | sdk: [stable, beta, dev] 30 | steps: 31 | - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f 32 | - uses: dart-lang/setup-dart@9a04e6d73cca37bd455e0608d7e5092f881fd603 33 | with: 34 | sdk: ${{ matrix.sdk }} 35 | - name: Install dependencies 36 | run: dart pub upgrade 37 | - name: Run Tests 38 | run: dart test 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### Dart template 2 | # Don’t commit the following directories created by pub. 3 | .buildlog 4 | .dart_tool/ 5 | .pub/ 6 | build/ 7 | packages 8 | .packages 9 | 10 | # Include when developing application packages. 11 | pubspec.lock 12 | 13 | # IDE 14 | .project 15 | .settings 16 | .idea 17 | .c9 18 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | # Below is a list of people and organizations that have contributed 2 | # to the Process project. Names should be added to the list like so: 3 | # 4 | # Name/Organization 5 | 6 | Google Inc. 7 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 3.1.5 2 | 3 | * Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. 4 | * Transfers the package source from https://github.com/flutter/packages 5 | to https://github.com/dart-lang/platform. 6 | 7 | ## 3.1.4 8 | 9 | * Updates minimum supported SDK version to Flutter 3.10/Dart 3.0. 10 | * Fixes new lint warnings. 11 | 12 | ## 3.1.3 13 | 14 | * Adds example app. 15 | 16 | ## 3.1.2 17 | 18 | * Adds pub topics to package metadata. 19 | * Updates minimum supported SDK version to Flutter 3.7/Dart 2.19. 20 | 21 | ## 3.1.1 22 | 23 | * Transfers the package source from https://github.com/google/platform.dart to 24 | https://github.com/flutter/packages. 25 | 26 | ## 3.1.0 27 | 28 | * Removed `Platform.packageRoot`, which was already marked deprecated, and which 29 | didn't work in Dart 2. 30 | 31 | ## 3.0.2 32 | 33 | * Added `FakePlatform.copyWith` function. 34 | 35 | ## 3.0.1 36 | 37 | * Added string constants for each of the supported platforms for use in switch 38 | statements. 39 | 40 | ## 3.0.0 41 | 42 | * First stable null safe release. 43 | 44 | ## 3.0.0-nullsafety.4 45 | 46 | * Update supported SDK range. 47 | 48 | ## 3.0.0-nullsafety.3 49 | 50 | * Update supported SDK range. 51 | 52 | ## 3.0.0-nullsafety.2 53 | 54 | * Update supported SDK range. 55 | 56 | ## 3.0.0-nullsafety.1 57 | 58 | * Migrate package to null-safe dart. 59 | 60 | ## 2.2.1 61 | 62 | * Add `operatingSystemVersion` 63 | 64 | ## 2.2.0 65 | 66 | * Declare compatibility with Dart 2 stable 67 | * Update dependency on `package:test` to 1.0 68 | 69 | ## 2.1.2 70 | 71 | * Relax sdk upper bound constraint to '<2.0.0' to allow 'edge' dart sdk use. 72 | 73 | ## 2.1.1 74 | 75 | * Bumped maximum Dart SDK version to 2.0.0-dev.infinity 76 | 77 | ## 2.1.0 78 | 79 | * Added `localeName` 80 | * Bumped minimum Dart SDK version to 1.24.0-dev.0.0 81 | 82 | ## 2.0.0 83 | 84 | * Added `stdinSupportsAnsi` and `stdinSupportsAnsi` 85 | * Removed `ansiSupported` 86 | 87 | ## 1.1.1 88 | 89 | * Updated `LocalPlatform` to use new `dart.io` API for ansi color support queries 90 | * Bumped minimum Dart SDK version to 1.23.0-dev.10.0 91 | 92 | ## 1.1.0 93 | 94 | * Added `ansiSupported` 95 | * Bumped minimum Dart SDK version to 1.23.0-dev.9.0 96 | 97 | ## 1.0.2 98 | 99 | * Minor doc updates 100 | 101 | ## 1.0.1 102 | 103 | * Added const constructors for `Platform` and `LocalPlatform` 104 | 105 | ## 1.0.0 106 | 107 | * Initial version 108 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to contribute 2 | 3 | We'd love to accept your patches and contributions to this project. There are 4 | just a few small guidelines you need to follow. 5 | 6 | ## Contributor License Agreement 7 | 8 | Contributions to this project must be accompanied by a Contributor License 9 | Agreement. You (or your employer) retain the copyright to your contribution, 10 | this simply gives us permission to use and redistribute your contributions as 11 | part of the project. Head over to to see 12 | your current agreements on file or to sign a new one. 13 | 14 | You generally only need to submit a CLA once, so if you've already submitted one 15 | (even if it was for a different project), you probably don't need to do it 16 | again. 17 | 18 | ## Code reviews 19 | 20 | All submissions, including submissions by project members, require review. We 21 | use GitHub pull requests for this purpose. Consult [GitHub Help] for more 22 | information on using pull requests. 23 | 24 | [GitHub Help]: https://help.github.com/articles/about-pull-requests/ 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2017, the Dart project authors. All rights reserved. 2 | Redistribution and use in source and binary forms, with or without 3 | modification, are permitted provided that the following conditions are 4 | met: 5 | 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above 9 | copyright notice, this list of conditions and the following 10 | disclaimer in the documentation and/or other materials provided 11 | with the distribution. 12 | * Neither the name of Google Inc. nor the names of its 13 | contributors may be used to endorse or promote products derived 14 | from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > [!IMPORTANT] 2 | > This repo has moved to https://github.com/dart-lang/core/tree/main/pkgs/platform 3 | 4 | [![Pub](https://img.shields.io/pub/v/platform.svg)](https://pub.dartlang.org/packages/platform) 5 | 6 | A generic platform abstraction for Dart. 7 | 8 | Like `dart:io`, `package:platform` supplies a rich, Dart-idiomatic API for 9 | accessing platform-specific information. 10 | 11 | `package:platform` provides a lightweight wrapper around the static `Platform` 12 | properties that exist in `dart:io`. However, it uses instance properties rather 13 | than static properties, making it possible to mock out in tests. 14 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:dart_flutter_team_lints/analysis_options.yaml 2 | 3 | analyzer: 4 | errors: 5 | # Allow having TODOs in the code 6 | todo: ignore 7 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # https://dart.dev/guides/libraries/private-files 2 | # Created by `dart pub` 3 | .dart_tool/ 4 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | A small example application demonstrating how to use the platform information 2 | APIs in `package:platform`. -------------------------------------------------------------------------------- /example/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the static analysis results for your project (errors, 2 | # warnings, and lints). 3 | # 4 | # This enables the 'recommended' set of lints from `package:lints`. 5 | # This set helps identify many issues that may lead to problems when running 6 | # or consuming Dart code, and enforces writing Dart using a single, idiomatic 7 | # style and format. 8 | # 9 | # If you want a smaller set of lints you can change this to specify 10 | # 'package:lints/core.yaml'. These are just the most critical lints 11 | # (the recommended set includes the core lints). 12 | # The core lints are also what is used by pub.dev for scoring packages. 13 | 14 | include: package:lints/recommended.yaml 15 | 16 | # Uncomment the following section to specify additional rules. 17 | 18 | # linter: 19 | # rules: 20 | # - camel_case_types 21 | 22 | # analyzer: 23 | # exclude: 24 | # - path/to/excluded/files/** 25 | 26 | # For more information about the core and recommended set of lints, see 27 | # https://dart.dev/go/core-lints 28 | 29 | # For additional information about configuring this file, see 30 | # https://dart.dev/guides/language/analysis-options 31 | -------------------------------------------------------------------------------- /example/bin/example.dart: -------------------------------------------------------------------------------- 1 | import 'package:platform/platform.dart'; 2 | 3 | void main(List arguments) { 4 | const LocalPlatform platform = LocalPlatform(); 5 | 6 | print('Operating System: ${platform.operatingSystem}.'); 7 | print('Local Hostname: ${platform.localHostname}.'); 8 | print('Number of Processors: ${platform.numberOfProcessors}.'); 9 | print('Path Separator: ${platform.pathSeparator}.'); 10 | print('Locale Name: ${platform.localeName}.'); 11 | print('Stdin Supports ANSI: ${platform.stdinSupportsAnsi}.'); 12 | print('Stdout Supports ANSI: ${platform.stdoutSupportsAnsi}.'); 13 | print('Executable Arguments: ${platform.executableArguments}.'); 14 | print('Dart Version: ${platform.version}.'); 15 | } 16 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: example 2 | description: Demonstrates how to use the platform api. 3 | version: 1.0.0 4 | publish_to: none 5 | 6 | environment: 7 | sdk: ^3.2.0 8 | 9 | dependencies: 10 | platform: 11 | path: ../ 12 | 13 | dev_dependencies: 14 | lints: ^4.0.0 15 | -------------------------------------------------------------------------------- /lib/platform.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // Core interfaces & classes. 6 | export 'src/interface/local_platform.dart'; 7 | export 'src/interface/platform.dart'; 8 | export 'src/testing/fake_platform.dart'; 9 | -------------------------------------------------------------------------------- /lib/src/interface/local_platform.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'dart:io' as io show Platform, stdin, stdout; 6 | 7 | import 'platform.dart'; 8 | 9 | /// `Platform` implementation that delegates directly to `dart:io`. 10 | class LocalPlatform extends Platform { 11 | /// Creates a new [LocalPlatform]. 12 | const LocalPlatform(); 13 | 14 | @override 15 | int get numberOfProcessors => io.Platform.numberOfProcessors; 16 | 17 | @override 18 | String get pathSeparator => io.Platform.pathSeparator; 19 | 20 | @override 21 | String get operatingSystem => io.Platform.operatingSystem; 22 | 23 | @override 24 | String get operatingSystemVersion => io.Platform.operatingSystemVersion; 25 | 26 | @override 27 | String get localHostname => io.Platform.localHostname; 28 | 29 | @override 30 | Map get environment => io.Platform.environment; 31 | 32 | @override 33 | String get executable => io.Platform.executable; 34 | 35 | @override 36 | String get resolvedExecutable => io.Platform.resolvedExecutable; 37 | 38 | @override 39 | Uri get script => io.Platform.script; 40 | 41 | @override 42 | List get executableArguments => io.Platform.executableArguments; 43 | 44 | @override 45 | String? get packageConfig => io.Platform.packageConfig; 46 | 47 | @override 48 | String get version => io.Platform.version; 49 | 50 | @override 51 | bool get stdinSupportsAnsi => io.stdin.supportsAnsiEscapes; 52 | 53 | @override 54 | bool get stdoutSupportsAnsi => io.stdout.supportsAnsiEscapes; 55 | 56 | @override 57 | String get localeName => io.Platform.localeName; 58 | } 59 | -------------------------------------------------------------------------------- /lib/src/interface/platform.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'dart:convert'; 6 | 7 | /// Provides API parity with the `Platform` class in `dart:io`, but using 8 | /// instance properties rather than static properties. This difference enables 9 | /// the use of these APIs in tests, where you can provide mock implementations. 10 | abstract class Platform { 11 | /// Creates a new [Platform]. 12 | const Platform(); 13 | 14 | /// A string constant to compare with [operatingSystem] to see if the platform 15 | /// is Linux. 16 | /// 17 | /// Useful in case statements when switching on [operatingSystem]. 18 | /// 19 | /// To just check if the platform is Linux, use [isLinux]. 20 | static const String linux = 'linux'; 21 | 22 | /// A string constant to compare with [operatingSystem] to see if the platform 23 | /// is Windows. 24 | /// 25 | /// Useful in case statements when switching on [operatingSystem]. 26 | /// 27 | /// To just check if the platform is Windows, use [isWindows]. 28 | static const String windows = 'windows'; 29 | 30 | /// A string constant to compare with [operatingSystem] to see if the platform 31 | /// is macOS. 32 | /// 33 | /// Useful in case statements when switching on [operatingSystem]. 34 | /// 35 | /// To just check if the platform is macOS, use [isMacOS]. 36 | static const String macOS = 'macos'; 37 | 38 | /// A string constant to compare with [operatingSystem] to see if the platform 39 | /// is Android. 40 | /// 41 | /// Useful in case statements when switching on [operatingSystem]. 42 | /// 43 | /// To just check if the platform is Android, use [isAndroid]. 44 | static const String android = 'android'; 45 | 46 | /// A string constant to compare with [operatingSystem] to see if the platform 47 | /// is iOS. 48 | /// 49 | /// Useful in case statements when switching on [operatingSystem]. 50 | /// 51 | /// To just check if the platform is iOS, use [isIOS]. 52 | static const String iOS = 'ios'; 53 | 54 | /// A string constant to compare with [operatingSystem] to see if the platform 55 | /// is Fuchsia. 56 | /// 57 | /// Useful in case statements when switching on [operatingSystem]. 58 | /// 59 | /// To just check if the platform is Fuchsia, use [isFuchsia]. 60 | static const String fuchsia = 'fuchsia'; 61 | 62 | /// A list of the possible values that [operatingSystem] can return. 63 | static const List operatingSystemValues = [ 64 | linux, 65 | macOS, 66 | windows, 67 | android, 68 | iOS, 69 | fuchsia, 70 | ]; 71 | 72 | /// The number of processors of the machine. 73 | int get numberOfProcessors; 74 | 75 | /// The path separator used by the operating system to separate 76 | /// components in file paths. 77 | String get pathSeparator; 78 | 79 | /// A string (`linux`, `macos`, `windows`, `android`, `ios`, or `fuchsia`) 80 | /// representing the operating system. 81 | /// 82 | /// The possible return values are available from [operatingSystemValues], and 83 | /// there are constants for each of the platforms to use in switch statements 84 | /// or conditionals (See [linux], [macOS], [windows], [android], [iOS], and 85 | /// [fuchsia]). 86 | String get operatingSystem; 87 | 88 | /// A string representing the version of the operating system or platform. 89 | String get operatingSystemVersion; 90 | 91 | /// Get the local hostname for the system. 92 | String get localHostname; 93 | 94 | /// True if the operating system is Linux. 95 | bool get isLinux => operatingSystem == linux; 96 | 97 | /// True if the operating system is OS X. 98 | bool get isMacOS => operatingSystem == macOS; 99 | 100 | /// True if the operating system is Windows. 101 | bool get isWindows => operatingSystem == windows; 102 | 103 | /// True if the operating system is Android. 104 | bool get isAndroid => operatingSystem == android; 105 | 106 | /// True if the operating system is iOS. 107 | bool get isIOS => operatingSystem == iOS; 108 | 109 | /// True if the operating system is Fuchsia 110 | bool get isFuchsia => operatingSystem == fuchsia; 111 | 112 | /// The environment for this process. 113 | /// 114 | /// The returned environment is an unmodifiable map whose content is 115 | /// retrieved from the operating system on its first use. 116 | /// 117 | /// Environment variables on Windows are case-insensitive. The map 118 | /// returned on Windows is therefore case-insensitive and will convert 119 | /// all keys to upper case. On other platforms the returned map is 120 | /// a standard case-sensitive map. 121 | Map get environment; 122 | 123 | /// The path of the executable used to run the script in this isolate. 124 | /// 125 | /// The path returned is the literal path used to run the script. This 126 | /// path might be relative or just be a name from which the executable 127 | /// was found by searching the `PATH`. 128 | /// 129 | /// To get the absolute path to the resolved executable use 130 | /// [resolvedExecutable]. 131 | String get executable; 132 | 133 | /// The path of the executable used to run the script in this 134 | /// isolate after it has been resolved by the OS. 135 | /// 136 | /// This is the absolute path, with all symlinks resolved, to the 137 | /// executable used to run the script. 138 | String get resolvedExecutable; 139 | 140 | /// The absolute URI of the script being run in this 141 | /// isolate. 142 | /// 143 | /// If the script argument on the command line is relative, 144 | /// it is resolved to an absolute URI before fetching the script, and 145 | /// this absolute URI is returned. 146 | /// 147 | /// URI resolution only does string manipulation on the script path, and this 148 | /// may be different from the file system's path resolution behavior. For 149 | /// example, a symbolic link immediately followed by '..' will not be 150 | /// looked up. 151 | /// 152 | /// If the executable environment does not support [script] an empty 153 | /// [Uri] is returned. 154 | Uri get script; 155 | 156 | /// The flags passed to the executable used to run the script in this 157 | /// isolate. These are the command-line flags between the executable name 158 | /// and the script name. Each fetch of `executableArguments` returns a new 159 | /// list containing the flags passed to the executable. 160 | List get executableArguments; 161 | 162 | /// The value of the `--packages` flag passed to the executable 163 | /// used to run the script in this isolate. This is the configuration which 164 | /// specifies how Dart packages are looked up. 165 | /// 166 | /// If there is no `--packages` flag, `null` is returned. 167 | String? get packageConfig; 168 | 169 | /// The version of the current Dart runtime. 170 | /// 171 | /// The returned `String` is formatted as the [semver](http://semver.org) 172 | /// version string of the current dart runtime, possibly followed by 173 | /// whitespace and other version and build details. 174 | String get version; 175 | 176 | /// When stdin is connected to a terminal, whether ANSI codes are supported. 177 | bool get stdinSupportsAnsi; 178 | 179 | /// When stdout is connected to a terminal, whether ANSI codes are supported. 180 | bool get stdoutSupportsAnsi; 181 | 182 | /// Get the name of the current locale. 183 | String get localeName; 184 | 185 | /// Returns a JSON-encoded representation of this platform. 186 | String toJson() { 187 | return const JsonEncoder.withIndent(' ').convert({ 188 | 'numberOfProcessors': numberOfProcessors, 189 | 'pathSeparator': pathSeparator, 190 | 'operatingSystem': operatingSystem, 191 | 'operatingSystemVersion': operatingSystemVersion, 192 | 'localHostname': localHostname, 193 | 'environment': environment, 194 | 'executable': executable, 195 | 'resolvedExecutable': resolvedExecutable, 196 | 'script': script.toString(), 197 | 'executableArguments': executableArguments, 198 | 'packageConfig': packageConfig, 199 | 'version': version, 200 | 'stdinSupportsAnsi': stdinSupportsAnsi, 201 | 'stdoutSupportsAnsi': stdoutSupportsAnsi, 202 | 'localeName': localeName, 203 | }); 204 | } 205 | } 206 | -------------------------------------------------------------------------------- /lib/src/testing/fake_platform.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'dart:convert'; 6 | 7 | import '../interface/platform.dart'; 8 | 9 | /// Provides a mutable implementation of the [Platform] interface. 10 | class FakePlatform extends Platform { 11 | /// Creates a new [FakePlatform] with the specified properties. 12 | /// 13 | /// Unspecified properties will *not* be assigned default values (they will 14 | /// remain `null`). If an unset non-null value is read, a [StateError] will 15 | /// be thrown instead of returning `null`. 16 | FakePlatform({ 17 | int? numberOfProcessors, 18 | String? pathSeparator, 19 | String? operatingSystem, 20 | String? operatingSystemVersion, 21 | String? localHostname, 22 | Map? environment, 23 | String? executable, 24 | String? resolvedExecutable, 25 | Uri? script, 26 | List? executableArguments, 27 | this.packageConfig, 28 | String? version, 29 | bool? stdinSupportsAnsi, 30 | bool? stdoutSupportsAnsi, 31 | String? localeName, 32 | }) : _numberOfProcessors = numberOfProcessors, 33 | _pathSeparator = pathSeparator, 34 | _operatingSystem = operatingSystem, 35 | _operatingSystemVersion = operatingSystemVersion, 36 | _localHostname = localHostname, 37 | _environment = environment, 38 | _executable = executable, 39 | _resolvedExecutable = resolvedExecutable, 40 | _script = script, 41 | _executableArguments = executableArguments, 42 | _version = version, 43 | _stdinSupportsAnsi = stdinSupportsAnsi, 44 | _stdoutSupportsAnsi = stdoutSupportsAnsi, 45 | _localeName = localeName; 46 | 47 | /// Creates a new [FakePlatform] with properties whose initial values mirror 48 | /// the specified [platform]. 49 | FakePlatform.fromPlatform(Platform platform) 50 | : _numberOfProcessors = platform.numberOfProcessors, 51 | _pathSeparator = platform.pathSeparator, 52 | _operatingSystem = platform.operatingSystem, 53 | _operatingSystemVersion = platform.operatingSystemVersion, 54 | _localHostname = platform.localHostname, 55 | _environment = Map.from(platform.environment), 56 | _executable = platform.executable, 57 | _resolvedExecutable = platform.resolvedExecutable, 58 | _script = platform.script, 59 | _executableArguments = List.from(platform.executableArguments), 60 | packageConfig = platform.packageConfig, 61 | _version = platform.version, 62 | _stdinSupportsAnsi = platform.stdinSupportsAnsi, 63 | _stdoutSupportsAnsi = platform.stdoutSupportsAnsi, 64 | _localeName = platform.localeName; 65 | 66 | /// Creates a new [FakePlatform] with properties extracted from the encoded 67 | /// JSON string. 68 | /// 69 | /// [json] must be a JSON string that matches the encoding produced by 70 | /// [toJson]. 71 | factory FakePlatform.fromJson(String json) { 72 | final map = const JsonDecoder().convert(json) as Map; 73 | return FakePlatform( 74 | numberOfProcessors: map['numberOfProcessors'] as int?, 75 | pathSeparator: map['pathSeparator'] as String?, 76 | operatingSystem: map['operatingSystem'] as String?, 77 | operatingSystemVersion: map['operatingSystemVersion'] as String?, 78 | localHostname: map['localHostname'] as String?, 79 | environment: 80 | (map['environment'] as Map).cast(), 81 | executable: map['executable'] as String?, 82 | resolvedExecutable: map['resolvedExecutable'] as String?, 83 | script: Uri.parse(map['script'] as String), 84 | executableArguments: 85 | (map['executableArguments'] as List).cast(), 86 | packageConfig: map['packageConfig'] as String?, 87 | version: map['version'] as String?, 88 | stdinSupportsAnsi: map['stdinSupportsAnsi'] as bool?, 89 | stdoutSupportsAnsi: map['stdoutSupportsAnsi'] as bool?, 90 | localeName: map['localeName'] as String?, 91 | ); 92 | } 93 | 94 | /// Creates a new [FakePlatform] from this one, with some properties replaced 95 | /// by the given properties. 96 | FakePlatform copyWith({ 97 | int? numberOfProcessors, 98 | String? pathSeparator, 99 | String? operatingSystem, 100 | String? operatingSystemVersion, 101 | String? localHostname, 102 | Map? environment, 103 | String? executable, 104 | String? resolvedExecutable, 105 | Uri? script, 106 | List? executableArguments, 107 | String? packageConfig, 108 | String? version, 109 | bool? stdinSupportsAnsi, 110 | bool? stdoutSupportsAnsi, 111 | String? localeName, 112 | }) { 113 | return FakePlatform( 114 | numberOfProcessors: numberOfProcessors ?? this.numberOfProcessors, 115 | pathSeparator: pathSeparator ?? this.pathSeparator, 116 | operatingSystem: operatingSystem ?? this.operatingSystem, 117 | operatingSystemVersion: 118 | operatingSystemVersion ?? this.operatingSystemVersion, 119 | localHostname: localHostname ?? this.localHostname, 120 | environment: environment ?? this.environment, 121 | executable: executable ?? this.executable, 122 | resolvedExecutable: resolvedExecutable ?? this.resolvedExecutable, 123 | script: script ?? this.script, 124 | executableArguments: executableArguments ?? this.executableArguments, 125 | packageConfig: packageConfig ?? this.packageConfig, 126 | version: version ?? this.version, 127 | stdinSupportsAnsi: stdinSupportsAnsi ?? this.stdinSupportsAnsi, 128 | stdoutSupportsAnsi: stdoutSupportsAnsi ?? this.stdoutSupportsAnsi, 129 | localeName: localeName ?? this.localeName, 130 | ); 131 | } 132 | 133 | @override 134 | int get numberOfProcessors => _throwIfNull(_numberOfProcessors); 135 | int? _numberOfProcessors; 136 | 137 | @override 138 | String get pathSeparator => _throwIfNull(_pathSeparator); 139 | String? _pathSeparator; 140 | 141 | @override 142 | String get operatingSystem => _throwIfNull(_operatingSystem); 143 | String? _operatingSystem; 144 | 145 | @override 146 | String get operatingSystemVersion => _throwIfNull(_operatingSystemVersion); 147 | String? _operatingSystemVersion; 148 | 149 | @override 150 | String get localHostname => _throwIfNull(_localHostname); 151 | String? _localHostname; 152 | 153 | @override 154 | Map get environment => _throwIfNull(_environment); 155 | Map? _environment; 156 | 157 | @override 158 | String get executable => _throwIfNull(_executable); 159 | String? _executable; 160 | 161 | @override 162 | String get resolvedExecutable => _throwIfNull(_resolvedExecutable); 163 | String? _resolvedExecutable; 164 | 165 | @override 166 | Uri get script => _throwIfNull(_script); 167 | Uri? _script; 168 | 169 | @override 170 | List get executableArguments => _throwIfNull(_executableArguments); 171 | List? _executableArguments; 172 | 173 | @override 174 | String? packageConfig; 175 | 176 | @override 177 | String get version => _throwIfNull(_version); 178 | String? _version; 179 | 180 | @override 181 | bool get stdinSupportsAnsi => _throwIfNull(_stdinSupportsAnsi); 182 | bool? _stdinSupportsAnsi; 183 | 184 | @override 185 | bool get stdoutSupportsAnsi => _throwIfNull(_stdoutSupportsAnsi); 186 | bool? _stdoutSupportsAnsi; 187 | 188 | @override 189 | String get localeName => _throwIfNull(_localeName); 190 | String? _localeName; 191 | 192 | T _throwIfNull(T? value) { 193 | if (value == null) { 194 | throw StateError( 195 | 'Tried to read property of FakePlatform but it was unset.'); 196 | } 197 | return value; 198 | } 199 | } 200 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: platform 2 | description: A pluggable, mockable platform information abstraction for Dart. 3 | repository: https://github.com/dart-lang/platform 4 | issue_tracker: https://github.com/dart-lang/platform/issues 5 | version: 3.1.5 6 | 7 | environment: 8 | sdk: ^3.2.0 9 | 10 | dev_dependencies: 11 | dart_flutter_team_lints: ^3.1.0 12 | test: ^1.16.8 13 | 14 | topics: 15 | - information 16 | - platform 17 | -------------------------------------------------------------------------------- /test/fake_platform_test.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'dart:io' as io; 6 | 7 | import 'package:platform/platform.dart'; 8 | import 'package:test/test.dart'; 9 | 10 | void _expectPlatformsEqual(Platform actual, Platform expected) { 11 | expect(actual.numberOfProcessors, expected.numberOfProcessors); 12 | expect(actual.pathSeparator, expected.pathSeparator); 13 | expect(actual.operatingSystem, expected.operatingSystem); 14 | expect(actual.operatingSystemVersion, expected.operatingSystemVersion); 15 | expect(actual.localHostname, expected.localHostname); 16 | expect(actual.environment, expected.environment); 17 | expect(actual.executable, expected.executable); 18 | expect(actual.resolvedExecutable, expected.resolvedExecutable); 19 | expect(actual.script, expected.script); 20 | expect(actual.executableArguments, expected.executableArguments); 21 | expect(actual.packageConfig, expected.packageConfig); 22 | expect(actual.version, expected.version); 23 | expect(actual.localeName, expected.localeName); 24 | } 25 | 26 | void main() { 27 | group('FakePlatform', () { 28 | late FakePlatform fake; 29 | late LocalPlatform local; 30 | 31 | setUp(() { 32 | fake = FakePlatform(); 33 | local = const LocalPlatform(); 34 | }); 35 | 36 | group('fromPlatform', () { 37 | setUp(() { 38 | fake = FakePlatform.fromPlatform(local); 39 | }); 40 | 41 | test('copiesAllProperties', () { 42 | _expectPlatformsEqual(fake, local); 43 | }); 44 | 45 | test('convertsPropertiesToMutable', () { 46 | final key = fake.environment.keys.first; 47 | 48 | expect(fake.environment[key], local.environment[key]); 49 | fake.environment[key] = 'FAKE'; 50 | expect(fake.environment[key], 'FAKE'); 51 | 52 | expect( 53 | fake.executableArguments.length, local.executableArguments.length); 54 | fake.executableArguments.add('ARG'); 55 | expect(fake.executableArguments.last, 'ARG'); 56 | }); 57 | }); 58 | 59 | group('copyWith', () { 60 | setUp(() { 61 | fake = FakePlatform.fromPlatform(local); 62 | }); 63 | 64 | test('overrides a value, but leaves others intact', () { 65 | final copy = fake.copyWith( 66 | numberOfProcessors: -1, 67 | ); 68 | expect(copy.numberOfProcessors, equals(-1)); 69 | expect(copy.pathSeparator, local.pathSeparator); 70 | expect(copy.operatingSystem, local.operatingSystem); 71 | expect(copy.operatingSystemVersion, local.operatingSystemVersion); 72 | expect(copy.localHostname, local.localHostname); 73 | expect(copy.environment, local.environment); 74 | expect(copy.executable, local.executable); 75 | expect(copy.resolvedExecutable, local.resolvedExecutable); 76 | expect(copy.script, local.script); 77 | expect(copy.executableArguments, local.executableArguments); 78 | expect(copy.packageConfig, local.packageConfig); 79 | expect(copy.version, local.version); 80 | expect(copy.localeName, local.localeName); 81 | }); 82 | test('can override all values', () { 83 | fake = FakePlatform( 84 | numberOfProcessors: 8, 85 | pathSeparator: ':', 86 | operatingSystem: 'fake', 87 | operatingSystemVersion: '0.1.0', 88 | localHostname: 'host', 89 | environment: {'PATH': '.'}, 90 | executable: 'executable', 91 | resolvedExecutable: '/executable', 92 | script: Uri.file('/platform/test/fake_platform_test.dart'), 93 | executableArguments: ['scriptarg'], 94 | version: '0.1.1', 95 | stdinSupportsAnsi: false, 96 | stdoutSupportsAnsi: true, 97 | localeName: 'local', 98 | ); 99 | final copy = fake.copyWith( 100 | numberOfProcessors: local.numberOfProcessors, 101 | pathSeparator: local.pathSeparator, 102 | operatingSystem: local.operatingSystem, 103 | operatingSystemVersion: local.operatingSystemVersion, 104 | localHostname: local.localHostname, 105 | environment: local.environment, 106 | executable: local.executable, 107 | resolvedExecutable: local.resolvedExecutable, 108 | script: local.script, 109 | executableArguments: local.executableArguments, 110 | packageConfig: local.packageConfig, 111 | version: local.version, 112 | stdinSupportsAnsi: local.stdinSupportsAnsi, 113 | stdoutSupportsAnsi: local.stdoutSupportsAnsi, 114 | localeName: local.localeName, 115 | ); 116 | _expectPlatformsEqual(copy, local); 117 | }); 118 | }); 119 | 120 | group('json', () { 121 | test('fromJson', () { 122 | final json = io.File('test/platform.json').readAsStringSync(); 123 | fake = FakePlatform.fromJson(json); 124 | expect(fake.numberOfProcessors, 8); 125 | expect(fake.pathSeparator, '/'); 126 | expect(fake.operatingSystem, 'macos'); 127 | expect(fake.operatingSystemVersion, '10.14.5'); 128 | expect(fake.localHostname, 'platform.test.org'); 129 | expect(fake.environment, { 130 | 'PATH': '/bin', 131 | 'PWD': '/platform', 132 | }); 133 | expect(fake.executable, '/bin/dart'); 134 | expect(fake.resolvedExecutable, '/bin/dart'); 135 | expect(fake.script, Uri.file('/platform/test/fake_platform_test.dart')); 136 | expect(fake.executableArguments, ['--checked']); 137 | expect(fake.packageConfig, null); 138 | expect(fake.version, '1.22.0'); 139 | expect(fake.localeName, 'de/de'); 140 | }); 141 | 142 | test('fromJsonToJson', () { 143 | fake = FakePlatform.fromJson(local.toJson()); 144 | _expectPlatformsEqual(fake, local); 145 | }); 146 | }); 147 | }); 148 | 149 | test('Throws when unset non-null values are read', () { 150 | final platform = FakePlatform(); 151 | 152 | expect(() => platform.numberOfProcessors, throwsA(isStateError)); 153 | expect(() => platform.pathSeparator, throwsA(isStateError)); 154 | expect(() => platform.operatingSystem, throwsA(isStateError)); 155 | expect(() => platform.operatingSystemVersion, throwsA(isStateError)); 156 | expect(() => platform.localHostname, throwsA(isStateError)); 157 | expect(() => platform.environment, throwsA(isStateError)); 158 | expect(() => platform.executable, throwsA(isStateError)); 159 | expect(() => platform.resolvedExecutable, throwsA(isStateError)); 160 | expect(() => platform.script, throwsA(isStateError)); 161 | expect(() => platform.executableArguments, throwsA(isStateError)); 162 | expect(() => platform.version, throwsA(isStateError)); 163 | expect(() => platform.localeName, throwsA(isStateError)); 164 | }); 165 | } 166 | -------------------------------------------------------------------------------- /test/platform.json: -------------------------------------------------------------------------------- 1 | { 2 | "numberOfProcessors": 8, 3 | "pathSeparator": "/", 4 | "operatingSystem": "macos", 5 | "operatingSystemVersion": "10.14.5", 6 | "localHostname": "platform.test.org", 7 | "environment": { 8 | "PATH": "/bin", 9 | "PWD": "/platform" 10 | }, 11 | "executable": "/bin/dart", 12 | "resolvedExecutable": "/bin/dart", 13 | "script": "file:///platform/test/fake_platform_test.dart", 14 | "executableArguments": [ 15 | "--checked" 16 | ], 17 | "packageConfig": null, 18 | "version": "1.22.0", 19 | "localeName": "de/de" 20 | } --------------------------------------------------------------------------------