From 64ee3a87d5a2113fd4a03bbce2672d9d4a510b0b Mon Sep 17 00:00:00 2001 From: Tomasz Jaworski Date: Fri, 1 Mar 2019 14:34:50 +0100 Subject: [PATCH 1/3] Update project for newer versions of Unity --- Assets/AssetStoreTools.meta | 9 - Assets/AssetStoreTools/Editor.meta | 9 - .../Editor/AssetStoreTools.dll | Bin 96768 -> 0 bytes .../Editor/AssetStoreTools.dll.meta | 22 - .../Editor/AssetStoreToolsExtra.dll | Bin 4096 -> 0 bytes .../Editor/AssetStoreToolsExtra.dll.meta | 22 - .../AssetStoreTools/Editor/DroidSansMono.ttf | Bin 117072 -> 0 bytes .../Editor/DroidSansMono.ttf.meta | 16 - Assets/AssetStoreTools/Editor/icon.png | Bin 11078 -> 0 bytes Assets/AssetStoreTools/Editor/icon.png.meta | 53 -- Assets/Editor/BuildScript.cs | 4 +- .../NSubstitute => Editor}/NSubstitute.dll | Bin .../NSubstitute.dll.meta | 20 +- Assets/Editor/Tests/AppFinderTest.cs | 4 +- Assets/Editor/Tests/BaseHttpDownloaderTest.cs | 6 +- Assets/Editor/Tests/ChunkedFileStreamTest.cs | 2 + .../Editor/Tests/ChunkedHttpDownloaderTest.cs | 2 + Assets/Editor/Tests/DownloadDirectoryTest.cs | 6 +- .../Tests/DownloadSpeedCalculatorTest.cs | 6 +- Assets/Editor/Tests/GZipStreamWrapperTest.cs | 4 +- .../Editor/Tests/InstallContentCommandTest.cs | 6 +- Assets/Editor/Tests/LocalDirectoryTest.cs | 6 +- Assets/Editor/Tests/LocalMetaDataTest.cs | 6 +- Assets/Editor/Tests/MagicBytesTest.cs | 4 +- Assets/Editor/Tests/MockCache.cs | 4 +- Assets/Editor/Tests/Pack1UnarchiverTest.cs | 6 +- .../Tests/RemoteResourceDownloaderTest.cs | 6 +- .../RemoteResourcePasswordGeneratorTest.cs | 6 +- Assets/Editor/Tests/TemporaryDirectoryTest.cs | 6 +- Assets/Editor/Tests/TestFixtures.cs | 6 +- Assets/Editor/Tests/TestHelpers.cs | 6 +- Assets/Editor/Tests/UnarchiverTest.cs | 6 +- .../Tests/ValidateLicenseCommandTest.cs | 6 +- .../PatchKit Patcher/Editor/BuildTargetOsx.cs | 16 + .../Editor/BuildTargetOsx.cs.meta | 3 + .../Editor/Building/CustomBuilding.cs | 21 +- .../Editor/Building/PostBuild.cs | 2 +- .../Editor/PatcherManifestCreator.cs | 4 + .../AppData/FileSystem/RetryStrategy.cs | 4 +- .../Scripts/AppUpdater/AppUpdater.cs | 6 +- .../Debug/PatcherLogRegisterTriggers.cs | 2 +- Assets/PatchKit Patcher/Scripts/Patcher.cs | 6 +- .../Scripts/UI/Dialogs/Dialog.cs | 2 +- .../Scripts/Utilities/Threading.cs | 2 +- Assets/UnityTestTools.meta | 9 - Assets/UnityTestTools/Assertions.meta | 5 - .../Assertions/AssertionComponent.cs | 379 ----------- .../Assertions/AssertionComponent.cs.meta | 8 - .../Assertions/AssertionException.cs | 24 - .../Assertions/AssertionException.cs.meta | 8 - .../UnityTestTools/Assertions/Assertions.cs | 42 -- .../Assertions/Assertions.cs.meta | 8 - .../UnityTestTools/Assertions/CheckMethod.cs | 36 -- .../Assertions/CheckMethod.cs.meta | 8 - .../UnityTestTools/Assertions/Comparers.meta | 5 - .../Assertions/Comparers/ActionBase.cs | 121 ---- .../Assertions/Comparers/ActionBase.cs.meta | 8 - .../Assertions/Comparers/BoolComparer.cs | 14 - .../Assertions/Comparers/BoolComparer.cs.meta | 8 - .../Assertions/Comparers/ColliderComparer.cs | 29 - .../Comparers/ColliderComparer.cs.meta | 8 - .../Assertions/Comparers/ComparerBase.cs | 145 ----- .../Assertions/Comparers/ComparerBase.cs.meta | 8 - .../Assertions/Comparers/FloatComparer.cs | 40 -- .../Comparers/FloatComparer.cs.meta | 8 - .../Assertions/Comparers/GeneralComparer.cs | 22 - .../Comparers/GeneralComparer.cs.meta | 8 - .../Assertions/Comparers/IntComparer.cs | 41 -- .../Assertions/Comparers/IntComparer.cs.meta | 8 - .../Comparers/IsRenderedByCamera.cs | 31 - .../Comparers/IsRenderedByCamera.cs.meta | 8 - .../Assertions/Comparers/StringComparer.cs | 42 -- .../Comparers/StringComparer.cs.meta | 8 - .../Assertions/Comparers/TransformComparer.cs | 26 - .../Comparers/TransformComparer.cs.meta | 8 - .../Comparers/ValueDoesNotChange.cs | 20 - .../Comparers/ValueDoesNotChange.cs.meta | 8 - .../Assertions/Comparers/Vector2Comparer.cs | 36 -- .../Comparers/Vector2Comparer.cs.meta | 8 - .../Assertions/Comparers/Vector3Comparer.cs | 32 - .../Comparers/Vector3Comparer.cs.meta | 8 - .../Assertions/Comparers/Vector4Comparer.cs | 38 -- .../Comparers/Vector4Comparer.cs.meta | 8 - .../Comparers/VectorComparerBase.cs | 18 - .../Comparers/VectorComparerBase.cs.meta | 8 - Assets/UnityTestTools/Assertions/Editor.meta | 5 - .../Editor/AssertionComponentEditor.cs | 226 ------- .../Editor/AssertionComponentEditor.cs.meta | 8 - .../Editor/AssertionExplorerWindow.cs | 194 ------ .../Editor/AssertionExplorerWindow.cs.meta | 8 - .../Editor/AssertionListRenderer.cs | 251 -------- .../Editor/AssertionListRenderer.cs.meta | 8 - .../Assertions/Editor/AssertionStripper.cs | 25 - .../Editor/AssertionStripper.cs.meta | 8 - .../Assertions/Editor/DropDownControl.cs | 78 --- .../Assertions/Editor/DropDownControl.cs.meta | 8 - .../Editor/GroupByComparerRenderer.cs | 20 - .../Editor/GroupByComparerRenderer.cs.meta | 8 - .../Editor/GroupByExecutionMethodRenderer.cs | 31 - .../GroupByExecutionMethodRenderer.cs.meta | 8 - .../Assertions/Editor/GroupByGORenderer.cs | 34 - .../Editor/GroupByGORenderer.cs.meta | 8 - .../Editor/GroupByNothingRenderer.cs | 20 - .../Editor/GroupByNothingRenderer.cs.meta | 8 - .../Assertions/Editor/GroupByTestsRenderer.cs | 29 - .../Editor/GroupByTestsRenderer.cs.meta | 8 - .../Assertions/Editor/PropertyPathSelector.cs | 207 ------ .../Editor/PropertyPathSelector.cs.meta | 8 - .../Assertions/Editor/PropertyResolver.cs | 188 ------ .../Editor/PropertyResolver.cs.meta | 8 - .../Assertions/InvalidPathException.cs | 14 - .../Assertions/InvalidPathException.cs.meta | 8 - .../Assertions/MemberResolver.cs | 208 ------ .../Assertions/MemberResolver.cs.meta | 8 - Assets/UnityTestTools/Common.meta | 5 - Assets/UnityTestTools/Common/Editor.meta | 4 - Assets/UnityTestTools/Common/Editor/Icons.cs | 57 -- .../Common/Editor/Icons.cs.meta | 8 - .../Common/Editor/ProjectSettingsBase.cs | 39 -- .../Common/Editor/ProjectSettingsBase.cs.meta | 8 - .../Common/Editor/ResultWriter.meta | 5 - .../Editor/ResultWriter/ResultSummarizer.cs | 173 ----- .../ResultWriter/ResultSummarizer.cs.meta | 8 - .../Editor/ResultWriter/StackTraceFilter.cs | 62 -- .../ResultWriter/StackTraceFilter.cs.meta | 8 - .../Editor/ResultWriter/XmlResultWriter.cs | 303 --------- .../ResultWriter/XmlResultWriter.cs.meta | 8 - Assets/UnityTestTools/Common/Editor/Styles.cs | 47 -- .../Common/Editor/Styles.cs.meta | 8 - .../Common/Editor/TestFilterSettings.cs | 104 --- .../Common/Editor/TestFilterSettings.cs.meta | 8 - .../UnityTestTools/Common/Editor/icons.meta | 4 - .../Common/Editor/icons/failed.png | Bin 1041 -> 0 bytes .../Common/Editor/icons/failed.png.meta | 35 -- .../Common/Editor/icons/ignored.png | Bin 1041 -> 0 bytes .../Common/Editor/icons/ignored.png.meta | 35 -- .../Common/Editor/icons/inconclusive.png | Bin 1041 -> 0 bytes .../Common/Editor/icons/inconclusive.png.meta | 35 -- .../Common/Editor/icons/normal.png | Bin 1041 -> 0 bytes .../Common/Editor/icons/normal.png.meta | 35 -- .../Common/Editor/icons/passed.png | Bin 1041 -> 0 bytes .../Common/Editor/icons/passed.png.meta | 35 -- .../Common/Editor/icons/stopwatch.png | Bin 1041 -> 0 bytes .../Common/Editor/icons/stopwatch.png.meta | 35 -- Assets/UnityTestTools/Common/ITestResult.cs | 29 - .../UnityTestTools/Common/ITestResult.cs.meta | 8 - Assets/UnityTestTools/Common/Settings.meta | 9 - .../IntegrationTestsRunnerSettings.asset | 15 - .../IntegrationTestsRunnerSettings.asset.meta | 8 - .../UnityTestTools/Common/TestResultState.cs | 46 -- .../Common/TestResultState.cs.meta | 8 - Assets/UnityTestTools/Documentation.url | 3 - Assets/UnityTestTools/Documentation.url.meta | 4 - .../IntegrationTestsFramework.meta | 5 - .../IntegrationTestsFramework/Libs.meta | 9 - .../Libs/Mono.Cecil.Mdb.dll | Bin 44544 -> 0 bytes .../Libs/Mono.Cecil.Mdb.dll.meta | 24 - .../Libs/Mono.Cecil.dll | Bin 280064 -> 0 bytes .../Libs/Mono.Cecil.dll.meta | 24 - .../IntegrationTestsFramework/TestRunner.meta | 5 - .../TestRunner/DTOFormatter.cs | 140 ----- .../TestRunner/DTOFormatter.cs.meta | 8 - .../TestRunner/Editor.meta | 5 - .../TestRunner/Editor/Batch.cs | 200 ------ .../TestRunner/Editor/Batch.cs.meta | 8 - .../TestRunner/Editor/EditorReferencesUtil.cs | 102 --- .../Editor/EditorReferencesUtil.cs.meta | 12 - .../TestRunner/Editor/GuiHelper.cs | 35 -- .../TestRunner/Editor/GuiHelper.cs.meta | 8 - .../IntegrationTestsHierarchyAnnotation.cs | 44 -- ...ntegrationTestsHierarchyAnnotation.cs.meta | 8 - .../Editor/IntegrationTestsRunnerSettings.cs | 25 - .../IntegrationTestsRunnerSettings.cs.meta | 8 - .../Editor/IntegrationTestsRunnerWindow.cs | 590 ------------------ .../IntegrationTestsRunnerWindow.cs.meta | 8 - .../TestRunner/Editor/PlatformRunner.meta | 4 - .../PlatformRunner/NetworkResultsReceiver.cs | 261 -------- .../NetworkResultsReceiver.cs.meta | 8 - .../Editor/PlatformRunner/PlatformRunner.cs | 130 ---- .../PlatformRunner/PlatformRunner.cs.meta | 8 - .../PlatformRunnerConfiguration.cs | 79 --- .../PlatformRunnerConfiguration.cs.meta | 8 - .../PlatformRunner/PlatformRunnerSettings.cs | 12 - .../PlatformRunnerSettings.cs.meta | 8 - .../PlatformRunnerSettingsWindow.cs | 318 ---------- .../PlatformRunnerSettingsWindow.cs.meta | 8 - .../PlayerSettingConfigurator.cs | 73 --- .../PlayerSettingConfigurator.cs.meta | 8 - .../TestRunner/Editor/Renderer.meta | 4 - .../Renderer/IntegrationTestGroupLine.cs | 84 --- .../Renderer/IntegrationTestGroupLine.cs.meta | 8 - .../Editor/Renderer/IntegrationTestLine.cs | 57 -- .../Renderer/IntegrationTestLine.cs.meta | 8 - .../Renderer/IntegrationTestRendererBase.cs | 161 ----- .../IntegrationTestRendererBase.cs.meta | 8 - .../Editor/Renderer/RenderingOptions.cs | 16 - .../Editor/Renderer/RenderingOptions.cs.meta | 8 - .../TestRunner/Editor/TestComponentEditor.cs | 129 ---- .../Editor/TestComponentEditor.cs.meta | 8 - .../TestRunner/ITestRunnerCallback.cs | 16 - .../TestRunner/ITestRunnerCallback.cs.meta | 8 - .../TestRunner/IntegrationTest.cs | 176 ------ .../TestRunner/IntegrationTest.cs.meta | 8 - .../TestRunner/IntegrationTestAttribute.cs | 24 - .../IntegrationTestAttribute.cs.meta | 8 - .../TestRunner/IntegrationTestsProvider.cs | 109 ---- .../IntegrationTestsProvider.cs.meta | 8 - .../TestRunner/NetworkResultSender.cs | 112 ---- .../TestRunner/NetworkResultSender.cs.meta | 8 - .../TestRunner/ResultDTO.cs | 168 ----- .../TestRunner/ResultDTO.cs.meta | 8 - .../TestRunner/TestComponent.cs | 412 ------------ .../TestRunner/TestComponent.cs.meta | 8 - .../TestRunner/TestResult.cs | 141 ----- .../TestRunner/TestResult.cs.meta | 8 - .../TestRunner/TestResultRenderer.cs | 83 --- .../TestRunner/TestResultRenderer.cs.meta | 8 - .../TestRunner/TestRunner.cs | 432 ------------- .../TestRunner/TestRunner.cs.meta | 8 - .../TestRunner/TestRunnerCallbackList.cs | 69 -- .../TestRunner/TestRunnerCallbackList.cs.meta | 8 - .../TestRunner/TestRunnerConfigurator.cs | 227 ------- .../TestRunner/TestRunnerConfigurator.cs.meta | 8 - .../TestingAssets.meta | 5 - .../TestingAssets/CallTesting.cs | 204 ------ .../TestingAssets/CallTesting.cs.meta | 8 - .../TestingAssets/CubeCollisionFailure.prefab | 104 --- .../CubeCollisionFailure.prefab.meta | 4 - .../TestingAssets/CubeCollisionSuccess.prefab | 104 --- .../CubeCollisionSuccess.prefab.meta | 4 - .../TestingAssets/CubeTriggerFailure.prefab | 104 --- .../CubeTriggerFailure.prefab.meta | 4 - .../TestingAssets/CubeTriggerSuccess.prefab | 104 --- .../CubeTriggerSuccess.prefab.meta | 4 - .../TestingAssets/Materials.meta | 5 - .../TestingAssets/Materials/green.mat | 30 - .../TestingAssets/Materials/green.mat.meta | 4 - .../TestingAssets/Materials/red.mat | 30 - .../TestingAssets/Materials/red.mat.meta | 4 - .../TestingAssets/green.png | Bin 140 -> 0 bytes .../TestingAssets/green.png.meta | 53 -- .../TestingAssets/red.png | Bin 139 -> 0 bytes .../TestingAssets/red.png.meta | 53 -- Assets/UnityTestTools/LICENSE.txt | 83 --- Assets/UnityTestTools/LICENSE.txt.meta | 4 - Assets/UnityTestTools/UnitTesting.meta | 5 - Assets/UnityTestTools/UnitTesting/Editor.meta | 4 - .../UnitTesting/Editor/NSubstitute.meta | 5 - Assets/UnityTestTools/changelog.txt | 216 ------- Assets/UnityTestTools/changelog.txt.meta | 4 - 250 files changed, 143 insertions(+), 10230 deletions(-) delete mode 100644 Assets/AssetStoreTools.meta delete mode 100644 Assets/AssetStoreTools/Editor.meta delete mode 100644 Assets/AssetStoreTools/Editor/AssetStoreTools.dll delete mode 100644 Assets/AssetStoreTools/Editor/AssetStoreTools.dll.meta delete mode 100644 Assets/AssetStoreTools/Editor/AssetStoreToolsExtra.dll delete mode 100644 Assets/AssetStoreTools/Editor/AssetStoreToolsExtra.dll.meta delete mode 100644 Assets/AssetStoreTools/Editor/DroidSansMono.ttf delete mode 100644 Assets/AssetStoreTools/Editor/DroidSansMono.ttf.meta delete mode 100644 Assets/AssetStoreTools/Editor/icon.png delete mode 100644 Assets/AssetStoreTools/Editor/icon.png.meta rename Assets/{UnityTestTools/UnitTesting/Editor/NSubstitute => Editor}/NSubstitute.dll (100%) rename Assets/{UnityTestTools/UnitTesting/Editor/NSubstitute => Editor}/NSubstitute.dll.meta (51%) create mode 100644 Assets/PatchKit Patcher/Editor/BuildTargetOsx.cs create mode 100644 Assets/PatchKit Patcher/Editor/BuildTargetOsx.cs.meta delete mode 100644 Assets/UnityTestTools.meta delete mode 100644 Assets/UnityTestTools/Assertions.meta delete mode 100644 Assets/UnityTestTools/Assertions/AssertionComponent.cs delete mode 100644 Assets/UnityTestTools/Assertions/AssertionComponent.cs.meta delete mode 100644 Assets/UnityTestTools/Assertions/AssertionException.cs delete mode 100644 Assets/UnityTestTools/Assertions/AssertionException.cs.meta delete mode 100644 Assets/UnityTestTools/Assertions/Assertions.cs delete mode 100644 Assets/UnityTestTools/Assertions/Assertions.cs.meta delete mode 100644 Assets/UnityTestTools/Assertions/CheckMethod.cs delete mode 100644 Assets/UnityTestTools/Assertions/CheckMethod.cs.meta delete mode 100644 Assets/UnityTestTools/Assertions/Comparers.meta delete mode 100644 Assets/UnityTestTools/Assertions/Comparers/ActionBase.cs delete mode 100644 Assets/UnityTestTools/Assertions/Comparers/ActionBase.cs.meta delete mode 100644 Assets/UnityTestTools/Assertions/Comparers/BoolComparer.cs delete mode 100644 Assets/UnityTestTools/Assertions/Comparers/BoolComparer.cs.meta delete mode 100644 Assets/UnityTestTools/Assertions/Comparers/ColliderComparer.cs delete mode 100644 Assets/UnityTestTools/Assertions/Comparers/ColliderComparer.cs.meta delete mode 100644 Assets/UnityTestTools/Assertions/Comparers/ComparerBase.cs delete mode 100644 Assets/UnityTestTools/Assertions/Comparers/ComparerBase.cs.meta delete mode 100644 Assets/UnityTestTools/Assertions/Comparers/FloatComparer.cs delete mode 100644 Assets/UnityTestTools/Assertions/Comparers/FloatComparer.cs.meta delete mode 100644 Assets/UnityTestTools/Assertions/Comparers/GeneralComparer.cs delete mode 100644 Assets/UnityTestTools/Assertions/Comparers/GeneralComparer.cs.meta delete mode 100644 Assets/UnityTestTools/Assertions/Comparers/IntComparer.cs delete mode 100644 Assets/UnityTestTools/Assertions/Comparers/IntComparer.cs.meta delete mode 100644 Assets/UnityTestTools/Assertions/Comparers/IsRenderedByCamera.cs delete mode 100644 Assets/UnityTestTools/Assertions/Comparers/IsRenderedByCamera.cs.meta delete mode 100644 Assets/UnityTestTools/Assertions/Comparers/StringComparer.cs delete mode 100644 Assets/UnityTestTools/Assertions/Comparers/StringComparer.cs.meta delete mode 100644 Assets/UnityTestTools/Assertions/Comparers/TransformComparer.cs delete mode 100644 Assets/UnityTestTools/Assertions/Comparers/TransformComparer.cs.meta delete mode 100644 Assets/UnityTestTools/Assertions/Comparers/ValueDoesNotChange.cs delete mode 100644 Assets/UnityTestTools/Assertions/Comparers/ValueDoesNotChange.cs.meta delete mode 100644 Assets/UnityTestTools/Assertions/Comparers/Vector2Comparer.cs delete mode 100644 Assets/UnityTestTools/Assertions/Comparers/Vector2Comparer.cs.meta delete mode 100644 Assets/UnityTestTools/Assertions/Comparers/Vector3Comparer.cs delete mode 100644 Assets/UnityTestTools/Assertions/Comparers/Vector3Comparer.cs.meta delete mode 100644 Assets/UnityTestTools/Assertions/Comparers/Vector4Comparer.cs delete mode 100644 Assets/UnityTestTools/Assertions/Comparers/Vector4Comparer.cs.meta delete mode 100644 Assets/UnityTestTools/Assertions/Comparers/VectorComparerBase.cs delete mode 100644 Assets/UnityTestTools/Assertions/Comparers/VectorComparerBase.cs.meta delete mode 100644 Assets/UnityTestTools/Assertions/Editor.meta delete mode 100644 Assets/UnityTestTools/Assertions/Editor/AssertionComponentEditor.cs delete mode 100644 Assets/UnityTestTools/Assertions/Editor/AssertionComponentEditor.cs.meta delete mode 100644 Assets/UnityTestTools/Assertions/Editor/AssertionExplorerWindow.cs delete mode 100644 Assets/UnityTestTools/Assertions/Editor/AssertionExplorerWindow.cs.meta delete mode 100644 Assets/UnityTestTools/Assertions/Editor/AssertionListRenderer.cs delete mode 100644 Assets/UnityTestTools/Assertions/Editor/AssertionListRenderer.cs.meta delete mode 100644 Assets/UnityTestTools/Assertions/Editor/AssertionStripper.cs delete mode 100644 Assets/UnityTestTools/Assertions/Editor/AssertionStripper.cs.meta delete mode 100644 Assets/UnityTestTools/Assertions/Editor/DropDownControl.cs delete mode 100644 Assets/UnityTestTools/Assertions/Editor/DropDownControl.cs.meta delete mode 100644 Assets/UnityTestTools/Assertions/Editor/GroupByComparerRenderer.cs delete mode 100644 Assets/UnityTestTools/Assertions/Editor/GroupByComparerRenderer.cs.meta delete mode 100644 Assets/UnityTestTools/Assertions/Editor/GroupByExecutionMethodRenderer.cs delete mode 100644 Assets/UnityTestTools/Assertions/Editor/GroupByExecutionMethodRenderer.cs.meta delete mode 100644 Assets/UnityTestTools/Assertions/Editor/GroupByGORenderer.cs delete mode 100644 Assets/UnityTestTools/Assertions/Editor/GroupByGORenderer.cs.meta delete mode 100644 Assets/UnityTestTools/Assertions/Editor/GroupByNothingRenderer.cs delete mode 100644 Assets/UnityTestTools/Assertions/Editor/GroupByNothingRenderer.cs.meta delete mode 100644 Assets/UnityTestTools/Assertions/Editor/GroupByTestsRenderer.cs delete mode 100644 Assets/UnityTestTools/Assertions/Editor/GroupByTestsRenderer.cs.meta delete mode 100644 Assets/UnityTestTools/Assertions/Editor/PropertyPathSelector.cs delete mode 100644 Assets/UnityTestTools/Assertions/Editor/PropertyPathSelector.cs.meta delete mode 100644 Assets/UnityTestTools/Assertions/Editor/PropertyResolver.cs delete mode 100644 Assets/UnityTestTools/Assertions/Editor/PropertyResolver.cs.meta delete mode 100644 Assets/UnityTestTools/Assertions/InvalidPathException.cs delete mode 100644 Assets/UnityTestTools/Assertions/InvalidPathException.cs.meta delete mode 100644 Assets/UnityTestTools/Assertions/MemberResolver.cs delete mode 100644 Assets/UnityTestTools/Assertions/MemberResolver.cs.meta delete mode 100644 Assets/UnityTestTools/Common.meta delete mode 100644 Assets/UnityTestTools/Common/Editor.meta delete mode 100644 Assets/UnityTestTools/Common/Editor/Icons.cs delete mode 100644 Assets/UnityTestTools/Common/Editor/Icons.cs.meta delete mode 100644 Assets/UnityTestTools/Common/Editor/ProjectSettingsBase.cs delete mode 100644 Assets/UnityTestTools/Common/Editor/ProjectSettingsBase.cs.meta delete mode 100644 Assets/UnityTestTools/Common/Editor/ResultWriter.meta delete mode 100644 Assets/UnityTestTools/Common/Editor/ResultWriter/ResultSummarizer.cs delete mode 100644 Assets/UnityTestTools/Common/Editor/ResultWriter/ResultSummarizer.cs.meta delete mode 100644 Assets/UnityTestTools/Common/Editor/ResultWriter/StackTraceFilter.cs delete mode 100644 Assets/UnityTestTools/Common/Editor/ResultWriter/StackTraceFilter.cs.meta delete mode 100644 Assets/UnityTestTools/Common/Editor/ResultWriter/XmlResultWriter.cs delete mode 100644 Assets/UnityTestTools/Common/Editor/ResultWriter/XmlResultWriter.cs.meta delete mode 100644 Assets/UnityTestTools/Common/Editor/Styles.cs delete mode 100644 Assets/UnityTestTools/Common/Editor/Styles.cs.meta delete mode 100644 Assets/UnityTestTools/Common/Editor/TestFilterSettings.cs delete mode 100644 Assets/UnityTestTools/Common/Editor/TestFilterSettings.cs.meta delete mode 100644 Assets/UnityTestTools/Common/Editor/icons.meta delete mode 100644 Assets/UnityTestTools/Common/Editor/icons/failed.png delete mode 100644 Assets/UnityTestTools/Common/Editor/icons/failed.png.meta delete mode 100644 Assets/UnityTestTools/Common/Editor/icons/ignored.png delete mode 100644 Assets/UnityTestTools/Common/Editor/icons/ignored.png.meta delete mode 100644 Assets/UnityTestTools/Common/Editor/icons/inconclusive.png delete mode 100644 Assets/UnityTestTools/Common/Editor/icons/inconclusive.png.meta delete mode 100644 Assets/UnityTestTools/Common/Editor/icons/normal.png delete mode 100644 Assets/UnityTestTools/Common/Editor/icons/normal.png.meta delete mode 100644 Assets/UnityTestTools/Common/Editor/icons/passed.png delete mode 100644 Assets/UnityTestTools/Common/Editor/icons/passed.png.meta delete mode 100644 Assets/UnityTestTools/Common/Editor/icons/stopwatch.png delete mode 100644 Assets/UnityTestTools/Common/Editor/icons/stopwatch.png.meta delete mode 100644 Assets/UnityTestTools/Common/ITestResult.cs delete mode 100644 Assets/UnityTestTools/Common/ITestResult.cs.meta delete mode 100644 Assets/UnityTestTools/Common/Settings.meta delete mode 100644 Assets/UnityTestTools/Common/Settings/IntegrationTestsRunnerSettings.asset delete mode 100644 Assets/UnityTestTools/Common/Settings/IntegrationTestsRunnerSettings.asset.meta delete mode 100644 Assets/UnityTestTools/Common/TestResultState.cs delete mode 100644 Assets/UnityTestTools/Common/TestResultState.cs.meta delete mode 100644 Assets/UnityTestTools/Documentation.url delete mode 100644 Assets/UnityTestTools/Documentation.url.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/Libs.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/Libs/Mono.Cecil.Mdb.dll delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/Libs/Mono.Cecil.Mdb.dll.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/Libs/Mono.Cecil.dll delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/Libs/Mono.Cecil.dll.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/DTOFormatter.cs delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/DTOFormatter.cs.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Batch.cs delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Batch.cs.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/EditorReferencesUtil.cs delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/EditorReferencesUtil.cs.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/GuiHelper.cs delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/GuiHelper.cs.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsHierarchyAnnotation.cs delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsHierarchyAnnotation.cs.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsRunnerSettings.cs delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsRunnerSettings.cs.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsRunnerWindow.cs delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsRunnerWindow.cs.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/NetworkResultsReceiver.cs delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/NetworkResultsReceiver.cs.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunner.cs delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunner.cs.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerConfiguration.cs delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerConfiguration.cs.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerSettings.cs delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerSettings.cs.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerSettingsWindow.cs delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerSettingsWindow.cs.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlayerSettingConfigurator.cs delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlayerSettingConfigurator.cs.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestGroupLine.cs delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestGroupLine.cs.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestLine.cs delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestLine.cs.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestRendererBase.cs delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestRendererBase.cs.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/RenderingOptions.cs delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/RenderingOptions.cs.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/TestComponentEditor.cs delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/TestComponentEditor.cs.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/ITestRunnerCallback.cs delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/ITestRunnerCallback.cs.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTest.cs delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTest.cs.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTestAttribute.cs delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTestAttribute.cs.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTestsProvider.cs delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTestsProvider.cs.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/NetworkResultSender.cs delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/NetworkResultSender.cs.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/ResultDTO.cs delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/ResultDTO.cs.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestComponent.cs delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestComponent.cs.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestResult.cs delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestResult.cs.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestResultRenderer.cs delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestResultRenderer.cs.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunner.cs delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunner.cs.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunnerCallbackList.cs delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunnerCallbackList.cs.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunnerConfigurator.cs delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunnerConfigurator.cs.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CallTesting.cs delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CallTesting.cs.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeCollisionFailure.prefab delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeCollisionFailure.prefab.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeCollisionSuccess.prefab delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeCollisionSuccess.prefab.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeTriggerFailure.prefab delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeTriggerFailure.prefab.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeTriggerSuccess.prefab delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeTriggerSuccess.prefab.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/Materials.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/Materials/green.mat delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/Materials/green.mat.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/Materials/red.mat delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/Materials/red.mat.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/green.png delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/green.png.meta delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/red.png delete mode 100644 Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/red.png.meta delete mode 100644 Assets/UnityTestTools/LICENSE.txt delete mode 100644 Assets/UnityTestTools/LICENSE.txt.meta delete mode 100644 Assets/UnityTestTools/UnitTesting.meta delete mode 100644 Assets/UnityTestTools/UnitTesting/Editor.meta delete mode 100644 Assets/UnityTestTools/UnitTesting/Editor/NSubstitute.meta delete mode 100644 Assets/UnityTestTools/changelog.txt delete mode 100644 Assets/UnityTestTools/changelog.txt.meta diff --git a/Assets/AssetStoreTools.meta b/Assets/AssetStoreTools.meta deleted file mode 100644 index cc9f49a3..00000000 --- a/Assets/AssetStoreTools.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: a0009ee3b43ec48af82b13a686f2a5fa -folderAsset: yes -timeCreated: 1490990507 -licenseType: Free -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/AssetStoreTools/Editor.meta b/Assets/AssetStoreTools/Editor.meta deleted file mode 100644 index f61a4683..00000000 --- a/Assets/AssetStoreTools/Editor.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 8ffcba85c19eb4c7e88ce05c37929384 -folderAsset: yes -timeCreated: 1490990507 -licenseType: Free -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/AssetStoreTools/Editor/AssetStoreTools.dll b/Assets/AssetStoreTools/Editor/AssetStoreTools.dll deleted file mode 100644 index e64fad3633b65ebf25025bf13f1ae13a303d79a8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 96768 zcmcG137izg^?yyzOwa7h>@hpb%)$b@EU>i0wH)f~uE2_TpC}@i3W^|yH1^^-&Sp`A z8c{(}6CzR3#QTVM{29eWQKL!JXgrB{n`jafP2!Q@|NDJaGt�_&fgd*{!bk>eZ`P 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 z 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 diff --git a/Assets/AssetStoreTools/Editor/AssetStoreTools.dll.meta b/Assets/AssetStoreTools/Editor/AssetStoreTools.dll.meta deleted file mode 100644 index 5244b496..00000000 --- a/Assets/AssetStoreTools/Editor/AssetStoreTools.dll.meta +++ /dev/null @@ -1,22 +0,0 @@ -fileFormatVersion: 2 -guid: f02b3fe0a866fca419671914a860554a -PluginImporter: - serializedVersion: 1 - iconMap: {} - executionOrder: {} - isPreloaded: 0 - platformData: - Any: - enabled: 0 - settings: {} - Editor: - enabled: 1 - settings: - DefaultValueInitialized: true - WindowsStoreApps: - enabled: 0 - settings: - CPU: AnyCPU - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/AssetStoreTools/Editor/AssetStoreToolsExtra.dll b/Assets/AssetStoreTools/Editor/AssetStoreToolsExtra.dll deleted file mode 100644 index 68bd2144acbaa69b3b504cd6d2387cbb92e36216..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 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 M07*qoM6N<$f{WZx3;+NC diff --git a/Assets/AssetStoreTools/Editor/icon.png.meta b/Assets/AssetStoreTools/Editor/icon.png.meta deleted file mode 100644 index 8813c5d6..00000000 --- a/Assets/AssetStoreTools/Editor/icon.png.meta +++ /dev/null @@ -1,53 +0,0 @@ -fileFormatVersion: 2 -guid: 3ef5b3d0acd79c3499f502f1b991678a -TextureImporter: - fileIDToRecycleName: {} - serializedVersion: 2 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - linearTexture: 0 - correctGamma: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: .25 - normalMapFilter: 0 - isReadable: 0 - grayScaleToAlpha: 0 - generateCubemap: 0 - cubemapConvolution: 0 - cubemapConvolutionSteps: 8 - cubemapConvolutionExponent: 1.5 - seamlessCubemap: 0 - textureFormat: -1 - maxTextureSize: 1024 - textureSettings: - filterMode: -1 - aniso: -1 - mipBias: -1 - wrapMode: -1 - nPOTScale: 1 - lightmap: 0 - rGBM: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: .5, y: .5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spritePixelsToUnits: 100 - alphaIsTransparency: 0 - textureType: -1 - buildTargetSettings: [] - spriteSheet: - sprites: [] - spritePackingTag: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Editor/BuildScript.cs b/Assets/Editor/BuildScript.cs index 05c851ec..4c9ec8c1 100644 --- a/Assets/Editor/BuildScript.cs +++ b/Assets/Editor/BuildScript.cs @@ -29,12 +29,12 @@ public static void BuildWindows64Development() public static void BuildOSX64Release() { - Build(BuildTarget.StandaloneOSXIntel64, false); + Build(BuildTargetOsx.Get(), false); } public static void BuildOSX64Development() { - Build(BuildTarget.StandaloneOSXIntel64, true); + Build(BuildTargetOsx.Get(), true); } public static void BuildLinux32Release() diff --git a/Assets/UnityTestTools/UnitTesting/Editor/NSubstitute/NSubstitute.dll b/Assets/Editor/NSubstitute.dll similarity index 100% rename from Assets/UnityTestTools/UnitTesting/Editor/NSubstitute/NSubstitute.dll rename to Assets/Editor/NSubstitute.dll diff --git a/Assets/UnityTestTools/UnitTesting/Editor/NSubstitute/NSubstitute.dll.meta b/Assets/Editor/NSubstitute.dll.meta similarity index 51% rename from Assets/UnityTestTools/UnitTesting/Editor/NSubstitute/NSubstitute.dll.meta rename to Assets/Editor/NSubstitute.dll.meta index 1cb4f6b3..9aa98933 100644 --- a/Assets/UnityTestTools/UnitTesting/Editor/NSubstitute/NSubstitute.dll.meta +++ b/Assets/Editor/NSubstitute.dll.meta @@ -1,19 +1,29 @@ fileFormatVersion: 2 -guid: 3c5e1afc6e0d68849ae6639aff58cfc7 +guid: 3c570bd8d8599e74aa5fc1c502637524 PluginImporter: - serializedVersion: 1 + externalObjects: {} + serializedVersion: 2 iconMap: {} executionOrder: {} + defineConstraints: [] isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 platformData: - Any: + - first: + Any: + second: enabled: 0 settings: {} - Editor: + - first: + Editor: Editor + second: enabled: 1 settings: DefaultValueInitialized: true - WindowsStoreApps: + - first: + Windows Store Apps: WindowsStoreApps + second: enabled: 0 settings: CPU: AnyCPU diff --git a/Assets/Editor/Tests/AppFinderTest.cs b/Assets/Editor/Tests/AppFinderTest.cs index 9c148023..9f644d27 100644 --- a/Assets/Editor/Tests/AppFinderTest.cs +++ b/Assets/Editor/Tests/AppFinderTest.cs @@ -1,4 +1,5 @@ -using System.IO; +#if UNITY_2018 +using System.IO; using NSubstitute; using NUnit.Framework; using PatchKit.Unity.Patcher; @@ -45,3 +46,4 @@ public void FindLinuxApp() Assert.AreEqual(dest, executable); } } +#endif \ No newline at end of file diff --git a/Assets/Editor/Tests/BaseHttpDownloaderTest.cs b/Assets/Editor/Tests/BaseHttpDownloaderTest.cs index ec5d9bf4..46a0e17c 100644 --- a/Assets/Editor/Tests/BaseHttpDownloaderTest.cs +++ b/Assets/Editor/Tests/BaseHttpDownloaderTest.cs @@ -1,4 +1,5 @@ -using System.IO; +#if UNITY_2018 +using System.IO; using System.Net; using NUnit.Framework; using NSubstitute; @@ -147,4 +148,5 @@ public void DownloadThrowsException_For_WebException() Assert.Catch(() => baseHttpDownloader.Download(CancellationToken.Empty)); } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Assets/Editor/Tests/ChunkedFileStreamTest.cs b/Assets/Editor/Tests/ChunkedFileStreamTest.cs index 2dadf85f..f660ae66 100644 --- a/Assets/Editor/Tests/ChunkedFileStreamTest.cs +++ b/Assets/Editor/Tests/ChunkedFileStreamTest.cs @@ -1,3 +1,4 @@ +#if UNITY_2018 using System; using System.IO; using NUnit.Framework; @@ -184,3 +185,4 @@ public void SaveInvalidSecondPass() } } } +#endif \ No newline at end of file diff --git a/Assets/Editor/Tests/ChunkedHttpDownloaderTest.cs b/Assets/Editor/Tests/ChunkedHttpDownloaderTest.cs index bfab868f..1bdfa8c0 100644 --- a/Assets/Editor/Tests/ChunkedHttpDownloaderTest.cs +++ b/Assets/Editor/Tests/ChunkedHttpDownloaderTest.cs @@ -1,3 +1,4 @@ +#if UNITY_2018 using System.IO; using System.Linq; using System.Collections; @@ -231,3 +232,4 @@ public void JobQueuing_SinglePartScenario() Assert.That(job.Range.End, Is.EqualTo(-1).Or.EqualTo(127)); } } +#endif \ No newline at end of file diff --git a/Assets/Editor/Tests/DownloadDirectoryTest.cs b/Assets/Editor/Tests/DownloadDirectoryTest.cs index ee9c5979..88f96049 100644 --- a/Assets/Editor/Tests/DownloadDirectoryTest.cs +++ b/Assets/Editor/Tests/DownloadDirectoryTest.cs @@ -1,4 +1,5 @@ -using System.IO; +#if UNITY_2018 +using System.IO; using NUnit.Framework; using PatchKit.Unity.Patcher.AppData.Local; @@ -76,4 +77,5 @@ public void Clear() Assert.IsFalse(File.Exists(filePath)); } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Assets/Editor/Tests/DownloadSpeedCalculatorTest.cs b/Assets/Editor/Tests/DownloadSpeedCalculatorTest.cs index 50ddd9d3..013626f4 100644 --- a/Assets/Editor/Tests/DownloadSpeedCalculatorTest.cs +++ b/Assets/Editor/Tests/DownloadSpeedCalculatorTest.cs @@ -1,4 +1,5 @@ -using System; +#if UNITY_2018 +using System; using NUnit.Framework; using PatchKit.Unity.Patcher.AppUpdater.Status; @@ -15,4 +16,5 @@ public void DownloadSpeed_For3Samples_ReturnsAverage() Assert.AreEqual(1000.0, downloadSpeedCalculator.BytesPerSecond, 0.1, "Download speed is not correct."); } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Assets/Editor/Tests/GZipStreamWrapperTest.cs b/Assets/Editor/Tests/GZipStreamWrapperTest.cs index 071165bf..696e7e5f 100644 --- a/Assets/Editor/Tests/GZipStreamWrapperTest.cs +++ b/Assets/Editor/Tests/GZipStreamWrapperTest.cs @@ -1,3 +1,4 @@ +#if UNITY_2018 using System; using System.IO; using System.Text; @@ -151,4 +152,5 @@ public void Wrapped_Read_Succeeds_On_Mocked_Stream() Assert.That(decompressed == RawData); } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Assets/Editor/Tests/InstallContentCommandTest.cs b/Assets/Editor/Tests/InstallContentCommandTest.cs index ceb6ecd9..e5c13f83 100644 --- a/Assets/Editor/Tests/InstallContentCommandTest.cs +++ b/Assets/Editor/Tests/InstallContentCommandTest.cs @@ -1,4 +1,5 @@ -using System.IO; +#if UNITY_2018 +using System.IO; using NSubstitute; using NUnit.Framework; using PatchKit.Unity.Patcher.AppData.Local; @@ -34,4 +35,5 @@ public void Install() //var command = new InstallContentCommand(1, ) } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Assets/Editor/Tests/LocalDirectoryTest.cs b/Assets/Editor/Tests/LocalDirectoryTest.cs index b7fe3612..65b8a9a7 100644 --- a/Assets/Editor/Tests/LocalDirectoryTest.cs +++ b/Assets/Editor/Tests/LocalDirectoryTest.cs @@ -1,4 +1,5 @@ -using System.IO; +#if UNITY_2018 +using System.IO; using NUnit.Framework; using PatchKit.Unity.Patcher.AppData.Local; @@ -29,4 +30,5 @@ public void PrepareForWriting_CreatesDirectory() Assert.IsTrue(Directory.Exists(_dirPath)); } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Assets/Editor/Tests/LocalMetaDataTest.cs b/Assets/Editor/Tests/LocalMetaDataTest.cs index a1767323..2518b636 100644 --- a/Assets/Editor/Tests/LocalMetaDataTest.cs +++ b/Assets/Editor/Tests/LocalMetaDataTest.cs @@ -1,4 +1,5 @@ -using System.IO; +#if UNITY_2018 +using System.IO; using NUnit.Framework; using PatchKit.Unity.Patcher.AppData.Local; @@ -51,4 +52,5 @@ public void SaveValidFileSinglePass() Assert.AreEqual(1, localMetaData2.GetEntryVersionId("a")); Assert.AreEqual(2, localMetaData2.GetEntryVersionId("b")); } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Assets/Editor/Tests/MagicBytesTest.cs b/Assets/Editor/Tests/MagicBytesTest.cs index a84bed29..524764af 100644 --- a/Assets/Editor/Tests/MagicBytesTest.cs +++ b/Assets/Editor/Tests/MagicBytesTest.cs @@ -1,3 +1,4 @@ +#if UNITY_2018 using NUnit.Framework; using PatchKit.Unity.Patcher.Data; @@ -50,4 +51,5 @@ public void IsLinuxExecutable_ForLinuxApp_ReturnsTrue() { Assert.IsTrue(MagicBytes.IsLinuxExecutable(_linuxApp)); } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Assets/Editor/Tests/MockCache.cs b/Assets/Editor/Tests/MockCache.cs index e3974ff6..75b6c0d8 100644 --- a/Assets/Editor/Tests/MockCache.cs +++ b/Assets/Editor/Tests/MockCache.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +#if UNITY_2018 +using System.Collections.Generic; using PatchKit.Unity.Patcher.AppData.Local; class MockCache : ICache @@ -19,3 +20,4 @@ public string GetValue(string key, string defaultValue = null) return defaultValue; } } +#endif \ No newline at end of file diff --git a/Assets/Editor/Tests/Pack1UnarchiverTest.cs b/Assets/Editor/Tests/Pack1UnarchiverTest.cs index 0eec227e..b1cd945e 100644 --- a/Assets/Editor/Tests/Pack1UnarchiverTest.cs +++ b/Assets/Editor/Tests/Pack1UnarchiverTest.cs @@ -1,4 +1,5 @@ -using System.IO; +#if UNITY_2018 +using System.IO; using System.Security.Cryptography; using System.Text; using NUnit.Framework; @@ -61,4 +62,5 @@ private string Md5File(string path) } } } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Assets/Editor/Tests/RemoteResourceDownloaderTest.cs b/Assets/Editor/Tests/RemoteResourceDownloaderTest.cs index 94851204..60ef9e14 100644 --- a/Assets/Editor/Tests/RemoteResourceDownloaderTest.cs +++ b/Assets/Editor/Tests/RemoteResourceDownloaderTest.cs @@ -1,4 +1,5 @@ -using System; +#if UNITY_2018 +using System; using System.IO; using NSubstitute; using NUnit.Framework; @@ -123,4 +124,5 @@ public void UseHttpDownloaderIfChunksAreNotAvailable() httpDownloader.ReceivedWithAnyArgs().Download(CancellationToken.Empty); chunkedHttpDownloader.DidNotReceiveWithAnyArgs().Download(CancellationToken.Empty); } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Assets/Editor/Tests/RemoteResourcePasswordGeneratorTest.cs b/Assets/Editor/Tests/RemoteResourcePasswordGeneratorTest.cs index 4b80654b..3a139dce 100644 --- a/Assets/Editor/Tests/RemoteResourcePasswordGeneratorTest.cs +++ b/Assets/Editor/Tests/RemoteResourcePasswordGeneratorTest.cs @@ -1,4 +1,5 @@ -using NUnit.Framework; +#if UNITY_2018 +using NUnit.Framework; using PatchKit.Unity.Patcher.AppData.Remote; public class RemoteResourcePasswordGeneratorTest @@ -12,4 +13,5 @@ public void Generate_ReturnsValidPassword() Assert.AreEqual("\x08\x07\x18\x24YWJjZDEyMzQx", password); } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Assets/Editor/Tests/TemporaryDirectoryTest.cs b/Assets/Editor/Tests/TemporaryDirectoryTest.cs index f7742b81..50f48773 100644 --- a/Assets/Editor/Tests/TemporaryDirectoryTest.cs +++ b/Assets/Editor/Tests/TemporaryDirectoryTest.cs @@ -1,4 +1,5 @@ -using System.IO; +#if UNITY_2018 +using System.IO; using NUnit.Framework; using PatchKit.Unity.Patcher.AppData.Local; @@ -88,4 +89,5 @@ public void GetUniquePath_ReturnsUniquePaths() } }); } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Assets/Editor/Tests/TestFixtures.cs b/Assets/Editor/Tests/TestFixtures.cs index b655cf74..90e77465 100644 --- a/Assets/Editor/Tests/TestFixtures.cs +++ b/Assets/Editor/Tests/TestFixtures.cs @@ -1,4 +1,5 @@ -using UnityEngine; +#if UNITY_2018 +using UnityEngine; class TestFixtures { @@ -16,4 +17,5 @@ public static string GetDirectoryPath(string dirName) { return System.IO.Path.Combine(BasePath, dirName); } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Assets/Editor/Tests/TestHelpers.cs b/Assets/Editor/Tests/TestHelpers.cs index 0dc86d8c..23af4f10 100644 --- a/Assets/Editor/Tests/TestHelpers.cs +++ b/Assets/Editor/Tests/TestHelpers.cs @@ -1,4 +1,5 @@ -using System.IO; +#if UNITY_2018 +using System.IO; public class TestHelpers { @@ -16,4 +17,5 @@ public static void DeleteTemporaryDirectory(string path) Directory.Delete(path, true); } } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Assets/Editor/Tests/UnarchiverTest.cs b/Assets/Editor/Tests/UnarchiverTest.cs index 0c901eb9..ba9f35a4 100644 --- a/Assets/Editor/Tests/UnarchiverTest.cs +++ b/Assets/Editor/Tests/UnarchiverTest.cs @@ -1,4 +1,5 @@ -using System; +#if UNITY_2018 +using System; using System.IO; using NUnit.Framework; using PatchKit.Unity.Patcher.AppData.Local; @@ -142,4 +143,5 @@ public void ProgressReporting() Assert.That(lastEntry, Is.Not.Null); Assert.That(lastEntry.Value, Is.EqualTo(lastAmount.Value)); } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Assets/Editor/Tests/ValidateLicenseCommandTest.cs b/Assets/Editor/Tests/ValidateLicenseCommandTest.cs index e24fc42a..788afc60 100644 --- a/Assets/Editor/Tests/ValidateLicenseCommandTest.cs +++ b/Assets/Editor/Tests/ValidateLicenseCommandTest.cs @@ -1,4 +1,5 @@ -using System; +#if UNITY_2018 +using System; using System.Collections.Generic; using NSubstitute; using NUnit.Framework; @@ -183,4 +184,5 @@ public void Execute_DisplaysProperDialogMessageForConnectionError() licenseDialog.DidNotReceive().Display(Arg.Is(type => type != LicenseDialogMessageType.None && type != LicenseDialogMessageType.ServiceUnavailable)); } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Assets/PatchKit Patcher/Editor/BuildTargetOsx.cs b/Assets/PatchKit Patcher/Editor/BuildTargetOsx.cs new file mode 100644 index 00000000..7a26a95a --- /dev/null +++ b/Assets/PatchKit Patcher/Editor/BuildTargetOsx.cs @@ -0,0 +1,16 @@ +using UnityEditor; + +namespace PatchKit.Unity +{ + public static class BuildTargetOsx + { + public static BuildTarget Get() + { +#if UNITY_2017_3_OR_NEWER + return BuildTarget.StandaloneOSX; +#else + return BuildTarget.StandaloneOSXIntel64; +#endif + } + } +} \ No newline at end of file diff --git a/Assets/PatchKit Patcher/Editor/BuildTargetOsx.cs.meta b/Assets/PatchKit Patcher/Editor/BuildTargetOsx.cs.meta new file mode 100644 index 00000000..8d70879c --- /dev/null +++ b/Assets/PatchKit Patcher/Editor/BuildTargetOsx.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a2dbda8667bc4a1391aa33c923b9b382 +timeCreated: 1551446928 \ No newline at end of file diff --git a/Assets/PatchKit Patcher/Editor/Building/CustomBuilding.cs b/Assets/PatchKit Patcher/Editor/Building/CustomBuilding.cs index ed1c35c5..b59b9b41 100644 --- a/Assets/PatchKit Patcher/Editor/Building/CustomBuilding.cs +++ b/Assets/PatchKit Patcher/Editor/Building/CustomBuilding.cs @@ -4,6 +4,7 @@ using System.Diagnostics; using System.IO; using System; +using UnityEditor.Build.Reporting; namespace PatchKit.Unity { @@ -42,7 +43,7 @@ public static void BuildLinux () [MenuItem("Tools/Build/OSX x64")] public static void BuildOsx64 () { - Build(BuildTarget.StandaloneOSXIntel64); + Build(BuildTargetOsx.Get()); } private static string PatcherExecutableName(BuildTarget target) @@ -56,7 +57,11 @@ private static string PatcherExecutableName(BuildTarget target) case BuildTarget.StandaloneLinux64: case BuildTarget.StandaloneLinuxUniversal: return "Patcher"; +#if UNITY_2017_3_OR_NEWER + case BuildTarget.StandaloneOSX: +#else case BuildTarget.StandaloneOSXIntel64: +#endif return "Patcher.app"; default: throw new NotSupportedException(); @@ -76,7 +81,11 @@ public static string PatcherDataDirectory(BuildTarget target, string executableP string patcherName = Path.GetFileNameWithoutExtension (executablePath); return Path.Combine(buildDir, patcherName + "_Data"); +#if UNITY_2017_3_OR_NEWER + case BuildTarget.StandaloneOSX: +#else case BuildTarget.StandaloneOSXIntel64: +#endif return Path.Combine(executablePath, "Contents"); default: throw new NotSupportedException(); @@ -148,8 +157,16 @@ private static void Build(BuildTarget target) return; } - string error = BuildPipeline.BuildPlayer(scenePaths, path + "/" + PatcherExecutableName(target), target, buildOptions); + #if UNITY_2018_1_OR_NEWER + var buildResult = BuildPipeline.BuildPlayer(scenePaths, path + "/" + PatcherExecutableName(target), target, buildOptions); + string error = buildResult.summary.result == BuildResult.Succeeded ? null : "Error"; + + #else + string error = BuildPipeline.BuildPlayer(scenePaths, path + "/" + PatcherExecutableName(target), target, buildOptions); + #endif + + if (!string.IsNullOrEmpty(error)) { EditorUtility.DisplayDialog("Error", error, "Ok"); diff --git a/Assets/PatchKit Patcher/Editor/Building/PostBuild.cs b/Assets/PatchKit Patcher/Editor/Building/PostBuild.cs index b7e5fdc8..ec5e61cf 100644 --- a/Assets/PatchKit Patcher/Editor/Building/PostBuild.cs +++ b/Assets/PatchKit Patcher/Editor/Building/PostBuild.cs @@ -13,7 +13,7 @@ public class PostBuild BuildTarget.StandaloneLinux64, BuildTarget.StandaloneWindows, BuildTarget.StandaloneWindows64, - BuildTarget.StandaloneOSXIntel64, + BuildTargetOsx.Get() }; [PostProcessBuild, UsedImplicitly] diff --git a/Assets/PatchKit Patcher/Editor/PatcherManifestCreator.cs b/Assets/PatchKit Patcher/Editor/PatcherManifestCreator.cs index 374f0ce8..dfb5493b 100644 --- a/Assets/PatchKit Patcher/Editor/PatcherManifestCreator.cs +++ b/Assets/PatchKit Patcher/Editor/PatcherManifestCreator.cs @@ -47,7 +47,11 @@ private static void PostProcessBuild(BuildTarget buildTarget, string buildPath) case BuildTarget.StandaloneWindows64: manifest = WindowsManifest(buildPath); break; +#if UNITY_2017_3_OR_NEWER + case BuildTarget.StandaloneOSX: +#else case BuildTarget.StandaloneOSXIntel64: +#endif manifest = OsxManifest(buildPath); break; case BuildTarget.StandaloneLinux: diff --git a/Assets/PatchKit Patcher/Scripts/AppData/FileSystem/RetryStrategy.cs b/Assets/PatchKit Patcher/Scripts/AppData/FileSystem/RetryStrategy.cs index 9190aa3e..9d40bb33 100644 --- a/Assets/PatchKit Patcher/Scripts/AppData/FileSystem/RetryStrategy.cs +++ b/Assets/PatchKit Patcher/Scripts/AppData/FileSystem/RetryStrategy.cs @@ -55,7 +55,7 @@ public bool ShouldRetry } } - public static void TryExecute(Action action, IRequestRetryStrategy retryStrategy, CancellationToken cancellationToken) + public static void TryExecute(Action action, IRequestRetryStrategy retryStrategy, PatchKit.Unity.Patcher.Cancellation.CancellationToken cancellationToken) { do { @@ -80,7 +80,7 @@ public static void TryExecute(Action action, IRequestRetryStrategy retryStrategy } while (retryStrategy.ShouldRetry); } - public static void TryExecute(Action action, CancellationToken cancellationToken) + public static void TryExecute(Action action, PatchKit.Unity.Patcher.Cancellation.CancellationToken cancellationToken) { TryExecute(action, new RetryStrategy(), cancellationToken); } diff --git a/Assets/PatchKit Patcher/Scripts/AppUpdater/AppUpdater.cs b/Assets/PatchKit Patcher/Scripts/AppUpdater/AppUpdater.cs index 3aa3caa8..3b6067aa 100644 --- a/Assets/PatchKit Patcher/Scripts/AppUpdater/AppUpdater.cs +++ b/Assets/PatchKit Patcher/Scripts/AppUpdater/AppUpdater.cs @@ -41,7 +41,7 @@ public AppUpdater(AppUpdaterContext context) Context = context; } - private void PreUpdate(CancellationToken cancellationToken) + private void PreUpdate(PatchKit.Unity.Patcher.Cancellation.CancellationToken cancellationToken) { DebugLogger.Log("Pre update integrity check"); @@ -112,7 +112,7 @@ private long CalculateRepairCost(AppContentSummary contentSummary, IEnumerable f.Size); } - public void Update(CancellationToken cancellationToken) + public void Update(PatchKit.Unity.Patcher.Cancellation.CancellationToken cancellationToken) { Assert.MethodCalledOnlyOnce(ref _updateHasBeenCalled, "Update"); @@ -153,7 +153,7 @@ public void Update(CancellationToken cancellationToken) } } - private bool TryHandleFallback(CancellationToken cancellationToken) + private bool TryHandleFallback(PatchKit.Unity.Patcher.Cancellation.CancellationToken cancellationToken) { var fallbackType = _strategyResolver.GetFallbackStrategy(_strategy.GetStrategyType()); diff --git a/Assets/PatchKit Patcher/Scripts/Debug/PatcherLogRegisterTriggers.cs b/Assets/PatchKit Patcher/Scripts/Debug/PatcherLogRegisterTriggers.cs index 41b80b8d..e2eea3fe 100644 --- a/Assets/PatchKit Patcher/Scripts/Debug/PatcherLogRegisterTriggers.cs +++ b/Assets/PatchKit Patcher/Scripts/Debug/PatcherLogRegisterTriggers.cs @@ -8,7 +8,7 @@ public class PatcherLogRegisterTriggers : IDisposable private readonly Subject _exceptionTrigger = new Subject(); - public IObservable ExceptionTrigger + public UniRx.IObservable ExceptionTrigger { get { return _exceptionTrigger; } } diff --git a/Assets/PatchKit Patcher/Scripts/Patcher.cs b/Assets/PatchKit Patcher/Scripts/Patcher.cs index 715f0c91..4e6c4243 100644 --- a/Assets/PatchKit Patcher/Scripts/Patcher.cs +++ b/Assets/PatchKit Patcher/Scripts/Patcher.cs @@ -58,7 +58,7 @@ public static Patcher Instance private bool _canStartThread = true; - private readonly CancellationTokenSource _threadCancellationTokenSource = new CancellationTokenSource(); + private readonly PatchKit.Unity.Patcher.Cancellation.CancellationTokenSource _threadCancellationTokenSource = new PatchKit.Unity.Patcher.Cancellation.CancellationTokenSource(); private Thread _thread; @@ -85,7 +85,7 @@ public static Patcher Instance private FileStream _lockFileStream; - private CancellationTokenSource _updateAppCancellationTokenSource; + private PatchKit.Unity.Patcher.Cancellation.CancellationTokenSource _updateAppCancellationTokenSource; public ErrorDialog ErrorDialog; @@ -837,7 +837,7 @@ private void ThreadUpdateApp(bool automatically, CancellationToken cancellationT _localVersionId.Value = _app.GetInstalledVersionId(); } - _updateAppCancellationTokenSource = new CancellationTokenSource(); + _updateAppCancellationTokenSource = new PatchKit.Unity.Patcher.Cancellation.CancellationTokenSource(); using (cancellationToken.Register(() => _updateAppCancellationTokenSource.Cancel())) { diff --git a/Assets/PatchKit Patcher/Scripts/UI/Dialogs/Dialog.cs b/Assets/PatchKit Patcher/Scripts/UI/Dialogs/Dialog.cs index 4bb6d898..b16cd5d6 100644 --- a/Assets/PatchKit Patcher/Scripts/UI/Dialogs/Dialog.cs +++ b/Assets/PatchKit Patcher/Scripts/UI/Dialogs/Dialog.cs @@ -22,7 +22,7 @@ protected void OnDisplayed() _dialogDisplayed.Set(); } - protected void Display(CancellationToken cancellationToken) + protected void Display(PatchKit.Unity.Patcher.Cancellation.CancellationToken cancellationToken) { Assert.IsFalse(_unityThread == Thread.CurrentThread, "Display dialog can be only used on separate thread."); diff --git a/Assets/PatchKit Patcher/Scripts/Utilities/Threading.cs b/Assets/PatchKit Patcher/Scripts/Utilities/Threading.cs index 7d0cc0ba..e555b7a4 100644 --- a/Assets/PatchKit Patcher/Scripts/Utilities/Threading.cs +++ b/Assets/PatchKit Patcher/Scripts/Utilities/Threading.cs @@ -70,7 +70,7 @@ public static IEnumerator StartThreadCoroutine(Func action, Action onSu /// /// Miliseconds, time to sleep /// token to check cancellation exception - public static void CancelableSleep(int duration, CancellationToken cancellationToken) + public static void CancelableSleep(int duration, PatchKit.Unity.Patcher.Cancellation.CancellationToken cancellationToken) { // FIX: Bug #692 int singleSleep = 100; diff --git a/Assets/UnityTestTools.meta b/Assets/UnityTestTools.meta deleted file mode 100644 index 1aaa58ee..00000000 --- a/Assets/UnityTestTools.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: e8ea46aeb27ac6945b9920b2aa505c7c -folderAsset: yes -timeCreated: 1484387678 -licenseType: Pro -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/UnityTestTools/Assertions.meta b/Assets/UnityTestTools/Assertions.meta deleted file mode 100644 index 229b8b81..00000000 --- a/Assets/UnityTestTools/Assertions.meta +++ /dev/null @@ -1,5 +0,0 @@ -fileFormatVersion: 2 -guid: b27b28700d3365146808b6e082748201 -folderAsset: yes -DefaultImporter: - userData: diff --git a/Assets/UnityTestTools/Assertions/AssertionComponent.cs b/Assets/UnityTestTools/Assertions/AssertionComponent.cs deleted file mode 100644 index fa40d488..00000000 --- a/Assets/UnityTestTools/Assertions/AssertionComponent.cs +++ /dev/null @@ -1,379 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using UnityEngine; -using Debug = UnityEngine.Debug; -using Object = UnityEngine.Object; - -namespace UnityTest -{ - [Serializable] - public class AssertionComponent : MonoBehaviour, IAssertionComponentConfigurator - { - [SerializeField] public float checkAfterTime = 1f; - [SerializeField] public bool repeatCheckTime = true; - [SerializeField] public float repeatEveryTime = 1f; - [SerializeField] public int checkAfterFrames = 1; - [SerializeField] public bool repeatCheckFrame = true; - [SerializeField] public int repeatEveryFrame = 1; - [SerializeField] public bool hasFailed; - - [SerializeField] public CheckMethod checkMethods = CheckMethod.Start; - [SerializeField] private ActionBase m_ActionBase; - - [SerializeField] public int checksPerformed = 0; - - private int m_CheckOnFrame; - - private string m_CreatedInFilePath = ""; - private int m_CreatedInFileLine = -1; - - public ActionBase Action - { - get { return m_ActionBase; } - set - { - m_ActionBase = value; - m_ActionBase.go = gameObject; - } - } - - public Object GetFailureReferenceObject() - { - #if UNITY_EDITOR - if (!string.IsNullOrEmpty(m_CreatedInFilePath)) - { - return UnityEditor.AssetDatabase.LoadAssetAtPath(m_CreatedInFilePath, typeof(Object)); - } - #endif - return this; - } - - public string GetCreationLocation() - { - if (!string.IsNullOrEmpty(m_CreatedInFilePath)) - { - var idx = m_CreatedInFilePath.LastIndexOf("\\") + 1; - return string.Format("{0}, line {1} ({2})", m_CreatedInFilePath.Substring(idx), m_CreatedInFileLine, m_CreatedInFilePath); - } - return ""; - } - - public void Awake() - { - if (!Debug.isDebugBuild) - Destroy(this); - OnComponentCopy(); - } - - public void OnValidate() - { - if (Application.isEditor) - OnComponentCopy(); - } - - private void OnComponentCopy() - { - if (m_ActionBase == null) return; - var oldActionList = Resources.FindObjectsOfTypeAll(typeof(AssertionComponent)).Where(o => ((AssertionComponent)o).m_ActionBase == m_ActionBase && o != this); - - // if it's not a copy but a new component don't do anything - if (!oldActionList.Any()) return; - if (oldActionList.Count() > 1) - Debug.LogWarning("More than one refence to comparer found. This shouldn't happen"); - - var oldAction = oldActionList.First() as AssertionComponent; - m_ActionBase = oldAction.m_ActionBase.CreateCopy(oldAction.gameObject, gameObject); - } - - public void Start() - { - CheckAssertionFor(CheckMethod.Start); - - if (IsCheckMethodSelected(CheckMethod.AfterPeriodOfTime)) - { - StartCoroutine("CheckPeriodically"); - } - if (IsCheckMethodSelected(CheckMethod.Update)) - { - m_CheckOnFrame = Time.frameCount + checkAfterFrames; - } - } - - public IEnumerator CheckPeriodically() - { - yield return new WaitForSeconds(checkAfterTime); - CheckAssertionFor(CheckMethod.AfterPeriodOfTime); - while (repeatCheckTime) - { - yield return new WaitForSeconds(repeatEveryTime); - CheckAssertionFor(CheckMethod.AfterPeriodOfTime); - } - } - - public bool ShouldCheckOnFrame() - { - if (Time.frameCount > m_CheckOnFrame) - { - if (repeatCheckFrame) - m_CheckOnFrame += repeatEveryFrame; - else - m_CheckOnFrame = Int32.MaxValue; - return true; - } - return false; - } - - public void OnDisable() - { - CheckAssertionFor(CheckMethod.OnDisable); - } - - public void OnEnable() - { - CheckAssertionFor(CheckMethod.OnEnable); - } - - public void OnDestroy() - { - CheckAssertionFor(CheckMethod.OnDestroy); - } - - public void Update() - { - if (IsCheckMethodSelected(CheckMethod.Update) && ShouldCheckOnFrame()) - { - CheckAssertionFor(CheckMethod.Update); - } - } - - public void FixedUpdate() - { - CheckAssertionFor(CheckMethod.FixedUpdate); - } - - public void LateUpdate() - { - CheckAssertionFor(CheckMethod.LateUpdate); - } - - public void OnControllerColliderHit() - { - CheckAssertionFor(CheckMethod.OnControllerColliderHit); - } - - public void OnParticleCollision() - { - CheckAssertionFor(CheckMethod.OnParticleCollision); - } - - public void OnJointBreak() - { - CheckAssertionFor(CheckMethod.OnJointBreak); - } - - public void OnBecameInvisible() - { - CheckAssertionFor(CheckMethod.OnBecameInvisible); - } - - public void OnBecameVisible() - { - CheckAssertionFor(CheckMethod.OnBecameVisible); - } - - public void OnTriggerEnter() - { - CheckAssertionFor(CheckMethod.OnTriggerEnter); - } - - public void OnTriggerExit() - { - CheckAssertionFor(CheckMethod.OnTriggerExit); - } - - public void OnTriggerStay() - { - CheckAssertionFor(CheckMethod.OnTriggerStay); - } - - public void OnCollisionEnter() - { - CheckAssertionFor(CheckMethod.OnCollisionEnter); - } - - public void OnCollisionExit() - { - CheckAssertionFor(CheckMethod.OnCollisionExit); - } - - public void OnCollisionStay() - { - CheckAssertionFor(CheckMethod.OnCollisionStay); - } - - public void OnTriggerEnter2D() - { - CheckAssertionFor(CheckMethod.OnTriggerEnter2D); - } - - public void OnTriggerExit2D() - { - CheckAssertionFor(CheckMethod.OnTriggerExit2D); - } - - public void OnTriggerStay2D() - { - CheckAssertionFor(CheckMethod.OnTriggerStay2D); - } - - public void OnCollisionEnter2D() - { - CheckAssertionFor(CheckMethod.OnCollisionEnter2D); - } - - public void OnCollisionExit2D() - { - CheckAssertionFor(CheckMethod.OnCollisionExit2D); - } - - public void OnCollisionStay2D() - { - CheckAssertionFor(CheckMethod.OnCollisionStay2D); - } - - private void CheckAssertionFor(CheckMethod checkMethod) - { - if (IsCheckMethodSelected(checkMethod)) - { - Assertions.CheckAssertions(this); - } - } - - public bool IsCheckMethodSelected(CheckMethod method) - { - return method == (checkMethods & method); - } - - - #region Assertion Component create methods - - public static T Create(CheckMethod checkOnMethods, GameObject gameObject, string propertyPath) where T : ActionBase - { - IAssertionComponentConfigurator configurator; - return Create(out configurator, checkOnMethods, gameObject, propertyPath); - } - - public static T Create(out IAssertionComponentConfigurator configurator, CheckMethod checkOnMethods, GameObject gameObject, string propertyPath) where T : ActionBase - { - return CreateAssertionComponent(out configurator, checkOnMethods, gameObject, propertyPath); - } - - public static T Create(CheckMethod checkOnMethods, GameObject gameObject, string propertyPath, GameObject gameObject2, string propertyPath2) where T : ComparerBase - { - IAssertionComponentConfigurator configurator; - return Create(out configurator, checkOnMethods, gameObject, propertyPath, gameObject2, propertyPath2); - } - - public static T Create(out IAssertionComponentConfigurator configurator, CheckMethod checkOnMethods, GameObject gameObject, string propertyPath, GameObject gameObject2, string propertyPath2) where T : ComparerBase - { - var comparer = CreateAssertionComponent(out configurator, checkOnMethods, gameObject, propertyPath); - comparer.compareToType = ComparerBase.CompareToType.CompareToObject; - comparer.other = gameObject2; - comparer.otherPropertyPath = propertyPath2; - return comparer; - } - - public static T Create(CheckMethod checkOnMethods, GameObject gameObject, string propertyPath, object constValue) where T : ComparerBase - { - IAssertionComponentConfigurator configurator; - return Create(out configurator, checkOnMethods, gameObject, propertyPath, constValue); - } - - public static T Create(out IAssertionComponentConfigurator configurator, CheckMethod checkOnMethods, GameObject gameObject, string propertyPath, object constValue) where T : ComparerBase - { - var comparer = CreateAssertionComponent(out configurator, checkOnMethods, gameObject, propertyPath); - if (constValue == null) - { - comparer.compareToType = ComparerBase.CompareToType.CompareToNull; - return comparer; - } - comparer.compareToType = ComparerBase.CompareToType.CompareToConstantValue; - comparer.ConstValue = constValue; - return comparer; - } - - private static T CreateAssertionComponent(out IAssertionComponentConfigurator configurator, CheckMethod checkOnMethods, GameObject gameObject, string propertyPath) where T : ActionBase - { - var ac = gameObject.AddComponent(); - ac.checkMethods = checkOnMethods; - var comparer = ScriptableObject.CreateInstance(); - ac.Action = comparer; - ac.Action.go = gameObject; - ac.Action.thisPropertyPath = propertyPath; - configurator = ac; - -#if !UNITY_METRO - var stackTrace = new StackTrace(true); - var thisFileName = stackTrace.GetFrame(0).GetFileName(); - for (int i = 1; i < stackTrace.FrameCount; i++) - { - var stackFrame = stackTrace.GetFrame(i); - if (stackFrame.GetFileName() != thisFileName) - { - string filePath = stackFrame.GetFileName().Substring(Application.dataPath.Length - "Assets".Length); - ac.m_CreatedInFilePath = filePath; - ac.m_CreatedInFileLine = stackFrame.GetFileLineNumber(); - break; - } - } -#endif // if !UNITY_METRO - return comparer; - } - - #endregion - - #region AssertionComponentConfigurator - public int UpdateCheckStartOnFrame { set { checkAfterFrames = value; } } - public int UpdateCheckRepeatFrequency { set { repeatEveryFrame = value; } } - public bool UpdateCheckRepeat { set { repeatCheckFrame = value; } } - public float TimeCheckStartAfter { set { checkAfterTime = value; } } - public float TimeCheckRepeatFrequency { set { repeatEveryTime = value; } } - public bool TimeCheckRepeat { set { repeatCheckTime = value; } } - public AssertionComponent Component { get { return this; } } - #endregion - } - - public interface IAssertionComponentConfigurator - { - ///

- /// If the assertion is evaluated in Update, after how many frame should the evaluation start. Deafult is 1 (first frame) - /// - int UpdateCheckStartOnFrame { set; } - /// - /// If the assertion is evaluated in Update and UpdateCheckRepeat is true, how many frame should pass between evaluations - /// - int UpdateCheckRepeatFrequency { set; } - /// - /// If the assertion is evaluated in Update, should the evaluation be repeated after UpdateCheckRepeatFrequency frames - /// - bool UpdateCheckRepeat { set; } - - /// - /// If the assertion is evaluated after a period of time, after how many seconds the first evaluation should be done - /// - float TimeCheckStartAfter { set; } - /// - /// If the assertion is evaluated after a period of time and TimeCheckRepeat is true, after how many seconds should the next evaluation happen - /// - float TimeCheckRepeatFrequency { set; } - /// - /// If the assertion is evaluated after a period, should the evaluation happen again after TimeCheckRepeatFrequency seconds - /// - bool TimeCheckRepeat { set; } - - AssertionComponent Component { get; } - } -} diff --git a/Assets/UnityTestTools/Assertions/AssertionComponent.cs.meta b/Assets/UnityTestTools/Assertions/AssertionComponent.cs.meta deleted file mode 100644 index 26f9ab45..00000000 --- a/Assets/UnityTestTools/Assertions/AssertionComponent.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 8bafa54482a87ac4cbd7ff1bfd1ac93a -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Assertions/AssertionException.cs b/Assets/UnityTestTools/Assertions/AssertionException.cs deleted file mode 100644 index 00c6d588..00000000 --- a/Assets/UnityTestTools/Assertions/AssertionException.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace UnityTest -{ - public class AssertionException : Exception - { - private readonly AssertionComponent m_Assertion; - - public AssertionException(AssertionComponent assertion) : base(assertion.Action.GetFailureMessage()) - { - m_Assertion = assertion; - } - - public override string StackTrace - { - get - { - return "Created in " + m_Assertion.GetCreationLocation(); - } - } - } -} diff --git a/Assets/UnityTestTools/Assertions/AssertionException.cs.meta b/Assets/UnityTestTools/Assertions/AssertionException.cs.meta deleted file mode 100644 index 9605bf01..00000000 --- a/Assets/UnityTestTools/Assertions/AssertionException.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: ef3769ab00d50bc4fbb05a9a91c741d9 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Assertions/Assertions.cs b/Assets/UnityTestTools/Assertions/Assertions.cs deleted file mode 100644 index 14b3fd6c..00000000 --- a/Assets/UnityTestTools/Assertions/Assertions.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; -using Object = UnityEngine.Object; - -namespace UnityTest -{ - public static class Assertions - { - public static void CheckAssertions() - { - var assertions = Object.FindObjectsOfType(typeof(AssertionComponent)) as AssertionComponent[]; - CheckAssertions(assertions); - } - - public static void CheckAssertions(AssertionComponent assertion) - { - CheckAssertions(new[] {assertion}); - } - - public static void CheckAssertions(GameObject gameObject) - { - CheckAssertions(gameObject.GetComponents()); - } - - public static void CheckAssertions(AssertionComponent[] assertions) - { - if (!Debug.isDebugBuild) - return; - foreach (var assertion in assertions) - { - assertion.checksPerformed++; - var result = assertion.Action.Compare(); - if (!result) - { - assertion.hasFailed = true; - assertion.Action.Fail(assertion); - } - } - } - } -} diff --git a/Assets/UnityTestTools/Assertions/Assertions.cs.meta b/Assets/UnityTestTools/Assertions/Assertions.cs.meta deleted file mode 100644 index 00878a4f..00000000 --- a/Assets/UnityTestTools/Assertions/Assertions.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 85280dad1e618c143bd3fb07a197b469 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Assertions/CheckMethod.cs b/Assets/UnityTestTools/Assertions/CheckMethod.cs deleted file mode 100644 index 07583dd3..00000000 --- a/Assets/UnityTestTools/Assertions/CheckMethod.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace UnityTest -{ - [Flags] - public enum CheckMethod - { - AfterPeriodOfTime = 1 << 0, - Start = 1 << 1, - Update = 1 << 2, - FixedUpdate = 1 << 3, - LateUpdate = 1 << 4, - OnDestroy = 1 << 5, - OnEnable = 1 << 6, - OnDisable = 1 << 7, - OnControllerColliderHit = 1 << 8, - OnParticleCollision = 1 << 9, - OnJointBreak = 1 << 10, - OnBecameInvisible = 1 << 11, - OnBecameVisible = 1 << 12, - OnTriggerEnter = 1 << 13, - OnTriggerExit = 1 << 14, - OnTriggerStay = 1 << 15, - OnCollisionEnter = 1 << 16, - OnCollisionExit = 1 << 17, - OnCollisionStay = 1 << 18, - OnTriggerEnter2D = 1 << 19, - OnTriggerExit2D = 1 << 20, - OnTriggerStay2D = 1 << 21, - OnCollisionEnter2D = 1 << 22, - OnCollisionExit2D = 1 << 23, - OnCollisionStay2D = 1 << 24, - } -} diff --git a/Assets/UnityTestTools/Assertions/CheckMethod.cs.meta b/Assets/UnityTestTools/Assertions/CheckMethod.cs.meta deleted file mode 100644 index d3f6ec9d..00000000 --- a/Assets/UnityTestTools/Assertions/CheckMethod.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: cbb75d1643c5a55439f8861a827f411b -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Assertions/Comparers.meta b/Assets/UnityTestTools/Assertions/Comparers.meta deleted file mode 100644 index 15d3a928..00000000 --- a/Assets/UnityTestTools/Assertions/Comparers.meta +++ /dev/null @@ -1,5 +0,0 @@ -fileFormatVersion: 2 -guid: bb9e10c25f478c84f826ea85b03ec179 -folderAsset: yes -DefaultImporter: - userData: diff --git a/Assets/UnityTestTools/Assertions/Comparers/ActionBase.cs b/Assets/UnityTestTools/Assertions/Comparers/ActionBase.cs deleted file mode 100644 index a73e0e25..00000000 --- a/Assets/UnityTestTools/Assertions/Comparers/ActionBase.cs +++ /dev/null @@ -1,121 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using UnityEngine; - -namespace UnityTest -{ - public abstract class ActionBase : ScriptableObject - { - public GameObject go; - protected object m_ObjVal; - - private MemberResolver m_MemberResolver; - - public string thisPropertyPath = ""; - public virtual Type[] GetAccepatbleTypesForA() - { - return null; - } - public virtual int GetDepthOfSearch() { return 2; } - - public virtual string[] GetExcludedFieldNames() - { - return new string[] { }; - } - - public bool Compare() - { - if (m_MemberResolver == null) - m_MemberResolver = new MemberResolver(go, thisPropertyPath); - m_ObjVal = m_MemberResolver.GetValue(UseCache); - var result = Compare(m_ObjVal); - return result; - } - - protected abstract bool Compare(object objVal); - - virtual protected bool UseCache { get { return false; } } - - public virtual Type GetParameterType() { return typeof(object); } - - public virtual string GetConfigurationDescription() - { - string result = ""; -#if !UNITY_METRO - foreach (var prop in GetType().GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly) - .Where(info => info.FieldType.IsSerializable)) - { - var value = prop.GetValue(this); - if (value is double) - value = ((double)value).ToString("0.########"); - if (value is float) - value = ((float)value).ToString("0.########"); - result += value + " "; - } -#endif // if !UNITY_METRO - return result; - } - - IEnumerable GetFields(Type type) - { -#if !UNITY_METRO - return type.GetFields(BindingFlags.Public | BindingFlags.Instance); -#else - return null; -#endif - } - - public ActionBase CreateCopy(GameObject oldGameObject, GameObject newGameObject) - { -#if !UNITY_METRO - var newObj = CreateInstance(GetType()) as ActionBase; -#else - var newObj = (ActionBase) this.MemberwiseClone(); -#endif - var fields = GetFields(GetType()); - foreach (var field in fields) - { - var value = field.GetValue(this); - if (value is GameObject) - { - if (value as GameObject == oldGameObject) - value = newGameObject; - } - field.SetValue(newObj, value); - } - return newObj; - } - - public virtual void Fail(AssertionComponent assertion) - { - Debug.LogException(new AssertionException(assertion), assertion.GetFailureReferenceObject()); - } - - public virtual string GetFailureMessage() - { - return GetType().Name + " assertion failed.\n(" + go + ")." + thisPropertyPath + " failed. Value: " + m_ObjVal; - } - } - - public abstract class ActionBaseGeneric : ActionBase - { - protected override bool Compare(object objVal) - { - return Compare((T)objVal); - } - protected abstract bool Compare(T objVal); - - public override Type[] GetAccepatbleTypesForA() - { - return new[] { typeof(T) }; - } - - public override Type GetParameterType() - { - return typeof(T); - } - protected override bool UseCache { get { return true; } } - } -} diff --git a/Assets/UnityTestTools/Assertions/Comparers/ActionBase.cs.meta b/Assets/UnityTestTools/Assertions/Comparers/ActionBase.cs.meta deleted file mode 100644 index 6d4c3ab0..00000000 --- a/Assets/UnityTestTools/Assertions/Comparers/ActionBase.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: b4995756bd539804e8143ff1e730f806 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Assertions/Comparers/BoolComparer.cs b/Assets/UnityTestTools/Assertions/Comparers/BoolComparer.cs deleted file mode 100644 index 3987cc27..00000000 --- a/Assets/UnityTestTools/Assertions/Comparers/BoolComparer.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace UnityTest -{ - public class BoolComparer : ComparerBaseGeneric - { - protected override bool Compare(bool a, bool b) - { - return a == b; - } - } -} diff --git a/Assets/UnityTestTools/Assertions/Comparers/BoolComparer.cs.meta b/Assets/UnityTestTools/Assertions/Comparers/BoolComparer.cs.meta deleted file mode 100644 index 7ee21b60..00000000 --- a/Assets/UnityTestTools/Assertions/Comparers/BoolComparer.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 2586c8e41f35d2f4fadde53020bf4207 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Assertions/Comparers/ColliderComparer.cs b/Assets/UnityTestTools/Assertions/Comparers/ColliderComparer.cs deleted file mode 100644 index cfca05df..00000000 --- a/Assets/UnityTestTools/Assertions/Comparers/ColliderComparer.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace UnityTest -{ - public class ColliderComparer : ComparerBaseGeneric - { - public enum CompareType - { - Intersects, - DoesNotIntersect - }; - - public CompareType compareType; - - protected override bool Compare(Bounds a, Bounds b) - { - switch (compareType) - { - case CompareType.Intersects: - return a.Intersects(b); - case CompareType.DoesNotIntersect: - return !a.Intersects(b); - } - throw new Exception(); - } - } -} diff --git a/Assets/UnityTestTools/Assertions/Comparers/ColliderComparer.cs.meta b/Assets/UnityTestTools/Assertions/Comparers/ColliderComparer.cs.meta deleted file mode 100644 index ab3aa477..00000000 --- a/Assets/UnityTestTools/Assertions/Comparers/ColliderComparer.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 4eff45b2ac4067b469d7994298341db6 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Assertions/Comparers/ComparerBase.cs b/Assets/UnityTestTools/Assertions/Comparers/ComparerBase.cs deleted file mode 100644 index db902118..00000000 --- a/Assets/UnityTestTools/Assertions/Comparers/ComparerBase.cs +++ /dev/null @@ -1,145 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; -using Object = System.Object; - -namespace UnityTest -{ - public abstract class ComparerBase : ActionBase - { - public enum CompareToType - { - CompareToObject, - CompareToConstantValue, - CompareToNull - } - - public CompareToType compareToType = CompareToType.CompareToObject; - - public GameObject other; - protected object m_ObjOtherVal; - public string otherPropertyPath = ""; - private MemberResolver m_MemberResolverB; - - protected abstract bool Compare(object a, object b); - - protected override bool Compare(object objValue) - { - if (compareToType == CompareToType.CompareToConstantValue) - { - m_ObjOtherVal = ConstValue; - } - else if (compareToType == CompareToType.CompareToNull) - { - m_ObjOtherVal = null; - } - else - { - if (other == null) - m_ObjOtherVal = null; - else - { - if (m_MemberResolverB == null) - m_MemberResolverB = new MemberResolver(other, otherPropertyPath); - m_ObjOtherVal = m_MemberResolverB.GetValue(UseCache); - } - } - return Compare(objValue, m_ObjOtherVal); - } - - public virtual Type[] GetAccepatbleTypesForB() - { - return null; - } - - #region Const value - - public virtual object ConstValue { get; set; } - public virtual object GetDefaultConstValue() - { - throw new NotImplementedException(); - } - - #endregion - - public override string GetFailureMessage() - { - var message = GetType().Name + " assertion failed.\n" + go.name + "." + thisPropertyPath + " " + compareToType; - switch (compareToType) - { - case CompareToType.CompareToObject: - message += " (" + other + ")." + otherPropertyPath + " failed."; - break; - case CompareToType.CompareToConstantValue: - message += " " + ConstValue + " failed."; - break; - case CompareToType.CompareToNull: - message += " failed."; - break; - } - message += " Expected: " + m_ObjOtherVal + " Actual: " + m_ObjVal; - return message; - } - } - - [Serializable] - public abstract class ComparerBaseGeneric : ComparerBaseGeneric - { - } - - [Serializable] - public abstract class ComparerBaseGeneric : ComparerBase - { - public T2 constantValueGeneric = default(T2); - - public override Object ConstValue - { - get - { - return constantValueGeneric; - } - set - { - constantValueGeneric = (T2)value; - } - } - - public override Object GetDefaultConstValue() - { - return default(T2); - } - - static bool IsValueType(Type type) - { -#if !UNITY_METRO - return type.IsValueType; -#else - return false; -#endif - } - - protected override bool Compare(object a, object b) - { - var type = typeof(T2); - if (b == null && IsValueType(type)) - { - throw new ArgumentException("Null was passed to a value-type argument"); - } - return Compare((T1)a, (T2)b); - } - - protected abstract bool Compare(T1 a, T2 b); - - public override Type[] GetAccepatbleTypesForA() - { - return new[] { typeof(T1) }; - } - - public override Type[] GetAccepatbleTypesForB() - { - return new[] {typeof(T2)}; - } - - protected override bool UseCache { get { return true; } } - } -} diff --git a/Assets/UnityTestTools/Assertions/Comparers/ComparerBase.cs.meta b/Assets/UnityTestTools/Assertions/Comparers/ComparerBase.cs.meta deleted file mode 100644 index 65909eb9..00000000 --- a/Assets/UnityTestTools/Assertions/Comparers/ComparerBase.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: c86508f389d643b40b6e1d7dcc1d4df2 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Assertions/Comparers/FloatComparer.cs b/Assets/UnityTestTools/Assertions/Comparers/FloatComparer.cs deleted file mode 100644 index ce0a2c24..00000000 --- a/Assets/UnityTestTools/Assertions/Comparers/FloatComparer.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace UnityTest -{ - public class FloatComparer : ComparerBaseGeneric - { - public enum CompareTypes - { - Equal, - NotEqual, - Greater, - Less - } - - public CompareTypes compareTypes; - public double floatingPointError = 0.0001f; - - protected override bool Compare(float a, float b) - { - switch (compareTypes) - { - case CompareTypes.Equal: - return Math.Abs(a - b) < floatingPointError; - case CompareTypes.NotEqual: - return Math.Abs(a - b) > floatingPointError; - case CompareTypes.Greater: - return a > b; - case CompareTypes.Less: - return a < b; - } - throw new Exception(); - } - public override int GetDepthOfSearch() - { - return 3; - } - } -} diff --git a/Assets/UnityTestTools/Assertions/Comparers/FloatComparer.cs.meta b/Assets/UnityTestTools/Assertions/Comparers/FloatComparer.cs.meta deleted file mode 100644 index 07353adf..00000000 --- a/Assets/UnityTestTools/Assertions/Comparers/FloatComparer.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: a4928c6c2b973874c8d4e6c9a69bb5b4 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Assertions/Comparers/GeneralComparer.cs b/Assets/UnityTestTools/Assertions/Comparers/GeneralComparer.cs deleted file mode 100644 index 96892aa6..00000000 --- a/Assets/UnityTestTools/Assertions/Comparers/GeneralComparer.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace UnityTest -{ - public class GeneralComparer : ComparerBase - { - public enum CompareType { AEqualsB, ANotEqualsB } - - public CompareType compareType; - - protected override bool Compare(object a, object b) - { - if (compareType == CompareType.AEqualsB) - return a.Equals(b); - if (compareType == CompareType.ANotEqualsB) - return !a.Equals(b); - throw new Exception(); - } - } -} diff --git a/Assets/UnityTestTools/Assertions/Comparers/GeneralComparer.cs.meta b/Assets/UnityTestTools/Assertions/Comparers/GeneralComparer.cs.meta deleted file mode 100644 index 6b7edb32..00000000 --- a/Assets/UnityTestTools/Assertions/Comparers/GeneralComparer.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 902961c69f102f4409c29b9e54258701 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Assertions/Comparers/IntComparer.cs b/Assets/UnityTestTools/Assertions/Comparers/IntComparer.cs deleted file mode 100644 index 25c43aad..00000000 --- a/Assets/UnityTestTools/Assertions/Comparers/IntComparer.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace UnityTest -{ - public class IntComparer : ComparerBaseGeneric - { - public enum CompareType - { - Equal, - NotEqual, - Greater, - GreaterOrEqual, - Less, - LessOrEqual - }; - - public CompareType compareType; - - protected override bool Compare(int a, int b) - { - switch (compareType) - { - case CompareType.Equal: - return a == b; - case CompareType.NotEqual: - return a != b; - case CompareType.Greater: - return a > b; - case CompareType.GreaterOrEqual: - return a >= b; - case CompareType.Less: - return a < b; - case CompareType.LessOrEqual: - return a <= b; - } - throw new Exception(); - } - } -} diff --git a/Assets/UnityTestTools/Assertions/Comparers/IntComparer.cs.meta b/Assets/UnityTestTools/Assertions/Comparers/IntComparer.cs.meta deleted file mode 100644 index 64f4fc3e..00000000 --- a/Assets/UnityTestTools/Assertions/Comparers/IntComparer.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: da4a3a521c5c1494aae123742ca5c8f5 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Assertions/Comparers/IsRenderedByCamera.cs b/Assets/UnityTestTools/Assertions/Comparers/IsRenderedByCamera.cs deleted file mode 100644 index bc5d370e..00000000 --- a/Assets/UnityTestTools/Assertions/Comparers/IsRenderedByCamera.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace UnityTest -{ - public class IsRenderedByCamera : ComparerBaseGeneric - { - public enum CompareType - { - IsVisible, - IsNotVisible, - }; - - public CompareType compareType; - - protected override bool Compare(Renderer renderer, Camera camera) - { - var planes = GeometryUtility.CalculateFrustumPlanes(camera); - var isVisible = GeometryUtility.TestPlanesAABB(planes, renderer.bounds); - switch (compareType) - { - case CompareType.IsVisible: - return isVisible; - case CompareType.IsNotVisible: - return !isVisible; - } - throw new Exception(); - } - } -} diff --git a/Assets/UnityTestTools/Assertions/Comparers/IsRenderedByCamera.cs.meta b/Assets/UnityTestTools/Assertions/Comparers/IsRenderedByCamera.cs.meta deleted file mode 100644 index 9cfc1f22..00000000 --- a/Assets/UnityTestTools/Assertions/Comparers/IsRenderedByCamera.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 8d45a1674f5e2e04485eafef922fac41 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Assertions/Comparers/StringComparer.cs b/Assets/UnityTestTools/Assertions/Comparers/StringComparer.cs deleted file mode 100644 index 398f3e9f..00000000 --- a/Assets/UnityTestTools/Assertions/Comparers/StringComparer.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace UnityTest -{ - public class StringComparer : ComparerBaseGeneric - { - public enum CompareType - { - Equal, - NotEqual, - Shorter, - Longer - } - - public CompareType compareType; - public StringComparison comparisonType = StringComparison.Ordinal; - public bool ignoreCase = false; - - protected override bool Compare(string a, string b) - { - if (ignoreCase) - { - a = a.ToLower(); - b = b.ToLower(); - } - switch (compareType) - { - case CompareType.Equal: - return String.Compare(a, b, comparisonType) == 0; - case CompareType.NotEqual: - return String.Compare(a, b, comparisonType) != 0; - case CompareType.Longer: - return String.Compare(a, b, comparisonType) > 0; - case CompareType.Shorter: - return String.Compare(a, b, comparisonType) < 0; - } - throw new Exception(); - } - } -} diff --git a/Assets/UnityTestTools/Assertions/Comparers/StringComparer.cs.meta b/Assets/UnityTestTools/Assertions/Comparers/StringComparer.cs.meta deleted file mode 100644 index a414f61c..00000000 --- a/Assets/UnityTestTools/Assertions/Comparers/StringComparer.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 58783f051e477fd4e93b42ec7a43bb64 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Assertions/Comparers/TransformComparer.cs b/Assets/UnityTestTools/Assertions/Comparers/TransformComparer.cs deleted file mode 100644 index 5221c032..00000000 --- a/Assets/UnityTestTools/Assertions/Comparers/TransformComparer.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace UnityTest -{ - public class TransformComparer : ComparerBaseGeneric - { - public enum CompareType { Equals, NotEquals } - - public CompareType compareType; - - protected override bool Compare(Transform a, Transform b) - { - if (compareType == CompareType.Equals) - { - return a.position == b.position; - } - if (compareType == CompareType.NotEquals) - { - return a.position != b.position; - } - throw new Exception(); - } - } -} diff --git a/Assets/UnityTestTools/Assertions/Comparers/TransformComparer.cs.meta b/Assets/UnityTestTools/Assertions/Comparers/TransformComparer.cs.meta deleted file mode 100644 index f3d72e46..00000000 --- a/Assets/UnityTestTools/Assertions/Comparers/TransformComparer.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 927f2d7e4f63632448b2a63d480e601a -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Assertions/Comparers/ValueDoesNotChange.cs b/Assets/UnityTestTools/Assertions/Comparers/ValueDoesNotChange.cs deleted file mode 100644 index 49a3cc76..00000000 --- a/Assets/UnityTestTools/Assertions/Comparers/ValueDoesNotChange.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace UnityTest -{ - public class ValueDoesNotChange : ActionBase - { - private object m_Value; - - protected override bool Compare(object a) - { - if (m_Value == null) - m_Value = a; - if (!m_Value.Equals(a)) - return false; - return true; - } - } -} diff --git a/Assets/UnityTestTools/Assertions/Comparers/ValueDoesNotChange.cs.meta b/Assets/UnityTestTools/Assertions/Comparers/ValueDoesNotChange.cs.meta deleted file mode 100644 index b913d35d..00000000 --- a/Assets/UnityTestTools/Assertions/Comparers/ValueDoesNotChange.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 9d6d16a58a17940419a1dcbff3c60ca5 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Assertions/Comparers/Vector2Comparer.cs b/Assets/UnityTestTools/Assertions/Comparers/Vector2Comparer.cs deleted file mode 100644 index 345d76d1..00000000 --- a/Assets/UnityTestTools/Assertions/Comparers/Vector2Comparer.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace UnityTest -{ - public class Vector2Comparer : VectorComparerBase - { - public enum CompareType - { - MagnitudeEquals, - MagnitudeNotEquals - } - - public CompareType compareType; - public float floatingPointError = 0.0001f; - - protected override bool Compare(Vector2 a, Vector2 b) - { - switch (compareType) - { - case CompareType.MagnitudeEquals: - return AreVectorMagnitudeEqual(a.magnitude, - b.magnitude, floatingPointError); - case CompareType.MagnitudeNotEquals: - return !AreVectorMagnitudeEqual(a.magnitude, - b.magnitude, floatingPointError); - } - throw new Exception(); - } - public override int GetDepthOfSearch() - { - return 3; - } - } -} diff --git a/Assets/UnityTestTools/Assertions/Comparers/Vector2Comparer.cs.meta b/Assets/UnityTestTools/Assertions/Comparers/Vector2Comparer.cs.meta deleted file mode 100644 index 19ef5d2e..00000000 --- a/Assets/UnityTestTools/Assertions/Comparers/Vector2Comparer.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: a713db190443e814f8254a5a59014ec4 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Assertions/Comparers/Vector3Comparer.cs b/Assets/UnityTestTools/Assertions/Comparers/Vector3Comparer.cs deleted file mode 100644 index 56f0b5b9..00000000 --- a/Assets/UnityTestTools/Assertions/Comparers/Vector3Comparer.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace UnityTest -{ - public class Vector3Comparer : VectorComparerBase - { - public enum CompareType - { - MagnitudeEquals, - MagnitudeNotEquals - } - - public CompareType compareType; - public double floatingPointError = 0.0001f; - - protected override bool Compare(Vector3 a, Vector3 b) - { - switch (compareType) - { - case CompareType.MagnitudeEquals: - return AreVectorMagnitudeEqual(a.magnitude, - b.magnitude, floatingPointError); - case CompareType.MagnitudeNotEquals: - return !AreVectorMagnitudeEqual(a.magnitude, - b.magnitude, floatingPointError); - } - throw new Exception(); - } - } -} diff --git a/Assets/UnityTestTools/Assertions/Comparers/Vector3Comparer.cs.meta b/Assets/UnityTestTools/Assertions/Comparers/Vector3Comparer.cs.meta deleted file mode 100644 index b871f248..00000000 --- a/Assets/UnityTestTools/Assertions/Comparers/Vector3Comparer.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 6febd2d5046657040b3da98b7010ee29 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Assertions/Comparers/Vector4Comparer.cs b/Assets/UnityTestTools/Assertions/Comparers/Vector4Comparer.cs deleted file mode 100644 index 4eda0439..00000000 --- a/Assets/UnityTestTools/Assertions/Comparers/Vector4Comparer.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace UnityTest -{ - public class Vector4Comparer : VectorComparerBase - { - public enum CompareType - { - MagnitudeEquals, - MagnitudeNotEquals - } - - public CompareType compareType; - public double floatingPointError; - - protected override bool Compare(Vector4 a, Vector4 b) - { - switch (compareType) - { - case CompareType.MagnitudeEquals: - return AreVectorMagnitudeEqual(a.magnitude, - b.magnitude, - floatingPointError); - case CompareType.MagnitudeNotEquals: - return !AreVectorMagnitudeEqual(a.magnitude, - b.magnitude, - floatingPointError); - } - throw new Exception(); - } - public override int GetDepthOfSearch() - { - return 3; - } - } -} diff --git a/Assets/UnityTestTools/Assertions/Comparers/Vector4Comparer.cs.meta b/Assets/UnityTestTools/Assertions/Comparers/Vector4Comparer.cs.meta deleted file mode 100644 index 1e0314f2..00000000 --- a/Assets/UnityTestTools/Assertions/Comparers/Vector4Comparer.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 383a85a79f164d04b8a56b0ff4e04cb7 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Assertions/Comparers/VectorComparerBase.cs b/Assets/UnityTestTools/Assertions/Comparers/VectorComparerBase.cs deleted file mode 100644 index cb394dfb..00000000 --- a/Assets/UnityTestTools/Assertions/Comparers/VectorComparerBase.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace UnityTest -{ - public abstract class VectorComparerBase : ComparerBaseGeneric - { - protected bool AreVectorMagnitudeEqual(float a, float b, double floatingPointError) - { - if (Math.Abs(a) < floatingPointError && Math.Abs(b) < floatingPointError) - return true; - if (Math.Abs(a - b) < floatingPointError) - return true; - return false; - } - } -} diff --git a/Assets/UnityTestTools/Assertions/Comparers/VectorComparerBase.cs.meta b/Assets/UnityTestTools/Assertions/Comparers/VectorComparerBase.cs.meta deleted file mode 100644 index d4da9f79..00000000 --- a/Assets/UnityTestTools/Assertions/Comparers/VectorComparerBase.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 7b35a237804d5eb42bd8c4e67568ae24 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Assertions/Editor.meta b/Assets/UnityTestTools/Assertions/Editor.meta deleted file mode 100644 index 2fa5238d..00000000 --- a/Assets/UnityTestTools/Assertions/Editor.meta +++ /dev/null @@ -1,5 +0,0 @@ -fileFormatVersion: 2 -guid: a28bb39b4fb20514990895d9cb4eaea9 -folderAsset: yes -DefaultImporter: - userData: diff --git a/Assets/UnityTestTools/Assertions/Editor/AssertionComponentEditor.cs b/Assets/UnityTestTools/Assertions/Editor/AssertionComponentEditor.cs deleted file mode 100644 index a2736a72..00000000 --- a/Assets/UnityTestTools/Assertions/Editor/AssertionComponentEditor.cs +++ /dev/null @@ -1,226 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using UnityEditor; -using UnityEngine; -using UnityEditor.SceneManagement; - -namespace UnityTest -{ - [CustomEditor(typeof(AssertionComponent))] - public class AssertionComponentEditor : Editor - { - private readonly DropDownControl m_ComparerDropDown = new DropDownControl(); - - private readonly PropertyPathSelector m_ThisPathSelector = new PropertyPathSelector("Compare"); - private readonly PropertyPathSelector m_OtherPathSelector = new PropertyPathSelector("Compare to"); - - #region GUI Contents - private readonly GUIContent m_GUICheckAfterTimeGuiContent = new GUIContent("Check after (seconds)", "After how many seconds the assertion should be checked"); - private readonly GUIContent m_GUIRepeatCheckTimeGuiContent = new GUIContent("Repeat check", "Should the check be repeated."); - private readonly GUIContent m_GUIRepeatEveryTimeGuiContent = new GUIContent("Frequency of repetitions", "How often should the check be done"); - private readonly GUIContent m_GUICheckAfterFramesGuiContent = new GUIContent("Check after (frames)", "After how many frames the assertion should be checked"); - private readonly GUIContent m_GUIRepeatCheckFrameGuiContent = new GUIContent("Repeat check", "Should the check be repeated."); - #endregion - - private static List allComparersList = null; - - public AssertionComponentEditor() - { - m_ComparerDropDown.convertForButtonLabel = type => type.Name; - m_ComparerDropDown.convertForGUIContent = type => type.Name; - m_ComparerDropDown.ignoreConvertForGUIContent = types => false; - m_ComparerDropDown.tooltip = "Comparer that will be used to compare values and determine the result of assertion."; - } - - public override void OnInspectorGUI() - { - var script = (AssertionComponent)target; - EditorGUILayout.BeginHorizontal(); - var obj = DrawComparerSelection(script); - script.checkMethods = (CheckMethod)EditorGUILayout.EnumMaskField(script.checkMethods, - EditorStyles.popup, - GUILayout.ExpandWidth(false)); - EditorGUILayout.EndHorizontal(); - - if (script.IsCheckMethodSelected(CheckMethod.AfterPeriodOfTime)) - { - DrawOptionsForAfterPeriodOfTime(script); - } - - if (script.IsCheckMethodSelected(CheckMethod.Update)) - { - DrawOptionsForOnUpdate(script); - } - - if (obj) - { - EditorGUILayout.Space(); - - m_ThisPathSelector.Draw(script.Action.go, script.Action, - script.Action.thisPropertyPath, script.Action.GetAccepatbleTypesForA(), - go => - { - script.Action.go = go; - AssertionExplorerWindow.Reload(); - }, - s => - { - script.Action.thisPropertyPath = s; - AssertionExplorerWindow.Reload(); - }); - - EditorGUILayout.Space(); - - DrawCustomFields(script); - - EditorGUILayout.Space(); - - if (script.Action is ComparerBase) - { - DrawCompareToType(script.Action as ComparerBase); - } - } - if(GUI.changed) - EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene()); - } - - private void DrawOptionsForAfterPeriodOfTime(AssertionComponent script) - { - EditorGUILayout.Space(); - script.checkAfterTime = EditorGUILayout.FloatField(m_GUICheckAfterTimeGuiContent, - script.checkAfterTime); - if (script.checkAfterTime < 0) - script.checkAfterTime = 0; - script.repeatCheckTime = EditorGUILayout.Toggle(m_GUIRepeatCheckTimeGuiContent, - script.repeatCheckTime); - if (script.repeatCheckTime) - { - script.repeatEveryTime = EditorGUILayout.FloatField(m_GUIRepeatEveryTimeGuiContent, - script.repeatEveryTime); - if (script.repeatEveryTime < 0) - script.repeatEveryTime = 0; - } - } - - private void DrawOptionsForOnUpdate(AssertionComponent script) - { - EditorGUILayout.Space(); - script.checkAfterFrames = EditorGUILayout.IntField(m_GUICheckAfterFramesGuiContent, - script.checkAfterFrames); - if (script.checkAfterFrames < 1) - script.checkAfterFrames = 1; - script.repeatCheckFrame = EditorGUILayout.Toggle(m_GUIRepeatCheckFrameGuiContent, - script.repeatCheckFrame); - if (script.repeatCheckFrame) - { - script.repeatEveryFrame = EditorGUILayout.IntField(m_GUIRepeatEveryTimeGuiContent, - script.repeatEveryFrame); - if (script.repeatEveryFrame < 1) - script.repeatEveryFrame = 1; - } - } - - private void DrawCompareToType(ComparerBase comparer) - { - comparer.compareToType = (ComparerBase.CompareToType)EditorGUILayout.EnumPopup("Compare to type", - comparer.compareToType, - EditorStyles.popup); - - if (comparer.compareToType == ComparerBase.CompareToType.CompareToConstantValue) - { - try - { - DrawConstCompareField(comparer); - } - catch (NotImplementedException) - { - Debug.LogWarning("This comparer can't compare to static value"); - comparer.compareToType = ComparerBase.CompareToType.CompareToObject; - } - } - else if (comparer.compareToType == ComparerBase.CompareToType.CompareToObject) - { - DrawObjectCompareField(comparer); - } - } - - private void DrawObjectCompareField(ComparerBase comparer) - { - m_OtherPathSelector.Draw(comparer.other, comparer, - comparer.otherPropertyPath, comparer.GetAccepatbleTypesForB(), - go => - { - comparer.other = go; - AssertionExplorerWindow.Reload(); - }, - s => - { - comparer.otherPropertyPath = s; - AssertionExplorerWindow.Reload(); - } - ); - } - - private void DrawConstCompareField(ComparerBase comparer) - { - if (comparer.ConstValue == null) - { - comparer.ConstValue = comparer.GetDefaultConstValue(); - } - - var so = new SerializedObject(comparer); - var sp = so.FindProperty("constantValueGeneric"); - if (sp != null) - { - EditorGUILayout.PropertyField(sp, new GUIContent("Constant"), true); - so.ApplyModifiedProperties(); - } - } - - private bool DrawComparerSelection(AssertionComponent script) - { - if(allComparersList == null) - { - allComparersList = new List(); - var allAssemblies = AppDomain.CurrentDomain.GetAssemblies(); - foreach (var assembly in allAssemblies) - { - var types = assembly.GetTypes(); - allComparersList.AddRange(types.Where(type => type.IsSubclassOf(typeof(ActionBase)) && !type.IsAbstract)); - } - } - var allComparers = allComparersList.ToArray(); - - if (script.Action == null) - script.Action = (ActionBase)CreateInstance(allComparers.First()); - - m_ComparerDropDown.Draw(script.Action.GetType(), allComparers, - type => - { - if (script.Action == null || script.Action.GetType().Name != type.Name) - { - script.Action = (ActionBase)CreateInstance(type); - AssertionExplorerWindow.Reload(); - } - }); - - return script.Action != null; - } - - private void DrawCustomFields(AssertionComponent script) - { - foreach (var prop in script.Action.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) - { - var so = new SerializedObject(script.Action); - var sp = so.FindProperty(prop.Name); - if (sp != null) - { - EditorGUILayout.PropertyField(sp, true); - so.ApplyModifiedProperties(); - } - } - } - } -} diff --git a/Assets/UnityTestTools/Assertions/Editor/AssertionComponentEditor.cs.meta b/Assets/UnityTestTools/Assertions/Editor/AssertionComponentEditor.cs.meta deleted file mode 100644 index eb4174d2..00000000 --- a/Assets/UnityTestTools/Assertions/Editor/AssertionComponentEditor.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: fd1cabf2c45d0a8489635607a6048621 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Assertions/Editor/AssertionExplorerWindow.cs b/Assets/UnityTestTools/Assertions/Editor/AssertionExplorerWindow.cs deleted file mode 100644 index ecd7fdaf..00000000 --- a/Assets/UnityTestTools/Assertions/Editor/AssertionExplorerWindow.cs +++ /dev/null @@ -1,194 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEditor; -using UnityEngine; - -#if UNITY_METRO -#warning Assertion component is not supported on Windows Store apps -#endif - -namespace UnityTest -{ - [Serializable] - public class AssertionExplorerWindow : EditorWindow - { - private List m_AllAssertions = new List(); - [SerializeField] - private string m_FilterText = ""; - [SerializeField] - private FilterType m_FilterType; - [SerializeField] - private List m_FoldMarkers = new List(); - [SerializeField] - private GroupByType m_GroupBy; - [SerializeField] - private Vector2 m_ScrollPosition = Vector2.zero; - private DateTime m_NextReload = DateTime.Now; - [SerializeField] - private static bool s_ShouldReload; - [SerializeField] - private ShowType m_ShowType; - - public AssertionExplorerWindow() - { - titleContent = new GUIContent("Assertion Explorer"); - } - - public void OnDidOpenScene() - { - ReloadAssertionList(); - } - - public void OnFocus() - { - ReloadAssertionList(); - } - - private void ReloadAssertionList() - { - m_NextReload = DateTime.Now.AddSeconds(1); - s_ShouldReload = true; - } - - public void OnHierarchyChange() - { - ReloadAssertionList(); - } - - public void OnInspectorUpdate() - { - if (s_ShouldReload && m_NextReload < DateTime.Now) - { - s_ShouldReload = false; - m_AllAssertions = new List((AssertionComponent[])Resources.FindObjectsOfTypeAll(typeof(AssertionComponent))); - Repaint(); - } - } - - public void OnGUI() - { - DrawMenuPanel(); - - m_ScrollPosition = EditorGUILayout.BeginScrollView(m_ScrollPosition); - if (m_AllAssertions != null) - GetResultRendere().Render(FilterResults(m_AllAssertions, m_FilterText.ToLower()), m_FoldMarkers); - EditorGUILayout.EndScrollView(); - } - - private IEnumerable FilterResults(List assertionComponents, string text) - { - if (m_ShowType == ShowType.ShowDisabled) - assertionComponents = assertionComponents.Where(c => !c.enabled).ToList(); - else if (m_ShowType == ShowType.ShowEnabled) - assertionComponents = assertionComponents.Where(c => c.enabled).ToList(); - - if (string.IsNullOrEmpty(text)) - return assertionComponents; - - switch (m_FilterType) - { - case FilterType.ComparerName: - return assertionComponents.Where(c => c.Action.GetType().Name.ToLower().Contains(text)); - case FilterType.AttachedGameObject: - return assertionComponents.Where(c => c.gameObject.name.ToLower().Contains(text)); - case FilterType.FirstComparedGameObjectPath: - return assertionComponents.Where(c => c.Action.thisPropertyPath.ToLower().Contains(text)); - case FilterType.FirstComparedGameObject: - return assertionComponents.Where(c => c.Action.go != null - && c.Action.go.name.ToLower().Contains(text)); - case FilterType.SecondComparedGameObjectPath: - return assertionComponents.Where(c => - c.Action is ComparerBase - && (c.Action as ComparerBase).otherPropertyPath.ToLower().Contains(text)); - case FilterType.SecondComparedGameObject: - return assertionComponents.Where(c => - c.Action is ComparerBase - && (c.Action as ComparerBase).other != null - && (c.Action as ComparerBase).other.name.ToLower().Contains(text)); - default: - return assertionComponents; - } - } - - private readonly IListRenderer m_GroupByComparerRenderer = new GroupByComparerRenderer(); - private readonly IListRenderer m_GroupByExecutionMethodRenderer = new GroupByExecutionMethodRenderer(); - private readonly IListRenderer m_GroupByGoRenderer = new GroupByGoRenderer(); - private readonly IListRenderer m_GroupByTestsRenderer = new GroupByTestsRenderer(); - private readonly IListRenderer m_GroupByNothingRenderer = new GroupByNothingRenderer(); - - private IListRenderer GetResultRendere() - { - switch (m_GroupBy) - { - case GroupByType.Comparer: - return m_GroupByComparerRenderer; - case GroupByType.ExecutionMethod: - return m_GroupByExecutionMethodRenderer; - case GroupByType.GameObjects: - return m_GroupByGoRenderer; - case GroupByType.Tests: - return m_GroupByTestsRenderer; - default: - return m_GroupByNothingRenderer; - } - } - - private void DrawMenuPanel() - { - EditorGUILayout.BeginHorizontal(EditorStyles.toolbar); - EditorGUILayout.LabelField("Group by:", Styles.toolbarLabel, GUILayout.MaxWidth(60)); - m_GroupBy = (GroupByType)EditorGUILayout.EnumPopup(m_GroupBy, EditorStyles.toolbarPopup, GUILayout.MaxWidth(150)); - - GUILayout.FlexibleSpace(); - - m_ShowType = (ShowType)EditorGUILayout.EnumPopup(m_ShowType, EditorStyles.toolbarPopup, GUILayout.MaxWidth(100)); - - EditorGUILayout.LabelField("Filter by:", Styles.toolbarLabel, GUILayout.MaxWidth(50)); - m_FilterType = (FilterType)EditorGUILayout.EnumPopup(m_FilterType, EditorStyles.toolbarPopup, GUILayout.MaxWidth(100)); - m_FilterText = GUILayout.TextField(m_FilterText, "ToolbarSeachTextField", GUILayout.MaxWidth(100)); - if (GUILayout.Button(GUIContent.none, string.IsNullOrEmpty(m_FilterText) ? "ToolbarSeachCancelButtonEmpty" : "ToolbarSeachCancelButton", GUILayout.ExpandWidth(false))) - m_FilterText = ""; - EditorGUILayout.EndHorizontal(); - } - - [MenuItem("Unity Test Tools/Assertion Explorer")] - public static AssertionExplorerWindow ShowWindow() - { - var w = GetWindow(typeof(AssertionExplorerWindow)); - w.Show(); - return w as AssertionExplorerWindow; - } - - private enum FilterType - { - ComparerName, - FirstComparedGameObject, - FirstComparedGameObjectPath, - SecondComparedGameObject, - SecondComparedGameObjectPath, - AttachedGameObject - } - - private enum ShowType - { - ShowAll, - ShowEnabled, - ShowDisabled - } - - private enum GroupByType - { - Nothing, - Comparer, - GameObjects, - ExecutionMethod, - Tests - } - - public static void Reload() - { - s_ShouldReload = true; - } - } -} diff --git a/Assets/UnityTestTools/Assertions/Editor/AssertionExplorerWindow.cs.meta b/Assets/UnityTestTools/Assertions/Editor/AssertionExplorerWindow.cs.meta deleted file mode 100644 index f5591ab4..00000000 --- a/Assets/UnityTestTools/Assertions/Editor/AssertionExplorerWindow.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 1a1e855053e7e2f46ace1dc93f2036f2 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Assertions/Editor/AssertionListRenderer.cs b/Assets/UnityTestTools/Assertions/Editor/AssertionListRenderer.cs deleted file mode 100644 index 31e1b1e5..00000000 --- a/Assets/UnityTestTools/Assertions/Editor/AssertionListRenderer.cs +++ /dev/null @@ -1,251 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEditor; -using UnityEngine; - -namespace UnityTest -{ - public interface IListRenderer - { - void Render(IEnumerable allAssertions, List foldMarkers); - } - - public abstract class AssertionListRenderer : IListRenderer - { - private static class Styles - { - public static readonly GUIStyle redLabel; - static Styles() - { - redLabel = new GUIStyle(EditorStyles.label); - redLabel.normal.textColor = Color.red; - } - } - - public void Render(IEnumerable allAssertions, List foldMarkers) - { - foreach (var grouping in GroupResult(allAssertions)) - { - var key = GetStringKey(grouping.Key); - bool isFolded = foldMarkers.Contains(key); - if (key != "") - { - EditorGUILayout.BeginHorizontal(); - - EditorGUI.BeginChangeCheck(); - isFolded = PrintFoldout(isFolded, - grouping.Key); - if (EditorGUI.EndChangeCheck()) - { - if (isFolded) - foldMarkers.Add(key); - else - foldMarkers.Remove(key); - } - EditorGUILayout.EndHorizontal(); - if (isFolded) - continue; - } - foreach (var assertionComponent in grouping) - { - EditorGUILayout.BeginVertical(); - EditorGUILayout.BeginHorizontal(); - - if (key != "") - GUILayout.Space(15); - - var assertionKey = assertionComponent.GetHashCode().ToString(); - bool isDetailsFolded = foldMarkers.Contains(assertionKey); - - EditorGUI.BeginChangeCheck(); - if (GUILayout.Button("", - EditorStyles.foldout, - GUILayout.Width(15))) - { - isDetailsFolded = !isDetailsFolded; - } - if (EditorGUI.EndChangeCheck()) - { - if (isDetailsFolded) - foldMarkers.Add(assertionKey); - else - foldMarkers.Remove(assertionKey); - } - PrintFoldedAssertionLine(assertionComponent); - EditorGUILayout.EndHorizontal(); - - if (isDetailsFolded) - { - EditorGUILayout.BeginHorizontal(); - if (key != "") - GUILayout.Space(15); - PrintAssertionLineDetails(assertionComponent); - EditorGUILayout.EndHorizontal(); - } - GUILayout.Box("", new[] {GUILayout.ExpandWidth(true), GUILayout.Height(1)}); - - EditorGUILayout.EndVertical(); - } - } - } - - protected abstract IEnumerable> GroupResult(IEnumerable assertionComponents); - - protected virtual string GetStringKey(T key) - { - return key.GetHashCode().ToString(); - } - - protected virtual bool PrintFoldout(bool isFolded, T key) - { - var content = new GUIContent(GetFoldoutDisplayName(key)); - var size = EditorStyles.foldout.CalcSize(content); - - var rect = GUILayoutUtility.GetRect(content, - EditorStyles.foldout, - GUILayout.MaxWidth(size.x)); - var res = EditorGUI.Foldout(rect, - !isFolded, - content, - true); - - return !res; - } - - protected virtual string GetFoldoutDisplayName(T key) - { - return key.ToString(); - } - - protected virtual void PrintFoldedAssertionLine(AssertionComponent assertionComponent) - { - EditorGUILayout.BeginHorizontal(); - - EditorGUILayout.BeginVertical(GUILayout.MaxWidth(300)); - EditorGUILayout.BeginHorizontal(GUILayout.MaxWidth(300)); - PrintPath(assertionComponent.Action.go, - assertionComponent.Action.thisPropertyPath); - EditorGUILayout.EndHorizontal(); - EditorGUILayout.EndVertical(); - - EditorGUILayout.BeginVertical(GUILayout.MaxWidth(250)); - var labelStr = assertionComponent.Action.GetType().Name; - var labelStr2 = assertionComponent.Action.GetConfigurationDescription(); - if (labelStr2 != "") - labelStr += "( " + labelStr2 + ")"; - EditorGUILayout.LabelField(labelStr); - EditorGUILayout.EndVertical(); - - if (assertionComponent.Action is ComparerBase) - { - var comparer = assertionComponent.Action as ComparerBase; - - var otherStrVal = "(no value selected)"; - EditorGUILayout.BeginVertical(); - EditorGUILayout.BeginHorizontal(GUILayout.MaxWidth(300)); - switch (comparer.compareToType) - { - case ComparerBase.CompareToType.CompareToObject: - if (comparer.other != null) - { - PrintPath(comparer.other, - comparer.otherPropertyPath); - } - else - { - EditorGUILayout.LabelField(otherStrVal, - Styles.redLabel); - } - break; - case ComparerBase.CompareToType.CompareToConstantValue: - otherStrVal = comparer.ConstValue.ToString(); - EditorGUILayout.LabelField(otherStrVal); - break; - case ComparerBase.CompareToType.CompareToNull: - otherStrVal = "null"; - EditorGUILayout.LabelField(otherStrVal); - break; - } - EditorGUILayout.EndHorizontal(); - EditorGUILayout.EndVertical(); - } - else - { - EditorGUILayout.LabelField(""); - } - EditorGUILayout.EndHorizontal(); - EditorGUILayout.Space(); - } - - protected virtual void PrintAssertionLineDetails(AssertionComponent assertionComponent) - { - EditorGUILayout.BeginHorizontal(); - - - EditorGUILayout.BeginVertical(GUILayout.MaxWidth(320)); - EditorGUILayout.BeginHorizontal(); - EditorGUILayout.LabelField("Attached to", - GUILayout.Width(70)); - var sss = EditorStyles.objectField.CalcSize(new GUIContent(assertionComponent.gameObject.name)); - EditorGUILayout.ObjectField(assertionComponent.gameObject, - typeof(GameObject), - true, - GUILayout.Width(sss.x)); - EditorGUILayout.EndHorizontal(); - EditorGUILayout.EndVertical(); - - - EditorGUILayout.BeginVertical(GUILayout.MaxWidth(250)); - EditorGUILayout.EnumMaskField(assertionComponent.checkMethods, - EditorStyles.popup, - GUILayout.MaxWidth(150)); - EditorGUILayout.EndVertical(); - - - EditorGUILayout.BeginVertical(); - EditorGUILayout.BeginHorizontal(); - EditorGUILayout.LabelField("Disabled", - GUILayout.Width(55)); - assertionComponent.enabled = !EditorGUILayout.Toggle(!assertionComponent.enabled, - GUILayout.Width(15)); - EditorGUILayout.EndHorizontal(); - EditorGUILayout.EndVertical(); - - EditorGUILayout.EndHorizontal(); - } - - private void PrintPath(GameObject go, string propertyPath) - { - string contentString = ""; - GUIStyle styleThisPath = EditorStyles.label; - if (go != null) - { - var sss = EditorStyles.objectField.CalcSize(new GUIContent(go.name)); - EditorGUILayout.ObjectField( - go, - typeof(GameObject), - true, - GUILayout.Width(sss.x)); - - if (!string.IsNullOrEmpty(propertyPath)) - contentString = "." + propertyPath; - } - else - { - contentString = "(no value selected)"; - styleThisPath = Styles.redLabel; - } - - var content = new GUIContent(contentString, - contentString); - var rect = GUILayoutUtility.GetRect(content, - EditorStyles.label, - GUILayout.MaxWidth(200)); - - EditorGUI.LabelField(rect, - content, - styleThisPath); - } - } -} diff --git a/Assets/UnityTestTools/Assertions/Editor/AssertionListRenderer.cs.meta b/Assets/UnityTestTools/Assertions/Editor/AssertionListRenderer.cs.meta deleted file mode 100644 index 8e6a0d45..00000000 --- a/Assets/UnityTestTools/Assertions/Editor/AssertionListRenderer.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: d83c02fb0f220344da42a8213ed36cb5 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Assertions/Editor/AssertionStripper.cs b/Assets/UnityTestTools/Assertions/Editor/AssertionStripper.cs deleted file mode 100644 index 1b6bd04d..00000000 --- a/Assets/UnityTestTools/Assertions/Editor/AssertionStripper.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEditor.Callbacks; -using UnityEngine; -using UnityTest; -using Object = UnityEngine.Object; - -public class AssertionStripper -{ - [PostProcessScene] - public static void OnPostprocessScene() - { - if (Debug.isDebugBuild) return; - RemoveAssertionsFromGameObjects(); - } - - private static void RemoveAssertionsFromGameObjects() - { - var allAssertions = Resources.FindObjectsOfTypeAll(typeof(AssertionComponent)) as AssertionComponent[]; - foreach (var assertion in allAssertions) - { - Object.DestroyImmediate(assertion); - } - } -} diff --git a/Assets/UnityTestTools/Assertions/Editor/AssertionStripper.cs.meta b/Assets/UnityTestTools/Assertions/Editor/AssertionStripper.cs.meta deleted file mode 100644 index bf18bbed..00000000 --- a/Assets/UnityTestTools/Assertions/Editor/AssertionStripper.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 95c9cd9570a6fba4198b6e4f15e11e5e -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Assertions/Editor/DropDownControl.cs b/Assets/UnityTestTools/Assertions/Editor/DropDownControl.cs deleted file mode 100644 index 79804f95..00000000 --- a/Assets/UnityTestTools/Assertions/Editor/DropDownControl.cs +++ /dev/null @@ -1,78 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEditor; -using UnityEngine; - -namespace UnityTest -{ - [Serializable] - internal class DropDownControl - { - private readonly GUILayoutOption[] m_ButtonLayoutOptions = { GUILayout.ExpandWidth(true) }; - public Func convertForButtonLabel = s => s.ToString(); - public Func convertForGUIContent = s => s.ToString(); - public Func ignoreConvertForGUIContent = t => t.Length <= 40; - public Action printContextMenu = null; - public string tooltip = ""; - - private object m_SelectedValue; - - - public void Draw(T selected, T[] options, Action onValueSelected) - { - Draw(null, - selected, - options, - onValueSelected); - } - - public void Draw(string label, T selected, T[] options, Action onValueSelected) - { - Draw(label, selected, () => options, onValueSelected); - } - - public void Draw(string label, T selected, Func loadOptions, Action onValueSelected) - { - if (!string.IsNullOrEmpty(label)) - EditorGUILayout.BeginHorizontal(); - var guiContent = new GUIContent(label); - var labelSize = EditorStyles.label.CalcSize(guiContent); - - if (!string.IsNullOrEmpty(label)) - GUILayout.Label(label, EditorStyles.label, GUILayout.Width(labelSize.x)); - - if (GUILayout.Button(new GUIContent(convertForButtonLabel(selected), tooltip), - EditorStyles.popup, m_ButtonLayoutOptions)) - { - if (Event.current.button == 0) - { - PrintMenu(loadOptions()); - } - else if (printContextMenu != null && Event.current.button == 1) - printContextMenu(selected); - } - - if (m_SelectedValue != null) - { - onValueSelected((T)m_SelectedValue); - m_SelectedValue = null; - } - if (!string.IsNullOrEmpty(label)) - EditorGUILayout.EndHorizontal(); - } - - public void PrintMenu(T[] options) - { - var menu = new GenericMenu(); - foreach (var s in options) - { - var localS = s; - menu.AddItem(new GUIContent((ignoreConvertForGUIContent(options) ? localS.ToString() : convertForGUIContent(localS))), - false, - () => { m_SelectedValue = localS; } - ); - } - menu.ShowAsContext(); - } - } -} diff --git a/Assets/UnityTestTools/Assertions/Editor/DropDownControl.cs.meta b/Assets/UnityTestTools/Assertions/Editor/DropDownControl.cs.meta deleted file mode 100644 index 424d2437..00000000 --- a/Assets/UnityTestTools/Assertions/Editor/DropDownControl.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 83ec3ed09f8f2f34ea7483e055f6d76d -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Assertions/Editor/GroupByComparerRenderer.cs b/Assets/UnityTestTools/Assertions/Editor/GroupByComparerRenderer.cs deleted file mode 100644 index 6d7875bc..00000000 --- a/Assets/UnityTestTools/Assertions/Editor/GroupByComparerRenderer.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEngine; - -namespace UnityTest -{ - public class GroupByComparerRenderer : AssertionListRenderer - { - protected override IEnumerable> GroupResult(IEnumerable assertionComponents) - { - return assertionComponents.GroupBy(c => c.Action.GetType()); - } - - protected override string GetStringKey(Type key) - { - return key.Name; - } - } -} diff --git a/Assets/UnityTestTools/Assertions/Editor/GroupByComparerRenderer.cs.meta b/Assets/UnityTestTools/Assertions/Editor/GroupByComparerRenderer.cs.meta deleted file mode 100644 index e9173993..00000000 --- a/Assets/UnityTestTools/Assertions/Editor/GroupByComparerRenderer.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: efab536803bd0154a8a7dc78e8767ad9 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Assertions/Editor/GroupByExecutionMethodRenderer.cs b/Assets/UnityTestTools/Assertions/Editor/GroupByExecutionMethodRenderer.cs deleted file mode 100644 index b4b6d3fc..00000000 --- a/Assets/UnityTestTools/Assertions/Editor/GroupByExecutionMethodRenderer.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEngine; - -namespace UnityTest -{ - public class GroupByExecutionMethodRenderer : AssertionListRenderer - { - protected override IEnumerable> GroupResult(IEnumerable assertionComponents) - { - var enumVals = Enum.GetValues(typeof(CheckMethod)).Cast(); - var pairs = new List(); - - foreach (var checkMethod in enumVals) - { - var components = assertionComponents.Where(c => (c.checkMethods & checkMethod) == checkMethod); - var componentPairs = components.Select(a => new CheckFunctionAssertionPair {checkMethod = checkMethod, assertionComponent = a}); - pairs.AddRange(componentPairs); - } - return pairs.GroupBy(pair => pair.checkMethod, - pair => pair.assertionComponent); - } - - private class CheckFunctionAssertionPair - { - public AssertionComponent assertionComponent; - public CheckMethod checkMethod; - } - } -} diff --git a/Assets/UnityTestTools/Assertions/Editor/GroupByExecutionMethodRenderer.cs.meta b/Assets/UnityTestTools/Assertions/Editor/GroupByExecutionMethodRenderer.cs.meta deleted file mode 100644 index e542ae1d..00000000 --- a/Assets/UnityTestTools/Assertions/Editor/GroupByExecutionMethodRenderer.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 97340abf816b1424fa835a4f26bbdc78 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Assertions/Editor/GroupByGORenderer.cs b/Assets/UnityTestTools/Assertions/Editor/GroupByGORenderer.cs deleted file mode 100644 index 6d76ca51..00000000 --- a/Assets/UnityTestTools/Assertions/Editor/GroupByGORenderer.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEditor; -using UnityEngine; - -namespace UnityTest -{ - public class GroupByGoRenderer : AssertionListRenderer - { - protected override IEnumerable> GroupResult(IEnumerable assertionComponents) - { - return assertionComponents.GroupBy(c => c.gameObject); - } - - protected override bool PrintFoldout(bool isFolded, GameObject key) - { - isFolded = base.PrintFoldout(isFolded, - key); - - EditorGUILayout.ObjectField(key, - typeof(GameObject), - true, - GUILayout.ExpandWidth(false)); - - return isFolded; - } - - protected override string GetFoldoutDisplayName(GameObject key) - { - return key.name; - } - } -} diff --git a/Assets/UnityTestTools/Assertions/Editor/GroupByGORenderer.cs.meta b/Assets/UnityTestTools/Assertions/Editor/GroupByGORenderer.cs.meta deleted file mode 100644 index a11d1dca..00000000 --- a/Assets/UnityTestTools/Assertions/Editor/GroupByGORenderer.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: cb824de9146b42343a985aaf63beffd1 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Assertions/Editor/GroupByNothingRenderer.cs b/Assets/UnityTestTools/Assertions/Editor/GroupByNothingRenderer.cs deleted file mode 100644 index db5d824a..00000000 --- a/Assets/UnityTestTools/Assertions/Editor/GroupByNothingRenderer.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEngine; - -namespace UnityTest -{ - public class GroupByNothingRenderer : AssertionListRenderer - { - protected override IEnumerable> GroupResult(IEnumerable assertionComponents) - { - return assertionComponents.GroupBy(c => ""); - } - - protected override string GetStringKey(string key) - { - return ""; - } - } -} diff --git a/Assets/UnityTestTools/Assertions/Editor/GroupByNothingRenderer.cs.meta b/Assets/UnityTestTools/Assertions/Editor/GroupByNothingRenderer.cs.meta deleted file mode 100644 index f7d9d2ac..00000000 --- a/Assets/UnityTestTools/Assertions/Editor/GroupByNothingRenderer.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 33bf96aa461ea1d478bb757c52f51c95 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Assertions/Editor/GroupByTestsRenderer.cs b/Assets/UnityTestTools/Assertions/Editor/GroupByTestsRenderer.cs deleted file mode 100644 index a126a513..00000000 --- a/Assets/UnityTestTools/Assertions/Editor/GroupByTestsRenderer.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEngine; - -namespace UnityTest -{ - public class GroupByTestsRenderer : AssertionListRenderer - { - protected override IEnumerable> GroupResult(IEnumerable assertionComponents) - { - return assertionComponents.GroupBy(c => - { - var temp = c.transform; - while (temp != null) - { - if (temp.GetComponent("TestComponent") != null) return c.gameObject; - temp = temp.parent.transform; - } - return null; - }); - } - - protected override string GetFoldoutDisplayName(GameObject key) - { - return key.name; - } - } -} diff --git a/Assets/UnityTestTools/Assertions/Editor/GroupByTestsRenderer.cs.meta b/Assets/UnityTestTools/Assertions/Editor/GroupByTestsRenderer.cs.meta deleted file mode 100644 index cbc31246..00000000 --- a/Assets/UnityTestTools/Assertions/Editor/GroupByTestsRenderer.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 5e577f31e55208b4d8a1774b958e6ed5 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Assertions/Editor/PropertyPathSelector.cs b/Assets/UnityTestTools/Assertions/Editor/PropertyPathSelector.cs deleted file mode 100644 index 3bf3911b..00000000 --- a/Assets/UnityTestTools/Assertions/Editor/PropertyPathSelector.cs +++ /dev/null @@ -1,207 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using UnityEditor; -using UnityEngine; - -namespace UnityTest -{ - public class PropertyPathSelector - { - private readonly DropDownControl m_ThisDropDown = new DropDownControl(); - private readonly Func m_ReplaceDotWithSlashAndAddGoGroup = s => s.Replace('.', '/'); - - private readonly string m_Name; - private bool m_FocusBackToEdit; - private SelectedPathError m_Error; - - public PropertyPathSelector(string name) - { - m_Name = name; - m_ThisDropDown.convertForGUIContent = m_ReplaceDotWithSlashAndAddGoGroup; - m_ThisDropDown.tooltip = "Select the path to the value you want to use for comparison."; - } - - public void Draw(GameObject go, ActionBase comparer, string propertPath, Type[] accepatbleTypes, Action onSelectedGo, Action onSelectedPath) - { - var newGo = (GameObject)EditorGUILayout.ObjectField(m_Name, go, typeof(GameObject), true); - if (newGo != go) - onSelectedGo(newGo); - - if (go != null) - { - var newPath = DrawListOfMethods(go, comparer, propertPath, accepatbleTypes, m_ThisDropDown); - - if (newPath != propertPath) - onSelectedPath(newPath); - } - } - - private string DrawListOfMethods(GameObject go, ActionBase comparer, string propertPath, Type[] accepatbleTypes, DropDownControl dropDown) - { - string result = propertPath; - if (accepatbleTypes == null) - { - result = DrawManualPropertyEditField(go, propertPath, accepatbleTypes, dropDown); - } - else - { - bool isPropertyOrFieldFound = true; - if (string.IsNullOrEmpty(result)) - { - var options = GetFieldsAndProperties(go, comparer, result, accepatbleTypes); - isPropertyOrFieldFound = options.Any(); - if (isPropertyOrFieldFound) - { - result = options.First(); - } - } - - if (isPropertyOrFieldFound) - { - dropDown.Draw(go.name + '.', result, - () => - { - try - { - var options = GetFieldsAndProperties(go, comparer, result, accepatbleTypes); - return options.ToArray(); - } - catch (Exception) - { - Debug.LogWarning("An exception was thrown while resolving a property list. Resetting property path."); - result = ""; - return new string[0]; - } - }, s => result = s); - } - else - { - result = DrawManualPropertyEditField(go, propertPath, accepatbleTypes, dropDown); - } - } - return result; - } - - private static List GetFieldsAndProperties(GameObject go, ActionBase comparer, string extendPath, Type[] accepatbleTypes) - { - var propertyResolver = new PropertyResolver {AllowedTypes = accepatbleTypes, ExcludedFieldNames = comparer.GetExcludedFieldNames()}; - var options = propertyResolver.GetFieldsAndPropertiesFromGameObject(go, comparer.GetDepthOfSearch(), extendPath).ToList(); - options.Sort((x, y) => - { - if (char.IsLower(x[0])) - return -1; - if (char.IsLower(y[0])) - return 1; - return x.CompareTo(y); - }); - return options; - } - - private string DrawManualPropertyEditField(GameObject go, string propertPath, Type[] acceptableTypes, DropDownControl dropDown) - { - var propertyResolver = new PropertyResolver { AllowedTypes = acceptableTypes }; - IList list; - - var loadProps = new Func(() => - { - try - { - list = propertyResolver.GetFieldsAndPropertiesUnderPath(go, propertPath); - } - catch (ArgumentException) - { - list = propertyResolver.GetFieldsAndPropertiesUnderPath(go, ""); - } - return list.ToArray(); - }); - - EditorGUILayout.BeginHorizontal(); - - var labelSize = EditorStyles.label.CalcSize(new GUIContent(go.name + '.')); - GUILayout.Label(go.name + (propertPath.Length > 0 ? "." : ""), EditorStyles.label, GUILayout.Width(labelSize.x)); - - string btnName = "hintBtn"; - if (GUI.GetNameOfFocusedControl() == btnName - && Event.current.type == EventType.KeyDown - && Event.current.keyCode == KeyCode.DownArrow) - { - Event.current.Use(); - dropDown.PrintMenu(loadProps()); - GUI.FocusControl(""); - m_FocusBackToEdit = true; - } - - EditorGUI.BeginChangeCheck(); - GUI.SetNextControlName(btnName); - var result = GUILayout.TextField(propertPath, EditorStyles.textField); - if (EditorGUI.EndChangeCheck()) - { - m_Error = DoesPropertyExist(go, result); - } - - if (m_FocusBackToEdit) - { - m_FocusBackToEdit = false; - GUI.FocusControl(btnName); - } - - if (GUILayout.Button("Clear", EditorStyles.miniButton, GUILayout.Width(38))) - { - result = ""; - GUI.FocusControl(null); - m_FocusBackToEdit = true; - m_Error = DoesPropertyExist(go, result); - } - EditorGUILayout.EndHorizontal(); - EditorGUILayout.BeginHorizontal(); - GUILayout.Label("", GUILayout.Width(labelSize.x)); - - dropDown.Draw("", result ?? "", loadProps, s => - { - result = s; - GUI.FocusControl(null); - m_FocusBackToEdit = true; - m_Error = DoesPropertyExist(go, result); - }); - EditorGUILayout.EndHorizontal(); - - switch (m_Error) - { - case SelectedPathError.InvalidPath: - EditorGUILayout.HelpBox("This property does not exist", MessageType.Error); - break; - case SelectedPathError.MissingComponent: - EditorGUILayout.HelpBox("This property or field is not attached or set. It will fail unless it will be attached before the check is perfomed.", MessageType.Warning); - break; - } - - return result; - } - - private SelectedPathError DoesPropertyExist(GameObject go, string propertPath) - { - try - { - object obj; - if (MemberResolver.TryGetValue(go, propertPath, out obj)) - return SelectedPathError.None; - return SelectedPathError.InvalidPath; - } - catch (TargetInvocationException e) - { - if (e.InnerException is MissingComponentException) - return SelectedPathError.MissingComponent; - throw; - } - } - - private enum SelectedPathError - { - None, - MissingComponent, - InvalidPath - } - } -} diff --git a/Assets/UnityTestTools/Assertions/Editor/PropertyPathSelector.cs.meta b/Assets/UnityTestTools/Assertions/Editor/PropertyPathSelector.cs.meta deleted file mode 100644 index b1998a87..00000000 --- a/Assets/UnityTestTools/Assertions/Editor/PropertyPathSelector.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 6619da1897737044080bdb8bc60eff87 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Assertions/Editor/PropertyResolver.cs b/Assets/UnityTestTools/Assertions/Editor/PropertyResolver.cs deleted file mode 100644 index 5d705daa..00000000 --- a/Assets/UnityTestTools/Assertions/Editor/PropertyResolver.cs +++ /dev/null @@ -1,188 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Text.RegularExpressions; -using UnityEngine; - -namespace UnityTest -{ - [Serializable] - public class PropertyResolver - { - public string[] ExcludedFieldNames { get; set; } - public Type[] ExcludedTypes { get; set; } - public Type[] AllowedTypes { get; set; } - - public PropertyResolver() - { - ExcludedFieldNames = new string[] { }; - ExcludedTypes = new Type[] { }; - AllowedTypes = new Type[] { }; - } - - public IList GetFieldsAndPropertiesUnderPath(GameObject go, string propertPath) - { - propertPath = propertPath.Trim(); - if (!PropertyPathIsValid(propertPath)) - { - throw new ArgumentException("Incorrect property path: " + propertPath); - } - - var idx = propertPath.LastIndexOf('.'); - - if (idx < 0) - { - var components = GetFieldsAndPropertiesFromGameObject(go, 2, null); - return components; - } - - var propertyToSearch = propertPath; - Type type; - if (MemberResolver.TryGetMemberType(go, propertyToSearch, out type)) - { - idx = propertPath.Length - 1; - } - else - { - propertyToSearch = propertPath.Substring(0, idx); - if (!MemberResolver.TryGetMemberType(go, propertyToSearch, out type)) - { - var components = GetFieldsAndPropertiesFromGameObject(go, 2, null); - return components.Where(s => s.StartsWith(propertPath.Substring(idx + 1))).ToArray(); - } - } - - var resultList = new List(); - var path = ""; - if (propertyToSearch.EndsWith(".")) - propertyToSearch = propertyToSearch.Substring(0, propertyToSearch.Length - 1); - foreach (var c in propertyToSearch) - { - if (c == '.') - resultList.Add(path); - path += c; - } - resultList.Add(path); - foreach (var prop in type.GetProperties().Where(info => info.GetIndexParameters().Length == 0)) - { - if (prop.Name.StartsWith(propertPath.Substring(idx + 1))) - resultList.Add(propertyToSearch + "." + prop.Name); - } - foreach (var prop in type.GetFields()) - { - if (prop.Name.StartsWith(propertPath.Substring(idx + 1))) - resultList.Add(propertyToSearch + "." + prop.Name); - } - return resultList.ToArray(); - } - - internal bool PropertyPathIsValid(string propertPath) - { - if (propertPath.StartsWith(".")) - return false; - if (propertPath.IndexOf("..") >= 0) - return false; - if (Regex.IsMatch(propertPath, @"\s")) - return false; - return true; - } - - public IList GetFieldsAndPropertiesFromGameObject(GameObject gameObject, int depthOfSearch, string extendPath) - { - if (depthOfSearch < 1) throw new ArgumentOutOfRangeException("depthOfSearch has to be greater than 0"); - - var goVals = GetPropertiesAndFieldsFromType(typeof(GameObject), - depthOfSearch - 1).Select(s => "gameObject." + s); - - var result = new List(); - if (AllowedTypes == null || !AllowedTypes.Any() || AllowedTypes.Contains(typeof(GameObject))) - result.Add("gameObject"); - result.AddRange(goVals); - - foreach (var componentType in GetAllComponents(gameObject)) - { - if (AllowedTypes == null || !AllowedTypes.Any() || AllowedTypes.Any(t => t.IsAssignableFrom(componentType))) - result.Add(componentType.Name); - - if (depthOfSearch > 1) - { - var vals = GetPropertiesAndFieldsFromType(componentType, depthOfSearch - 1); - var valsFullName = vals.Select(s => componentType.Name + "." + s); - result.AddRange(valsFullName); - } - } - - if (!string.IsNullOrEmpty(extendPath)) - { - var memberResolver = new MemberResolver(gameObject, extendPath); - var pathType = memberResolver.GetMemberType(); - var vals = GetPropertiesAndFieldsFromType(pathType, depthOfSearch - 1); - var valsFullName = vals.Select(s => extendPath + "." + s); - result.AddRange(valsFullName); - } - - return result; - } - - private string[] GetPropertiesAndFieldsFromType(Type type, int level) - { - level--; - - var result = new List(); - var fields = new List(); - fields.AddRange(type.GetFields().Where(f => !Attribute.IsDefined(f, typeof(ObsoleteAttribute))).ToArray()); - fields.AddRange(type.GetProperties().Where(info => info.GetIndexParameters().Length == 0 && !Attribute.IsDefined(info, typeof(ObsoleteAttribute))).ToArray()); - - foreach (var member in fields) - { - var memberType = GetMemberFieldType(member); - var memberTypeName = memberType.Name; - - if (AllowedTypes == null - || !AllowedTypes.Any() - || (AllowedTypes.Any(t => t.IsAssignableFrom(memberType)) && !ExcludedFieldNames.Contains(memberTypeName))) - { - result.Add(member.Name); - } - - if (level > 0 && IsTypeOrNameNotExcluded(memberType, memberTypeName)) - { - var vals = GetPropertiesAndFieldsFromType(memberType, level); - var valsFullName = vals.Select(s => member.Name + "." + s); - result.AddRange(valsFullName); - } - } - return result.ToArray(); - } - - private Type GetMemberFieldType(MemberInfo info) - { - if (info.MemberType == MemberTypes.Property) - return (info as PropertyInfo).PropertyType; - if (info.MemberType == MemberTypes.Field) - return (info as FieldInfo).FieldType; - throw new Exception("Only properties and fields are allowed"); - } - - internal Type[] GetAllComponents(GameObject gameObject) - { - var result = new List(); - var components = gameObject.GetComponents(typeof(Component)); - foreach (var component in components) - { - var componentType = component.GetType(); - if (IsTypeOrNameNotExcluded(componentType, null)) - { - result.Add(componentType); - } - } - return result.ToArray(); - } - - private bool IsTypeOrNameNotExcluded(Type memberType, string memberTypeName) - { - return !ExcludedTypes.Contains(memberType) && !ExcludedFieldNames.Contains(memberTypeName); - } - } -} diff --git a/Assets/UnityTestTools/Assertions/Editor/PropertyResolver.cs.meta b/Assets/UnityTestTools/Assertions/Editor/PropertyResolver.cs.meta deleted file mode 100644 index 22210c77..00000000 --- a/Assets/UnityTestTools/Assertions/Editor/PropertyResolver.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: bbbd193a27920d9478c2a766a7291d72 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Assertions/InvalidPathException.cs b/Assets/UnityTestTools/Assertions/InvalidPathException.cs deleted file mode 100644 index 9ddde07e..00000000 --- a/Assets/UnityTestTools/Assertions/InvalidPathException.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace UnityTest -{ - public class InvalidPathException : Exception - { - public InvalidPathException(string path) - : base("Invalid path part " + path) - { - } - } -} diff --git a/Assets/UnityTestTools/Assertions/InvalidPathException.cs.meta b/Assets/UnityTestTools/Assertions/InvalidPathException.cs.meta deleted file mode 100644 index a5f882dd..00000000 --- a/Assets/UnityTestTools/Assertions/InvalidPathException.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 3b85786dfd1aef544bf8bb873d6a4ebb -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Assertions/MemberResolver.cs b/Assets/UnityTestTools/Assertions/MemberResolver.cs deleted file mode 100644 index 65f7351c..00000000 --- a/Assets/UnityTestTools/Assertions/MemberResolver.cs +++ /dev/null @@ -1,208 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Text.RegularExpressions; -using UnityEngine; - -namespace UnityTest -{ - public class MemberResolver - { - private object m_CallingObjectRef; - private MemberInfo[] m_Callstack; - private readonly GameObject m_GameObject; - private readonly string m_Path; - - public MemberResolver(GameObject gameObject, string path) - { - path = path.Trim(); - ValidatePath(path); - - m_GameObject = gameObject; - m_Path = path.Trim(); - } - - public object GetValue(bool useCache) - { - if (useCache && m_CallingObjectRef != null) - { - object val = m_CallingObjectRef; - for (int i = 0; i < m_Callstack.Length; i++) - val = GetValueFromMember(val, m_Callstack[i]); - return val; - } - - object result = GetBaseObject(); - var fullCallStack = GetCallstack(); - - m_CallingObjectRef = result; - var tempCallstack = new List(); - for (int i = 0; i < fullCallStack.Length; i++) - { - var member = fullCallStack[i]; - result = GetValueFromMember(result, member); - tempCallstack.Add(member); - if (result == null) return null; - var type = result.GetType(); - - //String is not a value type but we don't want to cache it - if (!IsValueType(type) && type != typeof(System.String)) - { - tempCallstack.Clear(); - m_CallingObjectRef = result; - } - } - m_Callstack = tempCallstack.ToArray(); - return result; - } - - public Type GetMemberType() - { - var callstack = GetCallstack(); - if (callstack.Length == 0) return GetBaseObject().GetType(); - - var member = callstack[callstack.Length - 1]; - if (member is FieldInfo) - return (member as FieldInfo).FieldType; - if (member is MethodInfo) - return (member as MethodInfo).ReturnType; - return null; - } - - #region Static wrappers - public static bool TryGetMemberType(GameObject gameObject, string path, out Type value) - { - try - { - var mr = new MemberResolver(gameObject, path); - value = mr.GetMemberType(); - return true; - } - catch (InvalidPathException) - { - value = null; - return false; - } - } - - public static bool TryGetValue(GameObject gameObject, string path, out object value) - { - try - { - var mr = new MemberResolver(gameObject, path); - value = mr.GetValue(false); - return true; - } - catch (InvalidPathException) - { - value = null; - return false; - } - } - #endregion - - private object GetValueFromMember(object obj, MemberInfo memberInfo) - { - if (memberInfo is FieldInfo) - return (memberInfo as FieldInfo).GetValue(obj); - if (memberInfo is MethodInfo) - return (memberInfo as MethodInfo).Invoke(obj, null); - throw new InvalidPathException(memberInfo.Name); - } - - private object GetBaseObject() - { - if (string.IsNullOrEmpty(m_Path)) return m_GameObject; - var firstElement = m_Path.Split('.')[0]; - var comp = m_GameObject.GetComponent(firstElement); - if (comp != null) - return comp; - return m_GameObject; - } - - private MemberInfo[] GetCallstack() - { - if (m_Path == "") return new MemberInfo[0]; - var propsQueue = new Queue(m_Path.Split('.')); - - Type type = GetBaseObject().GetType(); - if (type != typeof(GameObject)) - propsQueue.Dequeue(); - - PropertyInfo propertyTemp; - FieldInfo fieldTemp; - var list = new List(); - while (propsQueue.Count != 0) - { - var nameToFind = propsQueue.Dequeue(); - fieldTemp = GetField(type, nameToFind); - if (fieldTemp != null) - { - type = fieldTemp.FieldType; - list.Add(fieldTemp); - continue; - } - propertyTemp = GetProperty(type, nameToFind); - if (propertyTemp != null) - { - type = propertyTemp.PropertyType; - var getMethod = GetGetMethod(propertyTemp); - list.Add(getMethod); - continue; - } - throw new InvalidPathException(nameToFind); - } - return list.ToArray(); - } - - private void ValidatePath(string path) - { - bool invalid = false; - if (path.StartsWith(".") || path.EndsWith(".")) - invalid = true; - if (path.IndexOf("..") >= 0) - invalid = true; - if (Regex.IsMatch(path, @"\s")) - invalid = true; - - if (invalid) - throw new InvalidPathException(path); - } - - private static bool IsValueType(Type type) - { - #if !UNITY_METRO - return type.IsValueType; - #else - return false; - #endif - } - - private static FieldInfo GetField(Type type, string fieldName) - { - #if !UNITY_METRO - return type.GetField(fieldName); - #else - return null; - #endif - } - - private static PropertyInfo GetProperty(Type type, string propertyName) - { - #if !UNITY_METRO - return type.GetProperty(propertyName); - #else - return null; - #endif - } - - private static MethodInfo GetGetMethod(PropertyInfo propertyInfo) - { - #if !UNITY_METRO - return propertyInfo.GetGetMethod(); - #else - return null; - #endif - } - } -} diff --git a/Assets/UnityTestTools/Assertions/MemberResolver.cs.meta b/Assets/UnityTestTools/Assertions/MemberResolver.cs.meta deleted file mode 100644 index 6b1ea425..00000000 --- a/Assets/UnityTestTools/Assertions/MemberResolver.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 80df8ef907961e34dbcc7c89b22729b9 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Common.meta b/Assets/UnityTestTools/Common.meta deleted file mode 100644 index 5f0acfe7..00000000 --- a/Assets/UnityTestTools/Common.meta +++ /dev/null @@ -1,5 +0,0 @@ -fileFormatVersion: 2 -guid: a2caba6436df568499c84c1c607ce766 -folderAsset: yes -DefaultImporter: - userData: diff --git a/Assets/UnityTestTools/Common/Editor.meta b/Assets/UnityTestTools/Common/Editor.meta deleted file mode 100644 index 2021d4fe..00000000 --- a/Assets/UnityTestTools/Common/Editor.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: f4ab061d0035ee545a936bdf8f3f8620 -DefaultImporter: - userData: diff --git a/Assets/UnityTestTools/Common/Editor/Icons.cs b/Assets/UnityTestTools/Common/Editor/Icons.cs deleted file mode 100644 index 8fd7bfae..00000000 --- a/Assets/UnityTestTools/Common/Editor/Icons.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using UnityEditor; -using UnityEngine; - -namespace UnityTest -{ - public static class Icons - { - const string k_IconsFolderName = "icons"; - private static readonly string k_IconsFolderPath = String.Format("UnityTestTools{0}Common{0}Editor{0}{1}", Path.DirectorySeparatorChar, k_IconsFolderName); - - private static readonly string k_IconsAssetsPath = ""; - - public static readonly Texture2D FailImg; - public static readonly Texture2D IgnoreImg; - public static readonly Texture2D SuccessImg; - public static readonly Texture2D UnknownImg; - public static readonly Texture2D InconclusiveImg; - public static readonly Texture2D StopwatchImg; - - public static readonly GUIContent GUIUnknownImg; - public static readonly GUIContent GUIInconclusiveImg; - public static readonly GUIContent GUIIgnoreImg; - public static readonly GUIContent GUISuccessImg; - public static readonly GUIContent GUIFailImg; - - static Icons() - { - var dirs = Directory.GetDirectories("Assets", k_IconsFolderName, SearchOption.AllDirectories).Where(s => s.EndsWith(k_IconsFolderPath)); - if (dirs.Any()) - k_IconsAssetsPath = dirs.First(); - else - Debug.LogWarning("The UnityTestTools asset folder path is incorrect. If you relocated the tools please change the path accordingly (Icons.cs)."); - - FailImg = LoadTexture("failed.png"); - IgnoreImg = LoadTexture("ignored.png"); - SuccessImg = LoadTexture("passed.png"); - UnknownImg = LoadTexture("normal.png"); - InconclusiveImg = LoadTexture("inconclusive.png"); - StopwatchImg = LoadTexture("stopwatch.png"); - - GUIUnknownImg = new GUIContent(UnknownImg); - GUIInconclusiveImg = new GUIContent(InconclusiveImg); - GUIIgnoreImg = new GUIContent(IgnoreImg); - GUISuccessImg = new GUIContent(SuccessImg); - GUIFailImg = new GUIContent(FailImg); - } - - private static Texture2D LoadTexture(string fileName) - { - return (Texture2D)AssetDatabase.LoadAssetAtPath(k_IconsAssetsPath + Path.DirectorySeparatorChar + fileName, typeof(Texture2D)); - } - } -} diff --git a/Assets/UnityTestTools/Common/Editor/Icons.cs.meta b/Assets/UnityTestTools/Common/Editor/Icons.cs.meta deleted file mode 100644 index 267269a9..00000000 --- a/Assets/UnityTestTools/Common/Editor/Icons.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 8571844b0c115b84cbe8b3f67e8dec04 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Common/Editor/ProjectSettingsBase.cs b/Assets/UnityTestTools/Common/Editor/ProjectSettingsBase.cs deleted file mode 100644 index 99cafad8..00000000 --- a/Assets/UnityTestTools/Common/Editor/ProjectSettingsBase.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using UnityEditor; -using UnityEngine; - -namespace UnityTest -{ - public abstract class ProjectSettingsBase : ScriptableObject - { - private static readonly string k_SettingsPath = Path.Combine("UnityTestTools", "Common"); - const string k_SettingsFolder = "Settings"; - - public virtual void Save() - { - EditorUtility.SetDirty(this); - } - - public static T Load() where T : ProjectSettingsBase, new () - { - var pathsInProject = Directory.GetDirectories("Assets", "*", SearchOption.AllDirectories) - .Where(s => s.Contains(k_SettingsPath)); - - if (pathsInProject.Count() == 0) Debug.LogError("Can't find settings path: " + k_SettingsPath); - - string pathInProject = Path.Combine(pathsInProject.First(), k_SettingsFolder); - var assetPath = Path.Combine(pathInProject, typeof(T).Name) + ".asset"; - var settings = AssetDatabase.LoadAssetAtPath(assetPath, typeof(T)) as T; - - if (settings != null) return settings; - - settings = CreateInstance(); - Directory.CreateDirectory(pathInProject); - AssetDatabase.CreateAsset(settings, assetPath); - return settings; - } - } -} diff --git a/Assets/UnityTestTools/Common/Editor/ProjectSettingsBase.cs.meta b/Assets/UnityTestTools/Common/Editor/ProjectSettingsBase.cs.meta deleted file mode 100644 index db5944b9..00000000 --- a/Assets/UnityTestTools/Common/Editor/ProjectSettingsBase.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 9ac961be07107124a88dcb81927143d4 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Common/Editor/ResultWriter.meta b/Assets/UnityTestTools/Common/Editor/ResultWriter.meta deleted file mode 100644 index 9b2e13b3..00000000 --- a/Assets/UnityTestTools/Common/Editor/ResultWriter.meta +++ /dev/null @@ -1,5 +0,0 @@ -fileFormatVersion: 2 -guid: 4ffbf5a07740aa5479651bd415f52ebb -folderAsset: yes -DefaultImporter: - userData: diff --git a/Assets/UnityTestTools/Common/Editor/ResultWriter/ResultSummarizer.cs b/Assets/UnityTestTools/Common/Editor/ResultWriter/ResultSummarizer.cs deleted file mode 100644 index cfd39ca3..00000000 --- a/Assets/UnityTestTools/Common/Editor/ResultWriter/ResultSummarizer.cs +++ /dev/null @@ -1,173 +0,0 @@ -// **************************************************************** -// Based on nUnit 2.6.2 (http://www.nunit.org/) -// **************************************************************** - -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace UnityTest -{ - /// - /// Summary description for ResultSummarizer. - /// - public class ResultSummarizer - { - private int m_ErrorCount; - private int m_FailureCount; - private int m_IgnoreCount; - private int m_InconclusiveCount; - private int m_NotRunnable; - private int m_ResultCount; - private int m_SkipCount; - private int m_SuccessCount; - private int m_TestsRun; - - private TimeSpan m_Duration; - - public ResultSummarizer(IEnumerable results) - { - foreach (var result in results) - Summarize(result); - } - - public bool Success - { - get { return m_FailureCount == 0; } - } - - /// - /// Returns the number of test cases for which results - /// have been summarized. Any tests excluded by use of - /// Category or Explicit attributes are not counted. - /// - public int ResultCount - { - get { return m_ResultCount; } - } - - /// - /// Returns the number of test cases actually run, which - /// is the same as ResultCount, less any Skipped, Ignored - /// or NonRunnable tests. - /// - public int TestsRun - { - get { return m_TestsRun; } - } - - /// - /// Returns the number of tests that passed - /// - public int Passed - { - get { return m_SuccessCount; } - } - - /// - /// Returns the number of test cases that had an error. - /// - public int Errors - { - get { return m_ErrorCount; } - } - - /// - /// Returns the number of test cases that failed. - /// - public int Failures - { - get { return m_FailureCount; } - } - - /// - /// Returns the number of test cases that failed. - /// - public int Inconclusive - { - get { return m_InconclusiveCount; } - } - - /// - /// Returns the number of test cases that were not runnable - /// due to errors in the signature of the class or method. - /// Such tests are also counted as Errors. - /// - public int NotRunnable - { - get { return m_NotRunnable; } - } - - /// - /// Returns the number of test cases that were skipped. - /// - public int Skipped - { - get { return m_SkipCount; } - } - - public int Ignored - { - get { return m_IgnoreCount; } - } - - public double Duration - { - get { return m_Duration.TotalSeconds; } - } - - public int TestsNotRun - { - get { return m_SkipCount + m_IgnoreCount + m_NotRunnable; } - } - - public void Summarize(ITestResult result) - { - m_Duration += TimeSpan.FromSeconds(result.Duration); - m_ResultCount++; - - if(!result.Executed) - { - if(result.IsIgnored) - { - m_IgnoreCount++; - return; - } - - m_SkipCount++; - return; - } - - switch (result.ResultState) - { - case TestResultState.Success: - m_SuccessCount++; - m_TestsRun++; - break; - case TestResultState.Failure: - m_FailureCount++; - m_TestsRun++; - break; - case TestResultState.Error: - case TestResultState.Cancelled: - m_ErrorCount++; - m_TestsRun++; - break; - case TestResultState.Inconclusive: - m_InconclusiveCount++; - m_TestsRun++; - break; - case TestResultState.NotRunnable: - m_NotRunnable++; - // errorCount++; - break; - case TestResultState.Ignored: - m_IgnoreCount++; - break; - default: - m_SkipCount++; - break; - } - } - } -} diff --git a/Assets/UnityTestTools/Common/Editor/ResultWriter/ResultSummarizer.cs.meta b/Assets/UnityTestTools/Common/Editor/ResultWriter/ResultSummarizer.cs.meta deleted file mode 100644 index ca3c41ff..00000000 --- a/Assets/UnityTestTools/Common/Editor/ResultWriter/ResultSummarizer.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: ce89106be5bd4204388d58510e4e55da -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Common/Editor/ResultWriter/StackTraceFilter.cs b/Assets/UnityTestTools/Common/Editor/ResultWriter/StackTraceFilter.cs deleted file mode 100644 index 686de926..00000000 --- a/Assets/UnityTestTools/Common/Editor/ResultWriter/StackTraceFilter.cs +++ /dev/null @@ -1,62 +0,0 @@ -// **************************************************************** -// Based on nUnit 2.6.2 (http://www.nunit.org/) -// **************************************************************** - -using System; -using System.Collections.Generic; -using System.IO; -using UnityEngine; - -namespace UnityTest -{ - /// - /// Summary description for StackTraceFilter. - /// - public class StackTraceFilter - { - public static string Filter(string stack) - { - if (stack == null) return null; - var sw = new StringWriter(); - var sr = new StringReader(stack); - - try - { - string line; - while ((line = sr.ReadLine()) != null) - { - if (!FilterLine(line)) - sw.WriteLine(line.Trim()); - } - } - catch (Exception) - { - return stack; - } - return sw.ToString(); - } - - static bool FilterLine(string line) - { - string[] patterns = - { - "NUnit.Core.TestCase", - "NUnit.Core.ExpectedExceptionTestCase", - "NUnit.Core.TemplateTestCase", - "NUnit.Core.TestResult", - "NUnit.Core.TestSuite", - "NUnit.Framework.Assertion", - "NUnit.Framework.Assert", - "System.Reflection.MonoMethod" - }; - - for (int i = 0; i < patterns.Length; i++) - { - if (line.IndexOf(patterns[i]) > 0) - return true; - } - - return false; - } - } -} diff --git a/Assets/UnityTestTools/Common/Editor/ResultWriter/StackTraceFilter.cs.meta b/Assets/UnityTestTools/Common/Editor/ResultWriter/StackTraceFilter.cs.meta deleted file mode 100644 index 70518439..00000000 --- a/Assets/UnityTestTools/Common/Editor/ResultWriter/StackTraceFilter.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: fe6b4d68575d4ba44b1d5c5c3f0e96d3 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Common/Editor/ResultWriter/XmlResultWriter.cs b/Assets/UnityTestTools/Common/Editor/ResultWriter/XmlResultWriter.cs deleted file mode 100644 index 3115e4f2..00000000 --- a/Assets/UnityTestTools/Common/Editor/ResultWriter/XmlResultWriter.cs +++ /dev/null @@ -1,303 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Security; -using System.Text; -using UnityEngine; - -namespace UnityTest -{ - public class XmlResultWriter - { - private readonly StringBuilder m_ResultWriter = new StringBuilder(); - private int m_Indend; - private readonly string m_SuiteName; - private readonly ITestResult[] m_Results; - string m_Platform; - - public XmlResultWriter(string suiteName, string platform, ITestResult[] results) - { - m_SuiteName = suiteName; - m_Results = results; - m_Platform = platform; - } - - private const string k_NUnitVersion = "2.6.2-Unity"; - - public string GetTestResult() - { - InitializeXmlFile(m_SuiteName, new ResultSummarizer(m_Results)); - foreach (var result in m_Results) - { - WriteResultElement(result); - } - TerminateXmlFile(); - return m_ResultWriter.ToString(); - } - - private void InitializeXmlFile(string resultsName, ResultSummarizer summaryResults) - { - WriteHeader(); - - DateTime now = DateTime.Now; - var attributes = new Dictionary - { - {"name", "Unity Tests"}, - {"total", summaryResults.TestsRun.ToString()}, - {"errors", summaryResults.Errors.ToString()}, - {"failures", summaryResults.Failures.ToString()}, - {"not-run", summaryResults.TestsNotRun.ToString()}, - {"inconclusive", summaryResults.Inconclusive.ToString()}, - {"ignored", summaryResults.Ignored.ToString()}, - {"skipped", summaryResults.Skipped.ToString()}, - {"invalid", summaryResults.NotRunnable.ToString()}, - {"date", now.ToString("yyyy-MM-dd")}, - {"time", now.ToString("HH:mm:ss")} - }; - - WriteOpeningElement("test-results", attributes); - - WriteEnvironment(m_Platform); - WriteCultureInfo(); - WriteTestSuite(resultsName, summaryResults); - WriteOpeningElement("results"); - } - - private void WriteOpeningElement(string elementName) - { - WriteOpeningElement(elementName, new Dictionary()); - } - - private void WriteOpeningElement(string elementName, Dictionary attributes) - { - WriteOpeningElement(elementName, attributes, false); - } - - - private void WriteOpeningElement(string elementName, Dictionary attributes, bool closeImmediatelly) - { - WriteIndend(); - m_Indend++; - m_ResultWriter.Append("<"); - m_ResultWriter.Append(elementName); - foreach (var attribute in attributes) - { - m_ResultWriter.AppendFormat(" {0}=\"{1}\"", attribute.Key, SecurityElement.Escape(attribute.Value)); - } - if (closeImmediatelly) - { - m_ResultWriter.Append(" /"); - m_Indend--; - } - m_ResultWriter.AppendLine(">"); - } - - private void WriteIndend() - { - for (int i = 0; i < m_Indend; i++) - { - m_ResultWriter.Append(" "); - } - } - - private void WriteClosingElement(string elementName) - { - m_Indend--; - WriteIndend(); - m_ResultWriter.AppendLine(""); - } - - private void WriteHeader() - { - m_ResultWriter.AppendLine(""); - m_ResultWriter.AppendLine(""); - } - - static string GetEnvironmentUserName() - { - return Environment.UserName; - } - - static string GetEnvironmentMachineName() - { - return Environment.MachineName; - } - - static string GetEnvironmentUserDomainName() - { - return Environment.UserDomainName; - } - - static string GetEnvironmentVersion() - { - return Environment.Version.ToString(); - } - - static string GetEnvironmentOSVersion() - { - return Environment.OSVersion.ToString(); - } - - static string GetEnvironmentOSVersionPlatform() - { - return Environment.OSVersion.Platform.ToString(); - } - - static string EnvironmentGetCurrentDirectory() - { - return Environment.CurrentDirectory; - } - - private void WriteEnvironment( string targetPlatform ) - { - var attributes = new Dictionary - { - {"nunit-version", k_NUnitVersion}, - {"clr-version", GetEnvironmentVersion()}, - {"os-version", GetEnvironmentOSVersion()}, - {"platform", GetEnvironmentOSVersionPlatform()}, - {"cwd", EnvironmentGetCurrentDirectory()}, - {"machine-name", GetEnvironmentMachineName()}, - {"user", GetEnvironmentUserName()}, - {"user-domain", GetEnvironmentUserDomainName()}, - {"unity-version", Application.unityVersion}, - {"unity-platform", targetPlatform} - }; - WriteOpeningElement("environment", attributes, true); - } - - private void WriteCultureInfo() - { - var attributes = new Dictionary - { - {"current-culture", CultureInfo.CurrentCulture.ToString()}, - {"current-uiculture", CultureInfo.CurrentUICulture.ToString()} - }; - WriteOpeningElement("culture-info", attributes, true); - } - - private void WriteTestSuite(string resultsName, ResultSummarizer summaryResults) - { - var attributes = new Dictionary - { - {"name", resultsName}, - {"type", "Assembly"}, - {"executed", "True"}, - {"result", summaryResults.Success ? "Success" : "Failure"}, - {"success", summaryResults.Success ? "True" : "False"}, - {"time", summaryResults.Duration.ToString("#####0.000", NumberFormatInfo.InvariantInfo)} - }; - WriteOpeningElement("test-suite", attributes); - } - - private void WriteResultElement(ITestResult result) - { - StartTestElement(result); - - switch (result.ResultState) - { - case TestResultState.Ignored: - case TestResultState.NotRunnable: - case TestResultState.Skipped: - WriteReasonElement(result); - break; - - case TestResultState.Failure: - case TestResultState.Error: - case TestResultState.Cancelled: - WriteFailureElement(result); - break; - case TestResultState.Success: - case TestResultState.Inconclusive: - if (result.Message != null) - WriteReasonElement(result); - break; - }; - - WriteClosingElement("test-case"); - } - - private void TerminateXmlFile() - { - WriteClosingElement("results"); - WriteClosingElement("test-suite"); - WriteClosingElement("test-results"); - } - - #region Element Creation Helpers - - private void StartTestElement(ITestResult result) - { - var attributes = new Dictionary - { - {"name", result.FullName}, - {"executed", result.Executed.ToString()} - }; - string resultString; - switch (result.ResultState) - { - case TestResultState.Cancelled: - resultString = TestResultState.Failure.ToString(); - break; - default: - resultString = result.ResultState.ToString(); - break; - } - attributes.Add("result", resultString); - if (result.Executed) - { - attributes.Add("success", result.IsSuccess.ToString()); - attributes.Add("time", result.Duration.ToString("#####0.000", NumberFormatInfo.InvariantInfo)); - } - WriteOpeningElement("test-case", attributes); - } - - private void WriteReasonElement(ITestResult result) - { - WriteOpeningElement("reason"); - WriteOpeningElement("message"); - WriteCData(result.Message); - WriteClosingElement("message"); - WriteClosingElement("reason"); - } - - private void WriteFailureElement(ITestResult result) - { - WriteOpeningElement("failure"); - WriteOpeningElement("message"); - WriteCData(result.Message); - WriteClosingElement("message"); - WriteOpeningElement("stack-trace"); - if (result.StackTrace != null) - WriteCData(StackTraceFilter.Filter(result.StackTrace)); - WriteClosingElement("stack-trace"); - WriteClosingElement("failure"); - } - - #endregion - - private void WriteCData(string text) - { - if (string.IsNullOrEmpty(text)) - return; - m_ResultWriter.AppendFormat("", text); - m_ResultWriter.AppendLine(); - } - - public void WriteToFile(string resultDestiantion, string resultFileName) - { - try - { - var path = Path.Combine(resultDestiantion, resultFileName); - Debug.Log("Saving results in " + path); - File.WriteAllText(path, GetTestResult(), Encoding.UTF8); - } - catch (Exception e) - { - Debug.LogError("Error while opening file"); - Debug.LogException(e); - } - } - } -} diff --git a/Assets/UnityTestTools/Common/Editor/ResultWriter/XmlResultWriter.cs.meta b/Assets/UnityTestTools/Common/Editor/ResultWriter/XmlResultWriter.cs.meta deleted file mode 100644 index 2fffa90d..00000000 --- a/Assets/UnityTestTools/Common/Editor/ResultWriter/XmlResultWriter.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: e9bba41ace7686d4ab0c400d1e7f55b7 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Common/Editor/Styles.cs b/Assets/UnityTestTools/Common/Editor/Styles.cs deleted file mode 100644 index 0caf6e1a..00000000 --- a/Assets/UnityTestTools/Common/Editor/Styles.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEditor; -using UnityEngine; - -namespace UnityTest -{ - public static class Styles - { - public static GUIStyle info; - public static GUIStyle testList; - - public static GUIStyle selectedFoldout; - public static GUIStyle foldout; - public static GUIStyle toolbarLabel; - - public static GUIStyle testName; - - private static readonly Color k_SelectedColor = new Color(0.3f, 0.5f, 0.85f); - - static Styles() - { - info = new GUIStyle(EditorStyles.wordWrappedLabel); - info.wordWrap = false; - info.stretchHeight = true; - info.margin.right = 15; - - testList = new GUIStyle("CN Box"); - testList.margin.top = 0; - testList.padding.left = 3; - - foldout = new GUIStyle(EditorStyles.foldout); - selectedFoldout = new GUIStyle(EditorStyles.foldout); - selectedFoldout.onFocused.textColor = selectedFoldout.focused.textColor = - selectedFoldout.onActive.textColor = selectedFoldout.active.textColor = - selectedFoldout.onNormal.textColor = selectedFoldout.normal.textColor = k_SelectedColor; - - toolbarLabel = new GUIStyle(EditorStyles.toolbarButton); - toolbarLabel.normal.background = null; - toolbarLabel.contentOffset = new Vector2(0, -2); - - testName = new GUIStyle(EditorStyles.label); - testName.padding.left += 12; - testName.focused.textColor = testName.onFocused.textColor = k_SelectedColor; - } - } -} diff --git a/Assets/UnityTestTools/Common/Editor/Styles.cs.meta b/Assets/UnityTestTools/Common/Editor/Styles.cs.meta deleted file mode 100644 index 294a6194..00000000 --- a/Assets/UnityTestTools/Common/Editor/Styles.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: a8b92379e11501742b1badcbb08da812 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Common/Editor/TestFilterSettings.cs b/Assets/UnityTestTools/Common/Editor/TestFilterSettings.cs deleted file mode 100644 index cef016a0..00000000 --- a/Assets/UnityTestTools/Common/Editor/TestFilterSettings.cs +++ /dev/null @@ -1,104 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; -using UnityEditor; -using System.Linq; - -namespace UnityTest -{ - public class TestFilterSettings - { - public bool ShowSucceeded; - public bool ShowFailed; - public bool ShowIgnored; - public bool ShowNotRun; - - public string FilterByName; - public int FilterByCategory; - - private GUIContent _succeededBtn; - private GUIContent _failedBtn; - private GUIContent _ignoredBtn; - private GUIContent _notRunBtn; - - public string[] AvailableCategories; - - private readonly string _prefsKey; - - public TestFilterSettings(string prefsKey) - { - _prefsKey = prefsKey; - Load(); - UpdateCounters(Enumerable.Empty()); - } - - public void Load() - { - ShowSucceeded = EditorPrefs.GetBool(_prefsKey + ".ShowSucceeded", true); - ShowFailed = EditorPrefs.GetBool(_prefsKey + ".ShowFailed", true); - ShowIgnored = EditorPrefs.GetBool(_prefsKey + ".ShowIgnored", true); - ShowNotRun = EditorPrefs.GetBool(_prefsKey + ".ShowNotRun", true); - FilterByName = EditorPrefs.GetString(_prefsKey + ".FilterByName", string.Empty); - FilterByCategory = EditorPrefs.GetInt(_prefsKey + ".FilterByCategory", 0); - } - - public void Save() - { - EditorPrefs.SetBool(_prefsKey + ".ShowSucceeded", ShowSucceeded); - EditorPrefs.SetBool(_prefsKey + ".ShowFailed", ShowFailed); - EditorPrefs.SetBool(_prefsKey + ".ShowIgnored", ShowIgnored); - EditorPrefs.SetBool(_prefsKey + ".ShowNotRun", ShowNotRun); - EditorPrefs.SetString(_prefsKey + ".FilterByName", FilterByName); - EditorPrefs.SetInt(_prefsKey + ".FilterByCategory", FilterByCategory); - } - - public void UpdateCounters(IEnumerable results) - { - var summary = new ResultSummarizer(results); - - _succeededBtn = new GUIContent(summary.Passed.ToString(), Icons.SuccessImg, "Show tests that succeeded"); - _failedBtn = new GUIContent((summary.Errors + summary.Failures + summary.Inconclusive).ToString(), Icons.FailImg, "Show tests that failed"); - _ignoredBtn = new GUIContent((summary.Ignored + summary.NotRunnable).ToString(), Icons.IgnoreImg, "Show tests that are ignored"); - _notRunBtn = new GUIContent((summary.TestsNotRun - summary.Ignored - summary.NotRunnable).ToString(), Icons.UnknownImg, "Show tests that didn't run"); - } - - public string[] GetSelectedCategories() - { - if(AvailableCategories == null) return new string[0]; - - return AvailableCategories.Where ((c, i) => (FilterByCategory & (1 << i)) != 0).ToArray(); - } - - public void OnGUI() - { - EditorGUI.BeginChangeCheck(); - - FilterByName = GUILayout.TextField(FilterByName, "ToolbarSeachTextField", GUILayout.MinWidth(100), GUILayout.MaxWidth(250), GUILayout.ExpandWidth(true)); - if(GUILayout.Button (GUIContent.none, string.IsNullOrEmpty(FilterByName) ? "ToolbarSeachCancelButtonEmpty" : "ToolbarSeachCancelButton")) - FilterByName = string.Empty; - - if (AvailableCategories != null && AvailableCategories.Length > 0) - FilterByCategory = EditorGUILayout.MaskField(FilterByCategory, AvailableCategories, EditorStyles.toolbarDropDown, GUILayout.MaxWidth(90)); - - ShowSucceeded = GUILayout.Toggle(ShowSucceeded, _succeededBtn, EditorStyles.toolbarButton); - ShowFailed = GUILayout.Toggle(ShowFailed, _failedBtn, EditorStyles.toolbarButton); - ShowIgnored = GUILayout.Toggle(ShowIgnored, _ignoredBtn, EditorStyles.toolbarButton); - ShowNotRun = GUILayout.Toggle(ShowNotRun, _notRunBtn, EditorStyles.toolbarButton); - - if(EditorGUI.EndChangeCheck()) Save (); - } - - public RenderingOptions BuildRenderingOptions() - { - var options = new RenderingOptions(); - options.showSucceeded = ShowSucceeded; - options.showFailed = ShowFailed; - options.showIgnored = ShowIgnored; - options.showNotRunned = ShowNotRun; - options.nameFilter = FilterByName; - options.categories = GetSelectedCategories(); - return options; - } - } - -} diff --git a/Assets/UnityTestTools/Common/Editor/TestFilterSettings.cs.meta b/Assets/UnityTestTools/Common/Editor/TestFilterSettings.cs.meta deleted file mode 100644 index 9a7a0e32..00000000 --- a/Assets/UnityTestTools/Common/Editor/TestFilterSettings.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 5a2d025e58bff433e963d0a4cd7599ef -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Common/Editor/icons.meta b/Assets/UnityTestTools/Common/Editor/icons.meta deleted file mode 100644 index 58c52486..00000000 --- a/Assets/UnityTestTools/Common/Editor/icons.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: e8bb6eae11352f44da0d6d8a8959b69e -DefaultImporter: - userData: diff --git a/Assets/UnityTestTools/Common/Editor/icons/failed.png b/Assets/UnityTestTools/Common/Editor/icons/failed.png deleted file mode 100644 index 7c0aba4c39aadc1b13bce95c85bbd61e2a0aadda..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1041 zcmds#KQBXJ6o*e+X{j_FXb4|`fy8X8+@`%1)gTc~B#ptsAi-#{nX8E)Qj=JWHlv{o z5|YMb@+pwi^P|1Fja!?=xq04m-t*_a=RNlx6bsozd?apW2{-2~pp&9E$~xVs=26kL z*{owtJ++&Q3ZA~L+{(6D|9}YD@#!$m*p54wiM@nV$)VA`)$v`k$eHV;m&Q_|N@Vkc zjDIDMW+kY@TMOAG|0TozP1`1^id}l7Jb_C-6Fg?sL1~Ls)paSGi1L8g)&IIyr0I?8|y}`l3LFT}L z1ABmMOaN5GgeeLU0m=yi@l7E10Eu8zxD6<2gv|h;_2ftq=McoIkwo93B7aZsAX1zdmZ^E_P~Lo`GgCo|{#0je05;L|y= x{~(Obb4=I-i4_}(nu!gY0Z>P?cpd=1K&=!{=T1BqYE=Z{db;|#taD0e0suQ^D8c{$ diff --git a/Assets/UnityTestTools/Common/Editor/icons/inconclusive.png.meta b/Assets/UnityTestTools/Common/Editor/icons/inconclusive.png.meta deleted file mode 100644 index 7c93bc45..00000000 --- a/Assets/UnityTestTools/Common/Editor/icons/inconclusive.png.meta +++ /dev/null @@ -1,35 +0,0 @@ -fileFormatVersion: 2 -guid: e28761099904678488cdddf7b6be2ceb -TextureImporter: - serializedVersion: 2 - mipmaps: - mipMapMode: 0 - enableMipMap: 0 - linearTexture: 1 - correctGamma: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: .25 - normalMapFilter: 0 - isReadable: 0 - grayScaleToAlpha: 0 - generateCubemap: 0 - seamlessCubemap: 0 - textureFormat: -1 - maxTextureSize: 1024 - textureSettings: - filterMode: -1 - aniso: 1 - mipBias: -1 - wrapMode: 1 - nPOTScale: 0 - lightmap: 0 - compressionQuality: 50 - textureType: 2 - buildTargetSettings: [] - userData: diff --git a/Assets/UnityTestTools/Common/Editor/icons/normal.png b/Assets/UnityTestTools/Common/Editor/icons/normal.png deleted file mode 100644 index 6a04f7951e1c8cd444038d7c122a43defb042d0d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1041 zcmeAS@N?(olHy`uVBq!ia0vp^{28_{{~`K zAT9>l+6ScJ0DFL0GMoXbD1xd2X*>_alc0PespAZDfv)%j#KuJGpp!D6bafYA#;O+} O>pWfkT-G@yGywqZQ$$Mu diff --git a/Assets/UnityTestTools/Common/Editor/icons/passed.png.meta b/Assets/UnityTestTools/Common/Editor/icons/passed.png.meta deleted file mode 100644 index 876d32d9..00000000 --- a/Assets/UnityTestTools/Common/Editor/icons/passed.png.meta +++ /dev/null @@ -1,35 +0,0 @@ -fileFormatVersion: 2 -guid: 31f7928179ee46d4690d274579efb037 -TextureImporter: - serializedVersion: 2 - mipmaps: - mipMapMode: 0 - enableMipMap: 0 - linearTexture: 1 - correctGamma: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: .25 - normalMapFilter: 0 - isReadable: 0 - grayScaleToAlpha: 0 - generateCubemap: 0 - seamlessCubemap: 0 - textureFormat: -1 - maxTextureSize: 1024 - textureSettings: - filterMode: -1 - aniso: 1 - mipBias: -1 - wrapMode: 1 - nPOTScale: 0 - lightmap: 0 - compressionQuality: 50 - textureType: 2 - buildTargetSettings: [] - userData: diff --git a/Assets/UnityTestTools/Common/Editor/icons/stopwatch.png b/Assets/UnityTestTools/Common/Editor/icons/stopwatch.png deleted file mode 100644 index ac5721c5f3acb01b587e0beebfd8818bd3444be3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1041 zcmdUuJxD@f6ox-D%oKA7Bbr(QTO^u_8Y-^XO%kaVqbO3Sp(yB&mIfiHR*5Jg9DCRsM4cYDijOI%J*UE(wuQOdln zYwdk*mnmi*|6<2~lAbdC+Uwqcw%;)v{RZ}OV)Fn1 diff --git a/Assets/UnityTestTools/Common/Editor/icons/stopwatch.png.meta b/Assets/UnityTestTools/Common/Editor/icons/stopwatch.png.meta deleted file mode 100644 index f39adad6..00000000 --- a/Assets/UnityTestTools/Common/Editor/icons/stopwatch.png.meta +++ /dev/null @@ -1,35 +0,0 @@ -fileFormatVersion: 2 -guid: f73f95ae19d51af47ad56044f2779aa1 -TextureImporter: - serializedVersion: 2 - mipmaps: - mipMapMode: 0 - enableMipMap: 0 - linearTexture: 1 - correctGamma: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: .25 - normalMapFilter: 0 - isReadable: 0 - grayScaleToAlpha: 0 - generateCubemap: 0 - seamlessCubemap: 0 - textureFormat: -1 - maxTextureSize: 1024 - textureSettings: - filterMode: -1 - aniso: 1 - mipBias: -1 - wrapMode: 1 - nPOTScale: 0 - lightmap: 0 - compressionQuality: 50 - textureType: 2 - buildTargetSettings: [] - userData: diff --git a/Assets/UnityTestTools/Common/ITestResult.cs b/Assets/UnityTestTools/Common/ITestResult.cs deleted file mode 100644 index 13f5fc3a..00000000 --- a/Assets/UnityTestTools/Common/ITestResult.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; -using UnityTest; - -public interface ITestResult -{ - TestResultState ResultState { get; } - - string Message { get; } - - string Logs { get; } - - bool Executed { get; } - - string Name { get; } - - string FullName { get; } - - string Id { get; } - - bool IsSuccess { get; } - - double Duration { get; } - - string StackTrace { get; } - - bool IsIgnored { get; } -} diff --git a/Assets/UnityTestTools/Common/ITestResult.cs.meta b/Assets/UnityTestTools/Common/ITestResult.cs.meta deleted file mode 100644 index 4864197a..00000000 --- a/Assets/UnityTestTools/Common/ITestResult.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: d1e4e2c4d00b3f2469494fc0f67cdeae -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Common/Settings.meta b/Assets/UnityTestTools/Common/Settings.meta deleted file mode 100644 index 93470c5b..00000000 --- a/Assets/UnityTestTools/Common/Settings.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: ca2c8df86920e0444aca6b59a0fe0a45 -folderAsset: yes -timeCreated: 1484387840 -licenseType: Pro -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/UnityTestTools/Common/Settings/IntegrationTestsRunnerSettings.asset b/Assets/UnityTestTools/Common/Settings/IntegrationTestsRunnerSettings.asset deleted file mode 100644 index 2f33e8b0..00000000 --- a/Assets/UnityTestTools/Common/Settings/IntegrationTestsRunnerSettings.asset +++ /dev/null @@ -1,15 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!114 &11400000 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 5d01dc4c8f278da489d7d54c83f19cb9, type: 3} - m_Name: IntegrationTestsRunnerSettings - m_EditorClassIdentifier: - blockUIWhenRunning: 1 - pauseOnTestFailure: 0 diff --git a/Assets/UnityTestTools/Common/Settings/IntegrationTestsRunnerSettings.asset.meta b/Assets/UnityTestTools/Common/Settings/IntegrationTestsRunnerSettings.asset.meta deleted file mode 100644 index d317a37a..00000000 --- a/Assets/UnityTestTools/Common/Settings/IntegrationTestsRunnerSettings.asset.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 29edbe2e215334846ba7ac06b16b3ba0 -timeCreated: 1484387840 -licenseType: Pro -NativeFormatImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/UnityTestTools/Common/TestResultState.cs b/Assets/UnityTestTools/Common/TestResultState.cs deleted file mode 100644 index 3dc4eb8c..00000000 --- a/Assets/UnityTestTools/Common/TestResultState.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace UnityTest -{ - public enum TestResultState : byte - { - Inconclusive = 0, - - /// - /// The test was not runnable. - /// - NotRunnable = 1, - - /// - /// The test has been skipped. - /// - Skipped = 2, - - /// - /// The test has been ignored. - /// - Ignored = 3, - - /// - /// The test succeeded - /// - Success = 4, - - /// - /// The test failed - /// - Failure = 5, - - /// - /// The test encountered an unexpected exception - /// - Error = 6, - - /// - /// The test was cancelled by the user - /// - Cancelled = 7 - } -} diff --git a/Assets/UnityTestTools/Common/TestResultState.cs.meta b/Assets/UnityTestTools/Common/TestResultState.cs.meta deleted file mode 100644 index e1576c7c..00000000 --- a/Assets/UnityTestTools/Common/TestResultState.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: da3ca54ee4cce064989d27165f3081fb -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/Documentation.url b/Assets/UnityTestTools/Documentation.url deleted file mode 100644 index 980b5854..00000000 --- a/Assets/UnityTestTools/Documentation.url +++ /dev/null @@ -1,3 +0,0 @@ -[InternetShortcut] -URL=https://bitbucket.org/Unity-Technologies/unitytesttools/wiki -IconIndex=0 \ No newline at end of file diff --git a/Assets/UnityTestTools/Documentation.url.meta b/Assets/UnityTestTools/Documentation.url.meta deleted file mode 100644 index b5db4964..00000000 --- a/Assets/UnityTestTools/Documentation.url.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: 28f1b62e1364e5a4e88f7bb94dbcf183 -DefaultImporter: - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework.meta b/Assets/UnityTestTools/IntegrationTestsFramework.meta deleted file mode 100644 index da228722..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework.meta +++ /dev/null @@ -1,5 +0,0 @@ -fileFormatVersion: 2 -guid: 241054a0fe63fbb4bb51609fce9b3112 -folderAsset: yes -DefaultImporter: - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/Libs.meta b/Assets/UnityTestTools/IntegrationTestsFramework/Libs.meta deleted file mode 100644 index 1b749751..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/Libs.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: e22ba039de7077c4aa95758ef723b803 -folderAsset: yes -timeCreated: 1445282049 -licenseType: Store -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/Libs/Mono.Cecil.Mdb.dll b/Assets/UnityTestTools/IntegrationTestsFramework/Libs/Mono.Cecil.Mdb.dll deleted file mode 100644 index 161d2fdc9b728475f7799f59634d3f42cc2e4710..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44544 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 R3;cgd^Z#Gj{|`Ly{{Tsl_^to| diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/Libs/Mono.Cecil.Mdb.dll.meta b/Assets/UnityTestTools/IntegrationTestsFramework/Libs/Mono.Cecil.Mdb.dll.meta deleted file mode 100644 index a040b4f3..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/Libs/Mono.Cecil.Mdb.dll.meta +++ /dev/null @@ -1,24 +0,0 @@ -fileFormatVersion: 2 -guid: 713231d47408a06408a45470c967bae8 -timeCreated: 1441797177 -licenseType: Store -PluginImporter: - serializedVersion: 1 - iconMap: {} - executionOrder: {} - isPreloaded: 0 - platformData: - Any: - enabled: 0 - settings: {} - Editor: - enabled: 1 - settings: - DefaultValueInitialized: true - WindowsStoreApps: - enabled: 0 - settings: - CPU: AnyCPU - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/Libs/Mono.Cecil.dll b/Assets/UnityTestTools/IntegrationTestsFramework/Libs/Mono.Cecil.dll deleted file mode 100644 index f55f7a5d011c6a36c694569265aad7b269d85844..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 280064 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 $uIBK8BM2f{#fBW!^FO!o4J0vCC5U7n6e{ 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 hxV9xbWkIML8hsyl04u4q={6EuebPoUk diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/Libs/Mono.Cecil.dll.meta b/Assets/UnityTestTools/IntegrationTestsFramework/Libs/Mono.Cecil.dll.meta deleted file mode 100644 index 88805bdd..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/Libs/Mono.Cecil.dll.meta +++ /dev/null @@ -1,24 +0,0 @@ -fileFormatVersion: 2 -guid: 28fc22990733f8f4ea1137f15e363609 -timeCreated: 1441797177 -licenseType: Store -PluginImporter: - serializedVersion: 1 - iconMap: {} - executionOrder: {} - isPreloaded: 0 - platformData: - Any: - enabled: 0 - settings: {} - Editor: - enabled: 1 - settings: - DefaultValueInitialized: true - WindowsStoreApps: - enabled: 0 - settings: - CPU: AnyCPU - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner.meta deleted file mode 100644 index c65a67d5..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner.meta +++ /dev/null @@ -1,5 +0,0 @@ -fileFormatVersion: 2 -guid: da93545c3ab1aa043bcfb22281b1f66c -folderAsset: yes -DefaultImporter: - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/DTOFormatter.cs b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/DTOFormatter.cs deleted file mode 100644 index f974b7c1..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/DTOFormatter.cs +++ /dev/null @@ -1,140 +0,0 @@ -using System; -using System.IO; -using System.Runtime.Serialization; -using System.Text; -using UnityEngine; - -namespace UnityTest -{ - - public class DTOFormatter { - - private interface ITransferInterface - { - void Transfer(ref ResultDTO.MessageType val); - void Transfer(ref TestResultState val); - void Transfer(ref byte val); - void Transfer(ref bool val); - void Transfer(ref int val); - void Transfer(ref float val); - void Transfer(ref double val); - void Transfer(ref string val); - } - - private class Writer : ITransferInterface - { - private readonly Stream _stream; - public Writer(Stream stream) { _stream = stream; } - - private void WriteConvertedNumber(byte[] bytes) - { - if(BitConverter.IsLittleEndian) - Array.Reverse(bytes); - _stream.Write(bytes, 0, bytes.Length); - } - - public void Transfer(ref ResultDTO.MessageType val) { _stream.WriteByte((byte)val); } - public void Transfer(ref TestResultState val) { _stream.WriteByte((byte)val); } - public void Transfer(ref byte val) { _stream.WriteByte(val); } - public void Transfer(ref bool val) { _stream.WriteByte((byte)(val ? 0x01 : 0x00)); } - public void Transfer(ref int val) { WriteConvertedNumber(BitConverter.GetBytes(val)); } - public void Transfer(ref float val) { WriteConvertedNumber(BitConverter.GetBytes(val)); } - public void Transfer(ref double val) { WriteConvertedNumber(BitConverter.GetBytes(val)); } - - public void Transfer(ref string val) - { - var bytes = Encoding.BigEndianUnicode.GetBytes(val); - int length = bytes.Length; - Transfer(ref length); - _stream.Write(bytes, 0, bytes.Length); - } - } - - private class Reader : ITransferInterface - { - private readonly Stream _stream; - public Reader(Stream stream) { _stream = stream; } - - private byte[] ReadConvertedNumber(int size) - { - byte[] buffer = new byte[size]; - _stream.Read (buffer, 0, buffer.Length); - if(BitConverter.IsLittleEndian) - Array.Reverse(buffer); - return buffer; - } - - public void Transfer(ref ResultDTO.MessageType val) { val = (ResultDTO.MessageType)_stream.ReadByte(); } - public void Transfer(ref TestResultState val) { val = (TestResultState)_stream.ReadByte(); } - public void Transfer(ref byte val) { val = (byte)_stream.ReadByte(); } - public void Transfer(ref bool val) { val = (_stream.ReadByte() != 0); } - public void Transfer(ref int val) { val = BitConverter.ToInt32(ReadConvertedNumber(4), 0); } - public void Transfer(ref float val) { val = BitConverter.ToSingle(ReadConvertedNumber(4), 0); } - public void Transfer(ref double val) { val = BitConverter.ToDouble(ReadConvertedNumber(8), 0); } - - public void Transfer(ref string val) - { - int length = 0; - Transfer (ref length); - var bytes = new byte[length]; - int remain = length; - int index = 0; - do { - int bytesRead = _stream.Read(bytes, index, remain); - remain -= bytesRead; - index += bytesRead; - } while (remain > 0); - val = Encoding.BigEndianUnicode.GetString(bytes); - } - } - - private void Transfer(ResultDTO dto, ITransferInterface transfer) - { - transfer.Transfer(ref dto.messageType); - - transfer.Transfer(ref dto.levelCount); - transfer.Transfer(ref dto.loadedLevel); - transfer.Transfer(ref dto.loadedLevelName); - - if(dto.messageType == ResultDTO.MessageType.Ping - || dto.messageType == ResultDTO.MessageType.RunStarted - || dto.messageType == ResultDTO.MessageType.RunFinished - || dto.messageType == ResultDTO.MessageType.RunInterrupted - || dto.messageType == ResultDTO.MessageType.AllScenesFinished) - return; - - transfer.Transfer(ref dto.testName); - transfer.Transfer(ref dto.testTimeout); - - if(dto.messageType == ResultDTO.MessageType.TestStarted) - return; - - if(transfer is Reader) - dto.testResult = new SerializableTestResult(); - SerializableTestResult str = (SerializableTestResult)dto.testResult; - - transfer.Transfer(ref str.resultState); - transfer.Transfer(ref str.message); - transfer.Transfer(ref str.executed); - transfer.Transfer(ref str.name); - transfer.Transfer(ref str.fullName); - transfer.Transfer(ref str.id); - transfer.Transfer(ref str.isSuccess); - transfer.Transfer(ref str.duration); - transfer.Transfer(ref str.stackTrace); - } - - public void Serialize (Stream stream, ResultDTO dto) - { - Transfer(dto, new Writer(stream)); - } - - public object Deserialize (Stream stream) - { - var result = (ResultDTO)FormatterServices.GetSafeUninitializedObject(typeof(ResultDTO)); - Transfer (result, new Reader(stream)); - return result; - } - } - -} \ No newline at end of file diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/DTOFormatter.cs.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/DTOFormatter.cs.meta deleted file mode 100644 index f83bde0c..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/DTOFormatter.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 7ae2470508a854b1c9df5375d03f8f58 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor.meta deleted file mode 100644 index bd38839c..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor.meta +++ /dev/null @@ -1,5 +0,0 @@ -fileFormatVersion: 2 -guid: caee08596a5965747b8edfde19e2f873 -folderAsset: yes -DefaultImporter: - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Batch.cs b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Batch.cs deleted file mode 100644 index da55f1d5..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Batch.cs +++ /dev/null @@ -1,200 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using UnityEditor; -using UnityEditorInternal; -using UnityEngine; -using UnityTest.IntegrationTests; -using UnityEditor.SceneManagement; - -namespace UnityTest -{ - public static partial class Batch - { - const string k_ResultFilePathParam = "-resultFilePath="; - private const string k_TestScenesParam = "-testscenes="; - private const string k_OtherBuildScenesParam = "-includeBuildScenes="; - const string k_TargetPlatformParam = "-targetPlatform="; - const string k_ResultFileDirParam = "-resultsFileDirectory="; - - public static int returnCodeTestsOk = 0; - public static int returnCodeTestsFailed = 2; - public static int returnCodeRunError = 3; - - public static void RunIntegrationTests() - { - var targetPlatform = GetTargetPlatform(); - var otherBuildScenes = GetSceneListFromParam (k_OtherBuildScenesParam); - - var testScenes = GetSceneListFromParam(k_TestScenesParam); - if (testScenes.Count == 0) - testScenes = FindTestScenesInProject(); - - RunIntegrationTests(targetPlatform, testScenes, otherBuildScenes); - } - - public static void RunIntegrationTests(BuildTarget ? targetPlatform) - { - var sceneList = FindTestScenesInProject(); - RunIntegrationTests(targetPlatform, sceneList, new List()); - } - - - public static void RunIntegrationTests(BuildTarget? targetPlatform, List testScenes, List otherBuildScenes) - { - if (targetPlatform.HasValue) - BuildAndRun(targetPlatform.Value, testScenes, otherBuildScenes); - else - RunInEditor(testScenes, otherBuildScenes); - } - - private static void BuildAndRun(BuildTarget target, List testScenes, List otherBuildScenes) - { - var resultFilePath = GetParameterArgument(k_ResultFileDirParam); - - const int port = 0; - var ipList = TestRunnerConfigurator.GetAvailableNetworkIPs(); - - var config = new PlatformRunnerConfiguration - { - buildTarget = target, - buildScenes = otherBuildScenes, - testScenes = testScenes, - projectName = "IntegrationTests", - resultsDir = resultFilePath, - sendResultsOverNetwork = InternalEditorUtility.inBatchMode, - ipList = ipList, - port = port - }; - - if (Application.isWebPlayer) - { - config.sendResultsOverNetwork = false; - Debug.Log("You can't use WebPlayer as active platform for running integration tests. Switching to Standalone"); - EditorUserBuildSettings.SwitchActiveBuildTarget(BuildTarget.StandaloneWindows); - } - - PlatformRunner.BuildAndRunInPlayer(config); - } - - private static void RunInEditor(List testScenes, List otherBuildScenes) - { - CheckActiveBuildTarget(); - - NetworkResultsReceiver.StopReceiver(); - if (testScenes == null || testScenes.Count == 0) - { - Debug.Log("No test scenes on the list"); - EditorApplication.Exit(returnCodeRunError); - return; - } - - string previousScenesXml = ""; - var serializer = new System.Xml.Serialization.XmlSerializer(typeof(EditorBuildSettingsScene[])); - using(StringWriter textWriter = new StringWriter()) - { - serializer.Serialize(textWriter, EditorBuildSettings.scenes); - previousScenesXml = textWriter.ToString(); - } - - EditorBuildSettings.scenes = (testScenes.Concat(otherBuildScenes).ToList()).Select(s => new EditorBuildSettingsScene(s, true)).ToArray(); - EditorSceneManager.OpenScene(testScenes.First()); - GuiHelper.SetConsoleErrorPause(false); - - var config = new PlatformRunnerConfiguration - { - resultsDir = GetParameterArgument(k_ResultFileDirParam), - ipList = TestRunnerConfigurator.GetAvailableNetworkIPs(), - port = PlatformRunnerConfiguration.TryToGetFreePort(), - runInEditor = true - }; - - var settings = new PlayerSettingConfigurator(true); - settings.AddConfigurationFile(TestRunnerConfigurator.integrationTestsNetwork, string.Join("\n", config.GetConnectionIPs())); - settings.AddConfigurationFile(TestRunnerConfigurator.testScenesToRun, string.Join ("\n", testScenes.ToArray())); - settings.AddConfigurationFile(TestRunnerConfigurator.previousScenes, previousScenesXml); - - NetworkResultsReceiver.StartReceiver(config); - - EditorApplication.isPlaying = true; - } - - private static string GetParameterArgument(string parameterName) - { - foreach (var arg in Environment.GetCommandLineArgs()) - { - if (arg.ToLower().StartsWith(parameterName.ToLower())) - { - return arg.Substring(parameterName.Length); - } - } - return null; - } - - static void CheckActiveBuildTarget() - { - var notSupportedPlatforms = new[] { "MetroPlayer", "WebPlayer", "WebPlayerStreamed" }; - if (notSupportedPlatforms.Contains(EditorUserBuildSettings.activeBuildTarget.ToString())) - { - Debug.Log("activeBuildTarget can not be " - + EditorUserBuildSettings.activeBuildTarget + - " use buildTarget parameter to open Unity."); - } - } - - private static BuildTarget ? GetTargetPlatform() - { - string platformString = null; - BuildTarget buildTarget; - foreach (var arg in Environment.GetCommandLineArgs()) - { - if (arg.ToLower().StartsWith(k_TargetPlatformParam.ToLower())) - { - platformString = arg.Substring(k_ResultFilePathParam.Length); - break; - } - } - try - { - if (platformString == null) return null; - buildTarget = (BuildTarget)Enum.Parse(typeof(BuildTarget), platformString); - } - catch - { - return null; - } - return buildTarget; - } - - private static List FindTestScenesInProject() - { - var integrationTestScenePattern = "*Test?.unity"; - return Directory.GetFiles("Assets", integrationTestScenePattern, SearchOption.AllDirectories).ToList(); - } - - private static List GetSceneListFromParam(string param) - { - var sceneList = new List(); - foreach (var arg in Environment.GetCommandLineArgs()) - { - if (arg.ToLower().StartsWith(param.ToLower())) - { - var scenesFromParam = arg.Substring(param.Length).Split(','); - foreach (var scene in scenesFromParam) - { - var sceneName = scene; - if (!sceneName.EndsWith(".unity")) - sceneName += ".unity"; - var foundScenes = Directory.GetFiles(Directory.GetCurrentDirectory(), sceneName, SearchOption.AllDirectories); - if (foundScenes.Length == 1) - sceneList.Add(foundScenes[0].Substring(Directory.GetCurrentDirectory().Length + 1)); - else - Debug.Log(sceneName + " not found or multiple entries found"); - } - } - } - return sceneList.Where(s => !string.IsNullOrEmpty(s)).Distinct().ToList(); - } - } -} diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Batch.cs.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Batch.cs.meta deleted file mode 100644 index 248a6ce2..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Batch.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 29d4fb050362c5b43aea52342045543a -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/EditorReferencesUtil.cs b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/EditorReferencesUtil.cs deleted file mode 100644 index 3d762b80..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/EditorReferencesUtil.cs +++ /dev/null @@ -1,102 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using UnityEditor; -using UnityEngine; -using Object = UnityEngine.Object; - -namespace UnityTest -{ - public static class EditorReferencesUtil - { - - public static List FindScenesWhichContainAsset(string file) - { - string assetPath = GetAssetPathFromFileNameAndExtension (file); - Object cur = AssetDatabase.LoadAssetAtPath(assetPath, typeof(Object)); - return AllScenes.Where(a => ADependsOnB(a, cur)).ToList(); - } - - private static string CleanPathSeparators(string s) - { - const string forwardSlash = "/"; - const string backSlash = "\\"; - return s.Replace(backSlash, forwardSlash); - } - - private static string GetRelativeAssetPathFromFullPath(string fullPath) - { - fullPath = CleanPathSeparators(fullPath); - if (fullPath.Contains(Application.dataPath)) - { - return fullPath.Replace(Application.dataPath, "Assets"); - } - Debug.LogWarning("Path does not point to a location within Assets: " + fullPath); - return null; - } - - private static string GetAssetPathFromFileNameAndExtension(string assetName) - { - string[] assets = AssetDatabase.FindAssets (Path.GetFileNameWithoutExtension (assetName)); - string assetPath = null; - - foreach (string guid in assets) { - string relativePath = AssetDatabase.GUIDToAssetPath (guid); - - if (Path.GetFileName (relativePath) == Path.GetFileName (assetName)) - assetPath = relativePath; - } - - return assetPath; - } - - private static List DirSearch(DirectoryInfo d, string searchFor) - { - List founditems = d.GetFiles(searchFor).ToList(); - - // Add (by recursing) subdirectory items. - DirectoryInfo[] dis = d.GetDirectories(); - foreach (DirectoryInfo di in dis) - founditems.AddRange(DirSearch(di, searchFor)); - - return (founditems); - } - - private static List AllScenes - { - get - { - // get every single one of the files in the Assets folder. - List files = DirSearch(new DirectoryInfo(Application.dataPath), "*.unity"); - - // now make them all into Asset references. - List assetRefs = new List(); - - foreach (FileInfo fi in files) - { - if (fi.Name.StartsWith(".")) - continue; // Unity ignores dotfiles. - assetRefs.Add(AssetDatabase.LoadMainAssetAtPath(GetRelativeAssetPathFromFullPath(fi.FullName))); - } - return assetRefs; - } - } - - private static bool ADependsOnB(Object obj, Object selectedObj) - { - if (selectedObj == null) return false; - - //optionally, exclude self. - if (selectedObj == obj) return false; - - Object[] dependencies = EditorUtility.CollectDependencies(new Object[1] { obj }); - if (dependencies.Length < 2) return false; // if there's only one, it's us. - - foreach (Object dep in dependencies) - if (dep == selectedObj) - return true; - return false; - } - } -} \ No newline at end of file diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/EditorReferencesUtil.cs.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/EditorReferencesUtil.cs.meta deleted file mode 100644 index 78bcfabf..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/EditorReferencesUtil.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: aad501c968b324cf3a8d1c52eb09ca04 -timeCreated: 1437322927 -licenseType: Store -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/GuiHelper.cs b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/GuiHelper.cs deleted file mode 100644 index 7c213ba0..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/GuiHelper.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Text.RegularExpressions; -using Mono.Cecil; -using Mono.Cecil.Cil; -using Mono.Cecil.Mdb; -using Mono.Collections.Generic; -using UnityEditor; -using UnityEditorInternal; -using UnityEngine; - -namespace UnityTest -{ - public static class GuiHelper - { - public static bool GetConsoleErrorPause() - { - Assembly assembly = Assembly.GetAssembly(typeof(SceneView)); - Type type = assembly.GetType("UnityEditorInternal.LogEntries"); - PropertyInfo method = type.GetProperty("consoleFlags"); - var result = (int)method.GetValue(new object(), new object[] { }); - return (result & (1 << 2)) != 0; - } - - public static void SetConsoleErrorPause(bool b) - { - Assembly assembly = Assembly.GetAssembly(typeof(SceneView)); - Type type = assembly.GetType("UnityEditorInternal.LogEntries"); - MethodInfo method = type.GetMethod("SetConsoleFlag"); - method.Invoke(new object(), new object[] { 1 << 2, b }); - } - } -} diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/GuiHelper.cs.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/GuiHelper.cs.meta deleted file mode 100644 index 596d39f3..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/GuiHelper.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: b0b95014154ef554485afc9c0316556d -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsHierarchyAnnotation.cs b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsHierarchyAnnotation.cs deleted file mode 100644 index 4aa5dc41..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsHierarchyAnnotation.cs +++ /dev/null @@ -1,44 +0,0 @@ -using UnityEngine; -using System.Collections; -using UnityEditor; - -namespace UnityTest -{ - - [InitializeOnLoad] - public class IntegrationTestsHierarchyAnnotation { - - static IntegrationTestsHierarchyAnnotation() - { - EditorApplication.hierarchyWindowItemOnGUI += DoAnnotationGUI; - } - - public static void DoAnnotationGUI(int id, Rect rect) - { - var obj = EditorUtility.InstanceIDToObject(id) as GameObject; - if(!obj) return; - - var tc = obj.GetComponent(); - if(!tc) return; - - if (!EditorApplication.isPlayingOrWillChangePlaymode - && rect.Contains(Event.current.mousePosition) - && Event.current.type == EventType.MouseDown - && Event.current.button == 1) - { - IntegrationTestRendererBase.DrawContextMenu(tc); - Event.current.Use (); - } - - EditorGUIUtility.SetIconSize(new Vector2(15, 15)); - var result = IntegrationTestsRunnerWindow.GetResultForTest(tc); - if (result != null) - { - var icon = result.Executed ? IntegrationTestRendererBase.GetIconForResult(result.resultType) : Icons.UnknownImg; - EditorGUI.LabelField(new Rect(rect.xMax - 18, rect.yMin - 2, rect.width, rect.height), new GUIContent(icon)); - } - EditorGUIUtility.SetIconSize(Vector2.zero); - } - } - -} \ No newline at end of file diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsHierarchyAnnotation.cs.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsHierarchyAnnotation.cs.meta deleted file mode 100644 index 4154bdc9..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsHierarchyAnnotation.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 219cdb080b08741948fc5deb8c7d47f0 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsRunnerSettings.cs b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsRunnerSettings.cs deleted file mode 100644 index 1e8e466d..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsRunnerSettings.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; -using UnityEditor; - -namespace UnityTest -{ - public class IntegrationTestsRunnerSettings : ProjectSettingsBase - { - public bool blockUIWhenRunning = true; - public bool pauseOnTestFailure; - - public void ToggleBlockUIWhenRunning () - { - blockUIWhenRunning = !blockUIWhenRunning; - Save (); - } - - public void TogglePauseOnTestFailure() - { - pauseOnTestFailure = !pauseOnTestFailure; - Save (); - } - } -} diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsRunnerSettings.cs.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsRunnerSettings.cs.meta deleted file mode 100644 index d18086a7..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsRunnerSettings.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 5d01dc4c8f278da489d7d54c83f19cb9 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsRunnerWindow.cs b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsRunnerWindow.cs deleted file mode 100644 index 2a5ed8d1..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsRunnerWindow.cs +++ /dev/null @@ -1,590 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; -using UnityEditor; -using UnityEngine; -using UnityTest.IntegrationTestRunner; -using UnityEngine.SceneManagement; - -namespace UnityTest -{ - [Serializable] - public class IntegrationTestsRunnerWindow : EditorWindow, IHasCustomMenu - { - #region GUI Contents - private readonly GUIContent m_GUICreateNewTest = new GUIContent("Create", "Create new test"); - private readonly GUIContent m_GUIRunSelectedTests = new GUIContent("Run Selected", "Run selected test(s)"); - private readonly GUIContent m_GUIRunAllTests = new GUIContent("Run All", "Run all tests"); - private readonly GUIContent m_GUIBlockUI = new GUIContent("Block UI when running", "Block UI when running tests"); - private readonly GUIContent m_GUIPauseOnFailure = new GUIContent("Pause on test failure"); - #endregion - - #region runner steerign vars - private static IntegrationTestsRunnerWindow s_Instance; - [SerializeField] private List m_TestsToRun; - [SerializeField] private List m_DynamicTestsToRun; - [SerializeField] private bool m_ReadyToRun; - private bool m_IsBuilding; - public static bool selectedInHierarchy; - private float m_HorizontalSplitBarPosition = 200; - private Vector2 m_TestInfoScroll, m_TestListScroll; - private IntegrationTestRendererBase[] m_TestLines; - private string m_CurrectSceneName; - private TestFilterSettings m_FilterSettings; - - Vector2 m_resultTextSize; - string m_resultText; - GameObject m_lastSelectedGO; - int m_resultTestMaxLength = 15000; - - [SerializeField] private GameObject m_SelectedLine; - [SerializeField] private List m_ResultList = new List(); - [SerializeField] private List m_FoldMarkers = new List(); - - private IntegrationTestsRunnerSettings m_Settings; - - #endregion - - - static IntegrationTestsRunnerWindow() - { - InitBackgroundRunners(); - } - - private static void InitBackgroundRunners() - { - EditorApplication.hierarchyWindowItemOnGUI -= OnHierarchyWindowItemDraw; - EditorApplication.hierarchyWindowItemOnGUI += OnHierarchyWindowItemDraw; - EditorApplication.hierarchyWindowChanged -= OnHierarchyChangeUpdate; - EditorApplication.hierarchyWindowChanged += OnHierarchyChangeUpdate; - EditorApplication.update -= BackgroundSceneChangeWatch; - EditorApplication.update += BackgroundSceneChangeWatch; - EditorApplication.playmodeStateChanged -= OnPlaymodeStateChanged; - EditorApplication.playmodeStateChanged += OnPlaymodeStateChanged; - } - - private static void OnPlaymodeStateChanged() - { - if (s_Instance && EditorApplication.isPlaying == EditorApplication.isPlayingOrWillChangePlaymode) - s_Instance.RebuildTestList(); - } - - public void OnDestroy() - { - EditorApplication.hierarchyWindowItemOnGUI -= OnHierarchyWindowItemDraw; - EditorApplication.update -= BackgroundSceneChangeWatch; - EditorApplication.hierarchyWindowChanged -= OnHierarchyChangeUpdate; - EditorApplication.playmodeStateChanged -= OnPlaymodeStateChanged; - - TestComponent.DestroyAllDynamicTests(); - } - - private static void BackgroundSceneChangeWatch() - { - if (!s_Instance) return; - var currentScene = SceneManager.GetActiveScene().path; - if (s_Instance.m_CurrectSceneName != null && s_Instance.m_CurrectSceneName == currentScene) return; - if (EditorApplication.isPlayingOrWillChangePlaymode) return; - TestComponent.DestroyAllDynamicTests(); - s_Instance.m_CurrectSceneName = currentScene; - s_Instance.m_ResultList.Clear(); - s_Instance.RebuildTestList(); - } - - public void OnEnable() - { - titleContent = new GUIContent("Integration Tests"); - s_Instance = this; - - m_Settings = ProjectSettingsBase.Load(); - m_FilterSettings = new TestFilterSettings("UnityTest.IntegrationTestsRunnerWindow"); - - InitBackgroundRunners(); - if (!EditorApplication.isPlayingOrWillChangePlaymode && !m_ReadyToRun) RebuildTestList(); - } - - public void OnSelectionChange() - { - if (EditorApplication.isPlayingOrWillChangePlaymode - || Selection.objects == null - || Selection.objects.Length == 0) return; - - if (Selection.gameObjects.Length == 1) - { - var go = Selection.gameObjects.Single(); - var temp = go.transform; - while (temp != null) - { - var tc = temp.GetComponent(); - if (tc != null) break; - temp = temp.parent; - } - - if (temp != null) - { - SelectInHierarchy(temp.gameObject); - Selection.activeGameObject = temp.gameObject; - m_SelectedLine = temp.gameObject; - } - } - } - - public static void OnHierarchyChangeUpdate() - { - if (!s_Instance || s_Instance.m_TestLines == null || EditorApplication.isPlayingOrWillChangePlaymode) return; - - // create a test runner if it doesn't exist - TestRunner.GetTestRunner(); - - // make tests are not places under a go that is not a test itself - foreach (var test in TestComponent.FindAllTestsOnScene()) - { - if (test.gameObject.transform.parent != null && test.gameObject.transform.parent.gameObject.GetComponent() == null) - { - test.gameObject.transform.parent = null; - Debug.LogWarning("Tests need to be on top of the hierarchy or directly under another test."); - } - } - if (selectedInHierarchy) selectedInHierarchy = false; - else s_Instance.RebuildTestList(); - } - - public static TestResult GetResultForTest(TestComponent tc) - { - if(!s_Instance) return new TestResult(tc); - return s_Instance.m_ResultList.FirstOrDefault(r => r.GameObject == tc.gameObject); - } - - public static void OnHierarchyWindowItemDraw(int id, Rect rect) - { - var o = EditorUtility.InstanceIDToObject(id); - if (o is GameObject) - { - var go = o as GameObject; - - if (Event.current.type == EventType.MouseDown - && Event.current.button == 0 - && rect.Contains(Event.current.mousePosition)) - { - var temp = go.transform; - while (temp != null) - { - var c = temp.GetComponent(); - if (c != null) break; - temp = temp.parent; - } - if (temp != null) SelectInHierarchy(temp.gameObject); - } - } - } - - private static void SelectInHierarchy(GameObject gameObject) - { - if (!s_Instance) return; - if (gameObject == s_Instance.m_SelectedLine && gameObject.activeInHierarchy) return; - if (EditorApplication.isPlayingOrWillChangePlaymode) return; - if (!gameObject.activeSelf) - { - selectedInHierarchy = true; - gameObject.SetActive(true); - } - - var tests = TestComponent.FindAllTestsOnScene(); - var skipList = gameObject.GetComponentsInChildren(typeof(TestComponent), true).ToList(); - tests.RemoveAll(skipList.Contains); - foreach (var test in tests) - { - var enable = test.GetComponentsInChildren(typeof(TestComponent), true).Any(c => c.gameObject == gameObject); - if (test.gameObject.activeSelf != enable) test.gameObject.SetActive(enable); - } - } - - private void RunTests(IList tests) - { - if (!tests.Any() || EditorApplication.isCompiling || EditorApplication.isPlayingOrWillChangePlaymode) - return; - FocusWindowIfItsOpen(GetType()); - - var testComponents = tests.Where(t => t is TestComponent).Cast().ToList(); - var dynaminTests = testComponents.Where(t => t.dynamic).ToList(); - m_DynamicTestsToRun = dynaminTests.Select(c => c.dynamicTypeName).ToList(); - testComponents.RemoveAll(dynaminTests.Contains); - - m_TestsToRun = testComponents.Select( tc => tc.gameObject ).ToList(); - - m_ReadyToRun = true; - TestComponent.DisableAllTests(); - - EditorApplication.isPlaying = true; - } - - public void Update() - { - if (m_ReadyToRun && EditorApplication.isPlaying) - { - m_ReadyToRun = false; - var testRunner = TestRunner.GetTestRunner(); - testRunner.TestRunnerCallback.Add(new RunnerCallback(this)); - var testComponents = m_TestsToRun.Select(go => go.GetComponent()).ToList(); - testRunner.InitRunner(testComponents, m_DynamicTestsToRun); - } - } - - private void RebuildTestList() - { - m_TestLines = null; - if (!TestComponent.AnyTestsOnScene() - && !TestComponent.AnyDynamicTestForCurrentScene()) return; - - if (!EditorApplication.isPlayingOrWillChangePlaymode) - { - var dynamicTestsOnScene = TestComponent.FindAllDynamicTestsOnScene(); - var dynamicTestTypes = TestComponent.GetTypesWithHelpAttribute(SceneManager.GetActiveScene().path); - - foreach (var dynamicTestType in dynamicTestTypes) - { - var existingTests = dynamicTestsOnScene.Where(component => component.dynamicTypeName == dynamicTestType.AssemblyQualifiedName); - if (existingTests.Any()) - { - var testComponent = existingTests.Single(); - foreach (var c in testComponent.gameObject.GetComponents()) - { - var type = Type.GetType(testComponent.dynamicTypeName); - if (c is TestComponent || c is Transform || type.IsInstanceOfType(c)) continue; - DestroyImmediate(c); - } - dynamicTestsOnScene.Remove(existingTests.Single()); - continue; - } - TestComponent.CreateDynamicTest(dynamicTestType); - } - - foreach (var testComponent in dynamicTestsOnScene) - DestroyImmediate(testComponent.gameObject); - } - - var topTestList = TestComponent.FindAllTopTestsOnScene(); - - var newResultList = new List(); - m_TestLines = ParseTestList(topTestList, newResultList); - - var oldDynamicResults = m_ResultList.Where(result => result.dynamicTest); - foreach (var oldResult in m_ResultList) - { - var result = newResultList.Find(r => r.Id == oldResult.Id); - if (result == null) continue; - result.Update(oldResult); - } - newResultList.AddRange(oldDynamicResults.Where(r => !newResultList.Contains(r))); - m_ResultList = newResultList; - - IntegrationTestRendererBase.RunTest = RunTests; - IntegrationTestGroupLine.FoldMarkers = m_FoldMarkers; - IntegrationTestLine.Results = m_ResultList; - - m_FilterSettings.UpdateCounters(m_ResultList.Cast()); - - m_FoldMarkers.RemoveAll(o => o == null); - - selectedInHierarchy = true; - Repaint(); - } - - - private IntegrationTestRendererBase[] ParseTestList(List testList, List results) - { - var tempList = new List(); - foreach (var testObject in testList) - { - if (!testObject.IsTestGroup()) - { - var result = new TestResult(testObject); - if (results != null) - results.Add(result); - tempList.Add(new IntegrationTestLine(testObject.gameObject, result)); - continue; - } - var group = new IntegrationTestGroupLine(testObject.gameObject); - var children = testObject.gameObject.GetComponentsInChildren(typeof(TestComponent), true).Cast().ToList(); - children = children.Where(c => c.gameObject.transform.parent == testObject.gameObject.transform).ToList(); - group.AddChildren(ParseTestList(children, results)); - tempList.Add(group); - } - tempList.Sort(); - return tempList.ToArray(); - } - - public void OnGUI() - { - if (BuildPipeline.isBuildingPlayer) - { - m_IsBuilding = true; - } - else if (m_IsBuilding) - { - m_IsBuilding = false; - Repaint(); - } - - PrintHeadPanel(); - - EditorGUILayout.BeginVertical(Styles.testList); - m_TestListScroll = EditorGUILayout.BeginScrollView(m_TestListScroll); - bool repaint = PrintTestList(m_TestLines); - GUILayout.FlexibleSpace(); - EditorGUILayout.EndScrollView(); - EditorGUILayout.EndVertical(); - - RenderDetails(); - - if (repaint) Repaint(); - } - - public void PrintHeadPanel() - { - EditorGUILayout.BeginHorizontal(EditorStyles.toolbar); - EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode); - if (GUILayout.Button(m_GUIRunAllTests, EditorStyles.toolbarButton)) - { - RunTests(TestComponent.FindAllTestsOnScene().Cast().ToList()); - } - EditorGUI.BeginDisabledGroup(!Selection.gameObjects.Any (t => t.GetComponent(typeof(ITestComponent)))); - if (GUILayout.Button(m_GUIRunSelectedTests, EditorStyles.toolbarButton)) - { - RunTests(Selection.gameObjects.Select(t => t.GetComponent(typeof(TestComponent))).Cast().ToList()); - } - EditorGUI.EndDisabledGroup(); - if (GUILayout.Button(m_GUICreateNewTest, EditorStyles.toolbarButton)) - { - var test = TestComponent.CreateTest(); - if (Selection.gameObjects.Length == 1 - && Selection.activeGameObject != null - && Selection.activeGameObject.GetComponent()) - { - test.transform.parent = Selection.activeGameObject.transform.parent; - } - Selection.activeGameObject = test; - RebuildTestList(); - } - EditorGUI.EndDisabledGroup(); - - GUILayout.FlexibleSpace (); - - m_FilterSettings.OnGUI (); - - EditorGUILayout.EndHorizontal (); - } - - public void AddItemsToMenu(GenericMenu menu) - { - menu.AddItem(m_GUIBlockUI, m_Settings.blockUIWhenRunning, m_Settings.ToggleBlockUIWhenRunning); - menu.AddItem(m_GUIPauseOnFailure, m_Settings.pauseOnTestFailure, m_Settings.TogglePauseOnTestFailure); - } - - private bool PrintTestList(IntegrationTestRendererBase[] renderedLines) - { - if (renderedLines == null) return false; - - var filter = m_FilterSettings.BuildRenderingOptions(); - - bool repaint = false; - foreach (var renderedLine in renderedLines) - { - repaint |= renderedLine.Render(filter); - } - return repaint; - } - - private void RenderDetails() - { - var ctrlId = GUIUtility.GetControlID(FocusType.Passive); - - Rect rect = GUILayoutUtility.GetLastRect(); - rect.y = rect.height + rect.y - 1; - rect.height = 3; - - EditorGUIUtility.AddCursorRect(rect, MouseCursor.ResizeVertical); - var e = Event.current; - switch (e.type) - { - case EventType.MouseDown: - if (GUIUtility.hotControl == 0 && rect.Contains(e.mousePosition)) - GUIUtility.hotControl = ctrlId; - break; - case EventType.MouseDrag: - if (GUIUtility.hotControl == ctrlId) - { - m_HorizontalSplitBarPosition -= e.delta.y; - if (m_HorizontalSplitBarPosition < 20) m_HorizontalSplitBarPosition = 20; - Repaint(); - } - break; - case EventType.MouseUp: - if (GUIUtility.hotControl == ctrlId) - GUIUtility.hotControl = 0; - break; - } - - m_TestInfoScroll = EditorGUILayout.BeginScrollView(m_TestInfoScroll, GUILayout.MinHeight(m_HorizontalSplitBarPosition)); - - if (m_SelectedLine != null) - UpdateResultText(m_SelectedLine); - - EditorGUILayout.SelectableLabel(m_resultText, Styles.info, - GUILayout.ExpandHeight(true), - GUILayout.ExpandWidth(true), - GUILayout.MinWidth(m_resultTextSize.x), - GUILayout.MinHeight(m_resultTextSize.y)); - EditorGUILayout.EndScrollView(); - } - - private void UpdateResultText(GameObject go) - { - if(go == m_lastSelectedGO) return; - m_lastSelectedGO = go; - var result = m_ResultList.Find(r => r.GameObject == go); - if (result == null) - { - m_resultText = string.Empty; - m_resultTextSize = Styles.info.CalcSize(new GUIContent(string.Empty)); - return; - } - var sb = new StringBuilder(result.Name.Trim()); - if (!string.IsNullOrEmpty(result.messages)) - { - sb.Append("\n---\n"); - sb.Append(result.messages.Trim()); - } - if (!string.IsNullOrEmpty(result.stacktrace)) - { - sb.Append("\n---\n"); - sb.Append(result.stacktrace.Trim()); - } - if(sb.Length>m_resultTestMaxLength) - { - sb.Length = m_resultTestMaxLength; - sb.AppendFormat("...\n\n---MESSAGE TRUNCATED AT {0} CHARACTERS---", m_resultTestMaxLength); - } - m_resultText = sb.ToString().Trim(); - m_resultTextSize = Styles.info.CalcSize(new GUIContent(m_resultText)); - } - - public void OnInspectorUpdate() - { - if (focusedWindow != this) Repaint(); - } - - private void SetCurrentTest(TestComponent tc) - { - foreach (var line in m_TestLines) - line.SetCurrentTest(tc); - } - - class RunnerCallback : ITestRunnerCallback - { - private readonly IntegrationTestsRunnerWindow m_Window; - private int m_TestNumber; - private int m_CurrentTestNumber; - - private readonly bool m_ConsoleErrorOnPauseValue; - private readonly bool m_RunInBackground; - private TestComponent m_CurrentTest; - - public RunnerCallback(IntegrationTestsRunnerWindow window) - { - m_Window = window; - - m_ConsoleErrorOnPauseValue = GuiHelper.GetConsoleErrorPause(); - GuiHelper.SetConsoleErrorPause(false); - m_RunInBackground = PlayerSettings.runInBackground; - PlayerSettings.runInBackground = true; - } - - public void RunStarted(string platform, List testsToRun) - { - EditorApplication.update += OnEditorUpdate; - m_TestNumber = testsToRun.Count; - foreach (var test in testsToRun) - { - var result = m_Window.m_ResultList.Find(r => r.TestComponent == test); - if (result != null) result.Reset(); - } - } - - public void RunFinished(List testResults) - { - m_Window.SetCurrentTest(null); - m_CurrentTest = null; - EditorApplication.update -= OnEditorUpdate; - EditorApplication.isPlaying = false; - EditorUtility.ClearProgressBar(); - GuiHelper.SetConsoleErrorPause(m_ConsoleErrorOnPauseValue); - PlayerSettings.runInBackground = m_RunInBackground; - } - - public void AllScenesFinished() - { - - } - - public void TestStarted(TestResult test) - { - m_Window.SetCurrentTest(test.TestComponent); - m_CurrentTest = test.TestComponent; - } - - - public void TestFinished(TestResult test) - { - m_CurrentTestNumber++; - - var result = m_Window.m_ResultList.Find(r => r.Id == test.Id); - if (result != null) - result.Update(test); - else - m_Window.m_ResultList.Add(test); - - if(test.IsFailure && m_Window.m_Settings.pauseOnTestFailure) - { - EditorUtility.ClearProgressBar(); - EditorApplication.isPaused = true; - } - } - - public void TestRunInterrupted(List testsNotRun) - { - Debug.Log("Test run interrupted"); - RunFinished(new List()); - } - - private void OnEditorUpdate() - { - if(!EditorApplication.isPlaying) - { - TestRunInterrupted(null); - return; - } - - if (m_Window.m_Settings.blockUIWhenRunning - && m_CurrentTest != null - && !EditorApplication.isPaused - && EditorUtility.DisplayCancelableProgressBar("Integration Test Runner", - "Running " + m_CurrentTest.Name, - (float)m_CurrentTestNumber / m_TestNumber)) - { - TestRunInterrupted(null); - } - } - } - - [MenuItem("Unity Test Tools/Integration Test Runner %#&t")] - public static IntegrationTestsRunnerWindow ShowWindow() - { - var w = GetWindow(typeof(IntegrationTestsRunnerWindow)); - w.Show(); - return w as IntegrationTestsRunnerWindow; - } - } -} diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsRunnerWindow.cs.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsRunnerWindow.cs.meta deleted file mode 100644 index 86b5775e..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsRunnerWindow.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 2c898357efb599944818326bb43ba879 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner.meta deleted file mode 100644 index b7631ee5..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: c44e9167d633ee94bb6e078238178308 -DefaultImporter: - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/NetworkResultsReceiver.cs b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/NetworkResultsReceiver.cs deleted file mode 100644 index f3be3380..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/NetworkResultsReceiver.cs +++ /dev/null @@ -1,261 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Net.Sockets; -using UnityEditor; -using UnityEditorInternal; -using UnityEngine; - -namespace UnityTest -{ - [Serializable] - public class NetworkResultsReceiver : EditorWindow - { - public static NetworkResultsReceiver Instance; - - private string m_StatusLabel; - private TcpListener m_Listener; - - [SerializeField] - private PlatformRunnerConfiguration m_Configuration; - - private List m_TestResults = new List(); - - #region steering variables - private bool m_RunFinished; - private bool m_Repaint; - - private TimeSpan m_TestTimeout = TimeSpan.Zero; - private DateTime m_LastMessageReceived; - private bool m_Running; - - public TimeSpan ReceiveMessageTimeout = TimeSpan.FromSeconds(30); - private readonly TimeSpan m_InitialConnectionTimeout = TimeSpan.FromSeconds(300); - private bool m_TestFailed; - #endregion - - private void AcceptCallback(TcpClient client) - { - m_Repaint = true; - ResultDTO dto; - try - { - m_LastMessageReceived = DateTime.Now; - using (var stream = client.GetStream()) - { - var bf = new DTOFormatter(); - dto = (ResultDTO)bf.Deserialize(stream); - stream.Close(); - } - client.Close(); - } - catch (ObjectDisposedException e) - { - Debug.LogException(e); - m_StatusLabel = "Got disconnected"; - return; - } - catch (Exception e) - { - Debug.LogException(e); - return; - } - - switch (dto.messageType) - { - case ResultDTO.MessageType.TestStarted: - m_StatusLabel = dto.testName; - m_TestTimeout = TimeSpan.FromSeconds(dto.testTimeout); - break; - case ResultDTO.MessageType.TestFinished: - m_TestResults.Add(dto.testResult); - m_TestTimeout = TimeSpan.Zero; - if (dto.testResult.Executed && dto.testResult.ResultState != TestResultState.Ignored && !dto.testResult.IsSuccess) - m_TestFailed = true; - break; - case ResultDTO.MessageType.RunStarted: - m_TestResults = new List(); - m_StatusLabel = "Run started: " + dto.loadedLevelName; - break; - case ResultDTO.MessageType.RunFinished: - WriteResultsToLog(dto, m_TestResults); - if (!string.IsNullOrEmpty(m_Configuration.resultsDir)) - { - var platform = m_Configuration.runInEditor ? "Editor" : m_Configuration.buildTarget.ToString(); - var resultWriter = new XmlResultWriter(dto.loadedLevelName, platform, m_TestResults.ToArray()); - try - { - if (!Directory.Exists(m_Configuration.resultsDir)) - { - Directory.CreateDirectory(m_Configuration.resultsDir); - } - var filePath = Path.Combine(m_Configuration.resultsDir, dto.loadedLevelName + ".xml"); - File.WriteAllText(filePath, resultWriter.GetTestResult()); - } - catch (Exception e) - { - Debug.LogException(e); - } - } - break; - case ResultDTO.MessageType.AllScenesFinished: - m_Running = false; - m_RunFinished = true; - break; - case ResultDTO.MessageType.Ping: - break; - } - } - - private void WriteResultsToLog(ResultDTO dto, List list) - { - string result = "Run finished for: " + dto.loadedLevelName; - var failCount = list.Count(t => t.Executed && !t.IsSuccess); - if (failCount == 0) - result += "\nAll tests passed"; - else - result += "\n" + failCount + " tests failed"; - - if (failCount == 0) - Debug.Log(result); - else - Debug.LogWarning(result); - } - - public void Update() - { - if (EditorApplication.isCompiling - && m_Listener != null) - { - m_Running = false; - m_Listener.Stop(); - return; - } - - if (m_Running) - { - try - { - if (m_Listener != null && m_Listener.Pending()) - { - using (var client = m_Listener.AcceptTcpClient()) - { - AcceptCallback(client); - client.Close(); - } - } - } - catch (InvalidOperationException e) - { - m_StatusLabel = "Exception happened: " + e.Message; - Repaint(); - Debug.LogException(e); - } - } - - if (m_Running) - { - var adjustedtestTimeout = m_TestTimeout.Add(m_TestTimeout); - var timeout = ReceiveMessageTimeout > adjustedtestTimeout ? ReceiveMessageTimeout : adjustedtestTimeout; - if ((DateTime.Now - m_LastMessageReceived) > timeout) - { - Debug.LogError("Timeout when waiting for test results"); - m_RunFinished = true; - } - } - if (m_RunFinished) - { - if (InternalEditorUtility.inBatchMode) - EditorApplication.Exit(m_TestFailed ? Batch.returnCodeTestsFailed : Batch.returnCodeTestsOk); - Close(); - } - if (m_Repaint) Repaint(); - } - - public void OnEnable() - { - minSize = new Vector2(300, 100); - titleContent = new GUIContent("Test run monitor"); - Instance = this; - m_StatusLabel = "Initializing..."; - if (EditorApplication.isCompiling) return; - EnableServer(); - } - - private void EnableServer() - { - if (m_Configuration == null) throw new Exception("No result receiver server configuration."); - - var ipAddress = IPAddress.Any; - if (m_Configuration.ipList != null && m_Configuration.ipList.Count == 1) - ipAddress = IPAddress.Parse(m_Configuration.ipList.Single()); - - var ipAddStr = Equals(ipAddress, IPAddress.Any) ? "[All interfaces]" : ipAddress.ToString(); - - m_Listener = new TcpListener(ipAddress, m_Configuration.port); - m_StatusLabel = "Waiting for connection on: " + ipAddStr + ":" + m_Configuration.port; - - try - { - m_Listener.Start(100); - } - catch (SocketException e) - { - m_StatusLabel = "Exception happened: " + e.Message; - Repaint(); - Debug.LogException(e); - } - m_Running = true; - m_LastMessageReceived = DateTime.Now + m_InitialConnectionTimeout; - } - - public void OnDisable() - { - Instance = null; - if (m_Listener != null) - m_Listener.Stop(); - } - - public void OnGUI() - { - EditorGUILayout.LabelField("Status:", EditorStyles.boldLabel); - EditorGUILayout.LabelField(m_StatusLabel); - GUILayout.FlexibleSpace(); - if (GUILayout.Button("Stop")) - { - StopReceiver(); - if (InternalEditorUtility.inBatchMode) - EditorApplication.Exit(Batch.returnCodeRunError); - } - } - - public static void StartReceiver(PlatformRunnerConfiguration configuration) - { - var w = (NetworkResultsReceiver)GetWindow(typeof(NetworkResultsReceiver), false); - w.SetConfiguration(configuration); - if (!EditorApplication.isCompiling) - { - w.EnableServer(); - } - w.Show(true); - } - - private void SetConfiguration(PlatformRunnerConfiguration configuration) - { - m_Configuration = configuration; - } - - public static void StopReceiver() - { - if (Instance == null) return; - try{ - Instance.Close(); - }catch(Exception e){ - Debug.LogException(e); - DestroyImmediate(Instance); - } - } - } -} diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/NetworkResultsReceiver.cs.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/NetworkResultsReceiver.cs.meta deleted file mode 100644 index cfc201e5..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/NetworkResultsReceiver.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: ade4197221f35dc44adb7649f99af2e7 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunner.cs b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunner.cs deleted file mode 100644 index 2f649b08..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunner.cs +++ /dev/null @@ -1,130 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net; -using System.Net.Sockets; -using UnityEditor; -using UnityEditorInternal; -using UnityEngine; -using System.Linq; - -namespace UnityTest.IntegrationTests -{ - public class PlatformRunner - { - public static BuildTarget defaultBuildTarget - { - get - { - var target = EditorPrefs.GetString("ITR-platformRunnerBuildTarget"); - BuildTarget buildTarget; - try - { - buildTarget = (BuildTarget)Enum.Parse(typeof(BuildTarget), target); - } - catch - { - return GetDefaultBuildTarget(); - } - return buildTarget; - } - set { EditorPrefs.SetString("ITR-platformRunnerBuildTarget", value.ToString()); } - } - - [MenuItem("Unity Test Tools/Platform Runner/Run current scene %#&r")] - public static void BuildAndRunCurrentScene() - { - Debug.Log("Building and running current test for " + defaultBuildTarget); - BuildAndRunInPlayer(new PlatformRunnerConfiguration(defaultBuildTarget)); - } - - [MenuItem("Unity Test Tools/Platform Runner/Run on platform %#r")] - public static void RunInPlayer() - { - var w = EditorWindow.GetWindow(typeof(PlatformRunnerSettingsWindow)); - w.Show(); - } - - public static void BuildAndRunInPlayer(PlatformRunnerConfiguration configuration) - { - NetworkResultsReceiver.StopReceiver(); - - var settings = new PlayerSettingConfigurator(false); - - if (configuration.sendResultsOverNetwork) - { - try - { - var l = new TcpListener(IPAddress.Any, configuration.port); - l.Start(); - configuration.port = ((IPEndPoint)l.Server.LocalEndPoint).Port; - l.Stop(); - } - catch (SocketException e) - { - Debug.LogException(e); - if (InternalEditorUtility.inBatchMode) - EditorApplication.Exit(Batch.returnCodeRunError); - } - } - - if (InternalEditorUtility.inBatchMode) - settings.AddConfigurationFile(TestRunnerConfigurator.batchRunFileMarker, ""); - - if (configuration.sendResultsOverNetwork) - settings.AddConfigurationFile(TestRunnerConfigurator.integrationTestsNetwork, - string.Join("\n", configuration.GetConnectionIPs())); - - settings.AddConfigurationFile (TestRunnerConfigurator.testScenesToRun, string.Join ("\n", configuration.testScenes.ToArray())); - - settings.ChangeSettingsForIntegrationTests(); - - AssetDatabase.Refresh(); - - var result = BuildPipeline.BuildPlayer(configuration.testScenes.Concat(configuration.buildScenes).ToArray(), - configuration.GetTempPath(), - configuration.buildTarget, - BuildOptions.AutoRunPlayer | BuildOptions.Development); - - settings.RevertSettingsChanges(); - settings.RemoveAllConfigurationFiles(); - - AssetDatabase.Refresh(); - - if (!string.IsNullOrEmpty(result)) - { - if (InternalEditorUtility.inBatchMode) - EditorApplication.Exit(Batch.returnCodeRunError); - return; - } - - if (configuration.sendResultsOverNetwork) - NetworkResultsReceiver.StartReceiver(configuration); - else if (InternalEditorUtility.inBatchMode) - EditorApplication.Exit(Batch.returnCodeTestsOk); - } - - private static BuildTarget GetDefaultBuildTarget() - { - switch (EditorUserBuildSettings.selectedBuildTargetGroup) - { - case BuildTargetGroup.Android: - return BuildTarget.Android; - case BuildTargetGroup.WebPlayer: - return BuildTarget.WebPlayer; - default: - { - switch (Application.platform) - { - case RuntimePlatform.WindowsPlayer: - return BuildTarget.StandaloneWindows; - case RuntimePlatform.OSXPlayer: - return BuildTarget.StandaloneOSXIntel; - case RuntimePlatform.LinuxPlayer: - return BuildTarget.StandaloneLinux; - } - return BuildTarget.WebPlayer; - } - } - } - } -} diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunner.cs.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunner.cs.meta deleted file mode 100644 index 5ecced0b..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunner.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: a3581fa3f207a8a4c9988b9f59a510d3 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerConfiguration.cs b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerConfiguration.cs deleted file mode 100644 index 1c0a7856..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerConfiguration.cs +++ /dev/null @@ -1,79 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Net.Sockets; -using UnityEditor; -using UnityEngine; -using UnityEngine.SceneManagement; - -[Serializable] -public class PlatformRunnerConfiguration -{ - public List buildScenes; - public List testScenes; - public BuildTarget buildTarget; - public bool runInEditor; - public string projectName = SceneManager.GetActiveScene().path; - - public string resultsDir = null; - public bool sendResultsOverNetwork; - public List ipList; - public int port; - - public PlatformRunnerConfiguration(BuildTarget buildTarget) - { - this.buildTarget = buildTarget; - projectName = SceneManager.GetActiveScene().path; - } - - public PlatformRunnerConfiguration() - : this(BuildTarget.StandaloneWindows) - { - } - - public string GetTempPath() - { - if (string.IsNullOrEmpty(projectName)) - projectName = Path.GetTempFileName(); - - var path = Path.Combine("Temp", projectName); - switch (buildTarget) - { - case BuildTarget.StandaloneWindows: - case BuildTarget.StandaloneWindows64: - return path + ".exe"; - case BuildTarget.StandaloneOSXIntel: - return path + ".app"; - case BuildTarget.Android: - return path + ".apk"; - default: - if (buildTarget.ToString() == "BlackBerry" || buildTarget.ToString() == "BB10") - return path + ".bar"; - return path; - } - } - - public string[] GetConnectionIPs() - { - return ipList.Select(ip => ip + ":" + port).ToArray(); - } - - public static int TryToGetFreePort() - { - var port = -1; - try - { - var l = new TcpListener(IPAddress.Any, 0); - l.Start(); - port = ((IPEndPoint)l.Server.LocalEndPoint).Port; - l.Stop(); - } - catch (SocketException e) - { - Debug.LogException(e); - } - return port; - } -} diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerConfiguration.cs.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerConfiguration.cs.meta deleted file mode 100644 index f747c6e5..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerConfiguration.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: b98fe8c3761da2d4b8cfd8bd6df7050f -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerSettings.cs b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerSettings.cs deleted file mode 100644 index 8b54c3a8..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerSettings.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using UnityEngine; - -namespace UnityTest -{ - public class PlatformRunnerSettings : ProjectSettingsBase - { - public string resultsPath; - public bool sendResultsOverNetwork = true; - public int port = 0; - } -} diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerSettings.cs.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerSettings.cs.meta deleted file mode 100644 index 1cc9a283..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerSettings.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 964f5f0db2c95bb41aa3dc3beba1f06b -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerSettingsWindow.cs b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerSettingsWindow.cs deleted file mode 100644 index 5ae9d077..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerSettingsWindow.cs +++ /dev/null @@ -1,318 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using UnityEditor; -using UnityEngine; -using Object = UnityEngine.Object; -using UnityEngine.SceneManagement; - -namespace UnityTest.IntegrationTests -{ - [Serializable] - public class PlatformRunnerSettingsWindow : EditorWindow - { - private BuildTarget m_BuildTarget; - - private List m_IntegrationTestScenes; - private List m_OtherScenesToBuild; - private List m_AllScenesInProject; - - private Vector2 m_ScrollPosition; - private readonly List m_Interfaces = new List(); - private readonly List m_SelectedScenes = new List(); - - private int m_SelectedInterface; - [SerializeField] - private bool m_AdvancedNetworkingSettings; - - private PlatformRunnerSettings m_Settings; - - private string m_SelectedSceneInAll; - private string m_SelectedSceneInTest; - private string m_SelectedSceneInBuild; - - readonly GUIContent m_Label = new GUIContent("Results target directory", "Directory where the results will be saved. If no value is specified, the results will be generated in project's data folder."); - - public PlatformRunnerSettingsWindow() - { - if (m_OtherScenesToBuild == null) - m_OtherScenesToBuild = new List (); - - if (m_IntegrationTestScenes == null) - m_IntegrationTestScenes = new List (); - - titleContent = new GUIContent("Platform runner"); - m_BuildTarget = PlatformRunner.defaultBuildTarget; - position.Set(position.xMin, position.yMin, 200, position.height); - m_AllScenesInProject = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.unity", SearchOption.AllDirectories).ToList(); - m_AllScenesInProject.Sort(); - var currentScene = (Directory.GetCurrentDirectory() + SceneManager.GetActiveScene().path).Replace("\\", "").Replace("/", ""); - var currentScenePath = m_AllScenesInProject.Where(s => s.Replace("\\", "").Replace("/", "") == currentScene); - m_SelectedScenes.AddRange(currentScenePath); - - m_Interfaces.Add("(Any)"); - m_Interfaces.AddRange(TestRunnerConfigurator.GetAvailableNetworkIPs()); - m_Interfaces.Add("127.0.0.1"); - - LoadFromPrefereneces (); - } - - public void OnEnable() - { - m_Settings = ProjectSettingsBase.Load(); - - // If not configured pre populate with all scenes that have test components on game objects - // This needs to be done outsie of constructor - if (m_IntegrationTestScenes.Count == 0) - m_IntegrationTestScenes = GetScenesWithTestComponents (m_AllScenesInProject); - } - - public void OnGUI() - { - EditorGUILayout.BeginVertical(); - GUIContent label; - - /* We have three lists here, The tests to run, supporting scenes to include in the build and the list of all scenes so users can - * pick the scenes they want to include. The motiviation here is that test scenes may require to additively load other scenes as part of the tests - */ - EditorGUILayout.BeginHorizontal (); - - // Integration Tests To Run - EditorGUILayout.BeginVertical (); - - label = new GUIContent("Tests:", "All Integration Test scenes that you wish to run on the platform"); - EditorGUILayout.LabelField(label, EditorStyles.boldLabel, GUILayout.Height(20f)); - - EditorGUI.BeginDisabledGroup(string.IsNullOrEmpty(m_SelectedSceneInTest)); - if (GUILayout.Button("Remove Integration Test")) { - m_IntegrationTestScenes.Remove(m_SelectedSceneInTest); - m_SelectedSceneInTest = ""; - } - EditorGUI.EndDisabledGroup(); - - DrawVerticalSceneList (ref m_IntegrationTestScenes, ref m_SelectedSceneInTest); - EditorGUILayout.EndVertical (); - - // Extra scenes to include in build - EditorGUILayout.BeginVertical (); - label = new GUIContent("Other Scenes in Build:", "If your Integration Tests additivly load any other scenes then you want to include them here so they are part of the build"); - EditorGUILayout.LabelField(label, EditorStyles.boldLabel, GUILayout.Height(20f)); - - - EditorGUI.BeginDisabledGroup(string.IsNullOrEmpty(m_SelectedSceneInBuild)); - if (GUILayout.Button("Remove From Build")) { - m_OtherScenesToBuild.Remove(m_SelectedSceneInBuild); - m_SelectedSceneInBuild = ""; - } - EditorGUI.EndDisabledGroup(); - - DrawVerticalSceneList (ref m_OtherScenesToBuild, ref m_SelectedSceneInBuild); - EditorGUILayout.EndVertical (); - - EditorGUILayout.Separator (); - - // All Scenes - EditorGUILayout.BeginVertical (); - label = new GUIContent("Availble Scenes", "These are all the scenes within your project, please select some to run tests"); - EditorGUILayout.LabelField(label, EditorStyles.boldLabel, GUILayout.Height(20f)); - - - EditorGUILayout.BeginHorizontal (); - EditorGUI.BeginDisabledGroup(string.IsNullOrEmpty(m_SelectedSceneInAll)); - if (GUILayout.Button("Add As Test")) { - if (!m_IntegrationTestScenes.Contains (m_SelectedSceneInAll) && !m_OtherScenesToBuild.Contains (m_SelectedSceneInAll)) { - m_IntegrationTestScenes.Add(m_SelectedSceneInAll); - } - } - - if (GUILayout.Button("Add to Build")) { - if (!m_IntegrationTestScenes.Contains (m_SelectedSceneInAll) && !m_OtherScenesToBuild.Contains (m_SelectedSceneInAll)) { - m_OtherScenesToBuild.Add(m_SelectedSceneInAll); - } - } - EditorGUI.EndDisabledGroup(); - - EditorGUILayout.EndHorizontal (); - - DrawVerticalSceneList (ref m_AllScenesInProject, ref m_SelectedSceneInAll); - EditorGUILayout.EndVertical (); - - // ButtoNetworkResultsReceiverns to edit scenes in lists - - - EditorGUILayout.EndHorizontal (); - - GUILayout.Space(3); - - // Select target platform - m_BuildTarget = (BuildTarget)EditorGUILayout.EnumPopup("Build tests for", m_BuildTarget); - - if (PlatformRunner.defaultBuildTarget != m_BuildTarget) - { - if (GUILayout.Button("Make default target platform")) - { - PlatformRunner.defaultBuildTarget = m_BuildTarget; - } - } - GUI.enabled = true; - - // Select various Network settings - DrawSetting(); - var build = GUILayout.Button("Build and run tests"); - EditorGUILayout.EndVertical(); - - if (build) - { - BuildAndRun (); - } - } - - private void DrawVerticalSceneList(ref List sourceList, ref string selectString) - { - m_ScrollPosition = EditorGUILayout.BeginScrollView(m_ScrollPosition, Styles.testList); - EditorGUI.indentLevel++; - foreach (var scenePath in sourceList) - { - var path = Path.GetFileNameWithoutExtension(scenePath); - var guiContent = new GUIContent(path, scenePath); - var rect = GUILayoutUtility.GetRect(guiContent, EditorStyles.label); - if (rect.Contains(Event.current.mousePosition)) - { - if (Event.current.type == EventType.mouseDown && Event.current.button == 0) - { - selectString = scenePath; - Event.current.Use(); - } - } - var style = new GUIStyle(EditorStyles.label); - - if (selectString == scenePath) - style.normal.textColor = new Color(0.3f, 0.5f, 0.85f); - EditorGUI.LabelField(rect, guiContent, style); - } - EditorGUI.indentLevel--; - EditorGUILayout.EndScrollView(); - } - - public static List GetScenesWithTestComponents(List allScenes) - { - List results = EditorReferencesUtil.FindScenesWhichContainAsset("TestComponent.cs"); - List integrationTestScenes = new List(); - - foreach (Object obj in results) { - string result = allScenes.FirstOrDefault(s => s.Contains(obj.name)); - if (!string.IsNullOrEmpty(result)) - integrationTestScenes.Add(result); - } - - return integrationTestScenes; - } - - private void DrawSetting() - { - EditorGUI.BeginChangeCheck(); - - EditorGUILayout.BeginHorizontal(); - m_Settings.resultsPath = EditorGUILayout.TextField(m_Label, m_Settings.resultsPath); - if (GUILayout.Button("Search", EditorStyles.miniButton, GUILayout.Width(50))) - { - var selectedPath = EditorUtility.SaveFolderPanel("Result files destination", m_Settings.resultsPath, ""); - if (!string.IsNullOrEmpty(selectedPath)) - m_Settings.resultsPath = Path.GetFullPath(selectedPath); - } - EditorGUILayout.EndHorizontal(); - - if (!string.IsNullOrEmpty(m_Settings.resultsPath)) - { - Uri uri; - if (!Uri.TryCreate(m_Settings.resultsPath, UriKind.Absolute, out uri) || !uri.IsFile || uri.IsWellFormedOriginalString()) - { - EditorGUILayout.HelpBox("Invalid URI path", MessageType.Warning); - } - } - - m_Settings.sendResultsOverNetwork = EditorGUILayout.Toggle("Send results to editor", m_Settings.sendResultsOverNetwork); - EditorGUI.BeginDisabledGroup(!m_Settings.sendResultsOverNetwork); - m_AdvancedNetworkingSettings = EditorGUILayout.Foldout(m_AdvancedNetworkingSettings, "Advanced network settings"); - if (m_AdvancedNetworkingSettings) - { - m_SelectedInterface = EditorGUILayout.Popup("Network interface", m_SelectedInterface, m_Interfaces.ToArray()); - EditorGUI.BeginChangeCheck(); - m_Settings.port = EditorGUILayout.IntField("Network port", m_Settings.port); - if (EditorGUI.EndChangeCheck()) - { - if (m_Settings.port > IPEndPoint.MaxPort) - m_Settings.port = IPEndPoint.MaxPort; - else if (m_Settings.port < IPEndPoint.MinPort) - m_Settings.port = IPEndPoint.MinPort; - } - } - - EditorGUI.EndDisabledGroup(); - - if (EditorGUI.EndChangeCheck()) - { - m_Settings.Save(); - } - } - - private void BuildAndRun() - { - SaveToPreferences (); - - var config = new PlatformRunnerConfiguration - { - buildTarget = m_BuildTarget, - buildScenes = m_OtherScenesToBuild, - testScenes = m_IntegrationTestScenes, - projectName = m_IntegrationTestScenes.Count > 1 ? "IntegrationTests" : Path.GetFileNameWithoutExtension(SceneManager.GetActiveScene().path), - resultsDir = m_Settings.resultsPath, - sendResultsOverNetwork = m_Settings.sendResultsOverNetwork, - ipList = m_Interfaces.Skip(1).ToList(), - port = m_Settings.port - }; - - if (m_SelectedInterface > 0) - config.ipList = new List {m_Interfaces.ElementAt(m_SelectedInterface)}; - - PlatformRunner.BuildAndRunInPlayer(config); - Close (); - } - - public void OnLostFocus() { - SaveToPreferences (); - } - - public void OnDestroy() { - SaveToPreferences (); - } - - private void SaveToPreferences() - { - EditorPrefs.SetString (Animator.StringToHash (Application.dataPath + "uttTestScenes").ToString (), String.Join (",",m_IntegrationTestScenes.ToArray())); - EditorPrefs.SetString (Animator.StringToHash (Application.dataPath + "uttBuildScenes").ToString (), String.Join (",",m_OtherScenesToBuild.ToArray())); - } - - private void LoadFromPrefereneces() - { - string storedTestScenes = EditorPrefs.GetString (Animator.StringToHash (Application.dataPath + "uttTestScenes").ToString ()); - string storedBuildScenes = EditorPrefs.GetString (Animator.StringToHash (Application.dataPath + "uttBuildScenes").ToString ()); - - List parsedTestScenes = storedTestScenes.Split (',').ToList (); - List parsedBuildScenes = storedBuildScenes.Split (',').ToList (); - - // Sanity check scenes actually exist - foreach (string str in parsedTestScenes) { - if (m_AllScenesInProject.Contains(str)) - m_IntegrationTestScenes.Add(str); - } - - foreach (string str in parsedBuildScenes) { - if (m_AllScenesInProject.Contains(str)) - m_OtherScenesToBuild.Add(str); - } - } - } -} diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerSettingsWindow.cs.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerSettingsWindow.cs.meta deleted file mode 100644 index 8fed609f..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerSettingsWindow.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 3819282b0887bc742911b89745080acb -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlayerSettingConfigurator.cs b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlayerSettingConfigurator.cs deleted file mode 100644 index 77aea814..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlayerSettingConfigurator.cs +++ /dev/null @@ -1,73 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using UnityEditor; -using UnityEngine; - -namespace UnityTest -{ - class PlayerSettingConfigurator - { - private string resourcesPath { - get { return m_Temp ? k_TempPath : m_ProjectResourcesPath; } - } - - private readonly string m_ProjectResourcesPath = Path.Combine("Assets", "Resources"); - const string k_TempPath = "Temp"; - private readonly bool m_Temp; - - private ResolutionDialogSetting m_DisplayResolutionDialog; - private bool m_RunInBackground; - private bool m_FullScreen; - private bool m_ResizableWindow; - private readonly List m_TempFileList = new List(); - - public PlayerSettingConfigurator(bool saveInTempFolder) - { - m_Temp = saveInTempFolder; - } - - public void ChangeSettingsForIntegrationTests() - { - m_DisplayResolutionDialog = PlayerSettings.displayResolutionDialog; - PlayerSettings.displayResolutionDialog = ResolutionDialogSetting.Disabled; - - m_RunInBackground = PlayerSettings.runInBackground; - PlayerSettings.runInBackground = true; - - m_FullScreen = PlayerSettings.defaultIsFullScreen; - PlayerSettings.defaultIsFullScreen = false; - - m_ResizableWindow = PlayerSettings.resizableWindow; - PlayerSettings.resizableWindow = true; - } - - public void RevertSettingsChanges() - { - PlayerSettings.defaultIsFullScreen = m_FullScreen; - PlayerSettings.runInBackground = m_RunInBackground; - PlayerSettings.displayResolutionDialog = m_DisplayResolutionDialog; - PlayerSettings.resizableWindow = m_ResizableWindow; - } - - public void AddConfigurationFile(string fileName, string content) - { - var resourcesPathExists = Directory.Exists(resourcesPath); - if (!resourcesPathExists) AssetDatabase.CreateFolder("Assets", "Resources"); - - var filePath = Path.Combine(resourcesPath, fileName); - File.WriteAllText(filePath, content); - - m_TempFileList.Add(filePath); - } - - public void RemoveAllConfigurationFiles() - { - foreach (var filePath in m_TempFileList) - AssetDatabase.DeleteAsset(filePath); - if (Directory.Exists(resourcesPath) - && Directory.GetFiles(resourcesPath).Length == 0) - AssetDatabase.DeleteAsset(resourcesPath); - } - } -} diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlayerSettingConfigurator.cs.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlayerSettingConfigurator.cs.meta deleted file mode 100644 index 732b8be9..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlayerSettingConfigurator.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: c7adbe43058d54047b6109b2e66894fd -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer.meta deleted file mode 100644 index ccb3c143..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: 5944b82e46f1682439d20b4c3a4f029c -DefaultImporter: - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestGroupLine.cs b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestGroupLine.cs deleted file mode 100644 index a7d86194..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestGroupLine.cs +++ /dev/null @@ -1,84 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEditor; -using UnityEngine; - -namespace UnityTest -{ - class IntegrationTestGroupLine : IntegrationTestRendererBase - { - public static List FoldMarkers; - private IntegrationTestRendererBase[] m_Children; - - public IntegrationTestGroupLine(GameObject gameObject) : base(gameObject) - { - } - - protected internal override void DrawLine(Rect rect, GUIContent label, bool isSelected, RenderingOptions options) - { - EditorGUI.BeginChangeCheck(); - var isClassFolded = !EditorGUI.Foldout(rect, !Folded, label, isSelected ? Styles.selectedFoldout : Styles.foldout); - if (EditorGUI.EndChangeCheck()) Folded = isClassFolded; - } - - private bool Folded - { - get { return FoldMarkers.Contains(m_GameObject); } - - set - { - if (value) FoldMarkers.Add(m_GameObject); - else FoldMarkers.RemoveAll(s => s == m_GameObject); - } - } - - protected internal override void Render(int indend, RenderingOptions options) - { - base.Render(indend, options); - if (!Folded) - foreach (var child in m_Children) - child.Render(indend + 1, options); - } - - protected internal override TestResult.ResultType GetResult() - { - bool ignored = false; - bool success = false; - foreach (var child in m_Children) - { - var result = child.GetResult(); - - if (result == TestResult.ResultType.Failed || result == TestResult.ResultType.FailedException || result == TestResult.ResultType.Timeout) - return TestResult.ResultType.Failed; - if (result == TestResult.ResultType.Success) - success = true; - else if (result == TestResult.ResultType.Ignored) - ignored = true; - else - ignored = false; - } - if (success) return TestResult.ResultType.Success; - if (ignored) return TestResult.ResultType.Ignored; - return TestResult.ResultType.NotRun; - } - - protected internal override bool IsVisible(RenderingOptions options) - { - return m_Children.Any(c => c.IsVisible(options)); - } - - public override bool SetCurrentTest(TestComponent tc) - { - m_IsRunning = false; - foreach (var child in m_Children) - m_IsRunning |= child.SetCurrentTest(tc); - return m_IsRunning; - } - - public void AddChildren(IntegrationTestRendererBase[] parseTestList) - { - m_Children = parseTestList; - } - } -} diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestGroupLine.cs.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestGroupLine.cs.meta deleted file mode 100644 index 00510641..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestGroupLine.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: f6dc74195aa98ef4da8901199cda4a63 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestLine.cs b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestLine.cs deleted file mode 100644 index e0b5d1ac..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestLine.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEditor; -using UnityEngine; - -namespace UnityTest -{ - class IntegrationTestLine : IntegrationTestRendererBase - { - public static List Results; - protected TestResult m_Result; - - public IntegrationTestLine(GameObject gameObject, TestResult testResult) : base(gameObject) - { - m_Result = testResult; - } - - protected internal override void DrawLine(Rect rect, GUIContent label, bool isSelected, RenderingOptions options) - { - if(Event.current.type != EventType.repaint) - return; - - Styles.testName.Draw (rect, label, false, false, false, isSelected); - - if (m_Result.IsTimeout) - { - float min, max; - Styles.testName.CalcMinMaxWidth(label, out min, out max); - var timeoutRect = new Rect(rect); - timeoutRect.x += min - 12; - Styles.testName.Draw(timeoutRect, s_GUITimeoutIcon, false, false, false, isSelected); - } - } - - protected internal override TestResult.ResultType GetResult() - { - if (!m_Result.Executed && test.ignored) return TestResult.ResultType.Ignored; - return m_Result.resultType; - } - - protected internal override bool IsVisible(RenderingOptions options) - { - if (!string.IsNullOrEmpty(options.nameFilter) && !m_GameObject.name.ToLower().Contains(options.nameFilter.ToLower())) return false; - if (!options.showSucceeded && m_Result.IsSuccess) return false; - if (!options.showFailed && m_Result.IsFailure) return false; - if (!options.showNotRunned && !m_Result.Executed) return false; - if (!options.showIgnored && test.ignored) return false; - return true; - } - - public override bool SetCurrentTest(TestComponent tc) - { - m_IsRunning = test == tc; - return m_IsRunning; - } - } -} diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestLine.cs.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestLine.cs.meta deleted file mode 100644 index 25c9f112..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestLine.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 212be02e4a7da194688b08ab0c946fbd -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestRendererBase.cs b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestRendererBase.cs deleted file mode 100644 index 5b026987..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestRendererBase.cs +++ /dev/null @@ -1,161 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEditor; -using UnityEngine; -using Object = UnityEngine.Object; - -namespace UnityTest -{ - public abstract class IntegrationTestRendererBase : IComparable - { - public static Action> RunTest; - - protected static bool s_Refresh; - - private static readonly GUIContent k_GUIRunSelected = new GUIContent("Run Selected"); - private static readonly GUIContent k_GUIRun = new GUIContent("Run"); - private static readonly GUIContent k_GUIDelete = new GUIContent("Delete"); - private static readonly GUIContent k_GUIDeleteSelected = new GUIContent("Delete selected"); - - protected static GUIContent s_GUITimeoutIcon = new GUIContent(Icons.StopwatchImg, "Timeout"); - - protected GameObject m_GameObject; - public TestComponent test; - private readonly string m_Name; - - protected IntegrationTestRendererBase(GameObject gameObject) - { - test = gameObject.GetComponent(typeof(TestComponent)) as TestComponent; - if (test == null) throw new ArgumentException("Provided GameObject is not a test object"); - m_GameObject = gameObject; - m_Name = test.Name; - } - - public int CompareTo(IntegrationTestRendererBase other) - { - return test.CompareTo(other.test); - } - - public bool Render(RenderingOptions options) - { - s_Refresh = false; - EditorGUIUtility.SetIconSize(new Vector2(15, 15)); - Render(0, options); - EditorGUIUtility.SetIconSize(Vector2.zero); - return s_Refresh; - } - - protected internal virtual void Render(int indend, RenderingOptions options) - { - if (!IsVisible(options)) return; - EditorGUILayout.BeginHorizontal(); - GUILayout.Space(indend * 10); - - var tempColor = GUI.color; - if (m_IsRunning) - { - var frame = Mathf.Abs(Mathf.Cos(Time.realtimeSinceStartup * 4)) * 0.6f + 0.4f; - GUI.color = new Color(1, 1, 1, frame); - } - - var isSelected = Selection.gameObjects.Contains(m_GameObject); - - var value = GetResult(); - var icon = GetIconForResult(value); - - var label = new GUIContent(m_Name, icon); - var labelRect = GUILayoutUtility.GetRect(label, EditorStyles.label, GUILayout.ExpandWidth(true), GUILayout.Height(18)); - - OnLeftMouseButtonClick(labelRect); - OnContextClick(labelRect); - DrawLine(labelRect, label, isSelected, options); - - if (m_IsRunning) GUI.color = tempColor; - EditorGUILayout.EndHorizontal(); - } - - protected void OnSelect() - { - if (!Event.current.control && !Event.current.command) - { - Selection.objects = new Object[0]; - GUIUtility.keyboardControl = 0; - } - - if ((Event.current.control || Event.current.command) && Selection.gameObjects.Contains(test.gameObject)) - Selection.objects = Selection.gameObjects.Where(o => o != test.gameObject).ToArray(); - else - Selection.objects = Selection.gameObjects.Concat(new[] { test.gameObject }).ToArray(); - } - - protected void OnLeftMouseButtonClick(Rect rect) - { - if (rect.Contains(Event.current.mousePosition) && Event.current.type == EventType.mouseDown && Event.current.button == 0) - { - rect.width = 20; - if (rect.Contains(Event.current.mousePosition)) return; - Event.current.Use(); - OnSelect(); - } - } - - protected void OnContextClick(Rect rect) - { - if (rect.Contains(Event.current.mousePosition) && Event.current.type == EventType.ContextClick) - { - DrawContextMenu(test); - } - } - - public static void DrawContextMenu(TestComponent testComponent) - { - if (EditorApplication.isPlayingOrWillChangePlaymode) return; - - var selectedTests = Selection.gameObjects.Where(go => go.GetComponent(typeof(TestComponent))); - var manySelected = selectedTests.Count() > 1; - - var m = new GenericMenu(); - if (manySelected) - { - // var testsToRun - m.AddItem(k_GUIRunSelected, false, data => RunTest(selectedTests.Select(o => o.GetComponent(typeof(TestComponent))).Cast().ToList()), null); - } - m.AddItem(k_GUIRun, false, data => RunTest(new[] { testComponent }), null); - m.AddSeparator(""); - m.AddItem(manySelected ? k_GUIDeleteSelected : k_GUIDelete, false, data => RemoveTests(selectedTests.ToArray()), null); - m.ShowAsContext(); - } - - private static void RemoveTests(GameObject[] testsToDelete) - { - foreach (var t in testsToDelete) - { - Undo.DestroyObjectImmediate(t); - } - } - - public static Texture GetIconForResult(TestResult.ResultType resultState) - { - switch (resultState) - { - case TestResult.ResultType.Success: - return Icons.SuccessImg; - case TestResult.ResultType.Timeout: - case TestResult.ResultType.Failed: - case TestResult.ResultType.FailedException: - return Icons.FailImg; - case TestResult.ResultType.Ignored: - return Icons.IgnoreImg; - default: - return Icons.UnknownImg; - } - } - - protected internal bool m_IsRunning; - protected internal abstract void DrawLine(Rect rect, GUIContent label, bool isSelected, RenderingOptions options); - protected internal abstract TestResult.ResultType GetResult(); - protected internal abstract bool IsVisible(RenderingOptions options); - public abstract bool SetCurrentTest(TestComponent tc); - } -} diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestRendererBase.cs.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestRendererBase.cs.meta deleted file mode 100644 index 1fb186ec..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestRendererBase.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 604645a3b57179a4d873906b625ef8ec -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/RenderingOptions.cs b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/RenderingOptions.cs deleted file mode 100644 index 5d16efc3..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/RenderingOptions.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace UnityTest -{ - public class RenderingOptions - { - public string nameFilter; - public bool showSucceeded; - public bool showFailed; - public bool showIgnored; - public bool showNotRunned; - public string[] categories; - } -} diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/RenderingOptions.cs.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/RenderingOptions.cs.meta deleted file mode 100644 index 6ecfc38c..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/RenderingOptions.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 5c0aec4b4a6d1b047a98e8cc213e1a36 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/TestComponentEditor.cs b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/TestComponentEditor.cs deleted file mode 100644 index 1b30f558..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/TestComponentEditor.cs +++ /dev/null @@ -1,129 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEditor; -using UnityEngine; -using Object = UnityEngine.Object; -using UnityEditor.SceneManagement; - -namespace UnityTest -{ - [CanEditMultipleObjects] - [CustomEditor(typeof(TestComponent))] - public class TestComponentEditor : Editor - { - private SerializedProperty m_ExpectException; - private SerializedProperty m_ExpectedExceptionList; - private SerializedProperty m_Ignored; - private SerializedProperty m_SucceedAssertions; - private SerializedProperty m_SucceedWhenExceptionIsThrown; - private SerializedProperty m_Timeout; - - #region GUI Contens - - private readonly GUIContent m_GUIExpectException = new GUIContent("Expect exception", "Should the test expect an exception"); - private readonly GUIContent m_GUIExpectExceptionList = new GUIContent("Expected exception list", "A comma separated list of exception types which will not fail the test when thrown"); - private readonly GUIContent m_GUIIgnore = new GUIContent("Ignore", "Ignore the tests in runs"); - private readonly GUIContent m_GUIIncludePlatforms = new GUIContent("Included platforms", "Platform on which the test should run"); - private readonly GUIContent m_GUISuccedOnAssertions = new GUIContent("Succeed on assertions", "Succeed after all assertions are executed"); - private readonly GUIContent m_GUISucceedWhenExceptionIsThrown = new GUIContent("Succeed when exception is thrown", "Should the test succeed when an expected exception is thrown"); - private readonly GUIContent m_GUITestName = new GUIContent("Test name", "Name of the test (is equal to the GameObject name)"); - private readonly GUIContent m_GUITimeout = new GUIContent("Timeout", "Number of seconds after which the test will timeout"); - - #endregion - - public void OnEnable() - { - m_Timeout = serializedObject.FindProperty("timeout"); - m_Ignored = serializedObject.FindProperty("ignored"); - m_SucceedAssertions = serializedObject.FindProperty("succeedAfterAllAssertionsAreExecuted"); - m_ExpectException = serializedObject.FindProperty("expectException"); - m_ExpectedExceptionList = serializedObject.FindProperty("expectedExceptionList"); - m_SucceedWhenExceptionIsThrown = serializedObject.FindProperty("succeedWhenExceptionIsThrown"); - } - - public override void OnInspectorGUI() - { - var component = (TestComponent)target; - - if (component.dynamic) - { - if(GUILayout.Button("Reload dynamic tests")) - { - TestComponent.DestroyAllDynamicTests(); - Selection.objects = new Object[0]; - IntegrationTestsRunnerWindow.selectedInHierarchy = false; - GUIUtility.ExitGUI(); - return; - } - EditorGUILayout.HelpBox("This is a test generated from code. No changes in the component will be persisted.", MessageType.Info); - } - - if (component.IsTestGroup()) - { - EditorGUI.BeginChangeCheck(); - var newGroupName = EditorGUILayout.TextField(m_GUITestName, component.name); - if (EditorGUI.EndChangeCheck()) component.name = newGroupName; - - serializedObject.ApplyModifiedProperties(); - return; - } - - serializedObject.Update(); - - EditorGUI.BeginDisabledGroup(serializedObject.isEditingMultipleObjects); - - EditorGUI.BeginChangeCheck(); - var newName = EditorGUILayout.TextField(m_GUITestName, component.name); - if (EditorGUI.EndChangeCheck()) component.name = newName; - - if (component.platformsToIgnore == null) - { - component.platformsToIgnore = GetListOfIgnoredPlatforms(Enum.GetNames(typeof(TestComponent.IncludedPlatforms)), (int)component.includedPlatforms); - } - - var enumList = Enum.GetNames(typeof(RuntimePlatform)); - var flags = GetFlagList(enumList, component.platformsToIgnore); - flags = EditorGUILayout.MaskField(m_GUIIncludePlatforms, flags, enumList, EditorStyles.popup); - var newList = GetListOfIgnoredPlatforms(enumList, flags); - if (!component.dynamic) - component.platformsToIgnore = newList; - EditorGUI.EndDisabledGroup(); - - EditorGUILayout.PropertyField(m_Timeout, m_GUITimeout); - EditorGUILayout.PropertyField(m_Ignored, m_GUIIgnore); - EditorGUILayout.PropertyField(m_SucceedAssertions, m_GUISuccedOnAssertions); - EditorGUILayout.PropertyField(m_ExpectException, m_GUIExpectException); - - EditorGUI.BeginDisabledGroup(!m_ExpectException.boolValue); - EditorGUILayout.PropertyField(m_ExpectedExceptionList, m_GUIExpectExceptionList); - EditorGUILayout.PropertyField(m_SucceedWhenExceptionIsThrown, m_GUISucceedWhenExceptionIsThrown); - EditorGUI.EndDisabledGroup(); - - if (!component.dynamic) - serializedObject.ApplyModifiedProperties(); - if (GUI.changed) - EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene()); - } - - private string[] GetListOfIgnoredPlatforms(string[] enumList, int flags) - { - var notSelectedPlatforms = new List(); - for (int i = 0; i < enumList.Length; i++) - { - var sel = (flags & (1 << i)) != 0; - if (!sel) notSelectedPlatforms.Add(enumList[i]); - } - return notSelectedPlatforms.ToArray(); - } - - private int GetFlagList(string[] enumList, string[] platformsToIgnore) - { - int flags = ~0; - for (int i = 0; i < enumList.Length; i++) - if (platformsToIgnore != null && platformsToIgnore.Any(s => s == enumList[i])) - flags &= ~(1 << i); - return flags; - } - } -} diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/TestComponentEditor.cs.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/TestComponentEditor.cs.meta deleted file mode 100644 index e3a1348a..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/TestComponentEditor.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 160889f21f4d5944b9f6fcaf9c33f684 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/ITestRunnerCallback.cs b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/ITestRunnerCallback.cs deleted file mode 100644 index c74dab9d..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/ITestRunnerCallback.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace UnityTest.IntegrationTestRunner -{ - public interface ITestRunnerCallback - { - void RunStarted(string platform, List testsToRun); - void RunFinished(List testResults); - void AllScenesFinished(); - void TestStarted(TestResult test); - void TestFinished(TestResult test); - void TestRunInterrupted(List testsNotRun); - } -} diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/ITestRunnerCallback.cs.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/ITestRunnerCallback.cs.meta deleted file mode 100644 index 3a1c54bd..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/ITestRunnerCallback.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 35af7d395e501a348ae1a0aa3c91dee4 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTest.cs b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTest.cs deleted file mode 100644 index de0e6d18..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTest.cs +++ /dev/null @@ -1,176 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using UnityEngine; - -public static class IntegrationTest -{ - public const string passMessage = "IntegrationTest Pass"; - public const string failMessage = "IntegrationTest Fail"; - - public static void Pass() - { - LogResult(passMessage); - } - - public static void Pass(GameObject go) - { - LogResult(go, passMessage); - } - - public static void Fail(string reason) - { - Fail(); - if (!string.IsNullOrEmpty(reason)) Debug.Log(reason); - } - - public static void Fail(GameObject go, string reason) - { - Fail(go); - if (!string.IsNullOrEmpty(reason)) Debug.Log(reason); - } - - public static void Fail() - { - LogResult(failMessage); - } - - public static void Fail(GameObject go) - { - LogResult(go, failMessage); - } - - public static void Assert(bool condition) - { - Assert(condition, ""); - } - - public static void Assert(GameObject go, bool condition) - { - Assert(go, condition, ""); - } - - public static void Assert(bool condition, string message) - { - if (!condition) - Fail(message); - } - - public static void Assert(GameObject go, bool condition, string message) - { - if (!condition) - Fail(go, message); - } - - private static void LogResult(string message) - { - Debug.Log(message); - } - - private static void LogResult(GameObject go, string message) - { - Debug.Log(message + " (" + FindTestObject(go).name + ")", go); - } - - private static GameObject FindTestObject(GameObject go) - { - var temp = go; - while (temp.transform.parent != null) - { - if (temp.GetComponent("TestComponent") != null) - return temp; - temp = temp.transform.parent.gameObject; - } - return go; - } - - #region Dynamic test attributes - - [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] - public class ExcludePlatformAttribute : Attribute - { - public string[] platformsToExclude; - - public ExcludePlatformAttribute(params RuntimePlatform[] platformsToExclude) - { - this.platformsToExclude = platformsToExclude.Select(platform => platform.ToString()).ToArray(); - } - } - - [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] - public class ExpectExceptions : Attribute - { - public string[] exceptionTypeNames; - public bool succeedOnException; - - public ExpectExceptions() : this(false) - { - } - - public ExpectExceptions(bool succeedOnException) : this(succeedOnException, new string[0]) - { - } - - public ExpectExceptions(bool succeedOnException, params string[] exceptionTypeNames) - { - this.succeedOnException = succeedOnException; - this.exceptionTypeNames = exceptionTypeNames; - } - - public ExpectExceptions(bool succeedOnException, params Type[] exceptionTypes) - : this(succeedOnException, exceptionTypes.Select(type => type.FullName).ToArray()) - { - } - - public ExpectExceptions(params string[] exceptionTypeNames) : this(false, exceptionTypeNames) - { - } - - public ExpectExceptions(params Type[] exceptionTypes) : this(false, exceptionTypes) - { - } - } - - [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] - public class IgnoreAttribute : Attribute - { - } - - [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] - public class DynamicTestAttribute : Attribute - { - private readonly string m_SceneName; - - public DynamicTestAttribute(string sceneName) - { - if (sceneName.EndsWith(".unity")) - sceneName = sceneName.Substring(0, sceneName.Length - ".unity".Length); - m_SceneName = sceneName; - } - - public bool IncludeOnScene(string sceneName) - { - var fileName = Path.GetFileNameWithoutExtension(sceneName); - return fileName == m_SceneName; - } - } - - [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] - public class SucceedWithAssertions : Attribute - { - } - - [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] - public class TimeoutAttribute : Attribute - { - public float timeout; - - public TimeoutAttribute(float seconds) - { - timeout = seconds; - } - } - - #endregion -} diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTest.cs.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTest.cs.meta deleted file mode 100644 index b6974b87..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTest.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: eb367bbc76e489443a4ebc8b0a8642f4 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTestAttribute.cs b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTestAttribute.cs deleted file mode 100644 index 9ca4e45f..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTestAttribute.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using UnityEngine; - -[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] -public class IntegrationTestAttribute : Attribute -{ - private readonly string m_Path; - - public IntegrationTestAttribute(string path) - { - if (path.EndsWith(".unity")) - path = path.Substring(0, path.Length - ".unity".Length); - m_Path = path; - } - - public bool IncludeOnScene(string scenePath) - { - if (scenePath == m_Path) return true; - var fileName = Path.GetFileNameWithoutExtension(scenePath); - return fileName == m_Path; - } -} diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTestAttribute.cs.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTestAttribute.cs.meta deleted file mode 100644 index 1c80721e..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTestAttribute.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: f1a5c61a06ed66e41a6ee1b5f88b5afd -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTestsProvider.cs b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTestsProvider.cs deleted file mode 100644 index c38d3c46..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTestsProvider.cs +++ /dev/null @@ -1,109 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEngine; - -namespace UnityTest.IntegrationTestRunner -{ - class IntegrationTestsProvider - { - internal Dictionary> testCollection = new Dictionary>(); - internal ITestComponent currentTestGroup; - internal IEnumerable testToRun; - - public IntegrationTestsProvider(IEnumerable tests) - { - testToRun = tests; - foreach (var test in tests.OrderBy(component => component)) - { - if (test.IsTestGroup()) - { - throw new Exception(test.Name + " is test a group"); - } - AddTestToList(test); - } - if (currentTestGroup == null) - { - currentTestGroup = FindInnerTestGroup(TestComponent.NullTestComponent); - } - } - - private void AddTestToList(ITestComponent test) - { - var group = test.GetTestGroup(); - if (!testCollection.ContainsKey(group)) - testCollection.Add(group, new HashSet()); - testCollection[group].Add(test); - if (group == TestComponent.NullTestComponent) return; - AddTestToList(group); - } - - public ITestComponent GetNextTest() - { - var test = testCollection[currentTestGroup].First(); - testCollection[currentTestGroup].Remove(test); - test.EnableTest(true); - return test; - } - - public void FinishTest(ITestComponent test) - { - try - { - test.EnableTest(false); - currentTestGroup = FindNextTestGroup(currentTestGroup); - } - catch (MissingReferenceException e) - { - Debug.LogException(e); - } - } - - private ITestComponent FindNextTestGroup(ITestComponent testGroup) - { - if (testGroup == null) - throw new Exception ("No test left"); - - if (testCollection[testGroup].Any()) - { - testGroup.EnableTest(true); - return FindInnerTestGroup(testGroup); - } - testCollection.Remove(testGroup); - testGroup.EnableTest(false); - - var parentTestGroup = testGroup.GetTestGroup(); - if (parentTestGroup == null) return null; - - testCollection[parentTestGroup].Remove(testGroup); - return FindNextTestGroup(parentTestGroup); - } - - private ITestComponent FindInnerTestGroup(ITestComponent group) - { - var innerGroups = testCollection[group]; - foreach (var innerGroup in innerGroups) - { - if (!innerGroup.IsTestGroup()) continue; - innerGroup.EnableTest(true); - return FindInnerTestGroup(innerGroup); - } - return group; - } - - public bool AnyTestsLeft() - { - return testCollection.Count != 0; - } - - public List GetRemainingTests() - { - var remainingTests = new List(); - foreach (var test in testCollection) - { - remainingTests.AddRange(test.Value); - } - return remainingTests; - } - } -} diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTestsProvider.cs.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTestsProvider.cs.meta deleted file mode 100644 index d444629a..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTestsProvider.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 21d32637b19ee51489062a66ad922193 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/NetworkResultSender.cs b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/NetworkResultSender.cs deleted file mode 100644 index 16145c09..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/NetworkResultSender.cs +++ /dev/null @@ -1,112 +0,0 @@ -#if !UNITY_METRO && (UNITY_PRO_LICENSE || !(UNITY_ANDROID || UNITY_IPHONE)) -#define UTT_SOCKETS_SUPPORTED -#endif -using System; -using System.Collections.Generic; -using UnityEngine; -using UnityTest.IntegrationTestRunner; - -#if UTT_SOCKETS_SUPPORTED -using System.Net.Sockets; -using System.Runtime.Serialization.Formatters.Binary; -#endif - -namespace UnityTest -{ - public class NetworkResultSender : ITestRunnerCallback - { -#if UTT_SOCKETS_SUPPORTED - private readonly TimeSpan m_ConnectionTimeout = TimeSpan.FromSeconds(5); - - private readonly string m_Ip; - private readonly int m_Port; -#endif - private bool m_LostConnection; - - public NetworkResultSender(string ip, int port) - { -#if UTT_SOCKETS_SUPPORTED - m_Ip = ip; - m_Port = port; -#endif - } - - private bool SendDTO(ResultDTO dto) - { - if (m_LostConnection) return false; -#if UTT_SOCKETS_SUPPORTED - try - { - using (var tcpClient = new TcpClient()) - { - var result = tcpClient.BeginConnect(m_Ip, m_Port, null, null); - var success = result.AsyncWaitHandle.WaitOne(m_ConnectionTimeout); - if (!success) - { - return false; - } - try - { - tcpClient.EndConnect(result); - } - catch (SocketException) - { - m_LostConnection = true; - return false; - } - - var bf = new DTOFormatter(); - bf.Serialize(tcpClient.GetStream(), dto); - tcpClient.GetStream().Close(); - tcpClient.Close(); - Debug.Log("Sent " + dto.messageType); - } - } - catch (SocketException e) - { - Debug.LogException(e); - m_LostConnection = true; - return false; - } -#endif // if UTT_SOCKETS_SUPPORTED - return true; - } - - public bool Ping() - { - var result = SendDTO(ResultDTO.CreatePing()); - m_LostConnection = false; - return result; - } - - public void RunStarted(string platform, List testsToRun) - { - SendDTO(ResultDTO.CreateRunStarted()); - } - - public void RunFinished(List testResults) - { - SendDTO(ResultDTO.CreateRunFinished(testResults)); - } - - public void TestStarted(TestResult test) - { - SendDTO(ResultDTO.CreateTestStarted(test)); - } - - public void TestFinished(TestResult test) - { - SendDTO(ResultDTO.CreateTestFinished(test)); - } - - public void AllScenesFinished() - { - SendDTO (ResultDTO.CreateAllScenesFinished ()); - } - - public void TestRunInterrupted(List testsNotRun) - { - RunFinished(new List()); - } - } -} diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/NetworkResultSender.cs.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/NetworkResultSender.cs.meta deleted file mode 100644 index 2ed06e13..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/NetworkResultSender.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 80b91644bbbc487479429368d4e8d596 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/ResultDTO.cs b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/ResultDTO.cs deleted file mode 100644 index e8a8e4e8..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/ResultDTO.cs +++ /dev/null @@ -1,168 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.SceneManagement; - -namespace UnityTest -{ - [Serializable] - public class ResultDTO - { - public MessageType messageType; - public int levelCount; - public int loadedLevel; - public string loadedLevelName; - public string testName; - public float testTimeout; - public ITestResult testResult; - - private ResultDTO(MessageType messageType) - { - this.messageType = messageType; - levelCount = UnityEngine.SceneManagement.SceneManager.sceneCount; - loadedLevel = UnityEngine.SceneManagement.SceneManager.GetActiveScene().buildIndex; - loadedLevelName = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name; - } - - public enum MessageType : byte - { - Ping, - RunStarted, - RunFinished, - TestStarted, - TestFinished, - RunInterrupted, - AllScenesFinished - } - - public static ResultDTO CreatePing() - { - var dto = new ResultDTO(MessageType.Ping); - return dto; - } - - public static ResultDTO CreateRunStarted() - { - var dto = new ResultDTO(MessageType.RunStarted); - return dto; - } - - public static ResultDTO CreateRunFinished(List testResults) - { - var dto = new ResultDTO(MessageType.RunFinished); - return dto; - } - - public static ResultDTO CreateTestStarted(TestResult test) - { - var dto = new ResultDTO(MessageType.TestStarted); - dto.testName = test.FullName; - dto.testTimeout = test.TestComponent.timeout; - return dto; - } - - public static ResultDTO CreateTestFinished(TestResult test) - { - var dto = new ResultDTO(MessageType.TestFinished); - dto.testName = test.FullName; - dto.testResult = GetSerializableTestResult(test); - return dto; - } - - public static ResultDTO CreateAllScenesFinished() - { - var dto = new ResultDTO(MessageType.AllScenesFinished); - return dto; - } - - private static ITestResult GetSerializableTestResult(TestResult test) - { - var str = new SerializableTestResult(); - - str.resultState = test.ResultState; - str.message = test.messages; - str.executed = test.Executed; - str.name = test.Name; - str.fullName = test.FullName; - str.id = test.id; - str.isSuccess = test.IsSuccess; - str.duration = test.duration; - str.stackTrace = test.stacktrace; - str.isIgnored = test.IsIgnored; - - return str; - } - } - - #region SerializableTestResult - [Serializable] - internal class SerializableTestResult : ITestResult - { - public TestResultState resultState; - public string message; - public bool executed; - public string name; - public string fullName; - public string id; - public bool isSuccess; - public double duration; - public string stackTrace; - public bool isIgnored; - - public TestResultState ResultState - { - get { return resultState; } - } - - public string Message - { - get { return message; } - } - - public string Logs - { - get { return null; } - } - - public bool Executed - { - get { return executed; } - } - - public string Name - { - get { return name; } - } - - public string FullName - { - get { return fullName; } - } - - public string Id - { - get { return id; } - } - - public bool IsSuccess - { - get { return isSuccess; } - } - - public double Duration - { - get { return duration; } - } - - public string StackTrace - { - get { return stackTrace; } - } - - public bool IsIgnored - { - get { return isIgnored; } - } - } - #endregion -} diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/ResultDTO.cs.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/ResultDTO.cs.meta deleted file mode 100644 index e34e61ff..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/ResultDTO.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 37c772b6d1ba4274aa96c83710cb27e8 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestComponent.cs b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestComponent.cs deleted file mode 100644 index d8d91646..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestComponent.cs +++ /dev/null @@ -1,412 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using UnityEngine; -using UnityEngine.SceneManagement; - -#if UNITY_EDITOR -using UnityEditor; -#endif - -namespace UnityTest -{ - public interface ITestComponent : IComparable - { - void EnableTest(bool enable); - bool IsTestGroup(); - GameObject gameObject { get; } - string Name { get; } - ITestComponent GetTestGroup(); - bool IsExceptionExpected(string exceptionType); - bool ShouldSucceedOnException(); - double GetTimeout(); - bool IsIgnored(); - bool ShouldSucceedOnAssertions(); - bool IsExludedOnThisPlatform(); - } - - public class TestComponent : MonoBehaviour, ITestComponent - { - public static ITestComponent NullTestComponent = new NullTestComponentImpl(); - - public float timeout = 5; - public bool ignored = false; - public bool succeedAfterAllAssertionsAreExecuted = false; - public bool expectException = false; - public string expectedExceptionList = ""; - public bool succeedWhenExceptionIsThrown = false; - public IncludedPlatforms includedPlatforms = (IncludedPlatforms) ~0L; - public string[] platformsToIgnore = null; - - public bool dynamic; - public string dynamicTypeName; - - public bool IsExludedOnThisPlatform() - { - return platformsToIgnore != null && platformsToIgnore.Any(platform => platform == Application.platform.ToString()); - } - - static bool IsAssignableFrom(Type a, Type b) - { -#if !UNITY_METRO - return a.IsAssignableFrom(b); -#else - return false; -#endif - } - - public bool IsExceptionExpected(string exception) - { - exception = exception.Trim(); - if (!expectException) - return false; - if(string.IsNullOrEmpty(expectedExceptionList.Trim())) - return true; - foreach (var expectedException in expectedExceptionList.Split(',').Select(e => e.Trim())) - { - if (exception == expectedException) - return true; - var exceptionType = Type.GetType(exception) ?? GetTypeByName(exception); - var expectedExceptionType = Type.GetType(expectedException) ?? GetTypeByName(expectedException); - if (exceptionType != null && expectedExceptionType != null && IsAssignableFrom(expectedExceptionType, exceptionType)) - return true; - } - return false; - } - - public bool ShouldSucceedOnException() - { - return succeedWhenExceptionIsThrown; - } - - public double GetTimeout() - { - return timeout; - } - - public bool IsIgnored() - { - return ignored; - } - - public bool ShouldSucceedOnAssertions() - { - return succeedAfterAllAssertionsAreExecuted; - } - - private static Type GetTypeByName(string className) - { -#if !UNITY_METRO - return AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes()).FirstOrDefault(type => type.Name == className); -#else - return null; -#endif - } - - public void OnValidate() - { - if (timeout < 0.01f) timeout = 0.01f; - } - - // Legacy - [Flags] - public enum IncludedPlatforms - { - WindowsEditor = 1 << 0, - OSXEditor = 1 << 1, - WindowsPlayer = 1 << 2, - OSXPlayer = 1 << 3, - LinuxPlayer = 1 << 4, - MetroPlayerX86 = 1 << 5, - MetroPlayerX64 = 1 << 6, - MetroPlayerARM = 1 << 7, - WindowsWebPlayer = 1 << 8, - OSXWebPlayer = 1 << 9, - Android = 1 << 10, -// ReSharper disable once InconsistentNaming - IPhonePlayer = 1 << 11, - TizenPlayer = 1 << 12, - WP8Player = 1 << 13, - BB10Player = 1 << 14, - NaCl = 1 << 15, - PS3 = 1 << 16, - XBOX360 = 1 << 17, - WiiPlayer = 1 << 18, - PSP2 = 1 << 19, - PS4 = 1 << 20, - PSMPlayer = 1 << 21, - XboxOne = 1 << 22, - } - - #region ITestComponent implementation - - public void EnableTest(bool enable) - { - if (enable && dynamic) - { - Type t = Type.GetType(dynamicTypeName); - var s = gameObject.GetComponent(t) as MonoBehaviour; - if (s != null) - DestroyImmediate(s); - - gameObject.AddComponent(t); - } - - if (gameObject.activeSelf != enable) gameObject.SetActive(enable); - } - - public int CompareTo(ITestComponent obj) - { - if (obj == NullTestComponent) - return 1; - var result = gameObject.name.CompareTo(obj.gameObject.name); - if (result == 0) - result = gameObject.GetInstanceID().CompareTo(obj.gameObject.GetInstanceID()); - return result; - } - - public bool IsTestGroup() - { - for (int i = 0; i < gameObject.transform.childCount; i++) - { - var childTc = gameObject.transform.GetChild(i).GetComponent(typeof(TestComponent)); - if (childTc != null) - return true; - } - return false; - } - - public string Name { get { return gameObject == null ? "" : gameObject.name; } } - - public ITestComponent GetTestGroup() - { - var parent = gameObject.transform.parent; - if (parent == null) - return NullTestComponent; - return parent.GetComponent(); - } - - public override bool Equals(object o) - { - if (o is TestComponent) - return this == (o as TestComponent); - return false; - } - - public override int GetHashCode() - { - return base.GetHashCode(); - } - - public static bool operator ==(TestComponent a, TestComponent b) - { - if (ReferenceEquals(a, b)) - return true; - if (((object)a == null) || ((object)b == null)) - return false; - if (a.dynamic && b.dynamic) - return a.dynamicTypeName == b.dynamicTypeName; - if (a.dynamic || b.dynamic) - return false; - return a.gameObject == b.gameObject; - } - - public static bool operator !=(TestComponent a, TestComponent b) - { - return !(a == b); - } - - #endregion - - #region Static helpers - - public static TestComponent CreateDynamicTest(Type type) - { - var go = CreateTest(type.Name); - go.hideFlags |= HideFlags.DontSave; - go.SetActive(false); - - var tc = go.GetComponent(); - tc.dynamic = true; - tc.dynamicTypeName = type.AssemblyQualifiedName; - -#if !UNITY_METRO - foreach (var typeAttribute in type.GetCustomAttributes(false)) - { - if (typeAttribute is IntegrationTest.TimeoutAttribute) - tc.timeout = (typeAttribute as IntegrationTest.TimeoutAttribute).timeout; - else if (typeAttribute is IntegrationTest.IgnoreAttribute) - tc.ignored = true; - else if (typeAttribute is IntegrationTest.SucceedWithAssertions) - tc.succeedAfterAllAssertionsAreExecuted = true; - else if (typeAttribute is IntegrationTest.ExcludePlatformAttribute) - tc.platformsToIgnore = (typeAttribute as IntegrationTest.ExcludePlatformAttribute).platformsToExclude; - else if (typeAttribute is IntegrationTest.ExpectExceptions) - { - var attribute = (typeAttribute as IntegrationTest.ExpectExceptions); - tc.expectException = true; - tc.expectedExceptionList = string.Join(",", attribute.exceptionTypeNames); - tc.succeedWhenExceptionIsThrown = attribute.succeedOnException; - } - } - go.AddComponent(type); -#endif // if !UNITY_METRO - return tc; - } - - public static GameObject CreateTest() - { - return CreateTest("New Test"); - } - - private static GameObject CreateTest(string name) - { - var go = new GameObject(name); - go.AddComponent(); -#if UNITY_EDITOR - Undo.RegisterCreatedObjectUndo(go, "Created test"); -#endif - return go; - } - - public static List FindAllTestsOnScene() - { - var tests = Resources.FindObjectsOfTypeAll (typeof(TestComponent)).Cast (); -#if UNITY_EDITOR - tests = tests.Where( t => {var p = PrefabUtility.GetPrefabType(t); return p != PrefabType.Prefab && p != PrefabType.ModelPrefab;} ); - -#endif - return tests.ToList (); - } - - public static List FindAllTopTestsOnScene() - { - return FindAllTestsOnScene().Where(component => component.gameObject.transform.parent == null).ToList(); - } - - public static List FindAllDynamicTestsOnScene() - { - return FindAllTestsOnScene().Where(t => t.dynamic).ToList(); - } - - public static void DestroyAllDynamicTests() - { - foreach (var dynamicTestComponent in FindAllDynamicTestsOnScene()) - DestroyImmediate(dynamicTestComponent.gameObject); - } - - public static void DisableAllTests() - { - foreach (var t in FindAllTestsOnScene()) t.EnableTest(false); - } - - public static bool AnyTestsOnScene() - { - return FindAllTestsOnScene().Any(); - } - - public static bool AnyDynamicTestForCurrentScene() - { -#if UNITY_EDITOR - return TestComponent.GetTypesWithHelpAttribute(SceneManager.GetActiveScene().name).Any(); -#else - return TestComponent.GetTypesWithHelpAttribute(SceneManager.GetActiveScene().name).Any(); -#endif - } - - #endregion - - private sealed class NullTestComponentImpl : ITestComponent - { - public int CompareTo(ITestComponent other) - { - if (other == this) return 0; - return -1; - } - - public void EnableTest(bool enable) - { - } - - public bool IsTestGroup() - { - throw new NotImplementedException(); - } - - public GameObject gameObject { get; private set; } - public string Name { get { return ""; } } - - public ITestComponent GetTestGroup() - { - return null; - } - - public bool IsExceptionExpected(string exceptionType) - { - throw new NotImplementedException(); - } - - public bool ShouldSucceedOnException() - { - throw new NotImplementedException(); - } - - public double GetTimeout() - { - throw new NotImplementedException(); - } - - public bool IsIgnored() - { - throw new NotImplementedException(); - } - - public bool ShouldSucceedOnAssertions() - { - throw new NotImplementedException(); - } - - public bool IsExludedOnThisPlatform() - { - throw new NotImplementedException(); - } - } - - public static IEnumerable GetTypesWithHelpAttribute(string sceneName) - { -#if !UNITY_METRO - foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) - { - Type[] types = null; - - try - { - types = assembly.GetTypes(); - } - catch (ReflectionTypeLoadException ex) - { - Debug.LogError("Failed to load types from: " + assembly.FullName); - foreach (Exception loadEx in ex.LoaderExceptions) - Debug.LogException(loadEx); - } - - if (types == null) - continue; - - foreach (Type type in types) - { - var attributes = type.GetCustomAttributes(typeof(IntegrationTest.DynamicTestAttribute), true); - if (attributes.Length == 1) - { - var a = attributes.Single() as IntegrationTest.DynamicTestAttribute; - if (a.IncludeOnScene(sceneName)) yield return type; - } - } - } -#else // if !UNITY_METRO - yield break; -#endif // if !UNITY_METRO - } - } -} diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestComponent.cs.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestComponent.cs.meta deleted file mode 100644 index fd67c93b..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestComponent.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: b1dba0b27b0864740a8720e920aa88c0 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestResult.cs b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestResult.cs deleted file mode 100644 index df67f714..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestResult.cs +++ /dev/null @@ -1,141 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace UnityTest -{ - [Serializable] - public class TestResult : ITestResult, IComparable - { - private readonly GameObject m_Go; - private string m_Name; - public ResultType resultType = ResultType.NotRun; - public double duration; - public string messages; - public string stacktrace; - public string id; - public bool dynamicTest; - - public TestComponent TestComponent; - - public GameObject GameObject - { - get { return m_Go; } - } - - public TestResult(TestComponent testComponent) - { - TestComponent = testComponent; - m_Go = testComponent.gameObject; - id = testComponent.gameObject.GetInstanceID().ToString(); - dynamicTest = testComponent.dynamic; - - if (m_Go != null) m_Name = m_Go.name; - - if (dynamicTest) - id = testComponent.dynamicTypeName; - } - - public void Update(TestResult oldResult) - { - resultType = oldResult.resultType; - duration = oldResult.duration; - messages = oldResult.messages; - stacktrace = oldResult.stacktrace; - } - - public enum ResultType - { - Success, - Failed, - Timeout, - NotRun, - FailedException, - Ignored - } - - public void Reset() - { - resultType = ResultType.NotRun; - duration = 0f; - messages = ""; - stacktrace = ""; - } - - #region ITestResult implementation - public TestResultState ResultState { - get - { - switch (resultType) - { - case ResultType.Success: return TestResultState.Success; - case ResultType.Failed: return TestResultState.Failure; - case ResultType.FailedException: return TestResultState.Error; - case ResultType.Ignored: return TestResultState.Ignored; - case ResultType.NotRun: return TestResultState.Skipped; - case ResultType.Timeout: return TestResultState.Cancelled; - default: throw new Exception(); - } - } - } - public string Message { get { return messages; } } - public string Logs { get { return null; } } - public bool Executed { get { return resultType != ResultType.NotRun; } } - public string Name { get { if (m_Go != null) m_Name = m_Go.name; return m_Name; } } - public string Id { get { return id; } } - public bool IsSuccess { get { return resultType == ResultType.Success; } } - public bool IsTimeout { get { return resultType == ResultType.Timeout; } } - public double Duration { get { return duration; } } - public string StackTrace { get { return stacktrace; } } - public string FullName { - get - { - var fullName = Name; - if (m_Go != null) - { - var tempGo = m_Go.transform.parent; - while (tempGo != null) - { - fullName = tempGo.name + "." + fullName; - tempGo = tempGo.transform.parent; - } - } - return fullName; - } - } - - public bool IsIgnored { get { return resultType == ResultType.Ignored; } } - public bool IsFailure - { - get - { - return resultType == ResultType.Failed - || resultType == ResultType.FailedException - || resultType == ResultType.Timeout; - } - } - #endregion - - #region IComparable, GetHashCode and Equals implementation - public override int GetHashCode() - { - return id.GetHashCode(); - } - - public int CompareTo(TestResult other) - { - var result = Name.CompareTo(other.Name); - if (result == 0) - result = m_Go.GetInstanceID().CompareTo(other.m_Go.GetInstanceID()); - return result; - } - - public override bool Equals(object obj) - { - if (obj is TestResult) - return GetHashCode() == obj.GetHashCode(); - return base.Equals(obj); - } - #endregion - } -} diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestResult.cs.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestResult.cs.meta deleted file mode 100644 index c604beaa..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestResult.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 68740a702763aaa4594e8319a05ae0d3 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestResultRenderer.cs b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestResultRenderer.cs deleted file mode 100644 index e838d7e2..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestResultRenderer.cs +++ /dev/null @@ -1,83 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEngine; - -public class TestResultRenderer -{ - private static class Styles - { - public static readonly GUIStyle SucceedLabelStyle; - public static readonly GUIStyle FailedLabelStyle; - public static readonly GUIStyle FailedMessagesStyle; - - static Styles() - { - SucceedLabelStyle = new GUIStyle("label"); - SucceedLabelStyle.normal.textColor = Color.green; - SucceedLabelStyle.fontSize = 48; - - FailedLabelStyle = new GUIStyle("label"); - FailedLabelStyle.normal.textColor = Color.red; - FailedLabelStyle.fontSize = 32; - - FailedMessagesStyle = new GUIStyle("label"); - FailedMessagesStyle.wordWrap = false; - FailedMessagesStyle.richText = true; - } - } - private readonly Dictionary> m_TestCollection = new Dictionary>(); - - private bool m_ShowResults; - Vector2 m_ScrollPosition; - private int m_FailureCount; - - public void ShowResults() - { - m_ShowResults = true; - Cursor.visible = true; - } - - public void AddResults(string sceneName, ITestResult result) - { - if (!m_TestCollection.ContainsKey(sceneName)) - m_TestCollection.Add(sceneName, new List()); - m_TestCollection[sceneName].Add(result); - if (result.Executed && !result.IsSuccess) - m_FailureCount++; - } - - public void Draw() - { - if (!m_ShowResults) return; - if (m_TestCollection.Count == 0) - { - GUILayout.Label("All test succeeded", Styles.SucceedLabelStyle, GUILayout.Width(600)); - } - else - { - int count = m_TestCollection.Sum (testGroup => testGroup.Value.Count); - GUILayout.Label(count + " tests failed!", Styles.FailedLabelStyle); - - m_ScrollPosition = GUILayout.BeginScrollView(m_ScrollPosition, GUILayout.ExpandWidth(true)); - var text = ""; - foreach (var testGroup in m_TestCollection) - { - text += "" + testGroup.Key + "\n"; - text += string.Join("\n", testGroup.Value - .Where(result => !result.IsSuccess) - .Select(result => result.Name + " " + result.ResultState + "\n" + result.Message) - .ToArray()); - } - GUILayout.TextArea(text, Styles.FailedMessagesStyle); - GUILayout.EndScrollView(); - } - if (GUILayout.Button("Close")) - Application.Quit(); - } - - public int FailureCount() - { - return m_FailureCount; - } -} diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestResultRenderer.cs.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestResultRenderer.cs.meta deleted file mode 100644 index 7d70150a..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestResultRenderer.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 7ae9d3b4b57cae343b7ff360f9deb628 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunner.cs b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunner.cs deleted file mode 100644 index 9c64a2f8..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunner.cs +++ /dev/null @@ -1,432 +0,0 @@ -// #define IMITATE_BATCH_MODE //uncomment if you want to imitate batch mode behaviour in non-batch mode mode run - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using UnityEngine; -using UnityTest.IntegrationTestRunner; -using System.IO; -using UnityEngine.SceneManagement; - -namespace UnityTest -{ - [Serializable] - public class TestRunner : MonoBehaviour - { - static private int TestSceneNumber = 0; - static private readonly TestResultRenderer k_ResultRenderer = new TestResultRenderer(); - - public TestComponent currentTest; - private List m_ResultList = new List(); - private List m_TestComponents; - - public bool isInitializedByRunner - { - get - { -#if !IMITATE_BATCH_MODE - if (Application.isEditor && !IsBatchMode()) - return true; -#endif - return false; - } - } - - private double m_StartTime; - private bool m_ReadyToRun; - - private string m_TestMessages; - private string m_Stacktrace; - private TestState m_TestState = TestState.Running; - - private TestRunnerConfigurator m_Configurator; - - public TestRunnerCallbackList TestRunnerCallback = new TestRunnerCallbackList(); - private IntegrationTestsProvider m_TestsProvider; - - private const string k_Prefix = "IntegrationTest"; - private const string k_StartedMessage = k_Prefix + " Started"; - private const string k_FinishedMessage = k_Prefix + " Finished"; - private const string k_TimeoutMessage = k_Prefix + " Timeout"; - private const string k_FailedMessage = k_Prefix + " Failed"; - private const string k_FailedExceptionMessage = k_Prefix + " Failed with exception"; - private const string k_IgnoredMessage = k_Prefix + " Ignored"; - private const string k_InterruptedMessage = k_Prefix + " Run interrupted"; - - - public void Awake() - { - m_Configurator = new TestRunnerConfigurator(); - if (isInitializedByRunner) return; - TestComponent.DisableAllTests(); - } - - public void Start() - { - if (isInitializedByRunner) return; - - if (m_Configurator.sendResultsOverNetwork) - { - var nrs = m_Configurator.ResolveNetworkConnection(); - if (nrs != null) - TestRunnerCallback.Add(nrs); - } - - TestComponent.DestroyAllDynamicTests(); - var dynamicTestTypes = TestComponent.GetTypesWithHelpAttribute(SceneManager.GetActiveScene().name); - foreach (var dynamicTestType in dynamicTestTypes) - TestComponent.CreateDynamicTest(dynamicTestType); - - var tests = TestComponent.FindAllTestsOnScene(); - - InitRunner(tests, dynamicTestTypes.Select(type => type.AssemblyQualifiedName).ToList()); - } - - public void InitRunner(List tests, List dynamicTestsToRun) - { - Application.logMessageReceived += LogHandler; - - // Init dynamic tests - foreach (var typeName in dynamicTestsToRun) - { - var t = Type.GetType(typeName); - if (t == null) continue; - var scriptComponents = Resources.FindObjectsOfTypeAll(t) as MonoBehaviour[]; - if (scriptComponents.Length == 0) - { - Debug.LogWarning(t + " not found. Skipping."); - continue; - } - if (scriptComponents.Length > 1) Debug.LogWarning("Multiple GameObjects refer to " + typeName); - tests.Add(scriptComponents.First().GetComponent()); - } - // create test structure - m_TestComponents = ParseListForGroups(tests).ToList(); - // create results for tests - m_ResultList = m_TestComponents.Select(component => new TestResult(component)).ToList(); - // init test provider - m_TestsProvider = new IntegrationTestsProvider(m_ResultList.Select(result => result.TestComponent as ITestComponent)); - m_ReadyToRun = true; - } - - private static IEnumerable ParseListForGroups(IEnumerable tests) - { - var results = new HashSet(); - foreach (var testResult in tests) - { - if (testResult.IsTestGroup()) - { - var childrenTestResult = testResult.gameObject.GetComponentsInChildren(typeof(TestComponent), true) - .Where(t => t != testResult) - .Cast() - .ToArray(); - foreach (var result in childrenTestResult) - { - if (!result.IsTestGroup()) - results.Add(result); - } - continue; - } - results.Add(testResult); - } - return results; - } - - public void Update() - { - if (m_ReadyToRun && Time.frameCount > 1) - { - m_ReadyToRun = false; - StartCoroutine("StateMachine"); - } - } - - public void OnDestroy() - { - if (currentTest != null) - { - var testResult = m_ResultList.Single(result => result.TestComponent == currentTest); - testResult.messages += "Test run interrupted (crash?)"; - LogMessage(k_InterruptedMessage); - FinishTest(TestResult.ResultType.Failed); - } - if (currentTest != null || (m_TestsProvider != null && m_TestsProvider.AnyTestsLeft())) - { - var remainingTests = m_TestsProvider.GetRemainingTests(); - TestRunnerCallback.TestRunInterrupted(remainingTests.ToList()); - } - Application.logMessageReceived -= LogHandler; - } - - private void LogHandler(string condition, string stacktrace, LogType type) - { - if (!condition.StartsWith(k_StartedMessage) && !condition.StartsWith(k_FinishedMessage)) - { - var msg = condition; - if (msg.StartsWith(k_Prefix)) msg = msg.Substring(k_Prefix.Length + 1); - if (currentTest != null && msg.EndsWith("(" + currentTest.name + ')')) msg = msg.Substring(0, msg.LastIndexOf('(')); - m_TestMessages += msg + "\n"; - } - switch (type) - { - case LogType.Exception: - { - var exceptionType = condition.Substring(0, condition.IndexOf(':')); - if (currentTest != null && currentTest.IsExceptionExpected(exceptionType)) - { - m_TestMessages += exceptionType + " was expected\n"; - if (currentTest.ShouldSucceedOnException()) - { - m_TestState = TestState.Success; - } - } - else - { - m_TestState = TestState.Exception; - m_Stacktrace = stacktrace; - } - } - break; - case LogType.Assert: - case LogType.Error: - m_TestState = TestState.Failure; - m_Stacktrace = stacktrace; - break; - case LogType.Log: - if (m_TestState == TestState.Running && condition.StartsWith(IntegrationTest.passMessage)) - { - m_TestState = TestState.Success; - } - if (condition.StartsWith(IntegrationTest.failMessage)) - { - m_TestState = TestState.Failure; - } - break; - } - } - - public IEnumerator StateMachine() - { - TestRunnerCallback.RunStarted(Application.platform.ToString(), m_TestComponents); - while (true) - { - if (!m_TestsProvider.AnyTestsLeft() && currentTest == null) - { - FinishTestRun(); - yield break; - } - if (currentTest == null) - { - StartNewTest(); - } - if (currentTest != null) - { - if (m_TestState == TestState.Running) - { - if(currentTest.ShouldSucceedOnAssertions()) - { - var assertionsToCheck = currentTest.gameObject.GetComponentsInChildren().Where(a => a.enabled).ToArray(); - if (assertionsToCheck.Any () && assertionsToCheck.All(a => a.checksPerformed > 0)) - { - IntegrationTest.Pass(currentTest.gameObject); - m_TestState = TestState.Success; - } - } - if (currentTest != null && Time.time > m_StartTime + currentTest.GetTimeout()) - { - m_TestState = TestState.Timeout; - } - } - - switch (m_TestState) - { - case TestState.Success: - LogMessage(k_FinishedMessage); - FinishTest(TestResult.ResultType.Success); - break; - case TestState.Failure: - LogMessage(k_FailedMessage); - FinishTest(TestResult.ResultType.Failed); - break; - case TestState.Exception: - LogMessage(k_FailedExceptionMessage); - FinishTest(TestResult.ResultType.FailedException); - break; - case TestState.Timeout: - LogMessage(k_TimeoutMessage); - FinishTest(TestResult.ResultType.Timeout); - break; - case TestState.Ignored: - LogMessage(k_IgnoredMessage); - FinishTest(TestResult.ResultType.Ignored); - break; - } - } - yield return null; - } - } - - private void LogMessage(string message) - { - if (currentTest != null) - Debug.Log(message + " (" + currentTest.Name + ")", currentTest.gameObject); - else - Debug.Log(message); - } - - private void FinishTestRun() - { - PrintResultToLog(); - TestRunnerCallback.RunFinished(m_ResultList); - LoadNextLevelOrQuit(); - } - - private void PrintResultToLog() - { - var resultString = ""; - resultString += "Passed: " + m_ResultList.Count(t => t.IsSuccess); - if (m_ResultList.Any(result => result.IsFailure)) - { - resultString += " Failed: " + m_ResultList.Count(t => t.IsFailure); - Debug.Log("Failed tests: " + string.Join(", ", m_ResultList.Where(t => t.IsFailure).Select(result => result.Name).ToArray())); - } - if (m_ResultList.Any(result => result.IsIgnored)) - { - resultString += " Ignored: " + m_ResultList.Count(t => t.IsIgnored); - Debug.Log("Ignored tests: " + string.Join(", ", - m_ResultList.Where(t => t.IsIgnored).Select(result => result.Name).ToArray())); - } - Debug.Log(resultString); - } - - private void LoadNextLevelOrQuit() - { - if (isInitializedByRunner) return; - - - TestSceneNumber += 1; - string testScene = m_Configurator.GetIntegrationTestScenes(TestSceneNumber); - - if (testScene != null) - SceneManager.LoadScene(Path.GetFileNameWithoutExtension(testScene)); - else - { - TestRunnerCallback.AllScenesFinished(); - k_ResultRenderer.ShowResults(); - -#if UNITY_EDITOR - var prevScenes = m_Configurator.GetPreviousScenesToRestore(); - if(prevScenes!=null) - { - UnityEditor.EditorBuildSettings.scenes = prevScenes; - } -#endif - - if (m_Configurator.isBatchRun && m_Configurator.sendResultsOverNetwork) - Application.Quit(); - } - } - - public void OnGUI() - { - k_ResultRenderer.Draw(); - } - - private void StartNewTest() - { - m_TestMessages = ""; - m_Stacktrace = ""; - m_TestState = TestState.Running; - - m_StartTime = Time.time; - currentTest = m_TestsProvider.GetNextTest() as TestComponent; - - var testResult = m_ResultList.Single(result => result.TestComponent == currentTest); - - if (currentTest != null && currentTest.IsExludedOnThisPlatform()) - { - m_TestState = TestState.Ignored; - Debug.Log(currentTest.gameObject.name + " is excluded on this platform"); - } - - // don't ignore test if user initiated it from the runner and it's the only test that is being run - if (currentTest != null - && (currentTest.IsIgnored() - && !(isInitializedByRunner && m_ResultList.Count == 1))) - m_TestState = TestState.Ignored; - - LogMessage(k_StartedMessage); - TestRunnerCallback.TestStarted(testResult); - } - - private void FinishTest(TestResult.ResultType result) - { - m_TestsProvider.FinishTest(currentTest); - var testResult = m_ResultList.Single(t => t.GameObject == currentTest.gameObject); - testResult.resultType = result; - testResult.duration = Time.time - m_StartTime; - testResult.messages = m_TestMessages; - testResult.stacktrace = m_Stacktrace; - TestRunnerCallback.TestFinished(testResult); - currentTest = null; - if (!testResult.IsSuccess - && testResult.Executed - && !testResult.IsIgnored) k_ResultRenderer.AddResults(SceneManager.GetActiveScene().name, testResult); - } - - #region Test Runner Helpers - - public static TestRunner GetTestRunner() - { - TestRunner testRunnerComponent = null; - var testRunnerComponents = Resources.FindObjectsOfTypeAll(typeof(TestRunner)); - - if (testRunnerComponents.Count() > 1) - foreach (var t in testRunnerComponents) DestroyImmediate(((TestRunner)t).gameObject); - else if (!testRunnerComponents.Any()) - testRunnerComponent = Create().GetComponent(); - else - testRunnerComponent = testRunnerComponents.Single() as TestRunner; - - return testRunnerComponent; - } - - private static GameObject Create() - { - var runner = new GameObject("TestRunner"); - runner.AddComponent(); - Debug.Log("Created Test Runner"); - return runner; - } - - private static bool IsBatchMode() - { -#if !UNITY_METRO - const string internalEditorUtilityClassName = "UnityEditorInternal.InternalEditorUtility, UnityEditor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"; - - var t = Type.GetType(internalEditorUtilityClassName, false); - if (t == null) return false; - - const string inBatchModeProperty = "inBatchMode"; - var prop = t.GetProperty(inBatchModeProperty); - return (bool)prop.GetValue(null, null); -#else // if !UNITY_METRO - return false; -#endif // if !UNITY_METRO - } - - #endregion - - enum TestState - { - Running, - Success, - Failure, - Exception, - Timeout, - Ignored - } - } -} diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunner.cs.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunner.cs.meta deleted file mode 100644 index 5ef068e2..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunner.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 5c3afc1c624179749bcdecf7b0224902 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunnerCallbackList.cs b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunnerCallbackList.cs deleted file mode 100644 index 91830d2a..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunnerCallbackList.cs +++ /dev/null @@ -1,69 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace UnityTest.IntegrationTestRunner -{ - public class TestRunnerCallbackList : ITestRunnerCallback - { - private readonly List m_CallbackList = new List(); - - public void Add(ITestRunnerCallback callback) - { - m_CallbackList.Add(callback); - } - - public void Remove(ITestRunnerCallback callback) - { - m_CallbackList.Remove(callback); - } - - public void RunStarted(string platform, List testsToRun) - { - foreach (var unitTestRunnerCallback in m_CallbackList) - { - unitTestRunnerCallback.RunStarted(platform, testsToRun); - } - } - - public void RunFinished(List testResults) - { - foreach (var unitTestRunnerCallback in m_CallbackList) - { - unitTestRunnerCallback.RunFinished(testResults); - } - } - - public void AllScenesFinished() - { - foreach (var unitTestRunnerCallback in m_CallbackList) - { - unitTestRunnerCallback.AllScenesFinished(); - } - } - - public void TestStarted(TestResult test) - { - foreach (var unitTestRunnerCallback in m_CallbackList) - { - unitTestRunnerCallback.TestStarted(test); - } - } - - public void TestFinished(TestResult test) - { - foreach (var unitTestRunnerCallback in m_CallbackList) - { - unitTestRunnerCallback.TestFinished(test); - } - } - - public void TestRunInterrupted(List testsNotRun) - { - foreach (var unitTestRunnerCallback in m_CallbackList) - { - unitTestRunnerCallback.TestRunInterrupted(testsNotRun); - } - } - } -} diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunnerCallbackList.cs.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunnerCallbackList.cs.meta deleted file mode 100644 index c39656ab..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunnerCallbackList.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 7729da83f7c08d244b5788c870a93780 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunnerConfigurator.cs b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunnerConfigurator.cs deleted file mode 100644 index b0b270d4..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunnerConfigurator.cs +++ /dev/null @@ -1,227 +0,0 @@ -#if !UNITY_METRO && !UNITY_WEBPLAYER && (UNITY_PRO_LICENSE || !(UNITY_ANDROID || UNITY_IPHONE)) -#define UTT_SOCKETS_SUPPORTED -#endif -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading; -using UnityEngine; -using UnityTest.IntegrationTestRunner; -#if UTT_SOCKETS_SUPPORTED -using System.Net; -using System.Net.Sockets; -using System.Net.NetworkInformation; -#endif - -#if UNITY_EDITOR -using UnityEditorInternal; -#endif - -namespace UnityTest -{ - public class TestRunnerConfigurator - { - public static string integrationTestsNetwork = "networkconfig.txt"; - public static string batchRunFileMarker = "batchrun.txt"; - public static string testScenesToRun = "testscenes.txt"; - public static string previousScenes = "previousScenes.txt"; - - public bool isBatchRun { get; private set; } - - public bool sendResultsOverNetwork { get; private set; } - -#if UTT_SOCKETS_SUPPORTED - private readonly List m_IPEndPointList = new List(); -#endif - - public TestRunnerConfigurator() - { - CheckForBatchMode(); - CheckForSendingResultsOverNetwork(); - } - -#if UNITY_EDITOR - public UnityEditor.EditorBuildSettingsScene[] GetPreviousScenesToRestore() - { - string text = null; - if (Application.isEditor) - { - text = GetTextFromTempFile(previousScenes); - } - - if(text != null) - { - var serializer = new System.Xml.Serialization.XmlSerializer(typeof(UnityEditor.EditorBuildSettingsScene[])); - using(var textReader = new StringReader(text)) - { - try - { - return (UnityEditor.EditorBuildSettingsScene[] )serializer.Deserialize(textReader); - } - catch (System.Xml.XmlException) - { - return null; - } - } - } - - return null; - } -#endif - - public string GetIntegrationTestScenes(int testSceneNum) - { - string text; - if (Application.isEditor) - text = GetTextFromTempFile(testScenesToRun); - else - text = GetTextFromTextAsset(testScenesToRun); - - List sceneList = new List(); - foreach (var line in text.Split(new[] {'\n'}, StringSplitOptions.RemoveEmptyEntries)) - { - sceneList.Add(line.ToString()); - } - - if (testSceneNum < sceneList.Count) - return sceneList.ElementAt(testSceneNum); - else - return null; - } - - private void CheckForSendingResultsOverNetwork() - { -#if UTT_SOCKETS_SUPPORTED - string text; - if (Application.isEditor) - text = GetTextFromTempFile(integrationTestsNetwork); - else - text = GetTextFromTextAsset(integrationTestsNetwork); - - if (text == null) return; - - sendResultsOverNetwork = true; - - m_IPEndPointList.Clear(); - - foreach (var line in text.Split(new[] {'\n'}, StringSplitOptions.RemoveEmptyEntries)) - { - var idx = line.IndexOf(':'); - if (idx == -1) throw new Exception(line); - var ip = line.Substring(0, idx); - var port = line.Substring(idx + 1); - m_IPEndPointList.Add(new IPEndPoint(IPAddress.Parse(ip), Int32.Parse(port))); - } -#endif // if UTT_SOCKETS_SUPPORTED - } - - private static string GetTextFromTextAsset(string fileName) - { - var nameWithoutExtension = fileName.Substring(0, fileName.LastIndexOf('.')); - var resultpathFile = Resources.Load(nameWithoutExtension) as TextAsset; - return resultpathFile != null ? resultpathFile.text : null; - } - - private static string GetTextFromTempFile(string fileName) - { - string text = null; - try - { -#if UNITY_EDITOR && !UNITY_WEBPLAYER - text = File.ReadAllText(Path.Combine("Temp", fileName)); -#endif - } - catch - { - return null; - } - return text; - } - - private void CheckForBatchMode() - { -#if IMITATE_BATCH_MODE - isBatchRun = true; -#elif UNITY_EDITOR - if (Application.isEditor && InternalEditorUtility.inBatchMode) - isBatchRun = true; -#else - if (GetTextFromTextAsset(batchRunFileMarker) != null) isBatchRun = true; -#endif - } - - public static List GetAvailableNetworkIPs() - { -#if UTT_SOCKETS_SUPPORTED - if (!NetworkInterface.GetIsNetworkAvailable()) - return new List{IPAddress.Loopback.ToString()}; - - var ipList = new List(); - var allIpsList = new List(); - - foreach (var netInterface in NetworkInterface.GetAllNetworkInterfaces()) - { - if (netInterface.NetworkInterfaceType != NetworkInterfaceType.Wireless80211 && - netInterface.NetworkInterfaceType != NetworkInterfaceType.Ethernet) - continue; - - var ipAdresses = netInterface.GetIPProperties().UnicastAddresses - .Where(a => a.Address.AddressFamily == AddressFamily.InterNetwork); - allIpsList.AddRange(ipAdresses); - - if (netInterface.OperationalStatus != OperationalStatus.Up) continue; - - ipList.AddRange(ipAdresses); - } - - //On Mac 10.10 all interfaces return OperationalStatus.Unknown, thus this workaround - if(!ipList.Any()) return allIpsList.Select(i => i.Address.ToString()).ToList(); - - // sort ip list by their masks to predict which ip belongs to lan network - ipList.Sort((ip1, ip2) => - { - var mask1 = BitConverter.ToInt32(ip1.IPv4Mask.GetAddressBytes().Reverse().ToArray(), 0); - var mask2 = BitConverter.ToInt32(ip2.IPv4Mask.GetAddressBytes().Reverse().ToArray(), 0); - return mask2.CompareTo(mask1); - }); - if (ipList.Count == 0) - return new List { IPAddress.Loopback.ToString() }; - return ipList.Select(i => i.Address.ToString()).ToList(); -#else - return new List(); -#endif // if UTT_SOCKETS_SUPPORTED - } - - public ITestRunnerCallback ResolveNetworkConnection() - { -#if UTT_SOCKETS_SUPPORTED - var nrsList = m_IPEndPointList.Select(ipEndPoint => new NetworkResultSender(ipEndPoint.Address.ToString(), ipEndPoint.Port)).ToList(); - - var timeout = TimeSpan.FromSeconds(30); - DateTime startTime = DateTime.Now; - while ((DateTime.Now - startTime) < timeout) - { - foreach (var networkResultSender in nrsList) - { - try - { - if (!networkResultSender.Ping()) continue; - } - catch (Exception e) - { - Debug.LogException(e); - sendResultsOverNetwork = false; - return null; - } - return networkResultSender; - } - Thread.Sleep(500); - } - Debug.LogError("Couldn't connect to the server: " + string.Join(", ", m_IPEndPointList.Select(ipep => ipep.Address + ":" + ipep.Port).ToArray())); - sendResultsOverNetwork = false; -#endif // if UTT_SOCKETS_SUPPORTED - return null; - } - } -} diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunnerConfigurator.cs.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunnerConfigurator.cs.meta deleted file mode 100644 index 42f72639..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunnerConfigurator.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 05aae864572254e478ed2f0489cdd335 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets.meta deleted file mode 100644 index 433c2954..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets.meta +++ /dev/null @@ -1,5 +0,0 @@ -fileFormatVersion: 2 -guid: 1d1ccbd729921544dbd71f7e80c405b6 -folderAsset: yes -DefaultImporter: - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CallTesting.cs b/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CallTesting.cs deleted file mode 100644 index 3badc58c..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CallTesting.cs +++ /dev/null @@ -1,204 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace UnityTest -{ - public class CallTesting : MonoBehaviour - { - public enum Functions - { - CallAfterSeconds, - CallAfterFrames, - Start, - Update, - FixedUpdate, - LateUpdate, - OnDestroy, - OnEnable, - OnDisable, - OnControllerColliderHit, - OnParticleCollision, - OnJointBreak, - OnBecameInvisible, - OnBecameVisible, - OnTriggerEnter, - OnTriggerExit, - OnTriggerStay, - OnCollisionEnter, - OnCollisionExit, - OnCollisionStay, - OnTriggerEnter2D, - OnTriggerExit2D, - OnTriggerStay2D, - OnCollisionEnter2D, - OnCollisionExit2D, - OnCollisionStay2D, - } - - public enum Method - { - Pass, - Fail - } - - public int afterFrames = 0; - public float afterSeconds = 0.0f; - public Functions callOnMethod = Functions.Start; - - public Method methodToCall; - private int m_StartFrame; - private float m_StartTime; - - private void TryToCallTesting(Functions invokingMethod) - { - if (invokingMethod == callOnMethod) - { - if (methodToCall == Method.Pass) - IntegrationTest.Pass(gameObject); - else - IntegrationTest.Fail(gameObject); - - afterFrames = 0; - afterSeconds = 0.0f; - m_StartTime = float.PositiveInfinity; - m_StartFrame = int.MinValue; - } - } - - public void Start() - { - m_StartTime = Time.time; - m_StartFrame = afterFrames; - TryToCallTesting(Functions.Start); - } - - public void Update() - { - TryToCallTesting(Functions.Update); - CallAfterSeconds(); - CallAfterFrames(); - } - - private void CallAfterFrames() - { - if (afterFrames > 0 && (m_StartFrame + afterFrames) <= Time.frameCount) - TryToCallTesting(Functions.CallAfterFrames); - } - - private void CallAfterSeconds() - { - if ((m_StartTime + afterSeconds) <= Time.time) - TryToCallTesting(Functions.CallAfterSeconds); - } - - public void OnDisable() - { - TryToCallTesting(Functions.OnDisable); - } - - public void OnEnable() - { - TryToCallTesting(Functions.OnEnable); - } - - public void OnDestroy() - { - TryToCallTesting(Functions.OnDestroy); - } - - public void FixedUpdate() - { - TryToCallTesting(Functions.FixedUpdate); - } - - public void LateUpdate() - { - TryToCallTesting(Functions.LateUpdate); - } - - public void OnControllerColliderHit() - { - TryToCallTesting(Functions.OnControllerColliderHit); - } - - public void OnParticleCollision() - { - TryToCallTesting(Functions.OnParticleCollision); - } - - public void OnJointBreak() - { - TryToCallTesting(Functions.OnJointBreak); - } - - public void OnBecameInvisible() - { - TryToCallTesting(Functions.OnBecameInvisible); - } - - public void OnBecameVisible() - { - TryToCallTesting(Functions.OnBecameVisible); - } - - public void OnTriggerEnter() - { - TryToCallTesting(Functions.OnTriggerEnter); - } - - public void OnTriggerExit() - { - TryToCallTesting(Functions.OnTriggerExit); - } - - public void OnTriggerStay() - { - TryToCallTesting(Functions.OnTriggerStay); - } - public void OnCollisionEnter() - { - TryToCallTesting(Functions.OnCollisionEnter); - } - - public void OnCollisionExit() - { - TryToCallTesting(Functions.OnCollisionExit); - } - - public void OnCollisionStay() - { - TryToCallTesting(Functions.OnCollisionStay); - } - - public void OnTriggerEnter2D() - { - TryToCallTesting(Functions.OnTriggerEnter2D); - } - - public void OnTriggerExit2D() - { - TryToCallTesting(Functions.OnTriggerExit2D); - } - - public void OnTriggerStay2D() - { - TryToCallTesting(Functions.OnTriggerStay2D); - } - - public void OnCollisionEnter2D() - { - TryToCallTesting(Functions.OnCollisionEnter2D); - } - - public void OnCollisionExit2D() - { - TryToCallTesting(Functions.OnCollisionExit2D); - } - - public void OnCollisionStay2D() - { - TryToCallTesting(Functions.OnCollisionStay2D); - } - } -} diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CallTesting.cs.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CallTesting.cs.meta deleted file mode 100644 index 91cbde1c..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CallTesting.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 0d545b1288d5fc74d8e6c961fb67ab18 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeCollisionFailure.prefab b/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeCollisionFailure.prefab deleted file mode 100644 index c1a23a92..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeCollisionFailure.prefab +++ /dev/null @@ -1,104 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!1 &100000 -GameObject: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - serializedVersion: 4 - m_Component: - - 4: {fileID: 400000} - - 33: {fileID: 3300000} - - 65: {fileID: 6500000} - - 23: {fileID: 2300000} - - 114: {fileID: 11400000} - m_Layer: 0 - m_Name: CubeCollisionFailure - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &400000 -Transform: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 100000} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: -5.1736994, y: 3.9978147, z: -16.24892} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 0 ---- !u!23 &2300000 -MeshRenderer: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 100000} - m_Enabled: 1 - m_CastShadows: 0 - m_ReceiveShadows: 0 - m_Materials: - - {fileID: 2100000, guid: 03f3b4747259a364b800508ac27e1c17, type: 2} - m_SubsetIndices: - m_StaticBatchRoot: {fileID: 0} - m_UseLightProbes: 0 - m_ReflectionProbeUsage: 1 - m_ProbeAnchor: {fileID: 0} - m_ScaleInLightmap: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingOrder: 0 ---- !u!33 &3300000 -MeshFilter: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 100000} - m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} ---- !u!65 &6500000 -BoxCollider: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 100000} - m_Material: {fileID: 0} - m_IsTrigger: 0 - m_Enabled: 1 - serializedVersion: 2 - m_Size: {x: 1, y: 1, z: 1} - m_Center: {x: 0, y: 0, z: 0} ---- !u!114 &11400000 -MonoBehaviour: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 100000} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 0d545b1288d5fc74d8e6c961fb67ab18, type: 3} - m_Name: - m_EditorClassIdentifier: - afterFrames: 0 - afterSeconds: 0 - callOnMethod: 17 - methodToCall: 1 ---- !u!1001 &100100000 -Prefab: - m_ObjectHideFlags: 1 - serializedVersion: 2 - m_Modification: - m_TransformParent: {fileID: 0} - m_Modifications: [] - m_RemovedComponents: [] - m_ParentPrefab: {fileID: 0} - m_RootGameObject: {fileID: 100000} - m_IsPrefabParent: 1 diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeCollisionFailure.prefab.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeCollisionFailure.prefab.meta deleted file mode 100644 index 777585e9..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeCollisionFailure.prefab.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: d5fc3c3488db1e74689f1fc67c33944a -NativeFormatImporter: - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeCollisionSuccess.prefab b/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeCollisionSuccess.prefab deleted file mode 100644 index 6fecda2b..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeCollisionSuccess.prefab +++ /dev/null @@ -1,104 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!1 &100000 -GameObject: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - serializedVersion: 4 - m_Component: - - 4: {fileID: 400000} - - 33: {fileID: 3300000} - - 65: {fileID: 6500000} - - 23: {fileID: 2300000} - - 114: {fileID: 11400000} - m_Layer: 0 - m_Name: CubeCollisionSuccess - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &400000 -Transform: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 100000} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: -5.1736994, y: 3.9978147, z: -16.24892} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 0 ---- !u!23 &2300000 -MeshRenderer: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 100000} - m_Enabled: 1 - m_CastShadows: 0 - m_ReceiveShadows: 0 - m_Materials: - - {fileID: 2100000, guid: 43da3275cd08d41429f56675d70c58df, type: 2} - m_SubsetIndices: - m_StaticBatchRoot: {fileID: 0} - m_UseLightProbes: 0 - m_ReflectionProbeUsage: 1 - m_ProbeAnchor: {fileID: 0} - m_ScaleInLightmap: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingOrder: 0 ---- !u!33 &3300000 -MeshFilter: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 100000} - m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} ---- !u!65 &6500000 -BoxCollider: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 100000} - m_Material: {fileID: 0} - m_IsTrigger: 0 - m_Enabled: 1 - serializedVersion: 2 - m_Size: {x: 1, y: 1, z: 1} - m_Center: {x: 0, y: 0, z: 0} ---- !u!114 &11400000 -MonoBehaviour: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 100000} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 0d545b1288d5fc74d8e6c961fb67ab18, type: 3} - m_Name: - m_EditorClassIdentifier: - afterFrames: 0 - afterSeconds: 0 - callOnMethod: 17 - methodToCall: 0 ---- !u!1001 &100100000 -Prefab: - m_ObjectHideFlags: 1 - serializedVersion: 2 - m_Modification: - m_TransformParent: {fileID: 0} - m_Modifications: [] - m_RemovedComponents: [] - m_ParentPrefab: {fileID: 0} - m_RootGameObject: {fileID: 100000} - m_IsPrefabParent: 1 diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeCollisionSuccess.prefab.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeCollisionSuccess.prefab.meta deleted file mode 100644 index 73ed4742..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeCollisionSuccess.prefab.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: 1228dff762eab21488cfefd42792c37b -NativeFormatImporter: - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeTriggerFailure.prefab b/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeTriggerFailure.prefab deleted file mode 100644 index a8289830..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeTriggerFailure.prefab +++ /dev/null @@ -1,104 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!1 &100000 -GameObject: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - serializedVersion: 4 - m_Component: - - 4: {fileID: 400000} - - 33: {fileID: 3300000} - - 65: {fileID: 6500000} - - 23: {fileID: 2300000} - - 114: {fileID: 11400000} - m_Layer: 0 - m_Name: CubeTriggerFailure - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &400000 -Transform: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 100000} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 0 ---- !u!23 &2300000 -MeshRenderer: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 100000} - m_Enabled: 1 - m_CastShadows: 0 - m_ReceiveShadows: 0 - m_Materials: - - {fileID: 2100000, guid: 03f3b4747259a364b800508ac27e1c17, type: 2} - m_SubsetIndices: - m_StaticBatchRoot: {fileID: 0} - m_UseLightProbes: 0 - m_ReflectionProbeUsage: 1 - m_ProbeAnchor: {fileID: 0} - m_ScaleInLightmap: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingOrder: 0 ---- !u!33 &3300000 -MeshFilter: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 100000} - m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} ---- !u!65 &6500000 -BoxCollider: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 100000} - m_Material: {fileID: 0} - m_IsTrigger: 1 - m_Enabled: 1 - serializedVersion: 2 - m_Size: {x: 1, y: 1, z: 1} - m_Center: {x: 0, y: 0, z: 0} ---- !u!114 &11400000 -MonoBehaviour: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 100000} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 0d545b1288d5fc74d8e6c961fb67ab18, type: 3} - m_Name: - m_EditorClassIdentifier: - afterFrames: 0 - afterSeconds: 0 - callOnMethod: 14 - methodToCall: 1 ---- !u!1001 &100100000 -Prefab: - m_ObjectHideFlags: 1 - serializedVersion: 2 - m_Modification: - m_TransformParent: {fileID: 0} - m_Modifications: [] - m_RemovedComponents: [] - m_ParentPrefab: {fileID: 0} - m_RootGameObject: {fileID: 100000} - m_IsPrefabParent: 1 diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeTriggerFailure.prefab.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeTriggerFailure.prefab.meta deleted file mode 100644 index e04b231f..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeTriggerFailure.prefab.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: 616ddafe39e02da4081e56f7f763af3c -NativeFormatImporter: - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeTriggerSuccess.prefab b/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeTriggerSuccess.prefab deleted file mode 100644 index cc6f8965..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeTriggerSuccess.prefab +++ /dev/null @@ -1,104 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!1 &100000 -GameObject: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - serializedVersion: 4 - m_Component: - - 4: {fileID: 400000} - - 33: {fileID: 3300000} - - 65: {fileID: 6500000} - - 23: {fileID: 2300000} - - 114: {fileID: 11400000} - m_Layer: 0 - m_Name: CubeTriggerSuccess - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &400000 -Transform: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 100000} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 0 ---- !u!23 &2300000 -MeshRenderer: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 100000} - m_Enabled: 1 - m_CastShadows: 0 - m_ReceiveShadows: 0 - m_Materials: - - {fileID: 2100000, guid: 43da3275cd08d41429f56675d70c58df, type: 2} - m_SubsetIndices: - m_StaticBatchRoot: {fileID: 0} - m_UseLightProbes: 0 - m_ReflectionProbeUsage: 1 - m_ProbeAnchor: {fileID: 0} - m_ScaleInLightmap: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingOrder: 0 ---- !u!33 &3300000 -MeshFilter: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 100000} - m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} ---- !u!65 &6500000 -BoxCollider: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 100000} - m_Material: {fileID: 0} - m_IsTrigger: 1 - m_Enabled: 1 - serializedVersion: 2 - m_Size: {x: 1, y: 1, z: 1} - m_Center: {x: 0, y: 0, z: 0} ---- !u!114 &11400000 -MonoBehaviour: - m_ObjectHideFlags: 1 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 100100000} - m_GameObject: {fileID: 100000} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 0d545b1288d5fc74d8e6c961fb67ab18, type: 3} - m_Name: - m_EditorClassIdentifier: - afterFrames: 0 - afterSeconds: 0 - callOnMethod: 14 - methodToCall: 0 ---- !u!1001 &100100000 -Prefab: - m_ObjectHideFlags: 1 - serializedVersion: 2 - m_Modification: - m_TransformParent: {fileID: 0} - m_Modifications: [] - m_RemovedComponents: [] - m_ParentPrefab: {fileID: 0} - m_RootGameObject: {fileID: 100000} - m_IsPrefabParent: 1 diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeTriggerSuccess.prefab.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeTriggerSuccess.prefab.meta deleted file mode 100644 index d16c91a5..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeTriggerSuccess.prefab.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: d940e636fd44be84e9b7e8da46f700ef -NativeFormatImporter: - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/Materials.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/Materials.meta deleted file mode 100644 index ea98c418..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/Materials.meta +++ /dev/null @@ -1,5 +0,0 @@ -fileFormatVersion: 2 -guid: 8d55f43641ba3c14eaa1156abc0edabd -folderAsset: yes -DefaultImporter: - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/Materials/green.mat b/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/Materials/green.mat deleted file mode 100644 index 7a2022eb..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/Materials/green.mat +++ /dev/null @@ -1,30 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!21 &2100000 -Material: - serializedVersion: 6 - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_Name: green - m_Shader: {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} - m_ShaderKeywords: - m_LightmapFlags: 5 - m_CustomRenderQueue: -1 - stringTagMap: {} - m_SavedProperties: - serializedVersion: 2 - m_TexEnvs: - data: - first: - name: _MainTex - second: - m_Texture: {fileID: 2800000, guid: 928be703400f4eb48af2f94d55bf3f74, type: 3} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - m_Floats: {} - m_Colors: - data: - first: - name: _Color - second: {r: 1, g: 1, b: 1, a: 1} diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/Materials/green.mat.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/Materials/green.mat.meta deleted file mode 100644 index 2cabfad7..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/Materials/green.mat.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: 43da3275cd08d41429f56675d70c58df -NativeFormatImporter: - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/Materials/red.mat b/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/Materials/red.mat deleted file mode 100644 index 3f06b36a..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/Materials/red.mat +++ /dev/null @@ -1,30 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!21 &2100000 -Material: - serializedVersion: 6 - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_Name: red - m_Shader: {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} - m_ShaderKeywords: - m_LightmapFlags: 5 - m_CustomRenderQueue: -1 - stringTagMap: {} - m_SavedProperties: - serializedVersion: 2 - m_TexEnvs: - data: - first: - name: _MainTex - second: - m_Texture: {fileID: 2800000, guid: 591632297e74ba34fa4c65d1265d370a, type: 3} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - m_Floats: {} - m_Colors: - data: - first: - name: _Color - second: {r: 1, g: 1, b: 1, a: 1} diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/Materials/red.mat.meta b/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/Materials/red.mat.meta deleted file mode 100644 index 90565c1e..00000000 --- a/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/Materials/red.mat.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: 03f3b4747259a364b800508ac27e1c17 -NativeFormatImporter: - userData: diff --git a/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/green.png b/Assets/UnityTestTools/IntegrationTestsFramework/TestingAssets/green.png deleted file mode 100644 index f4dcca21896885fb30c3a4b531f1fce4aaa573bb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 140 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBufiR<}hF1enP|?%HF~q_@`OYt&Z}!Zr4V+$+dEIy=Oc_{! eWCgQ?1cO^3)Abdn4$1))GkCiCxvX Date: Fri, 1 Mar 2019 14:36:28 +0100 Subject: [PATCH 2/3] Update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ab9d6d17..41b40433 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [Unreleased] +### Added +- Support for newer versions of Unity + ## [3.11.0] ### Added - Support for LZMA2 compression using XZ From fe244fa56d70c438b6f3d69ded0811ad9e783075 Mon Sep 17 00:00:00 2001 From: Tomasz Jaworski Date: Fri, 1 Mar 2019 14:36:59 +0100 Subject: [PATCH 3/3] Update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 41b40433..9a3ad2c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] ### Added -- Support for newer versions of Unity +- Support for newer versions of Unity (#1191) ## [3.11.0] ### Added