Skip to content

refactor: cleanup platform mocking #2730

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 23 commits into from
Mar 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

- Move replay and privacy from experimental to options ([#2755](https://github.com/getsentry/sentry-dart/pull/2755))
- Remove renderer from `flutter_context` ([#2751](https://github.com/getsentry/sentry-dart/pull/2751))
- Cleanup platform mocking ([#2730](https://github.com/getsentry/sentry-dart/pull/2730))
- The `PlatformChecker` was renamed to `RuntimeChecker`
- Moved `PlatformChecker.platform` to `options.platform`

## 9.0.0-alpha.1

Expand All @@ -28,8 +31,7 @@
- Responses are attached to the `Hint` object, which can be read in `beforeSend`/`beforeSendTransaction` callbacks via `hint.response`.
- For now, only the `dio` integration is supported.
- Enable privacy masking for screenshots by default ([#2728](https://github.com/getsentry/sentry-dart/pull/2728))



### Enhancements

- Replay: improve Android native interop performance by using JNI ([#2670](https://github.com/getsentry/sentry-dart/pull/2670))
Expand Down
2 changes: 1 addition & 1 deletion dart/lib/sentry.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export 'src/integration.dart';
export 'src/noop_isolate_error_integration.dart'
if (dart.library.io) 'src/isolate_error_integration.dart';
export 'src/performance_collector.dart';
export 'src/platform_checker.dart';
export 'src/runtime_checker.dart';
export 'src/protocol.dart';
export 'src/protocol/sentry_feedback.dart';
export 'src/protocol/sentry_proxy.dart';
Expand Down
4 changes: 2 additions & 2 deletions dart/lib/src/environment/environment_variables.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import '../platform_checker.dart';
import '../runtime_checker.dart';
import '_io_environment_variables.dart'
if (dart.library.js_interop) '_web_environment_variables.dart' as env;

Expand Down Expand Up @@ -28,7 +28,7 @@ abstract class EnvironmentVariables {

/// Returns an environment based on the compilation mode of Dart or Flutter.
/// This can be set as [SentryOptions.environment]
String environmentForMode(PlatformChecker checker) {
String environmentForMode(RuntimeChecker checker) {
// We infer the environment based on the release/non-release and profile
// constants.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ class IoEnricherEventProcessor implements EnricherEventProcessor {
}

return <String, dynamic>{
'compile_mode': _options.platformChecker.compileMode,
'compile_mode': _options.runtimeChecker.compileMode,
if (packageConfig != null) 'package_config': packageConfig,
// The following information could potentially contain PII
if (_options.sendDefaultPii) ...{
Expand Down
8 changes: 4 additions & 4 deletions dart/lib/src/event_processor/enricher/io_platform_memory.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,19 @@ class PlatformMemory {
final SentryOptions options;

int? getTotalPhysicalMemory() {
if (options.platformChecker.platform.isLinux) {
if (options.platform.isLinux) {
return _getLinuxMemInfoValue('MemTotal');
} else if (options.platformChecker.platform.isWindows) {
} else if (options.platform.isWindows) {
return _getWindowsWmicValue('ComputerSystem', 'TotalPhysicalMemory');
} else {
return null;
}
}

int? getFreePhysicalMemory() {
if (options.platformChecker.platform.isLinux) {
if (options.platform.isLinux) {
return _getLinuxMemInfoValue('MemFree');
} else if (options.platformChecker.platform.isWindows) {
} else if (options.platform.isWindows) {
return _getWindowsWmicValue('OS', 'FreePhysicalMemory');
} else {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class WebEnricherEventProcessor implements EnricherEventProcessor {

Map<String, dynamic> _getDartContext() {
return <String, dynamic>{
'compile_mode': _options.platformChecker.compileMode,
'compile_mode': _options.runtimeChecker.compileMode,
};
}

Expand Down
16 changes: 12 additions & 4 deletions dart/lib/src/load_dart_debug_images_integration.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
import 'dart:typed_data';

import 'package:meta/meta.dart';

import '../sentry.dart';
import 'event_processor.dart';
import 'hint.dart';
import 'hub.dart';
import 'integration.dart';
import 'protocol/debug_image.dart';
import 'protocol/debug_meta.dart';
import 'protocol/sentry_event.dart';
import 'protocol/sentry_level.dart';
import 'protocol/sentry_stack_trace.dart';
import 'sentry_options.dart';

class LoadDartDebugImagesIntegration extends Integration<SentryOptions> {
@override
Expand Down Expand Up @@ -83,11 +91,11 @@ class LoadImageIntegrationEventProcessor implements EventProcessor {
// It doesn't need to exist and is not used for symbolication.
late final String codeFile;

final platform = _options.platformChecker.platform;
final platform = _options.platform;

if (platform.isAndroid || platform.isWindows) {
type = 'elf';
debugId = _convertBuildIdToDebugId(stackTrace.buildId!, platform.endian);
debugId = _convertBuildIdToDebugId(stackTrace.buildId!, Endian.host);
if (platform.isAndroid) {
codeFile = 'libapp.so';
} else if (platform.isWindows) {
Expand Down
35 changes: 24 additions & 11 deletions dart/lib/src/platform/_io_platform.dart
Original file line number Diff line number Diff line change
@@ -1,20 +1,33 @@
import 'dart:io' as io show Platform;
import 'dart:io' as io;

import 'platform.dart';

const Platform instance = IOPlatform();

/// [Platform] implementation that delegates directly to `dart:io`.
class IOPlatform extends Platform {
/// Creates a new [IOPlatform].
const IOPlatform();
class PlatformBase {
const PlatformBase();

@override
String get operatingSystem => io.Platform.operatingSystem;
OperatingSystem get operatingSystem {
switch (io.Platform.operatingSystem) {
case 'macos':
return OperatingSystem.macos;
case 'windows':
return OperatingSystem.windows;
case 'linux':
return OperatingSystem.linux;
case 'android':

Check warning on line 17 in dart/lib/src/platform/_io_platform.dart

View check run for this annotation

Codecov / codecov/patch

dart/lib/src/platform/_io_platform.dart#L17

Added line #L17 was not covered by tests
return OperatingSystem.android;
case 'ios':

Check warning on line 19 in dart/lib/src/platform/_io_platform.dart

View check run for this annotation

Codecov / codecov/patch

dart/lib/src/platform/_io_platform.dart#L19

Added line #L19 was not covered by tests
return OperatingSystem.ios;
case 'fuchsia':

Check warning on line 21 in dart/lib/src/platform/_io_platform.dart

View check run for this annotation

Codecov / codecov/patch

dart/lib/src/platform/_io_platform.dart#L21

Added line #L21 was not covered by tests
return OperatingSystem.fuchsia;
default:
return OperatingSystem.unknown;
}
}

@override
String get operatingSystemVersion => io.Platform.operatingSystemVersion;
String? get operatingSystemVersion => io.Platform.operatingSystemVersion;

@override
String get localHostname => io.Platform.localHostname;

bool get isWeb => false;
}
36 changes: 15 additions & 21 deletions dart/lib/src/platform/_web_platform.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,30 @@ import 'package:web/web.dart' as web;

import 'platform.dart';

const Platform instance = WebPlatform();

/// [Platform] implementation that delegates to `dart:web`.
class WebPlatform extends Platform {
/// Creates a new [Platform].
const WebPlatform();

@override
String get operatingSystem => _browserPlatform();
class PlatformBase {
const PlatformBase();

@override
String get operatingSystemVersion => 'unknown';

@override
String get localHostname => web.window.location.hostname;
bool get isWeb => true;

String _browserPlatform() {
OperatingSystem get operatingSystem {
final navigatorPlatform = web.window.navigator.platform.toLowerCase();
if (navigatorPlatform.startsWith('mac')) {
return 'macos';
return OperatingSystem.macos;
}
if (navigatorPlatform.startsWith('win')) {
return 'windows';
return OperatingSystem.windows;
}
if (navigatorPlatform.contains('iphone') ||
navigatorPlatform.contains('ipad') ||
navigatorPlatform.contains('ipod')) {
return 'ios';
return OperatingSystem.ios;
}
if (navigatorPlatform.contains('android')) {
return 'android';
return OperatingSystem.android;
}
if (navigatorPlatform.contains('fuchsia')) {
return 'fuchsia';
return OperatingSystem.fuchsia;
}

// Since some phones can report a window.navigator.platform as Linux, fall
Expand All @@ -44,8 +34,12 @@ class WebPlatform extends Platform {
// pointing device, then we'll assume desktop linux, and otherwise we'll
// assume Android.
if (web.window.matchMedia('only screen and (pointer: fine)').matches) {
return 'linux';
return OperatingSystem.linux;
}
return 'android';
return OperatingSystem.android;
}

String? get operatingSystemVersion => null;

String get localHostname => web.window.location.hostname;
}
52 changes: 52 additions & 0 deletions dart/lib/src/platform/mock_platform.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import 'platform.dart';

class MockPlatform extends Platform {
@override
late final bool isWeb;

@override
late final OperatingSystem operatingSystem;

@override
late final String? operatingSystemVersion;

@override
late final bool supportsNativeIntegration;

MockPlatform(
{OperatingSystem? operatingSystem,
String? operatingSystemVersion,
bool? isWeb,
bool? supportsNativeIntegration}) {
this.isWeb = isWeb ?? super.isWeb;
this.operatingSystem = operatingSystem ?? super.operatingSystem;
this.operatingSystemVersion =
operatingSystemVersion ?? super.operatingSystemVersion;
this.supportsNativeIntegration =
supportsNativeIntegration ?? super.supportsNativeIntegration;
}

factory MockPlatform.android({bool isWeb = false}) {
return MockPlatform(operatingSystem: OperatingSystem.android, isWeb: isWeb);
}

factory MockPlatform.iOS({bool isWeb = false}) {
return MockPlatform(operatingSystem: OperatingSystem.ios, isWeb: isWeb);
}

factory MockPlatform.macOS({bool isWeb = false}) {
return MockPlatform(operatingSystem: OperatingSystem.macos, isWeb: isWeb);
}

factory MockPlatform.linux({bool isWeb = false}) {
return MockPlatform(operatingSystem: OperatingSystem.linux, isWeb: isWeb);
}

factory MockPlatform.windows({bool isWeb = false}) {
return MockPlatform(operatingSystem: OperatingSystem.windows, isWeb: isWeb);
}

factory MockPlatform.fuchsia({bool isWeb = false}) {
return MockPlatform(operatingSystem: OperatingSystem.fuchsia, isWeb: isWeb);
}
}
47 changes: 18 additions & 29 deletions dart/lib/src/platform/platform.dart
Original file line number Diff line number Diff line change
@@ -1,41 +1,30 @@
import 'dart:typed_data';

import '_io_platform.dart' if (dart.library.js_interop) '_web_platform.dart'
as platform;

const Platform instance = platform.instance;
as impl;

abstract class Platform {
class Platform extends impl.PlatformBase {
const Platform();

/// A string (`linux`, `macos`, `windows`, `android`, `ios`, or `fuchsia`)
/// representing the operating system.
String get operatingSystem;

/// A string representing the version of the operating system or platform.
String get operatingSystemVersion;
bool get isLinux => operatingSystem == OperatingSystem.linux;

/// Get the local hostname for the system.
String get localHostname;
bool get isMacOS => operatingSystem == OperatingSystem.macos;

/// Endianness of this platform.
Endian get endian => Endian.host;
bool get isWindows => operatingSystem == OperatingSystem.windows;

/// True if the operating system is Linux.
bool get isLinux => (operatingSystem == 'linux');
bool get isAndroid => operatingSystem == OperatingSystem.android;

/// True if the operating system is OS X.
bool get isMacOS => (operatingSystem == 'macos');
bool get isIOS => operatingSystem == OperatingSystem.ios;

/// True if the operating system is Windows.
bool get isWindows => (operatingSystem == 'windows');
bool get isFuchsia => operatingSystem == OperatingSystem.fuchsia;

/// True if the operating system is Android.
bool get isAndroid => (operatingSystem == 'android');

/// True if the operating system is iOS.
bool get isIOS => (operatingSystem == 'ios');
bool get supportsNativeIntegration => !isFuchsia;
}

/// True if the operating system is Fuchsia
bool get isFuchsia => (operatingSystem == 'fuchsia');
enum OperatingSystem {
android,
fuchsia,
ios,
linux,
macos,
windows,
unknown,
}
1 change: 1 addition & 0 deletions dart/lib/src/protocol/sdk_version.dart
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ class SdkVersion {
final json = AccessAwareMap(data);
final packagesJson = json['packages'] as List<dynamic>?;
final integrationsJson = json['integrations'] as List<dynamic>?;

return SdkVersion(
name: json['name'],
version: json['version'],
Expand Down
Loading
Loading