diff --git a/CHANGELOG.md b/CHANGELOG.md index 1271dd85f..d488ea94e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ ### Behavioural Changes and Deprecations - The `EnableMetrics` option is now marked as `[Obsolete]` and no longer has any effect, following the .NET SDK where metrics are always enabled. Disable the individual `Auto*Metrics` options instead, or filter emitted metrics with `SetBeforeSendMetric`. ([#2828](https://github.com/getsentry/sentry-unity/pull/2828)) +- The runtime assembly is now compiled for any platform except CloudRendering, EmbeddedLinux, PS4, tvOS and Xbox One, instead of an explicit allowlist. Platforms without a dedicated integration, like visionOS and the dedicated server targets now run the SDK in managed-only mode. ([#2834](https://github.com/getsentry/sentry-unity/pull/2834)) + +### Features + +- Added Nintendo Switch 2 support. The SDK now correctly recognises the platform, providing native support and automatic debug symbol upload. Switch 2 shares the existing `SwitchNativeSupportEnabled` option. ([#2834](https://github.com/getsentry/sentry-unity/pull/2834)) ### Fixes diff --git a/package-dev/Plugins/Switch/sentry_native_stubs.c.meta b/package-dev/Plugins/Switch/sentry_native_stubs.c.meta index 33f21e6e4..c72bd14c2 100644 --- a/package-dev/Plugins/Switch/sentry_native_stubs.c.meta +++ b/package-dev/Plugins/Switch/sentry_native_stubs.c.meta @@ -25,6 +25,7 @@ PluginImporter: Exclude Linux64: 1 Exclude OSXUniversal: 1 Exclude Switch: 0 + Exclude Switch2: 0 Exclude WebGL: 1 Exclude Win: 1 Exclude Win64: 1 @@ -46,6 +47,9 @@ PluginImporter: Switch: enabled: 1 settings: {} + Switch2: + enabled: 1 + settings: {} Win: enabled: 0 settings: diff --git a/package-dev/Runtime/Sentry.Unity.Native.Switch.dll.meta b/package-dev/Runtime/Sentry.Unity.Native.Switch.dll.meta index 25c262827..927a6240c 100644 --- a/package-dev/Runtime/Sentry.Unity.Native.Switch.dll.meta +++ b/package-dev/Runtime/Sentry.Unity.Native.Switch.dll.meta @@ -26,6 +26,7 @@ PluginImporter: Exclude OSXUniversal: 1 Exclude PS5: 1 Exclude Switch: 0 + Exclude Switch2: 0 Exclude WebGL: 1 Exclude Win: 1 Exclude Win64: 1 @@ -50,6 +51,9 @@ PluginImporter: Switch: enabled: 1 settings: {} + Switch2: + enabled: 1 + settings: {} Win: enabled: 0 settings: diff --git a/package-dev/Runtime/SentryInitialization.cs b/package-dev/Runtime/SentryInitialization.cs index ddb20b6a0..0e927bb4e 100644 --- a/package-dev/Runtime/SentryInitialization.cs +++ b/package-dev/Runtime/SentryInitialization.cs @@ -16,7 +16,7 @@ #define SENTRY_NATIVE #endif -#if UNITY_SWITCH +#if UNITY_SWITCH || UNITY_SWITCH2 #define SENTRY_NATIVE_SWITCH #endif diff --git a/package-dev/Runtime/io.sentry.unity.dev.runtime.asmdef b/package-dev/Runtime/io.sentry.unity.dev.runtime.asmdef index 357a78477..4e0605f2a 100644 --- a/package-dev/Runtime/io.sentry.unity.dev.runtime.asmdef +++ b/package-dev/Runtime/io.sentry.unity.dev.runtime.asmdef @@ -2,22 +2,14 @@ "name": "io.sentry.unity.dev.runtime", "rootNamespace": "", "references": [], - "includePlatforms": [ - "Android", - "Editor", - "iOS", - "LinuxStandalone64", - "macOSStandalone", - "Switch", - "PS5", - "WSA", - "WebGL", - "WindowsStandalone32", - "WindowsStandalone64", - "GameCoreXboxOne", - "GameCoreScarlett" + "includePlatforms": [], + "excludePlatforms": [ + "CloudRendering", + "EmbeddedLinux", + "PS4", + "XboxOne", + "tvOS" ], - "excludePlatforms": [], "allowUnsafeCode": false, "overrideReferences": false, "precompiledReferences": [], diff --git a/package/Runtime/io.sentry.unity.runtime.asmdef b/package/Runtime/io.sentry.unity.runtime.asmdef index e9e1c7df5..11acba8da 100644 --- a/package/Runtime/io.sentry.unity.runtime.asmdef +++ b/package/Runtime/io.sentry.unity.runtime.asmdef @@ -2,22 +2,14 @@ "name": "io.sentry.unity.runtime", "rootNamespace": "", "references": [], - "includePlatforms": [ - "Android", - "Editor", - "GameCoreScarlett", - "GameCoreXboxOne", - "iOS", - "LinuxStandalone64", - "macOSStandalone", - "PS5", - "Switch", - "WSA", - "WebGL", - "WindowsStandalone32", - "WindowsStandalone64" + "includePlatforms": [], + "excludePlatforms": [ + "CloudRendering", + "EmbeddedLinux", + "PS4", + "XboxOne", + "tvOS" ], - "excludePlatforms": [], "allowUnsafeCode": false, "overrideReferences": false, "precompiledReferences": [], diff --git a/src/Sentry.Unity.Editor/ConfigurationWindow/AdvancedTab.cs b/src/Sentry.Unity.Editor/ConfigurationWindow/AdvancedTab.cs index 1d3225929..1d2940afb 100644 --- a/src/Sentry.Unity.Editor/ConfigurationWindow/AdvancedTab.cs +++ b/src/Sentry.Unity.Editor/ConfigurationWindow/AdvancedTab.cs @@ -176,7 +176,7 @@ internal static void Display(ScriptableSentryUnityOptions options, SentryCliOpti options.PlayStationNativeSupportEnabled); options.SwitchNativeSupportEnabled = EditorGUILayout.Toggle( - new GUIContent("Nintendo Switch", "Whether to enable native scope sync support on Nintendo Switch."), + new GUIContent("Nintendo Switch", "Whether to enable native scope sync support on Nintendo Switch and Switch 2."), options.SwitchNativeSupportEnabled); } diff --git a/src/Sentry.Unity.Editor/Native/BuildPostProcess.cs b/src/Sentry.Unity.Editor/Native/BuildPostProcess.cs index 371e8f4ea..3a3629fe2 100644 --- a/src/Sentry.Unity.Editor/Native/BuildPostProcess.cs +++ b/src/Sentry.Unity.Editor/Native/BuildPostProcess.cs @@ -19,10 +19,12 @@ public static class BuildPostProcess public static void OnPostProcessBuild(BuildTarget target, string executablePath) { var targetGroup = BuildPipeline.GetBuildTargetGroup(target); - if (targetGroup is not BuildTargetGroup.Standalone - and not BuildTargetGroup.GameCoreXboxSeries - and not BuildTargetGroup.PS5 - and not BuildTargetGroup.Switch) + var isSupportedGroup = targetGroup is BuildTargetGroup.Standalone + or BuildTargetGroup.GameCoreXboxSeries + or BuildTargetGroup.PS5 + or BuildTargetGroup.Switch + || targetGroup.IsSwitch2(); + if (!isSupportedGroup) { return; } @@ -58,6 +60,7 @@ and not BuildTargetGroup.PS5 BuildTargetGroup.GameCoreXboxSeries => executablePath, BuildTargetGroup.PS5 => executablePath, BuildTargetGroup.Switch => Path.GetDirectoryName(executablePath), + _ when targetGroup.IsSwitch2() => Path.GetDirectoryName(executablePath), _ => string.Empty }; @@ -131,6 +134,8 @@ and not BuildTargetGroup.PS5 BuildTarget.GameCoreXboxSeries or BuildTarget.GameCoreXboxOne => options.XboxNativeSupportEnabled, BuildTarget.PS5 => options.PlayStationNativeSupportEnabled, BuildTarget.Switch => options.SwitchNativeSupportEnabled, + // Switch 2 reuses the Switch native support. + _ when target.IsSwitch2() => options.SwitchNativeSupportEnabled, _ => false, }; @@ -238,6 +243,11 @@ private static IEnumerable GetNativePluginArtifact( // No standalone crash handler for Switch - uses Nintendo's crash reporter break; default: + if (target.IsSwitch2()) + { + // No standalone crash handler for Switch - uses Nintendo's crash reporter + break; + } throw new ArgumentException($"Unsupported build target: {target}"); } } @@ -526,31 +536,43 @@ private static void UploadDebugSymbols(IDiagnosticLogger logger, BuildTarget tar break; case BuildTarget.Switch: - // IL2CPP output, Managed DLLs/PDBs, and Symbols - foreach (var dir in Directory.GetDirectories(buildOutputDir, "*_BackUpThisFolder_*")) - { - AddPath(paths, dir, logger); - } + AddSwitchPaths(); + break; - // Burst - foreach (var dir in Directory.GetDirectories(buildOutputDir, "*_BurstDebugInformation_*")) + default: + if (target.IsSwitch2()) { - AddPath(paths, dir, logger); + AddSwitchPaths(); + break; } - // When exporting as an NSP the assemblies are bundled inside the package. So we're also checking the build cache. - var beePath = Path.Combine(projectDir, "Library", "Bee", "artifacts", "SwitchPlayerBuildProgram"); - AddPath(paths, beePath, logger); - - // User-provided Sentry plugin - AddPath(paths, Path.GetFullPath("Assets/Plugins/Sentry/"), logger); - break; - - default: logger.LogError("Symbol upload for '{0}' is currently not supported.", target); return; } + void AddSwitchPaths() + { + // IL2CPP output, Managed DLLs/PDBs, and Symbols + foreach (var dir in Directory.GetDirectories(buildOutputDir, "*_BackUpThisFolder_*")) + { + AddPath(paths, dir, logger); + } + + // Burst + foreach (var dir in Directory.GetDirectories(buildOutputDir, "*_BurstDebugInformation_*")) + { + AddPath(paths, dir, logger); + } + + // When exporting as an NSP the assemblies are bundled inside the package. So we're also checking the + // build cache. The build program is named after the build target, i.e. `SwitchPlayerBuildProgram`. + var beePath = Path.Combine(projectDir, "Library", "Bee", "artifacts", $"{target}PlayerBuildProgram"); + AddPath(paths, beePath, logger); + + // User-provided Sentry plugin + AddPath(paths, Path.GetFullPath("Assets/Plugins/Sentry/"), logger); + } + // Possible duplicate but check for the .pdb files that Unity stores for script assemblies in `./Temp/ManagedSymbols/`. var managedSymbolsDirectory = Path.Combine(projectDir, "Temp", "ManagedSymbols"); AddPath(paths, managedSymbolsDirectory, logger); diff --git a/src/Sentry.Unity.Editor/Native/SwitchBuildTargets.cs b/src/Sentry.Unity.Editor/Native/SwitchBuildTargets.cs new file mode 100644 index 000000000..27395bd68 --- /dev/null +++ b/src/Sentry.Unity.Editor/Native/SwitchBuildTargets.cs @@ -0,0 +1,22 @@ +using System; +using UnityEditor; + +namespace Sentry.Unity.Editor.Native; + +/// +/// BuildTarget.Switch2 and BuildTargetGroup.Switch2 only exist in Unity 6000.3 +/// and newer, so matching by name instead. +/// +internal static class SwitchBuildTargets +{ + private const string Switch2Name = "Switch2"; + + internal static bool IsSwitch2(this BuildTarget target) => + string.Equals(target.ToString(), Switch2Name, StringComparison.Ordinal); + + internal static bool IsSwitch2(this BuildTargetGroup group) => + string.Equals(group.ToString(), Switch2Name, StringComparison.Ordinal); + + internal static bool IsSwitchFamily(this BuildTarget target) => + target is BuildTarget.Switch || target.IsSwitch2(); +} diff --git a/src/Sentry.Unity.Editor/Native/SwitchNativePluginBuildPreProcess.cs b/src/Sentry.Unity.Editor/Native/SwitchNativePluginBuildPreProcess.cs index 104ec7e92..ed03280e0 100644 --- a/src/Sentry.Unity.Editor/Native/SwitchNativePluginBuildPreProcess.cs +++ b/src/Sentry.Unity.Editor/Native/SwitchNativePluginBuildPreProcess.cs @@ -21,17 +21,24 @@ namespace Sentry.Unity.Editor.Native; /// internal class SwitchNativePluginBuildPreProcess : IPreprocessBuildWithReport { - private static readonly string[] RequiredFiles = + /// + /// Both platforms share one stub, so the required libraries are what differ between them. The build target's + /// name doubles as the directory name, i.e. `Switch` and `Switch2`. + /// + internal static string[] RequiredFilesFor(BuildTarget target) { - "Assets/Plugins/Sentry/Switch/libsentry.a", - "Assets/Plugins/Sentry/Switch/libzstd.a", - }; + return + [ + $"Assets/Plugins/Sentry/{target}/libsentry.a", + $"Assets/Plugins/Sentry/{target}/libzstd.a" + ]; + } public int callbackOrder => -100; public void OnPreprocessBuild(BuildReport report) { - if (report.summary.platform != BuildTarget.Switch) + if (!report.summary.platform.IsSwitchFamily()) { return; } @@ -39,14 +46,18 @@ public void OnPreprocessBuild(BuildReport report) var options = SentryScriptableObject.LoadOptions(isBuilding: true); var logger = options?.DiagnosticLogger ?? new UnityLogger(new SentryUnityOptions()); - ConfigureStub(logger, options?.SwitchNativeSupportEnabled ?? false); + ConfigureStub(logger, options?.SwitchNativeSupportEnabled ?? false, report.summary.platform); } - internal static void ConfigureStub(IDiagnosticLogger logger, bool nativeSupportEnabled) + internal static void ConfigureStub(IDiagnosticLogger logger, bool nativeSupportEnabled, BuildTarget target) { - logger.LogDebug("Switch native support: checking for required files:\n{0}", - string.Join("\n", RequiredFiles.Select(f => $" - {f}"))); + var requiredFiles = RequiredFilesFor(target); + + logger.LogDebug("{0} native support: checking for required files:\n{1}", + target, string.Join("\n", requiredFiles.Select(f => $" - {f}"))); + // One stub serves both platforms; the importer tracks compatibility per build target, so + // enabling it for one does not affect the other. var stubPath = Path.Combine("Packages", SentryPackageInfo.GetName(), "Plugins", "Switch", "sentry_native_stubs.c"); var importer = AssetImporter.GetAtPath(stubPath) as PluginImporter; @@ -56,18 +67,18 @@ internal static void ConfigureStub(IDiagnosticLogger logger, bool nativeSupportE return; } - var existingFiles = RequiredFiles.Where(File.Exists).ToList(); - var missingFiles = RequiredFiles.Except(existingFiles).ToList(); + var existingFiles = requiredFiles.Where(File.Exists).ToList(); + var missingFiles = requiredFiles.Except(existingFiles).ToList(); var someFilesPresent = existingFiles.Count > 0 && missingFiles.Count > 0; if (someFilesPresent) { - logger.LogError( - "Switch native support is partially configured. Missing files:\n{0}\n" + + logger.LogWarning( + "{0} native support is partially configured. Missing files:\n{1}\n" + "Please add all required files to enable native support, or remove all files to fall back on no-op stubs.\n" + "Build sentry-switch and copy the libraries to the expected locations. " + "See: https://github.com/getsentry/sentry-switch", - string.Join("\n", missingFiles.Select(f => $" - {f}")) + target, string.Join("\n", missingFiles.Select(f => $" - {f}")) ); return; } @@ -75,26 +86,26 @@ internal static void ConfigureStub(IDiagnosticLogger logger, bool nativeSupportE var allFilesPresent = missingFiles.Count == 0; if (allFilesPresent) { - logger.LogInfo("Switch native libraries found:\n{0}", - string.Join("\n", existingFiles.Select(f => $" - {f}"))); - importer.SetCompatibleWithPlatform(BuildTarget.Switch, false); + logger.LogInfo("{0} native libraries found:\n{1}", + target, string.Join("\n", existingFiles.Select(f => $" - {f}"))); + importer.SetCompatibleWithPlatform(target, false); } else { if (nativeSupportEnabled) { logger.LogWarning( - "Switch native support is enabled but required files are missing:\n{0}\n" + + "{0} native support is enabled but required files are missing:\n{1}\n" + "Build sentry-switch and copy the libraries to the expected locations. " + "See: https://github.com/getsentry/sentry-switch", - string.Join("\n", missingFiles.Select(f => $" - {f}")) + target, string.Join("\n", missingFiles.Select(f => $" - {f}")) ); } else { - logger.LogDebug("Switch native support is disabled. Enabling stubs (native calls will be no-op)."); + logger.LogDebug("{0} native support is disabled. Enabling stubs (native calls will be no-op).", target); } - importer.SetCompatibleWithPlatform(BuildTarget.Switch, true); + importer.SetCompatibleWithPlatform(target, true); } importer.SaveAndReimport(); diff --git a/src/Sentry.Unity.Native/SentryNativeBridge.cs b/src/Sentry.Unity.Native/SentryNativeBridge.cs index 2cf71b471..a01ddb6e7 100644 --- a/src/Sentry.Unity.Native/SentryNativeBridge.cs +++ b/src/Sentry.Unity.Native/SentryNativeBridge.cs @@ -31,7 +31,8 @@ public static bool Init(SentryUnityOptions options) UseLibC = Application.platform is RuntimePlatform.LinuxPlayer or RuntimePlatform.LinuxServer or RuntimePlatform.PS5 - or RuntimePlatform.Switch; + or RuntimePlatform.Switch + || Application.platform.IsSwitch2(); if ((Application.platform is RuntimePlatform.OSXPlayer or RuntimePlatform.OSXServer) && RuntimeInformation.ProcessArchitecture == Architecture.X64) diff --git a/src/Sentry.Unity/SentryUnityOptions.cs b/src/Sentry.Unity/SentryUnityOptions.cs index 1cb15ad5b..4e2767342 100644 --- a/src/Sentry.Unity/SentryUnityOptions.cs +++ b/src/Sentry.Unity/SentryUnityOptions.cs @@ -638,6 +638,7 @@ or RuntimePlatform.PS5 // Special casing Xbox: `Application.persistentDataPath` returns an empty string on packaged builds. if (IsKnownPlatform(application.Platform) && application.Platform is not RuntimePlatform.Switch + && !application.Platform.IsSwitch2() && application.Platform is not RuntimePlatform.GameCoreXboxSeries && application.Platform is not RuntimePlatform.GameCoreXboxOne) { @@ -664,7 +665,8 @@ or RuntimePlatform.WebGLPlayer or RuntimePlatform.GameCoreXboxSeries or RuntimePlatform.GameCoreXboxOne or RuntimePlatform.PS5 - or RuntimePlatform.Switch; + or RuntimePlatform.Switch + || platform.Value.IsSwitch2(); } public override string ToString() diff --git a/src/Sentry.Unity/SentryUnityOptionsExtensions.cs b/src/Sentry.Unity/SentryUnityOptionsExtensions.cs index cf2dc13dc..6370cf816 100644 --- a/src/Sentry.Unity/SentryUnityOptionsExtensions.cs +++ b/src/Sentry.Unity/SentryUnityOptionsExtensions.cs @@ -49,6 +49,12 @@ internal static bool IsValid(this SentryUnityOptions options) return true; } + /// + /// RuntimePlatform.Switch2 was only added in Unity 6000.3. + /// + internal static bool IsSwitch2(this RuntimePlatform platform) => + string.Equals(platform.ToString(), "Switch2", StringComparison.Ordinal); + internal static bool IsNativeSupportEnabled(this SentryUnityOptions options, RuntimePlatform? platform = null) { platform ??= ApplicationAdapter.Instance.Platform; @@ -62,6 +68,8 @@ internal static bool IsNativeSupportEnabled(this SentryUnityOptions options, Run RuntimePlatform.GameCoreXboxSeries or RuntimePlatform.GameCoreXboxOne => options.XboxNativeSupportEnabled, RuntimePlatform.PS5 => options.PlayStationNativeSupportEnabled, RuntimePlatform.Switch => options.SwitchNativeSupportEnabled, + // Switch 2 reuses the Switch native support. + _ when platform.Value.IsSwitch2() => options.SwitchNativeSupportEnabled, _ => false }; } diff --git a/test/Sentry.Unity.Editor.Tests/Native/SwitchNativeStubTests.cs b/test/Sentry.Unity.Editor.Tests/Native/SwitchNativeStubTests.cs index d967e2edc..a9b7371eb 100644 --- a/test/Sentry.Unity.Editor.Tests/Native/SwitchNativeStubTests.cs +++ b/test/Sentry.Unity.Editor.Tests/Native/SwitchNativeStubTests.cs @@ -1,9 +1,12 @@ +using System; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Text.RegularExpressions; using NUnit.Framework; +using Sentry.Unity.Editor.Native; +using UnityEditor; namespace Sentry.Unity.Editor.Tests.Native; @@ -41,4 +44,37 @@ public void Stub_ContainsEverySwitchNativeBinding() $"Switch binding '{entryPoint}' not found in {stubPath}"); } } + + [Test] + public void RequiredFilesFor_Switch_ProbesTheSwitchPluginDirectory() + { + var requiredFiles = SwitchNativePluginBuildPreProcess.RequiredFilesFor(BuildTarget.Switch); + + Assert.That(requiredFiles, Is.EquivalentTo(new[] + { + "Assets/Plugins/Sentry/Switch/libsentry.a", + "Assets/Plugins/Sentry/Switch/libzstd.a" + })); + } + + /// + /// Switch 2 is resolved by name because BuildTarget.Switch2 does not exist on the Unity versions the + /// SDK still supports, so this parses the member instead of referencing it and skips where it is unavailable. + /// + [Test] + public void RequiredFilesFor_Switch2_ProbesTheSwitch2PluginDirectory() + { + if (!Enum.TryParse("Switch2", out var switch2)) + { + Assert.Ignore("This Unity version predates 'BuildTarget.Switch2'."); + } + + var requiredFiles = SwitchNativePluginBuildPreProcess.RequiredFilesFor(switch2); + + Assert.That(requiredFiles, Is.EquivalentTo(new[] + { + "Assets/Plugins/Sentry/Switch2/libsentry.a", + "Assets/Plugins/Sentry/Switch2/libzstd.a" + })); + } } diff --git a/test/Sentry.Unity.Tests/SentryUnityOptionsExtensionsTests.cs b/test/Sentry.Unity.Tests/SentryUnityOptionsExtensionsTests.cs index 8ba703b9b..14308c1a3 100644 --- a/test/Sentry.Unity.Tests/SentryUnityOptionsExtensionsTests.cs +++ b/test/Sentry.Unity.Tests/SentryUnityOptionsExtensionsTests.cs @@ -1,3 +1,4 @@ +using System; using System.Linq; using NUnit.Framework; using Sentry.Unity.Tests.Stubs; @@ -207,4 +208,33 @@ public void IsNativeSupportEnabled_ConsolePlatforms_ReturnsExpectedValue( Assert.AreEqual(expectedResult, result); } + + /// + /// Switch 2 shares the Switch option. It is resolved by name because + /// RuntimePlatform.Switch2 does not exist on the Unity versions the SDK still supports, + /// so this parses the member instead of referencing it and skips where it is unavailable. + /// + [Test] + [TestCase(true, true)] + [TestCase(false, false)] + public void IsNativeSupportEnabled_Switch2_FollowsSwitchOption(bool optionEnabled, bool expectedResult) + { + if (!Enum.TryParse("Switch2", out var switch2)) + { + Assert.Ignore("This Unity version predates 'RuntimePlatform.Switch2'."); + } + + var options = _fixture.GetSut(); + options.SwitchNativeSupportEnabled = optionEnabled; + + Assert.AreEqual(expectedResult, options.IsNativeSupportEnabled(switch2)); + } + + [Test] + public void IsSwitch2_OtherPlatforms_ReturnsFalse() + { + Assert.IsFalse(RuntimePlatform.Switch.IsSwitch2()); + Assert.IsFalse(RuntimePlatform.PS5.IsSwitch2()); + Assert.IsFalse(RuntimePlatform.WindowsPlayer.IsSwitch2()); + } } diff --git a/test/Sentry.Unity.Tests/SentryUnityOptionsTests.cs b/test/Sentry.Unity.Tests/SentryUnityOptionsTests.cs index 091817e55..0959fa01c 100644 --- a/test/Sentry.Unity.Tests/SentryUnityOptionsTests.cs +++ b/test/Sentry.Unity.Tests/SentryUnityOptionsTests.cs @@ -1,3 +1,4 @@ +using System; using System.Linq; using NUnit.Framework; using Sentry.Unity.Integrations; @@ -55,6 +56,38 @@ public void Ctor_IfPlatformIsKnown_SetsCacheDirectoryPath(bool isKnownPlatform, Assert.AreEqual(sut.CacheDirectoryPath, expectedCacheDirectoryPath); } + /// + /// Switch 2 is resolved by name because RuntimePlatform.Switch2 does not exist on the Unity versions + /// the SDK still supports, so this parses the member instead of referencing it. + /// + private static RuntimePlatform GetSwitch2OrIgnore() + { + if (!Enum.TryParse("Switch2", out var switch2)) + { + Assert.Ignore("This Unity version predates 'RuntimePlatform.Switch2'."); + } + + return switch2; + } + + [Test] + public void IsKnownPlatform_Switch2_IsTrue() => + Assert.IsTrue(SentryUnityOptions.IsKnownPlatform(GetSwitch2OrIgnore())); + + /// + /// Just like on Switch, `Application.persistentDataPath` implicitly creates a directory and crashes. + /// + [Test] + public void Ctor_Switch2_DoesNotSetCacheDirectoryPath() + { + _fixture.Application.Platform = GetSwitch2OrIgnore(); + _fixture.Application.PersistentDataPath = "some/path"; + + var sut = _fixture.GetSut(); + + Assert.IsNull(sut.CacheDirectoryPath); + } + [Test] public void Ctor_IsGlobalModeEnabled_IsTrue() => Assert.IsTrue(_fixture.GetSut().IsGlobalModeEnabled);