From c08ad518ff82467b84bba4b1e9efdd78e87e7102 Mon Sep 17 00:00:00 2001 From: Breno Azevedo Date: Mon, 4 Nov 2019 18:07:51 -0300 Subject: [PATCH 01/12] Updated to work with Unity 2019.1 Version 1.5.9 (Updated by @brenoazevedo) * Updated to work with Unity 2019.1 * Replaced obsolete ExpectedExceptionAttribute calls according to https://github.com/nunit/nunit/issues/799 * Fixed obsolete Application.isWebPlayer and WebPlayer calls, now use WebGL instead --- Scripts/Resolvers/FindWithTagResolver.cs | 7 ++----- .../GetComponentInChildrenTest.cs | 10 ++++++---- .../ConvenienceAttributes/GetComponentTest.cs | 10 ++++++---- .../DependencyInjection/InjectPropertyTest.cs | 13 ++++++++----- .../TestRunner/Editor/Batch.cs | 2 +- .../Editor/PlatformRunner/PlatformRunner.cs | 8 ++++---- .../PlatformRunner/PlatformRunnerSettingsWindow.cs | 2 +- .../Editor/Renderer/IntegrationTestLine.cs | 2 +- .../Editor/Renderer/IntegrationTestRendererBase.cs | 2 +- UnityTestTools/changelog.txt | 5 +++++ 10 files changed, 35 insertions(+), 26 deletions(-) diff --git a/Scripts/Resolvers/FindWithTagResolver.cs b/Scripts/Resolvers/FindWithTagResolver.cs index a9c55f2..1fb6e32 100644 --- a/Scripts/Resolvers/FindWithTagResolver.cs +++ b/Scripts/Resolvers/FindWithTagResolver.cs @@ -16,14 +16,11 @@ public object Resolve(Injectable injectable) { return null; } - else if (injectable.Type != typeof(GameObject)) + if (injectable.Type != typeof(GameObject)) { return gameObject.GetComponent(injectable.Type); } - else - { - return gameObject; - } + return gameObject; } } } \ No newline at end of file diff --git a/Tests/Editor/Integration/ConvenienceAttributes/GetComponentInChildrenTest.cs b/Tests/Editor/Integration/ConvenienceAttributes/GetComponentInChildrenTest.cs index b821877..6a28dd2 100644 --- a/Tests/Editor/Integration/ConvenienceAttributes/GetComponentInChildrenTest.cs +++ b/Tests/Editor/Integration/ConvenienceAttributes/GetComponentInChildrenTest.cs @@ -124,12 +124,14 @@ private void SetUpWithoutSpecificDependencyAndInject() } [Test] - [ExpectedException(typeof(InjectionException))] + //[ExpectedException(typeof(InjectionException))] public void InjectNonMonoBehaviour() { - var obj = new NonMonoBehaviourTestClass(); - - DependencyContainer.Instance.Inject(obj); + Assert.Throws(() => + { + var obj = new NonMonoBehaviourTestClass(); + DependencyContainer.Instance.Inject(obj); + }); } [TearDown] diff --git a/Tests/Editor/Integration/ConvenienceAttributes/GetComponentTest.cs b/Tests/Editor/Integration/ConvenienceAttributes/GetComponentTest.cs index 5539d99..ab201db 100644 --- a/Tests/Editor/Integration/ConvenienceAttributes/GetComponentTest.cs +++ b/Tests/Editor/Integration/ConvenienceAttributes/GetComponentTest.cs @@ -119,12 +119,14 @@ private void SetUpWithoutSpecificDependencyAndInject() } [Test] - [ExpectedException(typeof(InjectionException))] +// [ExpectedException(typeof(InjectionException))] public void InjectNonMonoBehaviour() { - var obj = new GetComponentNonMonoBehaviourTestClass(); - - DependencyContainer.Instance.Inject(obj); + Assert.Throws(() => + { + var obj = new GetComponentNonMonoBehaviourTestClass(); + DependencyContainer.Instance.Inject(obj); + }); } [TearDown] diff --git a/Tests/Editor/Integration/DependencyInjection/InjectPropertyTest.cs b/Tests/Editor/Integration/DependencyInjection/InjectPropertyTest.cs index ece75e7..292a6c5 100644 --- a/Tests/Editor/Integration/DependencyInjection/InjectPropertyTest.cs +++ b/Tests/Editor/Integration/DependencyInjection/InjectPropertyTest.cs @@ -92,11 +92,14 @@ public void DependencyNotMet() } [Test] - [ExpectedException(typeof(InjectionException))] - public void BothInjectAndProvideIsInvalid() { - gameObject.AddComponent(); - - new GameObjectInjector(gameObject).Inject(); +// [ExpectedException(typeof(InjectionException))] + public void BothInjectAndProvideIsInvalid() + { + Assert.Throws(() => + { + gameObject.AddComponent(); + new GameObjectInjector(gameObject).Inject(); + }); } [TearDown] diff --git a/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Batch.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Batch.cs index da55f1d..f99fc9b 100644 --- a/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Batch.cs +++ b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Batch.cs @@ -68,7 +68,7 @@ private static void BuildAndRun(BuildTarget target, List testScenes, Lis port = port }; - if (Application.isWebPlayer) + if (Application.platform == RuntimePlatform.WebGLPlayer) //(Application.isWebPlayer) { config.sendResultsOverNetwork = false; Debug.Log("You can't use WebPlayer as active platform for running integration tests. Switching to Standalone"); diff --git a/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunner.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunner.cs index 2f649b0..76522b4 100644 --- a/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunner.cs +++ b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunner.cs @@ -90,7 +90,7 @@ public static void BuildAndRunInPlayer(PlatformRunnerConfiguration configuration AssetDatabase.Refresh(); - if (!string.IsNullOrEmpty(result)) + if (result != null) //!string.IsNullOrEmpty(result) { if (InternalEditorUtility.inBatchMode) EditorApplication.Exit(Batch.returnCodeRunError); @@ -109,8 +109,8 @@ private static BuildTarget GetDefaultBuildTarget() { case BuildTargetGroup.Android: return BuildTarget.Android; - case BuildTargetGroup.WebPlayer: - return BuildTarget.WebPlayer; + case BuildTargetGroup.WebGL: //WebPlayer + return BuildTarget.WebGL; default: { switch (Application.platform) @@ -122,7 +122,7 @@ private static BuildTarget GetDefaultBuildTarget() case RuntimePlatform.LinuxPlayer: return BuildTarget.StandaloneLinux; } - return BuildTarget.WebPlayer; + return BuildTarget.WebGL; //WebPlayer } } } diff --git a/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerSettingsWindow.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerSettingsWindow.cs index 5ae9d07..56a29ca 100644 --- a/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerSettingsWindow.cs +++ b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerSettingsWindow.cs @@ -180,7 +180,7 @@ private void DrawVerticalSceneList(ref List sourceList, ref string selec var rect = GUILayoutUtility.GetRect(guiContent, EditorStyles.label); if (rect.Contains(Event.current.mousePosition)) { - if (Event.current.type == EventType.mouseDown && Event.current.button == 0) + if (Event.current.type == EventType.MouseDown && Event.current.button == 0) { selectString = scenePath; Event.current.Use(); diff --git a/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestLine.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestLine.cs index e0b5d1a..7d6b368 100644 --- a/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestLine.cs +++ b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestLine.cs @@ -17,7 +17,7 @@ public IntegrationTestLine(GameObject gameObject, TestResult testResult) : base( protected internal override void DrawLine(Rect rect, GUIContent label, bool isSelected, RenderingOptions options) { - if(Event.current.type != EventType.repaint) + if(Event.current.type != EventType.Repaint) return; Styles.testName.Draw (rect, label, false, false, false, isSelected); diff --git a/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestRendererBase.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestRendererBase.cs index 5b02698..bc79d03 100644 --- a/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestRendererBase.cs +++ b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestRendererBase.cs @@ -91,7 +91,7 @@ protected void OnSelect() protected void OnLeftMouseButtonClick(Rect rect) { - if (rect.Contains(Event.current.mousePosition) && Event.current.type == EventType.mouseDown && Event.current.button == 0) + 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; diff --git a/UnityTestTools/changelog.txt b/UnityTestTools/changelog.txt index fca9560..0645834 100644 --- a/UnityTestTools/changelog.txt +++ b/UnityTestTools/changelog.txt @@ -1,3 +1,8 @@ +Version 1.5.9 (Updated by @brenoazevedo) +* Updated to work with Unity 2019.1 +* Replaced obsolete ExpectedExceptionAttribute calls according to https://github.com/nunit/nunit/issues/799 +* Fixed obsolete Application.isWebPlayer and WebPlayer calls, now use WebGL instead + Version 1.5.8 - Bugfixes From 7d39b93dba882710135c537f698c1f4e8c777ec0 Mon Sep 17 00:00:00 2001 From: Breno Azevedo Date: Tue, 5 Nov 2019 03:09:03 -0300 Subject: [PATCH 02/12] Updated readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4d958eb..e4cf80c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Syrinj ###### **Lightweight dependency injection** & convenient attributes for Unity -### [Release 1.1.1 available here!](https://github.com/mfav/syrinj/releases/tag/1.1.1) (8/1/16) +### Updated to work with Unity 2019.1 --- From 0bc8d2fe980a6843ed0c14fc08cc59b3c9c9e828 Mon Sep 17 00:00:00 2001 From: Breno Azevedo Date: Mon, 11 Nov 2019 21:57:56 -0300 Subject: [PATCH 03/12] Added 'FindResourceOfType' documentation The main goal for FindResourceOfType is to reliably find a derived ScriptableObject type within a Resources folder, preventing direct (drag-and-drop) references. It could be argued that, with the new nested Prefabs system, one could do the same with the provider object being tied to a Prefab. Nevertheless, being code-only, I'll argument that FindResourceOfType is safer - although slower on boot times, since internally it uses Resources.LoadAll. A good / moderate usage of the convenience attribute would be, for instance, a GameData scriptableObject which holds references to all other Scriptable Assets in the project. --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e4cf80c..9ff8d17 100644 --- a/README.md +++ b/README.md @@ -122,7 +122,7 @@ public class GoodHomingMissile { } ``` -Make sense? That's dependency injection. The `GoodHomingMissile` has a dependency of a `Player` target, and the `RocketLauncher` tells it which target to move towards on construction! This is a good practice because you know that if a `GoodHomingMissile` is created, it must have had its target specified. +Makes sense? That's dependency injection. The `GoodHomingMissile` has a dependency of a `Player` target, and the `RocketLauncher` tells it which target to move towards on construction! This is a good practice because you know that if a `GoodHomingMissile` is created, it must have had its target specified. If you're a Unity developer, you may already notice a slight issue. In Unity, you don't instantiate objects with constructors! Instead, you call `GameObject.Instantiate()`. One workaround is to make an `Initialize()` method: @@ -205,6 +205,10 @@ public class ExampleProvider : MonoBehaviour [Provides] [FindObjectOfType(typeof(Canvas))] private Canvas UIRootProvider; // any convenience attribute can be combined with "Provides" + + [Provides] + [FindResourceOfType(typeof(GameData))] + private GameData _gameData; // Finds the first asset of type GameData in a 'Resources' folder within your project [Provides] public float RandomNumberProvider @@ -260,6 +264,7 @@ public class ExampleInjectee : MonoBehaviour | `[Find]` | `string GameObjectName` | Finds a GameObject in scene with a given name. | | `[FindWithTag]` | `string Tag` | Finds a GameObject in scene with a given tag. | | `[FindObjectOfType]` | `System.Type ComponentType` | Finds a component in the scene with a given type. | +| `[FindResourceOfType]` | `System.Type ComponentType` | Finds the first asset of a given type in a 'Resources' folder | ##### Injection attributes: From bed3519f18d85c1c9c71d5dea22cc4ccd85a5fd6 Mon Sep 17 00:00:00 2001 From: Breno Azevedo Date: Fri, 8 Oct 2021 17:20:27 -0300 Subject: [PATCH 04/12] Updated to work with Unity 2021.1, added [FindResourceOfType] * Re-added [FindResourceOfType] to the project * Removed UnityTestTools folder (not compatible with 2021.1 due to VS/mscorlib conflicts). The UnityTest scene might not work as a result. --- Scripts/Attributes.meta | 9 - Scripts/Attributes/AnimatorStringHash.cs.meta | 12 - Scripts/Attributes/FindAttribute.cs.meta | 12 - .../FindObjectOfTypeAttribute.cs.meta | 12 - .../Attributes/FindRelativeAttribute.cs.meta | 12 - .../Attributes/FindResourceOfTypeAttribute.cs | 18 + .../Attributes/FindWithTagAttribute.cs.meta | 12 - .../Attributes/GetComponentAttribute.cs.meta | 12 - .../GetComponentInChildrenAttribute.cs.meta | 12 - Scripts/Attributes/InjectAttribute.cs.meta | 12 - Scripts/Attributes/InstanceAttribute.cs.meta | 12 - Scripts/Attributes/ProvidesAttribute.cs.meta | 12 - Scripts/Attributes/SingletonAttribute.cs.meta | 12 - .../UnityConvenienceAttribute.cs.meta | 12 - .../UnityDependencyAttribute.cs.meta | 12 - .../Attributes/UnityInjectorAttribute.cs.meta | 12 - .../Attributes/UnityProviderAttribute.cs.meta | 12 - Scripts/DependencyContainer.cs.meta | 12 - Scripts/Exceptions.meta | 9 - Scripts/Exceptions/InjectionException.cs.meta | 12 - Scripts/GameObjectInjector.cs.meta | 12 - Scripts/Graph.meta | 9 - Scripts/Graph/DependencyMap.cs.meta | 12 - Scripts/Injection.meta | 9 - Scripts/Injection/Injectable.cs.meta | 12 - Scripts/Injection/InjectableFactory.cs.meta | 12 - Scripts/Injection/InjectableField.cs.meta | 12 - Scripts/Injection/InjectableProperty.cs.meta | 12 - Scripts/InjectorComponent.cs.meta | 12 - Scripts/Provider.cs.meta | 12 - Scripts/Provision.meta | 9 - Scripts/Provision/FieldProvider.cs.meta | 12 - Scripts/Provision/IProvider.cs.meta | 12 - Scripts/Provision/InstanceProvider.cs.meta | 12 - Scripts/Provision/PropertyProvider.cs.meta | 12 - Scripts/Provision/ProviderFactory.cs.meta | 12 - Scripts/Provision/SingletonProvider.cs.meta | 12 - Scripts/Reflection.meta | 9 - Scripts/Reflection/AttributeCache.cs.meta | 12 - Scripts/Reflection/MemberEvaluator.cs.meta | 12 - Scripts/Resolvers.meta | 9 - .../AnimatorStringHashResolver.cs.meta | 12 - .../FindObjectOfTypeResolver.cs.meta | 12 - .../Resolvers/FindRelativeResolver.cs.meta | 12 - Scripts/Resolvers/FindResolver.cs.meta | 12 - .../Resolvers/FindResourceOfTypeResolver.cs | 42 ++ Scripts/Resolvers/FindWithTagResolver.cs.meta | 12 - .../GetComponentInChildrenResolver.cs.meta | 12 - .../Resolvers/GetComponentResolver.cs.meta | 12 - Scripts/Resolvers/IResolver.cs.meta | 12 - Scripts/Resolvers/ResolverGroups.cs.meta | 12 - .../RuntimeInjectableMonoBehaviour.cs.meta | 12 - Scripts/SceneInjector.cs.meta | 12 - Scripts/TransformExtensions.cs.meta | 12 - Syrinj.unitypackage | Bin 18515 -> 0 bytes Tests/Editor.meta | 9 - Tests/TestScene.unity.meta | 8 - 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 -- UnityTestTools/Assertions/Assertions.cs.meta | 8 - UnityTestTools/Assertions/CheckMethod.cs | 36 -- UnityTestTools/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 - 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 - UnityTestTools/Assertions/MemberResolver.cs | 208 ------ .../Assertions/MemberResolver.cs.meta | 8 - UnityTestTools/Common.meta | 5 - UnityTestTools/Common/Editor.meta | 4 - UnityTestTools/Common/Editor/Icons.cs | 57 -- UnityTestTools/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 - UnityTestTools/Common/Editor/Styles.cs | 47 -- UnityTestTools/Common/Editor/Styles.cs.meta | 8 - .../Common/Editor/TestFilterSettings.cs | 104 --- .../Common/Editor/TestFilterSettings.cs.meta | 8 - UnityTestTools/Common/Editor/icons.meta | 4 - UnityTestTools/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 -- UnityTestTools/Common/Editor/icons/normal.png | Bin 1041 -> 0 bytes .../Common/Editor/icons/normal.png.meta | 35 -- UnityTestTools/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 -- UnityTestTools/Common/ITestResult.cs | 29 - UnityTestTools/Common/ITestResult.cs.meta | 8 - UnityTestTools/Common/Settings.meta | 9 - .../IntegrationTestsRunnerSettings.asset | Bin 4204 -> 0 bytes .../IntegrationTestsRunnerSettings.asset.meta | 8 - UnityTestTools/Common/TestResultState.cs | 46 -- UnityTestTools/Common/TestResultState.cs.meta | 8 - UnityTestTools/Documentation.url | 3 - UnityTestTools/Documentation.url.meta | 4 - UnityTestTools/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 | Bin 7348 -> 0 bytes .../CubeCollisionFailure.prefab.meta | 4 - .../TestingAssets/CubeCollisionSuccess.prefab | Bin 9336 -> 0 bytes .../CubeCollisionSuccess.prefab.meta | 4 - .../TestingAssets/CubeTriggerFailure.prefab | Bin 7348 -> 0 bytes .../CubeTriggerFailure.prefab.meta | 4 - .../TestingAssets/CubeTriggerSuccess.prefab | Bin 9336 -> 0 bytes .../CubeTriggerSuccess.prefab.meta | 4 - .../TestingAssets/Materials.meta | 5 - .../TestingAssets/Materials/green.mat | Bin 4212 -> 0 bytes .../TestingAssets/Materials/green.mat.meta | 4 - .../TestingAssets/Materials/red.mat | Bin 4208 -> 0 bytes .../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 -- UnityTestTools/LICENSE.txt | 83 --- UnityTestTools/LICENSE.txt.meta | 4 - UnityTestTools/UnitTesting.meta | 5 - UnityTestTools/UnitTesting/Editor.meta | 4 - .../UnitTesting/Editor/NSubstitute.meta | 5 - .../Editor/NSubstitute/NSubstitute.dll | Bin 327680 -> 0 bytes .../Editor/NSubstitute/NSubstitute.dll.meta | 22 - UnityTestTools/changelog.txt | 221 ------- UnityTestTools/changelog.txt.meta | 4 - 264 files changed, 60 insertions(+), 10193 deletions(-) delete mode 100644 Scripts/Attributes.meta delete mode 100644 Scripts/Attributes/AnimatorStringHash.cs.meta delete mode 100644 Scripts/Attributes/FindAttribute.cs.meta delete mode 100644 Scripts/Attributes/FindObjectOfTypeAttribute.cs.meta delete mode 100644 Scripts/Attributes/FindRelativeAttribute.cs.meta create mode 100644 Scripts/Attributes/FindResourceOfTypeAttribute.cs delete mode 100644 Scripts/Attributes/FindWithTagAttribute.cs.meta delete mode 100644 Scripts/Attributes/GetComponentAttribute.cs.meta delete mode 100644 Scripts/Attributes/GetComponentInChildrenAttribute.cs.meta delete mode 100644 Scripts/Attributes/InjectAttribute.cs.meta delete mode 100644 Scripts/Attributes/InstanceAttribute.cs.meta delete mode 100644 Scripts/Attributes/ProvidesAttribute.cs.meta delete mode 100644 Scripts/Attributes/SingletonAttribute.cs.meta delete mode 100644 Scripts/Attributes/UnityConvenienceAttribute.cs.meta delete mode 100644 Scripts/Attributes/UnityDependencyAttribute.cs.meta delete mode 100644 Scripts/Attributes/UnityInjectorAttribute.cs.meta delete mode 100644 Scripts/Attributes/UnityProviderAttribute.cs.meta delete mode 100644 Scripts/DependencyContainer.cs.meta delete mode 100644 Scripts/Exceptions.meta delete mode 100644 Scripts/Exceptions/InjectionException.cs.meta delete mode 100644 Scripts/GameObjectInjector.cs.meta delete mode 100644 Scripts/Graph.meta delete mode 100644 Scripts/Graph/DependencyMap.cs.meta delete mode 100644 Scripts/Injection.meta delete mode 100644 Scripts/Injection/Injectable.cs.meta delete mode 100644 Scripts/Injection/InjectableFactory.cs.meta delete mode 100644 Scripts/Injection/InjectableField.cs.meta delete mode 100644 Scripts/Injection/InjectableProperty.cs.meta delete mode 100644 Scripts/InjectorComponent.cs.meta delete mode 100644 Scripts/Provider.cs.meta delete mode 100644 Scripts/Provision.meta delete mode 100644 Scripts/Provision/FieldProvider.cs.meta delete mode 100644 Scripts/Provision/IProvider.cs.meta delete mode 100644 Scripts/Provision/InstanceProvider.cs.meta delete mode 100644 Scripts/Provision/PropertyProvider.cs.meta delete mode 100644 Scripts/Provision/ProviderFactory.cs.meta delete mode 100644 Scripts/Provision/SingletonProvider.cs.meta delete mode 100644 Scripts/Reflection.meta delete mode 100644 Scripts/Reflection/AttributeCache.cs.meta delete mode 100644 Scripts/Reflection/MemberEvaluator.cs.meta delete mode 100644 Scripts/Resolvers.meta delete mode 100644 Scripts/Resolvers/AnimatorStringHashResolver.cs.meta delete mode 100644 Scripts/Resolvers/FindObjectOfTypeResolver.cs.meta delete mode 100644 Scripts/Resolvers/FindRelativeResolver.cs.meta delete mode 100644 Scripts/Resolvers/FindResolver.cs.meta create mode 100644 Scripts/Resolvers/FindResourceOfTypeResolver.cs delete mode 100644 Scripts/Resolvers/FindWithTagResolver.cs.meta delete mode 100644 Scripts/Resolvers/GetComponentInChildrenResolver.cs.meta delete mode 100644 Scripts/Resolvers/GetComponentResolver.cs.meta delete mode 100644 Scripts/Resolvers/IResolver.cs.meta delete mode 100644 Scripts/Resolvers/ResolverGroups.cs.meta delete mode 100644 Scripts/RuntimeInjectableMonoBehaviour.cs.meta delete mode 100644 Scripts/SceneInjector.cs.meta delete mode 100644 Scripts/TransformExtensions.cs.meta delete mode 100644 Syrinj.unitypackage delete mode 100644 Tests/Editor.meta delete mode 100644 Tests/TestScene.unity.meta delete mode 100644 UnityTestTools/Assertions.meta delete mode 100644 UnityTestTools/Assertions/AssertionComponent.cs delete mode 100644 UnityTestTools/Assertions/AssertionComponent.cs.meta delete mode 100644 UnityTestTools/Assertions/AssertionException.cs delete mode 100644 UnityTestTools/Assertions/AssertionException.cs.meta delete mode 100644 UnityTestTools/Assertions/Assertions.cs delete mode 100644 UnityTestTools/Assertions/Assertions.cs.meta delete mode 100644 UnityTestTools/Assertions/CheckMethod.cs delete mode 100644 UnityTestTools/Assertions/CheckMethod.cs.meta delete mode 100644 UnityTestTools/Assertions/Comparers.meta delete mode 100644 UnityTestTools/Assertions/Comparers/ActionBase.cs delete mode 100644 UnityTestTools/Assertions/Comparers/ActionBase.cs.meta delete mode 100644 UnityTestTools/Assertions/Comparers/BoolComparer.cs delete mode 100644 UnityTestTools/Assertions/Comparers/BoolComparer.cs.meta delete mode 100644 UnityTestTools/Assertions/Comparers/ColliderComparer.cs delete mode 100644 UnityTestTools/Assertions/Comparers/ColliderComparer.cs.meta delete mode 100644 UnityTestTools/Assertions/Comparers/ComparerBase.cs delete mode 100644 UnityTestTools/Assertions/Comparers/ComparerBase.cs.meta delete mode 100644 UnityTestTools/Assertions/Comparers/FloatComparer.cs delete mode 100644 UnityTestTools/Assertions/Comparers/FloatComparer.cs.meta delete mode 100644 UnityTestTools/Assertions/Comparers/GeneralComparer.cs delete mode 100644 UnityTestTools/Assertions/Comparers/GeneralComparer.cs.meta delete mode 100644 UnityTestTools/Assertions/Comparers/IntComparer.cs delete mode 100644 UnityTestTools/Assertions/Comparers/IntComparer.cs.meta delete mode 100644 UnityTestTools/Assertions/Comparers/IsRenderedByCamera.cs delete mode 100644 UnityTestTools/Assertions/Comparers/IsRenderedByCamera.cs.meta delete mode 100644 UnityTestTools/Assertions/Comparers/StringComparer.cs delete mode 100644 UnityTestTools/Assertions/Comparers/StringComparer.cs.meta delete mode 100644 UnityTestTools/Assertions/Comparers/TransformComparer.cs delete mode 100644 UnityTestTools/Assertions/Comparers/TransformComparer.cs.meta delete mode 100644 UnityTestTools/Assertions/Comparers/ValueDoesNotChange.cs delete mode 100644 UnityTestTools/Assertions/Comparers/ValueDoesNotChange.cs.meta delete mode 100644 UnityTestTools/Assertions/Comparers/Vector2Comparer.cs delete mode 100644 UnityTestTools/Assertions/Comparers/Vector2Comparer.cs.meta delete mode 100644 UnityTestTools/Assertions/Comparers/Vector3Comparer.cs delete mode 100644 UnityTestTools/Assertions/Comparers/Vector3Comparer.cs.meta delete mode 100644 UnityTestTools/Assertions/Comparers/Vector4Comparer.cs delete mode 100644 UnityTestTools/Assertions/Comparers/Vector4Comparer.cs.meta delete mode 100644 UnityTestTools/Assertions/Comparers/VectorComparerBase.cs delete mode 100644 UnityTestTools/Assertions/Comparers/VectorComparerBase.cs.meta delete mode 100644 UnityTestTools/Assertions/Editor.meta delete mode 100644 UnityTestTools/Assertions/Editor/AssertionComponentEditor.cs delete mode 100644 UnityTestTools/Assertions/Editor/AssertionComponentEditor.cs.meta delete mode 100644 UnityTestTools/Assertions/Editor/AssertionExplorerWindow.cs delete mode 100644 UnityTestTools/Assertions/Editor/AssertionExplorerWindow.cs.meta delete mode 100644 UnityTestTools/Assertions/Editor/AssertionListRenderer.cs delete mode 100644 UnityTestTools/Assertions/Editor/AssertionListRenderer.cs.meta delete mode 100644 UnityTestTools/Assertions/Editor/AssertionStripper.cs delete mode 100644 UnityTestTools/Assertions/Editor/AssertionStripper.cs.meta delete mode 100644 UnityTestTools/Assertions/Editor/DropDownControl.cs delete mode 100644 UnityTestTools/Assertions/Editor/DropDownControl.cs.meta delete mode 100644 UnityTestTools/Assertions/Editor/GroupByComparerRenderer.cs delete mode 100644 UnityTestTools/Assertions/Editor/GroupByComparerRenderer.cs.meta delete mode 100644 UnityTestTools/Assertions/Editor/GroupByExecutionMethodRenderer.cs delete mode 100644 UnityTestTools/Assertions/Editor/GroupByExecutionMethodRenderer.cs.meta delete mode 100644 UnityTestTools/Assertions/Editor/GroupByGORenderer.cs delete mode 100644 UnityTestTools/Assertions/Editor/GroupByGORenderer.cs.meta delete mode 100644 UnityTestTools/Assertions/Editor/GroupByNothingRenderer.cs delete mode 100644 UnityTestTools/Assertions/Editor/GroupByNothingRenderer.cs.meta delete mode 100644 UnityTestTools/Assertions/Editor/GroupByTestsRenderer.cs delete mode 100644 UnityTestTools/Assertions/Editor/GroupByTestsRenderer.cs.meta delete mode 100644 UnityTestTools/Assertions/Editor/PropertyPathSelector.cs delete mode 100644 UnityTestTools/Assertions/Editor/PropertyPathSelector.cs.meta delete mode 100644 UnityTestTools/Assertions/Editor/PropertyResolver.cs delete mode 100644 UnityTestTools/Assertions/Editor/PropertyResolver.cs.meta delete mode 100644 UnityTestTools/Assertions/InvalidPathException.cs delete mode 100644 UnityTestTools/Assertions/InvalidPathException.cs.meta delete mode 100644 UnityTestTools/Assertions/MemberResolver.cs delete mode 100644 UnityTestTools/Assertions/MemberResolver.cs.meta delete mode 100644 UnityTestTools/Common.meta delete mode 100644 UnityTestTools/Common/Editor.meta delete mode 100644 UnityTestTools/Common/Editor/Icons.cs delete mode 100644 UnityTestTools/Common/Editor/Icons.cs.meta delete mode 100644 UnityTestTools/Common/Editor/ProjectSettingsBase.cs delete mode 100644 UnityTestTools/Common/Editor/ProjectSettingsBase.cs.meta delete mode 100644 UnityTestTools/Common/Editor/ResultWriter.meta delete mode 100644 UnityTestTools/Common/Editor/ResultWriter/ResultSummarizer.cs delete mode 100644 UnityTestTools/Common/Editor/ResultWriter/ResultSummarizer.cs.meta delete mode 100644 UnityTestTools/Common/Editor/ResultWriter/StackTraceFilter.cs delete mode 100644 UnityTestTools/Common/Editor/ResultWriter/StackTraceFilter.cs.meta delete mode 100644 UnityTestTools/Common/Editor/ResultWriter/XmlResultWriter.cs delete mode 100644 UnityTestTools/Common/Editor/ResultWriter/XmlResultWriter.cs.meta delete mode 100644 UnityTestTools/Common/Editor/Styles.cs delete mode 100644 UnityTestTools/Common/Editor/Styles.cs.meta delete mode 100644 UnityTestTools/Common/Editor/TestFilterSettings.cs delete mode 100644 UnityTestTools/Common/Editor/TestFilterSettings.cs.meta delete mode 100644 UnityTestTools/Common/Editor/icons.meta delete mode 100644 UnityTestTools/Common/Editor/icons/failed.png delete mode 100644 UnityTestTools/Common/Editor/icons/failed.png.meta delete mode 100644 UnityTestTools/Common/Editor/icons/ignored.png delete mode 100644 UnityTestTools/Common/Editor/icons/ignored.png.meta delete mode 100644 UnityTestTools/Common/Editor/icons/inconclusive.png delete mode 100644 UnityTestTools/Common/Editor/icons/inconclusive.png.meta delete mode 100644 UnityTestTools/Common/Editor/icons/normal.png delete mode 100644 UnityTestTools/Common/Editor/icons/normal.png.meta delete mode 100644 UnityTestTools/Common/Editor/icons/passed.png delete mode 100644 UnityTestTools/Common/Editor/icons/passed.png.meta delete mode 100644 UnityTestTools/Common/Editor/icons/stopwatch.png delete mode 100644 UnityTestTools/Common/Editor/icons/stopwatch.png.meta delete mode 100644 UnityTestTools/Common/ITestResult.cs delete mode 100644 UnityTestTools/Common/ITestResult.cs.meta delete mode 100644 UnityTestTools/Common/Settings.meta delete mode 100644 UnityTestTools/Common/Settings/IntegrationTestsRunnerSettings.asset delete mode 100644 UnityTestTools/Common/Settings/IntegrationTestsRunnerSettings.asset.meta delete mode 100644 UnityTestTools/Common/TestResultState.cs delete mode 100644 UnityTestTools/Common/TestResultState.cs.meta delete mode 100644 UnityTestTools/Documentation.url delete mode 100644 UnityTestTools/Documentation.url.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/Libs.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/Libs/Mono.Cecil.Mdb.dll delete mode 100644 UnityTestTools/IntegrationTestsFramework/Libs/Mono.Cecil.Mdb.dll.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/Libs/Mono.Cecil.dll delete mode 100644 UnityTestTools/IntegrationTestsFramework/Libs/Mono.Cecil.dll.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/DTOFormatter.cs delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/DTOFormatter.cs.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Batch.cs delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Batch.cs.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/EditorReferencesUtil.cs delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/EditorReferencesUtil.cs.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/GuiHelper.cs delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/GuiHelper.cs.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsHierarchyAnnotation.cs delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsHierarchyAnnotation.cs.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsRunnerSettings.cs delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsRunnerSettings.cs.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsRunnerWindow.cs delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsRunnerWindow.cs.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/NetworkResultsReceiver.cs delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/NetworkResultsReceiver.cs.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunner.cs delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunner.cs.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerConfiguration.cs delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerConfiguration.cs.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerSettings.cs delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerSettings.cs.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerSettingsWindow.cs delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerSettingsWindow.cs.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlayerSettingConfigurator.cs delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlayerSettingConfigurator.cs.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestGroupLine.cs delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestGroupLine.cs.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestLine.cs delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestLine.cs.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestRendererBase.cs delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestRendererBase.cs.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/RenderingOptions.cs delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/RenderingOptions.cs.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/TestComponentEditor.cs delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/TestComponentEditor.cs.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/ITestRunnerCallback.cs delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/ITestRunnerCallback.cs.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTest.cs delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTest.cs.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTestAttribute.cs delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTestAttribute.cs.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTestsProvider.cs delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTestsProvider.cs.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/NetworkResultSender.cs delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/NetworkResultSender.cs.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/ResultDTO.cs delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/ResultDTO.cs.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/TestComponent.cs delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/TestComponent.cs.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/TestResult.cs delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/TestResult.cs.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/TestResultRenderer.cs delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/TestResultRenderer.cs.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunner.cs delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunner.cs.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunnerCallbackList.cs delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunnerCallbackList.cs.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunnerConfigurator.cs delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunnerConfigurator.cs.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestingAssets.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestingAssets/CallTesting.cs delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestingAssets/CallTesting.cs.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeCollisionFailure.prefab delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeCollisionFailure.prefab.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeCollisionSuccess.prefab delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeCollisionSuccess.prefab.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeTriggerFailure.prefab delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeTriggerFailure.prefab.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeTriggerSuccess.prefab delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeTriggerSuccess.prefab.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestingAssets/Materials.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestingAssets/Materials/green.mat delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestingAssets/Materials/green.mat.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestingAssets/Materials/red.mat delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestingAssets/Materials/red.mat.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestingAssets/green.png delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestingAssets/green.png.meta delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestingAssets/red.png delete mode 100644 UnityTestTools/IntegrationTestsFramework/TestingAssets/red.png.meta delete mode 100644 UnityTestTools/LICENSE.txt delete mode 100644 UnityTestTools/LICENSE.txt.meta delete mode 100644 UnityTestTools/UnitTesting.meta delete mode 100644 UnityTestTools/UnitTesting/Editor.meta delete mode 100644 UnityTestTools/UnitTesting/Editor/NSubstitute.meta delete mode 100644 UnityTestTools/UnitTesting/Editor/NSubstitute/NSubstitute.dll delete mode 100644 UnityTestTools/UnitTesting/Editor/NSubstitute/NSubstitute.dll.meta delete mode 100644 UnityTestTools/changelog.txt delete mode 100644 UnityTestTools/changelog.txt.meta diff --git a/Scripts/Attributes.meta b/Scripts/Attributes.meta deleted file mode 100644 index e841209..0000000 --- a/Scripts/Attributes.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 87251fa85510ae746a9a5f863b2b5e50 -folderAsset: yes -timeCreated: 1466614196 -licenseType: Free -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Attributes/AnimatorStringHash.cs.meta b/Scripts/Attributes/AnimatorStringHash.cs.meta deleted file mode 100644 index 09585b1..0000000 --- a/Scripts/Attributes/AnimatorStringHash.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 8cd0de5151409b04f926d719753636f3 -timeCreated: 1500726963 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Attributes/FindAttribute.cs.meta b/Scripts/Attributes/FindAttribute.cs.meta deleted file mode 100644 index fed1af9..0000000 --- a/Scripts/Attributes/FindAttribute.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: a55408c4373465146bfed640a1c44948 -timeCreated: 1466616548 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Attributes/FindObjectOfTypeAttribute.cs.meta b/Scripts/Attributes/FindObjectOfTypeAttribute.cs.meta deleted file mode 100644 index 2dbc1cd..0000000 --- a/Scripts/Attributes/FindObjectOfTypeAttribute.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 5477e14d58c78ff4096c3b0f2d060fd7 -timeCreated: 1466617275 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Attributes/FindRelativeAttribute.cs.meta b/Scripts/Attributes/FindRelativeAttribute.cs.meta deleted file mode 100644 index 8d0e510..0000000 --- a/Scripts/Attributes/FindRelativeAttribute.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: d897b2233322ecb4d9c13413f87bb364 -timeCreated: 1500115353 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Attributes/FindResourceOfTypeAttribute.cs b/Scripts/Attributes/FindResourceOfTypeAttribute.cs new file mode 100644 index 0000000..1fa11d5 --- /dev/null +++ b/Scripts/Attributes/FindResourceOfTypeAttribute.cs @@ -0,0 +1,18 @@ +using System; +using Syrinj.Attributes; + +namespace Syrinj +{ + public class FindResourceOfTypeAttribute : UnityConvenienceAttribute + { + public readonly Type ComponentType; + + public FindResourceOfTypeAttribute() + { } + + public FindResourceOfTypeAttribute(Type componentType) + { + ComponentType = componentType; + } + } +} diff --git a/Scripts/Attributes/FindWithTagAttribute.cs.meta b/Scripts/Attributes/FindWithTagAttribute.cs.meta deleted file mode 100644 index 63ff9c5..0000000 --- a/Scripts/Attributes/FindWithTagAttribute.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 3bebc1727653027478b23e7a9dcd8a0e -timeCreated: 1466617275 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Attributes/GetComponentAttribute.cs.meta b/Scripts/Attributes/GetComponentAttribute.cs.meta deleted file mode 100644 index d207ab4..0000000 --- a/Scripts/Attributes/GetComponentAttribute.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 618d01578d4beed4b8b78ff12ab0ff23 -timeCreated: 1466614205 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Attributes/GetComponentInChildrenAttribute.cs.meta b/Scripts/Attributes/GetComponentInChildrenAttribute.cs.meta deleted file mode 100644 index cc99467..0000000 --- a/Scripts/Attributes/GetComponentInChildrenAttribute.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 6013f9c6fbf5ba44292c74cac665e5da -timeCreated: 1466616548 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Attributes/InjectAttribute.cs.meta b/Scripts/Attributes/InjectAttribute.cs.meta deleted file mode 100644 index 51c612c..0000000 --- a/Scripts/Attributes/InjectAttribute.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: bfd3caa0911457f4ab2f2e893a8c5598 -timeCreated: 1466836344 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Attributes/InstanceAttribute.cs.meta b/Scripts/Attributes/InstanceAttribute.cs.meta deleted file mode 100644 index e876c6b..0000000 --- a/Scripts/Attributes/InstanceAttribute.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: d10dc94d4cf504ff980fc6e62d395cca -timeCreated: 1468265366 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Attributes/ProvidesAttribute.cs.meta b/Scripts/Attributes/ProvidesAttribute.cs.meta deleted file mode 100644 index a0ce6c2..0000000 --- a/Scripts/Attributes/ProvidesAttribute.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: f8760f65e0a1c3342b7862a6377a7c48 -timeCreated: 1466881442 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Attributes/SingletonAttribute.cs.meta b/Scripts/Attributes/SingletonAttribute.cs.meta deleted file mode 100644 index de72fa8..0000000 --- a/Scripts/Attributes/SingletonAttribute.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 3e953c85735be4e909c904c1b310f353 -timeCreated: 1468264412 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Attributes/UnityConvenienceAttribute.cs.meta b/Scripts/Attributes/UnityConvenienceAttribute.cs.meta deleted file mode 100644 index 4d3b7be..0000000 --- a/Scripts/Attributes/UnityConvenienceAttribute.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 86ae74ffa2ee03a4785ad60850ec0f5f -timeCreated: 1467008628 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Attributes/UnityDependencyAttribute.cs.meta b/Scripts/Attributes/UnityDependencyAttribute.cs.meta deleted file mode 100644 index e87cf21..0000000 --- a/Scripts/Attributes/UnityDependencyAttribute.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 3de7ee53d90e91a4182289726ddcca1a -timeCreated: 1466638905 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Attributes/UnityInjectorAttribute.cs.meta b/Scripts/Attributes/UnityInjectorAttribute.cs.meta deleted file mode 100644 index bf78038..0000000 --- a/Scripts/Attributes/UnityInjectorAttribute.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: c8988e9be4bc76144ac9bb654ac64e9e -timeCreated: 1466881442 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Attributes/UnityProviderAttribute.cs.meta b/Scripts/Attributes/UnityProviderAttribute.cs.meta deleted file mode 100644 index 8be1333..0000000 --- a/Scripts/Attributes/UnityProviderAttribute.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 111dc3f8becf38e41b618327f4960e75 -timeCreated: 1466881441 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/DependencyContainer.cs.meta b/Scripts/DependencyContainer.cs.meta deleted file mode 100644 index 4969288..0000000 --- a/Scripts/DependencyContainer.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 8061a4d642ed7a2499de4fa3e4c25241 -timeCreated: 1466982391 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Exceptions.meta b/Scripts/Exceptions.meta deleted file mode 100644 index 167ffe5..0000000 --- a/Scripts/Exceptions.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 4d70d97d8196dde49a13e2a274371cc3 -folderAsset: yes -timeCreated: 1466622335 -licenseType: Free -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Exceptions/InjectionException.cs.meta b/Scripts/Exceptions/InjectionException.cs.meta deleted file mode 100644 index ea4de3a..0000000 --- a/Scripts/Exceptions/InjectionException.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 3a7a1c43fbff9ec4a90f0f342bb2ef8a -timeCreated: 1467008627 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/GameObjectInjector.cs.meta b/Scripts/GameObjectInjector.cs.meta deleted file mode 100644 index 09dd56a..0000000 --- a/Scripts/GameObjectInjector.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 7740b3f00aa510e4997ec42d6218001d -timeCreated: 1466618029 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Graph.meta b/Scripts/Graph.meta deleted file mode 100644 index a66e772..0000000 --- a/Scripts/Graph.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 84f5e9f84d3d6da42bd317d7eceabd9a -folderAsset: yes -timeCreated: 1466881441 -licenseType: Free -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Graph/DependencyMap.cs.meta b/Scripts/Graph/DependencyMap.cs.meta deleted file mode 100644 index 7642cf2..0000000 --- a/Scripts/Graph/DependencyMap.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 4e43f7dfe63bb314aa62bc100a4ae6d1 -timeCreated: 1467008627 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Injection.meta b/Scripts/Injection.meta deleted file mode 100644 index 15d2ce5..0000000 --- a/Scripts/Injection.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 3263961fd06f1a240b78aacdf69cd64c -folderAsset: yes -timeCreated: 1466633601 -licenseType: Free -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Injection/Injectable.cs.meta b/Scripts/Injection/Injectable.cs.meta deleted file mode 100644 index 5a05633..0000000 --- a/Scripts/Injection/Injectable.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: e695f1b1b9a18b345afba4bca847ee01 -timeCreated: 1466638905 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Injection/InjectableFactory.cs.meta b/Scripts/Injection/InjectableFactory.cs.meta deleted file mode 100644 index e857197..0000000 --- a/Scripts/Injection/InjectableFactory.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: f80daf69a0b75464c9df4c79fcd94b4a -timeCreated: 1466638905 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Injection/InjectableField.cs.meta b/Scripts/Injection/InjectableField.cs.meta deleted file mode 100644 index 6cb2cca..0000000 --- a/Scripts/Injection/InjectableField.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 29b2b1d26bb847f408fa714181b097ff -timeCreated: 1466638905 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Injection/InjectableProperty.cs.meta b/Scripts/Injection/InjectableProperty.cs.meta deleted file mode 100644 index 3b2a3b9..0000000 --- a/Scripts/Injection/InjectableProperty.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: af35da25f6db583498af531c5e3924da -timeCreated: 1466638905 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/InjectorComponent.cs.meta b/Scripts/InjectorComponent.cs.meta deleted file mode 100644 index bd41892..0000000 --- a/Scripts/InjectorComponent.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 540508dedfd6d564e80cfaa99954153a -timeCreated: 1467060438 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: -1000 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Provider.cs.meta b/Scripts/Provider.cs.meta deleted file mode 100644 index 0493c70..0000000 --- a/Scripts/Provider.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 03cbc8867ef564a5897356dee3e01e59 -timeCreated: 1468352113 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Provision.meta b/Scripts/Provision.meta deleted file mode 100644 index 93eb305..0000000 --- a/Scripts/Provision.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: f25eb24661b3544c69731487f8987570 -folderAsset: yes -timeCreated: 1468358857 -licenseType: Free -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Provision/FieldProvider.cs.meta b/Scripts/Provision/FieldProvider.cs.meta deleted file mode 100644 index a71e5a1..0000000 --- a/Scripts/Provision/FieldProvider.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 2f3e6ea72d4bd44c7b3effaabc826c57 -timeCreated: 1468435897 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Provision/IProvider.cs.meta b/Scripts/Provision/IProvider.cs.meta deleted file mode 100644 index 6690ecf..0000000 --- a/Scripts/Provision/IProvider.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 1478fe85473f0473badf72d966663d8c -timeCreated: 1468435756 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Provision/InstanceProvider.cs.meta b/Scripts/Provision/InstanceProvider.cs.meta deleted file mode 100644 index 048b673..0000000 --- a/Scripts/Provision/InstanceProvider.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 84453227f1b484f1f934602842be500d -timeCreated: 1468435898 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Provision/PropertyProvider.cs.meta b/Scripts/Provision/PropertyProvider.cs.meta deleted file mode 100644 index ac66fe9..0000000 --- a/Scripts/Provision/PropertyProvider.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 6df8920ccbd974c11850c34055fb31cf -timeCreated: 1468435898 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Provision/ProviderFactory.cs.meta b/Scripts/Provision/ProviderFactory.cs.meta deleted file mode 100644 index a358cc7..0000000 --- a/Scripts/Provision/ProviderFactory.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 1a17a28eb418f427897758874d02b6b7 -timeCreated: 1468435897 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Provision/SingletonProvider.cs.meta b/Scripts/Provision/SingletonProvider.cs.meta deleted file mode 100644 index f00c88b..0000000 --- a/Scripts/Provision/SingletonProvider.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: efe1bd85192a54f24838ad5f5c7f6b28 -timeCreated: 1468435814 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Reflection.meta b/Scripts/Reflection.meta deleted file mode 100644 index 7ae06f5..0000000 --- a/Scripts/Reflection.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 5aec7eb1075a3954c87781af5297979b -folderAsset: yes -timeCreated: 1466881441 -licenseType: Free -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Reflection/AttributeCache.cs.meta b/Scripts/Reflection/AttributeCache.cs.meta deleted file mode 100644 index 7549898..0000000 --- a/Scripts/Reflection/AttributeCache.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 79e3ea3ccc22fbf429ea4cee3c4cb9af -timeCreated: 1466881441 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Reflection/MemberEvaluator.cs.meta b/Scripts/Reflection/MemberEvaluator.cs.meta deleted file mode 100644 index 505af34..0000000 --- a/Scripts/Reflection/MemberEvaluator.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 46301e1020279934c98afdd657de046d -timeCreated: 1466982391 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Resolvers.meta b/Scripts/Resolvers.meta deleted file mode 100644 index 0270c8d..0000000 --- a/Scripts/Resolvers.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: a694f2e24a7a533478865bd4cd1e3575 -folderAsset: yes -timeCreated: 1466638905 -licenseType: Free -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Resolvers/AnimatorStringHashResolver.cs.meta b/Scripts/Resolvers/AnimatorStringHashResolver.cs.meta deleted file mode 100644 index b4e695b..0000000 --- a/Scripts/Resolvers/AnimatorStringHashResolver.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 009222d1cd871a544889009de57437c5 -timeCreated: 1500727672 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Resolvers/FindObjectOfTypeResolver.cs.meta b/Scripts/Resolvers/FindObjectOfTypeResolver.cs.meta deleted file mode 100644 index 11bc864..0000000 --- a/Scripts/Resolvers/FindObjectOfTypeResolver.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: f726efc06b62da249ba211eae9d03010 -timeCreated: 1466639585 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Resolvers/FindRelativeResolver.cs.meta b/Scripts/Resolvers/FindRelativeResolver.cs.meta deleted file mode 100644 index a4fa3b5..0000000 --- a/Scripts/Resolvers/FindRelativeResolver.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 4197c79585cac9047adebe6bab30f283 -timeCreated: 1500115352 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Resolvers/FindResolver.cs.meta b/Scripts/Resolvers/FindResolver.cs.meta deleted file mode 100644 index 9d47c3a..0000000 --- a/Scripts/Resolvers/FindResolver.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 67a6a05362b1efa419ab99d0783d5ce4 -timeCreated: 1466639585 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Resolvers/FindResourceOfTypeResolver.cs b/Scripts/Resolvers/FindResourceOfTypeResolver.cs new file mode 100644 index 0000000..07f8189 --- /dev/null +++ b/Scripts/Resolvers/FindResourceOfTypeResolver.cs @@ -0,0 +1,42 @@ +using Syrinj.Attributes; +using Syrinj.Injection; +using UnityEditor; +using UnityEngine; + +namespace Syrinj.Resolvers +{ + public class FindResourceOfTypeResolver : IResolver + { + public object Resolve(Injectable injectable) + { + //FindObjectOfTypeAttribute + var attribute = (FindResourceOfTypeAttribute)injectable.Attribute; + if (attribute.ComponentType == null) + { + var resources = Resources.FindObjectsOfTypeAll(injectable.Type); + return resources?[0]; + } + else + { + var resources = Resources.FindObjectsOfTypeAll(attribute.ComponentType); + return resources?[0]; + } + } + // public static T[] GetAllInstances() where T : ScriptableObject + // { + // string[] + // guids = AssetDatabase.FindAssets("t:" + + // typeof(T) + // .Name); //FindAssets uses tags check documentation for more info + // T[] a = new T[guids.Length]; + // for (int i = 0; i < guids.Length; i++) //probably could get optimized + // { + // string path = AssetDatabase.GUIDToAssetPath(guids[i]); + // a[i] = AssetDatabase.LoadAssetAtPath(path); + // } + // + // return a; + // } + } + +} \ No newline at end of file diff --git a/Scripts/Resolvers/FindWithTagResolver.cs.meta b/Scripts/Resolvers/FindWithTagResolver.cs.meta deleted file mode 100644 index 901b5b2..0000000 --- a/Scripts/Resolvers/FindWithTagResolver.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: dc34034d4129e1c4eab07011639faaa6 -timeCreated: 1466639585 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Resolvers/GetComponentInChildrenResolver.cs.meta b/Scripts/Resolvers/GetComponentInChildrenResolver.cs.meta deleted file mode 100644 index b17222b..0000000 --- a/Scripts/Resolvers/GetComponentInChildrenResolver.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: f2917ab0f37454c4e81f42eed7423a7f -timeCreated: 1466639585 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Resolvers/GetComponentResolver.cs.meta b/Scripts/Resolvers/GetComponentResolver.cs.meta deleted file mode 100644 index 2eb4c67..0000000 --- a/Scripts/Resolvers/GetComponentResolver.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 20b31af21158c154f8f10f09940fba14 -timeCreated: 1466638905 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Resolvers/IResolver.cs.meta b/Scripts/Resolvers/IResolver.cs.meta deleted file mode 100644 index 899acce..0000000 --- a/Scripts/Resolvers/IResolver.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 45a808144e16f29409471df4831faebd -timeCreated: 1466638905 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/Resolvers/ResolverGroups.cs.meta b/Scripts/Resolvers/ResolverGroups.cs.meta deleted file mode 100644 index e0c07f1..0000000 --- a/Scripts/Resolvers/ResolverGroups.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: cf43466cb17bea84aa6af694cf8b88df -timeCreated: 1466638905 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/RuntimeInjectableMonoBehaviour.cs.meta b/Scripts/RuntimeInjectableMonoBehaviour.cs.meta deleted file mode 100644 index 4f882d2..0000000 --- a/Scripts/RuntimeInjectableMonoBehaviour.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 4e8faf7e7a8fb264595629f4ba41ed57 -timeCreated: 1466617308 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/SceneInjector.cs.meta b/Scripts/SceneInjector.cs.meta deleted file mode 100644 index cf0ccca..0000000 --- a/Scripts/SceneInjector.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: fd73084e4db341340ab261f79e2d1390 -timeCreated: 1467060438 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: -1001 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Scripts/TransformExtensions.cs.meta b/Scripts/TransformExtensions.cs.meta deleted file mode 100644 index eb7abdf..0000000 --- a/Scripts/TransformExtensions.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 5fee824a3aeed9849bf4cd79d2ff5fae -timeCreated: 1506951666 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Syrinj.unitypackage b/Syrinj.unitypackage deleted file mode 100644 index 95fc3b48981564b71c805ae6b35362f0d2f05dd7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18515 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 oa4a%R{J-ebengCn_0D%MaN&o-= diff --git a/Tests/Editor.meta b/Tests/Editor.meta deleted file mode 100644 index 736fe0e..0000000 --- a/Tests/Editor.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 7bf3ea44311344044a529b98e25cd54e -folderAsset: yes -timeCreated: 1466904892 -licenseType: Free -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/TestScene.unity.meta b/Tests/TestScene.unity.meta deleted file mode 100644 index ed1e684..0000000 --- a/Tests/TestScene.unity.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 1fed733f92de1f4489be1461f640f88e -timeCreated: 1466912509 -licenseType: Free -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityTestTools/Assertions.meta b/UnityTestTools/Assertions.meta deleted file mode 100644 index 229b8b8..0000000 --- a/UnityTestTools/Assertions.meta +++ /dev/null @@ -1,5 +0,0 @@ -fileFormatVersion: 2 -guid: b27b28700d3365146808b6e082748201 -folderAsset: yes -DefaultImporter: - userData: diff --git a/UnityTestTools/Assertions/AssertionComponent.cs b/UnityTestTools/Assertions/AssertionComponent.cs deleted file mode 100644 index fa40d48..0000000 --- a/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/UnityTestTools/Assertions/AssertionComponent.cs.meta b/UnityTestTools/Assertions/AssertionComponent.cs.meta deleted file mode 100644 index 26f9ab4..0000000 --- a/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/UnityTestTools/Assertions/AssertionException.cs b/UnityTestTools/Assertions/AssertionException.cs deleted file mode 100644 index 00c6d58..0000000 --- a/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/UnityTestTools/Assertions/AssertionException.cs.meta b/UnityTestTools/Assertions/AssertionException.cs.meta deleted file mode 100644 index 9605bf0..0000000 --- a/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/UnityTestTools/Assertions/Assertions.cs b/UnityTestTools/Assertions/Assertions.cs deleted file mode 100644 index 14b3fd6..0000000 --- a/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/UnityTestTools/Assertions/Assertions.cs.meta b/UnityTestTools/Assertions/Assertions.cs.meta deleted file mode 100644 index 00878a4..0000000 --- a/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/UnityTestTools/Assertions/CheckMethod.cs b/UnityTestTools/Assertions/CheckMethod.cs deleted file mode 100644 index 07583dd..0000000 --- a/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/UnityTestTools/Assertions/CheckMethod.cs.meta b/UnityTestTools/Assertions/CheckMethod.cs.meta deleted file mode 100644 index d3f6ec9..0000000 --- a/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/UnityTestTools/Assertions/Comparers.meta b/UnityTestTools/Assertions/Comparers.meta deleted file mode 100644 index 15d3a92..0000000 --- a/UnityTestTools/Assertions/Comparers.meta +++ /dev/null @@ -1,5 +0,0 @@ -fileFormatVersion: 2 -guid: bb9e10c25f478c84f826ea85b03ec179 -folderAsset: yes -DefaultImporter: - userData: diff --git a/UnityTestTools/Assertions/Comparers/ActionBase.cs b/UnityTestTools/Assertions/Comparers/ActionBase.cs deleted file mode 100644 index a73e0e2..0000000 --- a/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/UnityTestTools/Assertions/Comparers/ActionBase.cs.meta b/UnityTestTools/Assertions/Comparers/ActionBase.cs.meta deleted file mode 100644 index 6d4c3ab..0000000 --- a/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/UnityTestTools/Assertions/Comparers/BoolComparer.cs b/UnityTestTools/Assertions/Comparers/BoolComparer.cs deleted file mode 100644 index 3987cc2..0000000 --- a/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/UnityTestTools/Assertions/Comparers/BoolComparer.cs.meta b/UnityTestTools/Assertions/Comparers/BoolComparer.cs.meta deleted file mode 100644 index 7ee21b6..0000000 --- a/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/UnityTestTools/Assertions/Comparers/ColliderComparer.cs b/UnityTestTools/Assertions/Comparers/ColliderComparer.cs deleted file mode 100644 index cfca05d..0000000 --- a/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/UnityTestTools/Assertions/Comparers/ColliderComparer.cs.meta b/UnityTestTools/Assertions/Comparers/ColliderComparer.cs.meta deleted file mode 100644 index ab3aa47..0000000 --- a/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/UnityTestTools/Assertions/Comparers/ComparerBase.cs b/UnityTestTools/Assertions/Comparers/ComparerBase.cs deleted file mode 100644 index db90211..0000000 --- a/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/UnityTestTools/Assertions/Comparers/ComparerBase.cs.meta b/UnityTestTools/Assertions/Comparers/ComparerBase.cs.meta deleted file mode 100644 index 65909eb..0000000 --- a/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/UnityTestTools/Assertions/Comparers/FloatComparer.cs b/UnityTestTools/Assertions/Comparers/FloatComparer.cs deleted file mode 100644 index ce0a2c2..0000000 --- a/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/UnityTestTools/Assertions/Comparers/FloatComparer.cs.meta b/UnityTestTools/Assertions/Comparers/FloatComparer.cs.meta deleted file mode 100644 index 07353ad..0000000 --- a/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/UnityTestTools/Assertions/Comparers/GeneralComparer.cs b/UnityTestTools/Assertions/Comparers/GeneralComparer.cs deleted file mode 100644 index 96892aa..0000000 --- a/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/UnityTestTools/Assertions/Comparers/GeneralComparer.cs.meta b/UnityTestTools/Assertions/Comparers/GeneralComparer.cs.meta deleted file mode 100644 index 6b7edb3..0000000 --- a/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/UnityTestTools/Assertions/Comparers/IntComparer.cs b/UnityTestTools/Assertions/Comparers/IntComparer.cs deleted file mode 100644 index 25c43aa..0000000 --- a/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/UnityTestTools/Assertions/Comparers/IntComparer.cs.meta b/UnityTestTools/Assertions/Comparers/IntComparer.cs.meta deleted file mode 100644 index 64f4fc3..0000000 --- a/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/UnityTestTools/Assertions/Comparers/IsRenderedByCamera.cs b/UnityTestTools/Assertions/Comparers/IsRenderedByCamera.cs deleted file mode 100644 index bc5d370..0000000 --- a/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/UnityTestTools/Assertions/Comparers/IsRenderedByCamera.cs.meta b/UnityTestTools/Assertions/Comparers/IsRenderedByCamera.cs.meta deleted file mode 100644 index 9cfc1f2..0000000 --- a/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/UnityTestTools/Assertions/Comparers/StringComparer.cs b/UnityTestTools/Assertions/Comparers/StringComparer.cs deleted file mode 100644 index 398f3e9..0000000 --- a/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/UnityTestTools/Assertions/Comparers/StringComparer.cs.meta b/UnityTestTools/Assertions/Comparers/StringComparer.cs.meta deleted file mode 100644 index a414f61..0000000 --- a/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/UnityTestTools/Assertions/Comparers/TransformComparer.cs b/UnityTestTools/Assertions/Comparers/TransformComparer.cs deleted file mode 100644 index 5221c03..0000000 --- a/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/UnityTestTools/Assertions/Comparers/TransformComparer.cs.meta b/UnityTestTools/Assertions/Comparers/TransformComparer.cs.meta deleted file mode 100644 index f3d72e4..0000000 --- a/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/UnityTestTools/Assertions/Comparers/ValueDoesNotChange.cs b/UnityTestTools/Assertions/Comparers/ValueDoesNotChange.cs deleted file mode 100644 index 49a3cc7..0000000 --- a/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/UnityTestTools/Assertions/Comparers/ValueDoesNotChange.cs.meta b/UnityTestTools/Assertions/Comparers/ValueDoesNotChange.cs.meta deleted file mode 100644 index b913d35..0000000 --- a/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/UnityTestTools/Assertions/Comparers/Vector2Comparer.cs b/UnityTestTools/Assertions/Comparers/Vector2Comparer.cs deleted file mode 100644 index 345d76d..0000000 --- a/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/UnityTestTools/Assertions/Comparers/Vector2Comparer.cs.meta b/UnityTestTools/Assertions/Comparers/Vector2Comparer.cs.meta deleted file mode 100644 index 19ef5d2..0000000 --- a/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/UnityTestTools/Assertions/Comparers/Vector3Comparer.cs b/UnityTestTools/Assertions/Comparers/Vector3Comparer.cs deleted file mode 100644 index 56f0b5b..0000000 --- a/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/UnityTestTools/Assertions/Comparers/Vector3Comparer.cs.meta b/UnityTestTools/Assertions/Comparers/Vector3Comparer.cs.meta deleted file mode 100644 index b871f24..0000000 --- a/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/UnityTestTools/Assertions/Comparers/Vector4Comparer.cs b/UnityTestTools/Assertions/Comparers/Vector4Comparer.cs deleted file mode 100644 index 4eda043..0000000 --- a/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/UnityTestTools/Assertions/Comparers/Vector4Comparer.cs.meta b/UnityTestTools/Assertions/Comparers/Vector4Comparer.cs.meta deleted file mode 100644 index 1e0314f..0000000 --- a/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/UnityTestTools/Assertions/Comparers/VectorComparerBase.cs b/UnityTestTools/Assertions/Comparers/VectorComparerBase.cs deleted file mode 100644 index cb394df..0000000 --- a/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/UnityTestTools/Assertions/Comparers/VectorComparerBase.cs.meta b/UnityTestTools/Assertions/Comparers/VectorComparerBase.cs.meta deleted file mode 100644 index d4da9f7..0000000 --- a/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/UnityTestTools/Assertions/Editor.meta b/UnityTestTools/Assertions/Editor.meta deleted file mode 100644 index 2fa5238..0000000 --- a/UnityTestTools/Assertions/Editor.meta +++ /dev/null @@ -1,5 +0,0 @@ -fileFormatVersion: 2 -guid: a28bb39b4fb20514990895d9cb4eaea9 -folderAsset: yes -DefaultImporter: - userData: diff --git a/UnityTestTools/Assertions/Editor/AssertionComponentEditor.cs b/UnityTestTools/Assertions/Editor/AssertionComponentEditor.cs deleted file mode 100644 index a2736a7..0000000 --- a/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/UnityTestTools/Assertions/Editor/AssertionComponentEditor.cs.meta b/UnityTestTools/Assertions/Editor/AssertionComponentEditor.cs.meta deleted file mode 100644 index eb4174d..0000000 --- a/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/UnityTestTools/Assertions/Editor/AssertionExplorerWindow.cs b/UnityTestTools/Assertions/Editor/AssertionExplorerWindow.cs deleted file mode 100644 index ecd7fda..0000000 --- a/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/UnityTestTools/Assertions/Editor/AssertionExplorerWindow.cs.meta b/UnityTestTools/Assertions/Editor/AssertionExplorerWindow.cs.meta deleted file mode 100644 index f5591ab..0000000 --- a/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/UnityTestTools/Assertions/Editor/AssertionListRenderer.cs b/UnityTestTools/Assertions/Editor/AssertionListRenderer.cs deleted file mode 100644 index 31e1b1e..0000000 --- a/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/UnityTestTools/Assertions/Editor/AssertionListRenderer.cs.meta b/UnityTestTools/Assertions/Editor/AssertionListRenderer.cs.meta deleted file mode 100644 index 8e6a0d4..0000000 --- a/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/UnityTestTools/Assertions/Editor/AssertionStripper.cs b/UnityTestTools/Assertions/Editor/AssertionStripper.cs deleted file mode 100644 index 1b6bd04..0000000 --- a/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/UnityTestTools/Assertions/Editor/AssertionStripper.cs.meta b/UnityTestTools/Assertions/Editor/AssertionStripper.cs.meta deleted file mode 100644 index bf18bbe..0000000 --- a/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/UnityTestTools/Assertions/Editor/DropDownControl.cs b/UnityTestTools/Assertions/Editor/DropDownControl.cs deleted file mode 100644 index 79804f9..0000000 --- a/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/UnityTestTools/Assertions/Editor/DropDownControl.cs.meta b/UnityTestTools/Assertions/Editor/DropDownControl.cs.meta deleted file mode 100644 index 424d243..0000000 --- a/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/UnityTestTools/Assertions/Editor/GroupByComparerRenderer.cs b/UnityTestTools/Assertions/Editor/GroupByComparerRenderer.cs deleted file mode 100644 index 6d7875b..0000000 --- a/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/UnityTestTools/Assertions/Editor/GroupByComparerRenderer.cs.meta b/UnityTestTools/Assertions/Editor/GroupByComparerRenderer.cs.meta deleted file mode 100644 index e917399..0000000 --- a/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/UnityTestTools/Assertions/Editor/GroupByExecutionMethodRenderer.cs b/UnityTestTools/Assertions/Editor/GroupByExecutionMethodRenderer.cs deleted file mode 100644 index b4b6d3f..0000000 --- a/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/UnityTestTools/Assertions/Editor/GroupByExecutionMethodRenderer.cs.meta b/UnityTestTools/Assertions/Editor/GroupByExecutionMethodRenderer.cs.meta deleted file mode 100644 index e542ae1..0000000 --- a/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/UnityTestTools/Assertions/Editor/GroupByGORenderer.cs b/UnityTestTools/Assertions/Editor/GroupByGORenderer.cs deleted file mode 100644 index 6d76ca5..0000000 --- a/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/UnityTestTools/Assertions/Editor/GroupByGORenderer.cs.meta b/UnityTestTools/Assertions/Editor/GroupByGORenderer.cs.meta deleted file mode 100644 index a11d1dc..0000000 --- a/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/UnityTestTools/Assertions/Editor/GroupByNothingRenderer.cs b/UnityTestTools/Assertions/Editor/GroupByNothingRenderer.cs deleted file mode 100644 index db5d824..0000000 --- a/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/UnityTestTools/Assertions/Editor/GroupByNothingRenderer.cs.meta b/UnityTestTools/Assertions/Editor/GroupByNothingRenderer.cs.meta deleted file mode 100644 index f7d9d2a..0000000 --- a/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/UnityTestTools/Assertions/Editor/GroupByTestsRenderer.cs b/UnityTestTools/Assertions/Editor/GroupByTestsRenderer.cs deleted file mode 100644 index a126a51..0000000 --- a/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/UnityTestTools/Assertions/Editor/GroupByTestsRenderer.cs.meta b/UnityTestTools/Assertions/Editor/GroupByTestsRenderer.cs.meta deleted file mode 100644 index cbc3124..0000000 --- a/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/UnityTestTools/Assertions/Editor/PropertyPathSelector.cs b/UnityTestTools/Assertions/Editor/PropertyPathSelector.cs deleted file mode 100644 index 3bf3911..0000000 --- a/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/UnityTestTools/Assertions/Editor/PropertyPathSelector.cs.meta b/UnityTestTools/Assertions/Editor/PropertyPathSelector.cs.meta deleted file mode 100644 index b1998a8..0000000 --- a/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/UnityTestTools/Assertions/Editor/PropertyResolver.cs b/UnityTestTools/Assertions/Editor/PropertyResolver.cs deleted file mode 100644 index 5d705da..0000000 --- a/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/UnityTestTools/Assertions/Editor/PropertyResolver.cs.meta b/UnityTestTools/Assertions/Editor/PropertyResolver.cs.meta deleted file mode 100644 index 22210c7..0000000 --- a/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/UnityTestTools/Assertions/InvalidPathException.cs b/UnityTestTools/Assertions/InvalidPathException.cs deleted file mode 100644 index 9ddde07..0000000 --- a/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/UnityTestTools/Assertions/InvalidPathException.cs.meta b/UnityTestTools/Assertions/InvalidPathException.cs.meta deleted file mode 100644 index a5f882d..0000000 --- a/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/UnityTestTools/Assertions/MemberResolver.cs b/UnityTestTools/Assertions/MemberResolver.cs deleted file mode 100644 index 65f7351..0000000 --- a/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/UnityTestTools/Assertions/MemberResolver.cs.meta b/UnityTestTools/Assertions/MemberResolver.cs.meta deleted file mode 100644 index 6b1ea42..0000000 --- a/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/UnityTestTools/Common.meta b/UnityTestTools/Common.meta deleted file mode 100644 index 5f0acfe..0000000 --- a/UnityTestTools/Common.meta +++ /dev/null @@ -1,5 +0,0 @@ -fileFormatVersion: 2 -guid: a2caba6436df568499c84c1c607ce766 -folderAsset: yes -DefaultImporter: - userData: diff --git a/UnityTestTools/Common/Editor.meta b/UnityTestTools/Common/Editor.meta deleted file mode 100644 index 2021d4f..0000000 --- a/UnityTestTools/Common/Editor.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: f4ab061d0035ee545a936bdf8f3f8620 -DefaultImporter: - userData: diff --git a/UnityTestTools/Common/Editor/Icons.cs b/UnityTestTools/Common/Editor/Icons.cs deleted file mode 100644 index 8fd7bfa..0000000 --- a/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/UnityTestTools/Common/Editor/Icons.cs.meta b/UnityTestTools/Common/Editor/Icons.cs.meta deleted file mode 100644 index 267269a..0000000 --- a/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/UnityTestTools/Common/Editor/ProjectSettingsBase.cs b/UnityTestTools/Common/Editor/ProjectSettingsBase.cs deleted file mode 100644 index 99cafad..0000000 --- a/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/UnityTestTools/Common/Editor/ProjectSettingsBase.cs.meta b/UnityTestTools/Common/Editor/ProjectSettingsBase.cs.meta deleted file mode 100644 index db5944b..0000000 --- a/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/UnityTestTools/Common/Editor/ResultWriter.meta b/UnityTestTools/Common/Editor/ResultWriter.meta deleted file mode 100644 index 9b2e13b..0000000 --- a/UnityTestTools/Common/Editor/ResultWriter.meta +++ /dev/null @@ -1,5 +0,0 @@ -fileFormatVersion: 2 -guid: 4ffbf5a07740aa5479651bd415f52ebb -folderAsset: yes -DefaultImporter: - userData: diff --git a/UnityTestTools/Common/Editor/ResultWriter/ResultSummarizer.cs b/UnityTestTools/Common/Editor/ResultWriter/ResultSummarizer.cs deleted file mode 100644 index cfd39ca..0000000 --- a/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/UnityTestTools/Common/Editor/ResultWriter/ResultSummarizer.cs.meta b/UnityTestTools/Common/Editor/ResultWriter/ResultSummarizer.cs.meta deleted file mode 100644 index ca3c41f..0000000 --- a/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/UnityTestTools/Common/Editor/ResultWriter/StackTraceFilter.cs b/UnityTestTools/Common/Editor/ResultWriter/StackTraceFilter.cs deleted file mode 100644 index 686de92..0000000 --- a/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/UnityTestTools/Common/Editor/ResultWriter/StackTraceFilter.cs.meta b/UnityTestTools/Common/Editor/ResultWriter/StackTraceFilter.cs.meta deleted file mode 100644 index 7051843..0000000 --- a/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/UnityTestTools/Common/Editor/ResultWriter/XmlResultWriter.cs b/UnityTestTools/Common/Editor/ResultWriter/XmlResultWriter.cs deleted file mode 100644 index 3115e4f..0000000 --- a/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/UnityTestTools/Common/Editor/ResultWriter/XmlResultWriter.cs.meta b/UnityTestTools/Common/Editor/ResultWriter/XmlResultWriter.cs.meta deleted file mode 100644 index 2fffa90..0000000 --- a/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/UnityTestTools/Common/Editor/Styles.cs b/UnityTestTools/Common/Editor/Styles.cs deleted file mode 100644 index 0caf6e1..0000000 --- a/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/UnityTestTools/Common/Editor/Styles.cs.meta b/UnityTestTools/Common/Editor/Styles.cs.meta deleted file mode 100644 index 294a619..0000000 --- a/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/UnityTestTools/Common/Editor/TestFilterSettings.cs b/UnityTestTools/Common/Editor/TestFilterSettings.cs deleted file mode 100644 index cef016a..0000000 --- a/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/UnityTestTools/Common/Editor/TestFilterSettings.cs.meta b/UnityTestTools/Common/Editor/TestFilterSettings.cs.meta deleted file mode 100644 index 9a7a0e3..0000000 --- a/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/UnityTestTools/Common/Editor/icons.meta b/UnityTestTools/Common/Editor/icons.meta deleted file mode 100644 index 58c5248..0000000 --- a/UnityTestTools/Common/Editor/icons.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: e8bb6eae11352f44da0d6d8a8959b69e -DefaultImporter: - userData: diff --git a/UnityTestTools/Common/Editor/icons/failed.png b/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/UnityTestTools/Common/Editor/icons/inconclusive.png.meta b/UnityTestTools/Common/Editor/icons/inconclusive.png.meta deleted file mode 100644 index 7c93bc4..0000000 --- a/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/UnityTestTools/Common/Editor/icons/normal.png b/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/UnityTestTools/Common/Editor/icons/passed.png.meta b/UnityTestTools/Common/Editor/icons/passed.png.meta deleted file mode 100644 index 876d32d..0000000 --- a/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/UnityTestTools/Common/Editor/icons/stopwatch.png b/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/UnityTestTools/Common/Editor/icons/stopwatch.png.meta b/UnityTestTools/Common/Editor/icons/stopwatch.png.meta deleted file mode 100644 index f39adad..0000000 --- a/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/UnityTestTools/Common/ITestResult.cs b/UnityTestTools/Common/ITestResult.cs deleted file mode 100644 index 13f5fc3..0000000 --- a/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/UnityTestTools/Common/ITestResult.cs.meta b/UnityTestTools/Common/ITestResult.cs.meta deleted file mode 100644 index 4864197..0000000 --- a/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/UnityTestTools/Common/Settings.meta b/UnityTestTools/Common/Settings.meta deleted file mode 100644 index d03eeaf..0000000 --- a/UnityTestTools/Common/Settings.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 5538a37a2f8dd4431a01ba05e90a9239 -folderAsset: yes -timeCreated: 1468257983 -licenseType: Free -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityTestTools/Common/Settings/IntegrationTestsRunnerSettings.asset b/UnityTestTools/Common/Settings/IntegrationTestsRunnerSettings.asset deleted file mode 100644 index a6dadbac87e05edd83e94472bc3346a92922f2b7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4204 zcmeH~y=xRf7{=eZjYi{F{EA;-%A`67i6|&?0dr;*^!&oc5H338R?oe#J12@LTjgI! z&?Z$H5y8LV8Vd`HfR$K^t&NrE^UUt86Y(DqW?=4}`R)5YGxO|TF(ScbkQyQ5K?N651bHI;4pN6BmC+x7WAQEIuXf2`!WZh2FXG53l*H`sN+* z4tNK=1Kt7efOo(<;2rP|cnAJd2kbouduJTneNJN>#zrqEO@mt(?@=l5Ryw(*jlm5o J%?~@M{SBp~k;4E0 diff --git a/UnityTestTools/Common/Settings/IntegrationTestsRunnerSettings.asset.meta b/UnityTestTools/Common/Settings/IntegrationTestsRunnerSettings.asset.meta deleted file mode 100644 index 7681a12..0000000 --- a/UnityTestTools/Common/Settings/IntegrationTestsRunnerSettings.asset.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: d79484cb1b4f64a408be275e4b455652 -timeCreated: 1468257983 -licenseType: Free -NativeFormatImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityTestTools/Common/TestResultState.cs b/UnityTestTools/Common/TestResultState.cs deleted file mode 100644 index 3dc4eb8..0000000 --- a/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/UnityTestTools/Common/TestResultState.cs.meta b/UnityTestTools/Common/TestResultState.cs.meta deleted file mode 100644 index e1576c7..0000000 --- a/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/UnityTestTools/Documentation.url b/UnityTestTools/Documentation.url deleted file mode 100644 index 980b585..0000000 --- a/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/UnityTestTools/Documentation.url.meta b/UnityTestTools/Documentation.url.meta deleted file mode 100644 index b5db496..0000000 --- a/UnityTestTools/Documentation.url.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: 28f1b62e1364e5a4e88f7bb94dbcf183 -DefaultImporter: - userData: diff --git a/UnityTestTools/IntegrationTestsFramework.meta b/UnityTestTools/IntegrationTestsFramework.meta deleted file mode 100644 index da22872..0000000 --- a/UnityTestTools/IntegrationTestsFramework.meta +++ /dev/null @@ -1,5 +0,0 @@ -fileFormatVersion: 2 -guid: 241054a0fe63fbb4bb51609fce9b3112 -folderAsset: yes -DefaultImporter: - userData: diff --git a/UnityTestTools/IntegrationTestsFramework/Libs.meta b/UnityTestTools/IntegrationTestsFramework/Libs.meta deleted file mode 100644 index 1b74975..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/Libs/Mono.Cecil.Mdb.dll b/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/UnityTestTools/IntegrationTestsFramework/Libs/Mono.Cecil.Mdb.dll.meta b/UnityTestTools/IntegrationTestsFramework/Libs/Mono.Cecil.Mdb.dll.meta deleted file mode 100644 index a040b4f..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/Libs/Mono.Cecil.dll b/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/UnityTestTools/IntegrationTestsFramework/Libs/Mono.Cecil.dll.meta b/UnityTestTools/IntegrationTestsFramework/Libs/Mono.Cecil.dll.meta deleted file mode 100644 index 88805bd..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner.meta b/UnityTestTools/IntegrationTestsFramework/TestRunner.meta deleted file mode 100644 index c65a67d..0000000 --- a/UnityTestTools/IntegrationTestsFramework/TestRunner.meta +++ /dev/null @@ -1,5 +0,0 @@ -fileFormatVersion: 2 -guid: da93545c3ab1aa043bcfb22281b1f66c -folderAsset: yes -DefaultImporter: - userData: diff --git a/UnityTestTools/IntegrationTestsFramework/TestRunner/DTOFormatter.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/DTOFormatter.cs deleted file mode 100644 index f974b7c..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/DTOFormatter.cs.meta b/UnityTestTools/IntegrationTestsFramework/TestRunner/DTOFormatter.cs.meta deleted file mode 100644 index f83bde0..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor.meta b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor.meta deleted file mode 100644 index bd38839..0000000 --- a/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor.meta +++ /dev/null @@ -1,5 +0,0 @@ -fileFormatVersion: 2 -guid: caee08596a5965747b8edfde19e2f873 -folderAsset: yes -DefaultImporter: - userData: diff --git a/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Batch.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Batch.cs deleted file mode 100644 index f99fc9b..0000000 --- a/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.platform == RuntimePlatform.WebGLPlayer) //(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/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Batch.cs.meta b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Batch.cs.meta deleted file mode 100644 index 248a6ce..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/EditorReferencesUtil.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/EditorReferencesUtil.cs deleted file mode 100644 index 3d762b8..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/EditorReferencesUtil.cs.meta b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/EditorReferencesUtil.cs.meta deleted file mode 100644 index 78bcfab..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/GuiHelper.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/GuiHelper.cs deleted file mode 100644 index 7c213ba..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/GuiHelper.cs.meta b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/GuiHelper.cs.meta deleted file mode 100644 index 596d39f..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsHierarchyAnnotation.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsHierarchyAnnotation.cs deleted file mode 100644 index 4aa5dc4..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsHierarchyAnnotation.cs.meta b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsHierarchyAnnotation.cs.meta deleted file mode 100644 index 4154bdc..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsRunnerSettings.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsRunnerSettings.cs deleted file mode 100644 index 1e8e466..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsRunnerSettings.cs.meta b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsRunnerSettings.cs.meta deleted file mode 100644 index d18086a..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsRunnerWindow.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsRunnerWindow.cs deleted file mode 100644 index 2a5ed8d..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsRunnerWindow.cs.meta b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/IntegrationTestsRunnerWindow.cs.meta deleted file mode 100644 index 86b5775..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner.meta b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner.meta deleted file mode 100644 index b7631ee..0000000 --- a/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: c44e9167d633ee94bb6e078238178308 -DefaultImporter: - userData: diff --git a/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/NetworkResultsReceiver.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/NetworkResultsReceiver.cs deleted file mode 100644 index f3be338..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/NetworkResultsReceiver.cs.meta b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/NetworkResultsReceiver.cs.meta deleted file mode 100644 index cfc201e..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunner.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunner.cs deleted file mode 100644 index 76522b4..0000000 --- a/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 (result != null) //!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.WebGL: //WebPlayer - return BuildTarget.WebGL; - default: - { - switch (Application.platform) - { - case RuntimePlatform.WindowsPlayer: - return BuildTarget.StandaloneWindows; - case RuntimePlatform.OSXPlayer: - return BuildTarget.StandaloneOSXIntel; - case RuntimePlatform.LinuxPlayer: - return BuildTarget.StandaloneLinux; - } - return BuildTarget.WebGL; //WebPlayer - } - } - } - } -} diff --git a/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunner.cs.meta b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunner.cs.meta deleted file mode 100644 index 5ecced0..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerConfiguration.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerConfiguration.cs deleted file mode 100644 index 1c0a785..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerConfiguration.cs.meta b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerConfiguration.cs.meta deleted file mode 100644 index f747c6e..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerSettings.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerSettings.cs deleted file mode 100644 index 8b54c3a..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerSettings.cs.meta b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerSettings.cs.meta deleted file mode 100644 index 1cc9a28..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerSettingsWindow.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerSettingsWindow.cs deleted file mode 100644 index 56a29ca..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerSettingsWindow.cs.meta b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlatformRunnerSettingsWindow.cs.meta deleted file mode 100644 index 8fed609..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlayerSettingConfigurator.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlayerSettingConfigurator.cs deleted file mode 100644 index 77aea81..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlayerSettingConfigurator.cs.meta b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/PlatformRunner/PlayerSettingConfigurator.cs.meta deleted file mode 100644 index 732b8be..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer.meta b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer.meta deleted file mode 100644 index ccb3c14..0000000 --- a/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: 5944b82e46f1682439d20b4c3a4f029c -DefaultImporter: - userData: diff --git a/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestGroupLine.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestGroupLine.cs deleted file mode 100644 index a7d8619..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestGroupLine.cs.meta b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestGroupLine.cs.meta deleted file mode 100644 index 0051064..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestLine.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestLine.cs deleted file mode 100644 index 7d6b368..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestLine.cs.meta b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestLine.cs.meta deleted file mode 100644 index 25c9f11..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestRendererBase.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestRendererBase.cs deleted file mode 100644 index bc79d03..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestRendererBase.cs.meta b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/IntegrationTestRendererBase.cs.meta deleted file mode 100644 index 1fb186e..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/RenderingOptions.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/RenderingOptions.cs deleted file mode 100644 index 5d16efc..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/RenderingOptions.cs.meta b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/Renderer/RenderingOptions.cs.meta deleted file mode 100644 index 6ecfc38..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/TestComponentEditor.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/TestComponentEditor.cs deleted file mode 100644 index 1b30f55..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/TestComponentEditor.cs.meta b/UnityTestTools/IntegrationTestsFramework/TestRunner/Editor/TestComponentEditor.cs.meta deleted file mode 100644 index e3a1348..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/ITestRunnerCallback.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/ITestRunnerCallback.cs deleted file mode 100644 index c74dab9..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/ITestRunnerCallback.cs.meta b/UnityTestTools/IntegrationTestsFramework/TestRunner/ITestRunnerCallback.cs.meta deleted file mode 100644 index 3a1c54b..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTest.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTest.cs deleted file mode 100644 index de0e6d1..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTest.cs.meta b/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTest.cs.meta deleted file mode 100644 index b6974b8..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTestAttribute.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTestAttribute.cs deleted file mode 100644 index 9ca4e45..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTestAttribute.cs.meta b/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTestAttribute.cs.meta deleted file mode 100644 index 1c80721..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTestsProvider.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTestsProvider.cs deleted file mode 100644 index c38d3c4..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTestsProvider.cs.meta b/UnityTestTools/IntegrationTestsFramework/TestRunner/IntegrationTestsProvider.cs.meta deleted file mode 100644 index d444629..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/NetworkResultSender.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/NetworkResultSender.cs deleted file mode 100644 index 16145c0..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/NetworkResultSender.cs.meta b/UnityTestTools/IntegrationTestsFramework/TestRunner/NetworkResultSender.cs.meta deleted file mode 100644 index 2ed06e1..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/ResultDTO.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/ResultDTO.cs deleted file mode 100644 index e8a8e4e..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/ResultDTO.cs.meta b/UnityTestTools/IntegrationTestsFramework/TestRunner/ResultDTO.cs.meta deleted file mode 100644 index e34e61f..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/TestComponent.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/TestComponent.cs deleted file mode 100644 index d8d9164..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/TestComponent.cs.meta b/UnityTestTools/IntegrationTestsFramework/TestRunner/TestComponent.cs.meta deleted file mode 100644 index fd67c93..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/TestResult.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/TestResult.cs deleted file mode 100644 index df67f71..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/TestResult.cs.meta b/UnityTestTools/IntegrationTestsFramework/TestRunner/TestResult.cs.meta deleted file mode 100644 index c604bea..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/TestResultRenderer.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/TestResultRenderer.cs deleted file mode 100644 index e838d7e..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/TestResultRenderer.cs.meta b/UnityTestTools/IntegrationTestsFramework/TestRunner/TestResultRenderer.cs.meta deleted file mode 100644 index 7d70150..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunner.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunner.cs deleted file mode 100644 index 9c64a2f..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunner.cs.meta b/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunner.cs.meta deleted file mode 100644 index 5ef068e..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunnerCallbackList.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunnerCallbackList.cs deleted file mode 100644 index 91830d2..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunnerCallbackList.cs.meta b/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunnerCallbackList.cs.meta deleted file mode 100644 index c39656a..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunnerConfigurator.cs b/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunnerConfigurator.cs deleted file mode 100644 index 8e7f322..0000000 --- a/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 e) - { - 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/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunnerConfigurator.cs.meta b/UnityTestTools/IntegrationTestsFramework/TestRunner/TestRunnerConfigurator.cs.meta deleted file mode 100644 index 42f7263..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestingAssets.meta b/UnityTestTools/IntegrationTestsFramework/TestingAssets.meta deleted file mode 100644 index 433c295..0000000 --- a/UnityTestTools/IntegrationTestsFramework/TestingAssets.meta +++ /dev/null @@ -1,5 +0,0 @@ -fileFormatVersion: 2 -guid: 1d1ccbd729921544dbd71f7e80c405b6 -folderAsset: yes -DefaultImporter: - userData: diff --git a/UnityTestTools/IntegrationTestsFramework/TestingAssets/CallTesting.cs b/UnityTestTools/IntegrationTestsFramework/TestingAssets/CallTesting.cs deleted file mode 100644 index 3badc58..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestingAssets/CallTesting.cs.meta b/UnityTestTools/IntegrationTestsFramework/TestingAssets/CallTesting.cs.meta deleted file mode 100644 index 91cbde1..0000000 --- a/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/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeCollisionFailure.prefab b/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeCollisionFailure.prefab deleted file mode 100644 index d8faebf18355c98abf6e59c8ac64c003250fcc6d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7348 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 diff --git a/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeCollisionFailure.prefab.meta b/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeCollisionFailure.prefab.meta deleted file mode 100644 index 777585e..0000000 --- a/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeCollisionFailure.prefab.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: d5fc3c3488db1e74689f1fc67c33944a -NativeFormatImporter: - userData: diff --git a/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeCollisionSuccess.prefab b/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeCollisionSuccess.prefab deleted file mode 100644 index 1b7e571fb407b6617f636c816deb1fc55b856b5e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9336 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 PNQdE7R35Od6Eyzs)C<&k diff --git a/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeCollisionSuccess.prefab.meta b/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeCollisionSuccess.prefab.meta deleted file mode 100644 index 73ed474..0000000 --- a/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeCollisionSuccess.prefab.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: 1228dff762eab21488cfefd42792c37b -NativeFormatImporter: - userData: diff --git a/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeTriggerFailure.prefab b/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeTriggerFailure.prefab deleted file mode 100644 index 1f929e3e9092de2da61f4be48fdba9057b0ef268..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7348 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 b$|3W37k^H!!M;9?B2eaM=VZsSPtN}@Hj*LD diff --git a/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeTriggerFailure.prefab.meta b/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeTriggerFailure.prefab.meta deleted file mode 100644 index e04b231..0000000 --- a/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeTriggerFailure.prefab.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: 616ddafe39e02da4081e56f7f763af3c -NativeFormatImporter: - userData: diff --git a/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeTriggerSuccess.prefab b/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeTriggerSuccess.prefab deleted file mode 100644 index 947a40f12e53d4f198d92b7fd045fe2b0608de9f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9336 zcmeHNOK%)S5N-nr3E}++A-vX3A~=O8i9`;_@gq*K6eo+2Bgk#d&h&J3cU5=QS5-Y$ zYT^T>j&3NW_A529Mt61k_=)2ux^JpKwzsz*raIlW7m_%c(Y;_jO!}#s2{O&EL5?zp zpMg@3((TH8oS!&N#{0l9cN(@ zPg4J8s=L8*Ge~uuo3YeB>iPg(DCj;$f2gw$t^)AT!v z3))*Qjt-SNE*>#t#dxS}- z({L?^c;<;kd(04V4?K<%?Qube(NXF|d%`q%9AtSK#w#@MC0b-w=qDxBz%Fc>2AgV{ ze_;zx5si~$Y|7&-3vX&xzNh6l_PN~)Qq>9afO|hvLlMTg3c93a=Tl}RsjH;V>GqYR~Wz3*9u4!`dVlBYe8uB z71k?FzA{QTOtYNzMVdK?P}s~1t|wK-8arg;l`&VZ2`HB~?uNaajXSzR1uq7hI%O`U zku!_*GYkbVa}<_hP!9z#bGNjkprFpseJGG7Zq`ijvlOhf3`_xgJQE+m6s-GhOi9Cb zQ~FFDqES%XNO$dX68oFXDF9quh zI_s4?`qEC+tvtxXw(&}3B=WN8qSO@EmXjocP}y`l57#v_`HG-(!U5uz(jd;dNxC{B z8X^)HUcvJ&0@7;S3j(t8m5%3MiiY0l2Z#bGMD3EMTujKfE+$YgvIF3Xgh{op!FXfb z^~MlFq8-JwZ*sdA_IT|#xm`k`-~R@;%P_~azstVkRKajF$wForaP5I1O^C2rGVH;i z$BW*Cpyv=J-nl{RP*j4P zqpMC%15+|Yt`Q9QXy-}fG4LwUq8RB7F4i&7U@D&ud$6eEj!tRPq41H%8Yl%t-UUw? z1>OJPY5nWSOwuZgC7TVhywwXj$&HNlOa_;hQd!bP-PYu=CA9~nmK^$oRQ6)H(#uza zwRuv)4IW#Rb)V}Ys0-xWC^!!T8mAb&m$g`Q0r)h zq1MErGeO?&Ehb4`gSj3D-Xi&!OH)#*TcifJlv1H;?c_?PS@)Z1vP^3PKF0;M4TEi* zU-~C&G2Cl9Zuck=g|nEDUFlgYoyYhQLFbmHj`5>4bjDb4GDIQ5eC#ZjW1V9)^biNR z0cDS*{KmbwaY63p$NAl^d-;F47dAI+K5_%xSxfzhe6*HI_cCVBRqC`=#h6L!P4IZPl0l2wE=JOvGpeH|MpPL78| zjN)L*d^zJyM;eX7J?TEmQzMW;adddD!$AM*7pRmf;xNg#iNib_ADH2*aTq>;xoIJs zV6n)hEh-mu)P?pVS<`90DQ7haHI{5YNT|3agMhqb?vq*`q$?E5V`O;-4tl|X7tTnB z0y>nsMe-bqA#=yfYnEwzhU7@qb1H-S6@n=jD>UWtSFDg{$97KtT-VP?42eDbUJs(a z`3&ZzC4+i){=TzsZ-Wy4ioB@1bX*X(HSd%>1=?w+q>b;iQ!-6)bcH%E>eXajcZx3< zMy0D63%XTRS{@Ho*eo`znxbGsJo!1nfO^Wap~`5Ude$W?b?P}XVG-ZG`P;iiJn-Nj z4|yu+@o+Dx3QO;w^CDF$->?ddW1*;EC3aek38pIPP_0{yx*Vl&sAdH$o?u@)sA`=$ICny4`46hHD0;BMZobiv!+f*Rp?}oqM|mUF8U1?*vTya{ z+&AN&fB3_NTk%&1zgz$I6CS@D%RPY=I1`A80`bSqBZ~+zP#~JKQY;6=K!JED0HfLd zvbLd5tKTLrhz%(1l{gP59_oNj7Fq#bcKHtcpzgM&Y#W>{pYepcyUG@fDT^GB+P15G z91o2H4cV>oJUF}4xY(tiUNc>GqH}|eF_Gilmusi~t_@pxXY*?}9N(R8I2x}}RIsj? F|4*8G%i;h4 diff --git a/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeTriggerSuccess.prefab.meta b/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeTriggerSuccess.prefab.meta deleted file mode 100644 index d16c91a..0000000 --- a/UnityTestTools/IntegrationTestsFramework/TestingAssets/CubeTriggerSuccess.prefab.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: d940e636fd44be84e9b7e8da46f700ef -NativeFormatImporter: - userData: diff --git a/UnityTestTools/IntegrationTestsFramework/TestingAssets/Materials.meta b/UnityTestTools/IntegrationTestsFramework/TestingAssets/Materials.meta deleted file mode 100644 index ea98c41..0000000 --- a/UnityTestTools/IntegrationTestsFramework/TestingAssets/Materials.meta +++ /dev/null @@ -1,5 +0,0 @@ -fileFormatVersion: 2 -guid: 8d55f43641ba3c14eaa1156abc0edabd -folderAsset: yes -DefaultImporter: - userData: diff --git a/UnityTestTools/IntegrationTestsFramework/TestingAssets/Materials/green.mat b/UnityTestTools/IntegrationTestsFramework/TestingAssets/Materials/green.mat deleted file mode 100644 index ac8a70c46e15524e38ca537f26657a596e87c9d3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4212 zcmeHK$!-)e5Ovu1eP4&2up}V~s}PVt5)gun2;n+%W;~fjo$ko(pbQ7pf5MedfdAkV z_y8o1NQ8P--Gisq16K}HQje=$&sF8;vfZQ9)=;TEPARpOT56OU9~v1NY2H@9*4EYr z==~r)FSIi@(4m^tiBV)&0}`?xKdDlisF{Bjxv^2TRGVFRYwGT4&@j`XUQE;mGQt%E zZLU|V&fcGD1TMBytIkA85JwMaeASw!UZ`qoA}7Ao78F&$i0yH_k;O*9Nb*t0s^i_u0*pX%9P|#(%VIMO zBt9;2Hi#C9iI;jw_(o(1qf%)ntkrELzgQDm!psY`kA$x*ViLSJ%*{5!KqQ*z^_I4( zp`GU5?b6wWU{>Z@x?wC>5slf{;h~}SVq>R=Lu^PH8@t5R6@5MmT)S%HWn*1?u4Rlv z4*H#GWSxOYxF~mLgSk*rDb6LmOz78Ubt-x%C@FKH0Hup`id62Uz79o%@utmZ{N3$h>;XpR-|9=l65 zZwnpwa7Y7ERx~HX)HRtmbOOb8w24xw>(FrElO9m13NLFjjI~p%ygN=6?06M>o9(Ad z>|UVRW;3DU#9plwkeH$$=}f_nS3lC(61$Z0H1d^7KIel{SuXuhqJ$mo1nDY=}@|=4SKJ5F+^zNf$#7Ct6JUVU^;7FiI_-F~H znEV)F^5lCR9pj##a>8$xAehBhGm{hf!GUA=mIqX-!h1|s#C{Hj7n7%W(A+rulkswxfod|3%y z#hN5uv30tg)Zph2BOAVdd;V$o=XqANFaw07a_T(WLr*#n#{N~N-E|w-#`_2?i@IC z=NI?}{({i2d&ZHc#&G4}u9DSKKdDs;N@y?#SrKX!C*ky}rIa zKnWJL{8>XJ80M@j3<#P2Dm+&`-C1c1sx!VL|fwpmRv#eI3EkeIHYZK9`pd`(O0;Dd&DN=cW`Z^R5##>g0%7cV~ zPl>u1{L#z~ zTdzDgMm7jzL{;5+a6Iev5xf(^rAkaajv5NE6CM;Q4j`utLEVZq$eB##q&Zo@d+aVR zct_}zheH^UvZOgJrmn@z(+w2cu_jWbu0z9)hdiKC72ein7;C52_;j2p*wGYwo9$;y z?4F~UW;3DW#96HrkXWMc>0H5%rtj%|iCt2867fnV5Bs20HnW%v7YGCHP>}5&*PTqh z2pb7wL@i|UrL5PVu6d;MZOzc_FW-}it@Rrrj_&REtTc=iFZL&Uzw_J`b) zhg{*7*lTQm)YGon{Acs!D@CUsgg_ zu_lREY@J>w^;r*p`t|zj%WpsChiX5QFSsK6(r2L0K%ap=1APYm9|rI;S<~P*5dTf_ m7UGL`VOj?feZ}JqOuyr+D}5$~)J%ZI|K0_D?a`TIr2YdBGPa5U diff --git a/UnityTestTools/IntegrationTestsFramework/TestingAssets/Materials/red.mat.meta b/UnityTestTools/IntegrationTestsFramework/TestingAssets/Materials/red.mat.meta deleted file mode 100644 index 90565c1..0000000 --- a/UnityTestTools/IntegrationTestsFramework/TestingAssets/Materials/red.mat.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: 03f3b4747259a364b800508ac27e1c17 -NativeFormatImporter: - userData: diff --git a/UnityTestTools/IntegrationTestsFramework/TestingAssets/green.png b/UnityTestTools/IntegrationTestsFramework/TestingAssets/green.png deleted file mode 100644 index f4dcca21896885fb30c3a4b531f1fce4aaa573bb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 140 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 Gb*L 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

>JutcluU}C9Q;`=N4(7=E;iM)N|S@ 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%0D|oKv`vX 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 SFbEg~3<3rLgTVg-f&Tzf%r6E2 diff --git a/UnityTestTools/UnitTesting/Editor/NSubstitute/NSubstitute.dll.meta b/UnityTestTools/UnitTesting/Editor/NSubstitute/NSubstitute.dll.meta deleted file mode 100644 index 1cb4f6b..0000000 --- a/UnityTestTools/UnitTesting/Editor/NSubstitute/NSubstitute.dll.meta +++ /dev/null @@ -1,22 +0,0 @@ -fileFormatVersion: 2 -guid: 3c5e1afc6e0d68849ae6639aff58cfc7 -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/UnityTestTools/changelog.txt b/UnityTestTools/changelog.txt deleted file mode 100644 index 0645834..0000000 --- a/UnityTestTools/changelog.txt +++ /dev/null @@ -1,221 +0,0 @@ -Version 1.5.9 (Updated by @brenoazevedo) -* Updated to work with Unity 2019.1 -* Replaced obsolete ExpectedExceptionAttribute calls according to https://github.com/nunit/nunit/issues/799 -* Fixed obsolete Application.isWebPlayer and WebPlayer calls, now use WebGL instead - -Version 1.5.8 - -- Bugfixes - -Version 1.5.7 - -- Updated tools for Unity 5.3 - -Version 1.5.6 - -- Updated Mono.Cecil.dll and Mono.Cecil.Mdb.dll libraries - -Version 1.5.5 - -- Unit Tests Runner rendering improvments -- Platform runner can include auxiliary scenes -- other improvments and bugfixes - -Version 1.5.4 - -- APIs updates - -Version 1.5.3 - -- Bug fixes - -Version 1.5.2 - -- Bug fixes -- Minor improvments - -Version 1.5.1 - -- removed redundant and not applicable options -- fixed 5.0 related bugs - -Version 1.5.0 - -- Unity 5 related compatibility changes - -Version 1.4.6 - -- Bug fixes -- Minor improvments - -Version 1.4.5 - -- Added "Pause on test failure" option for integration tests -- bugfixes and code refactorization -- fixed UI bug where test details were not refreshed is the label was focused - -Version 1.4.4 - -- Minimal supported Unity version is now 4.3 -- UI changes -- code refactoring - -Version 1.4.3 - -- Remove reference to Resources.LoadAssetAtPath from runtime code - -Version 1.4.2 - -(assertion component) -- fixed string comparer bug that prevented updating the value - -(unit tests) -- unit test runner will log to stdout now -- fixes issues with opening tests in IDEs - -(integration tests) -- transform component is now visible for integration tests components -- added better support for mac's keyboard -- fixed 'succeed on assertion' for code generated assertion - -(other) -- minor bugfixes -- general improvments - -Version 1.4.1 - -- Fixed platform compilation issues -- Fixed typos in labels -- Removed docs and left a link to online docs -- Added Unity version and target platform to result files -- Other bugfixes - -Version 1.4 - -(integration tests) -- Platform runner will send the results back to the editor via TCP now -- Added naming convention for running tests in batch mode -- It's possible to cancel the run in the editor in between the tests now -- Added message filtering for integration tests results -- Added check for RegisterLogCallback in case something else overrides it -- Error messages will now fail integration tests -- Fixed dynamic integration tests not being properly reset -- Fixed platform runner for BlackBerry platform - -(assertion component) -- fixed the component editor - -(common) -- Made settings to be saved per project -- Fixed resolving icons when there are more UnityTestTools folders in the project -- Fixed process return code when running in batch mode - -Version 1.3.2 - -- Fixed integration tests performance issues - -Version 1.3.1 - -- Updated Japanese docs - -Version 1.3 - -Fixes: -(unit tests) -- nUnit will no longer change the Environment.CurrentDirectory when running tests -- fixed issues with asserting GameObject == null -(integration tests) -- fix the issue with passing or failing test in first frame -- fixed bug where ignored tests were still run in ITF -(assertion component) -- fixed resolving properties to include derived types - -Improvements: -(unit tests) -- refactored result renderer -- reenabled Random attribute -- added Category filter -- NSubstitute updated to version 1.7.2 -- result now will be dimmed after recompilation -- running tests in background will now work without having the window focused -- all assemblies in the project referencing 'nunit.framework' will now be included in the test list -(integration tests) -- updated platform exclusion mechanism -- refactored result renderer -- the runner should work even if the runner window is not focused -- added possibility to create integration tests from code -- the runner will now always run in background (if the window is not focused) -(assertion component) -- added API for creating assertions from code -- added new example -(common) -- GUI improvements -- you no longer need to change the path to icons when moving the tools to another directory -- made test details/results resizeable and scrollable -- added character escape for generated result XML - -Version 1.2.1 -- Fixed Unit Test Batch runner - -Version 1.2 -Fixes: -- Windows Store related compilation issues -- other -Improvements: -(unit tests) -- unit test runner can run in background now without having the runner window open -- unit test batch runner can take a result file path as a parameter -- changed undo system for unit test runner and UnityUnitTest base class -- execution time in now visible in test details -- fixed a bug with tests that inherit from a base test class -(integration tests) -- added hierarchical structure for integration tests -- added Player runner to automate running integration tests on platforms -- Integration tests batch runner can take a result directory as a parameter -- Integration tests batch runner can run tests on platforms -- results are rendered in a player -(assertion component) -- changed default failure messages -- it's possible to override failure action on comparer failure -- added code stripper for assertions. -- vast performance improvement -- fixed bugs -Other: -- "Hide in hierarchy" option was removed from integration test runner -- "Focus on selection" option was removed from integration test runner -- "Hide test runner" option was removed from integration test runner -- result files for unit tests and integration tests are now not generated when running tests from the editor -- UI improvements -- removed UnityScript and Boo examples -- WP8 compatibility fixes - -Version 1.1.1 -Other: -- Documentation in Japanese was added - -Version 1.1 -Fixes: -- fixed display error that happened when unit test class inherited from another TestFixture class -- fixed false positive result when "Succeed on assertions" was checked and no assertions were present in the test -- fixed XmlResultWriter to be generate XML file compatible with XSD scheme -- XmlResultWriter result writer was rewritten to remove XML libraries dependency -- Fixed an issue with a check that should be executed once after a specified frame in OnUpdate. -- added missing file UnityUnitTest.cs -Improvements: -- Added Japanese translation of the documentation -- ErrorPause value will be reverted to previous state after test run finishes -- Assertion Component will not copy reference to a GameObject if the GameObject is the same as the component is attached to. Instead, it will set the reference to the new GameObject. -- Integration tests batch runner can now run multiple scenes -- Unit test runner will now include tests written in UnityScript and Boo -- Unit tests will not run automatically if the compilation failes -- Added scene auto-save option to the Unit Test Runner -Other: -- changed icons -- restructured project files -- moved XmlResultWriter to Common folder -- added UnityScript and Boo unit tests examples -- added more unit tests examples -- Test runners visual adjustments - -Version 1.0 -- Initial release \ No newline at end of file diff --git a/UnityTestTools/changelog.txt.meta b/UnityTestTools/changelog.txt.meta deleted file mode 100644 index 8c28fef..0000000 --- a/UnityTestTools/changelog.txt.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: 29b770d9107643740b69cb98b00430aa -TextScriptImporter: - userData: From 68a99c68915f16e9a60c15ed8d39424cf944c93d Mon Sep 17 00:00:00 2001 From: Breno Azevedo Date: Fri, 8 Oct 2021 17:21:03 -0300 Subject: [PATCH 05/12] Updated readme.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9ff8d17..be2529f 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Syrinj ###### **Lightweight dependency injection** & convenient attributes for Unity -### Updated to work with Unity 2019.1 +### Updated to work with Unity 2021.1 --- From db0ee1b59da4c1e4f20749a016f7d69d2fb2756f Mon Sep 17 00:00:00 2001 From: Breno Azevedo Date: Fri, 8 Oct 2021 17:27:01 -0300 Subject: [PATCH 06/12] Added 'DependencyContainer called more than once' error treatment (by KAW0) --- Scripts/DependencyContainer.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Scripts/DependencyContainer.cs b/Scripts/DependencyContainer.cs index 6158ef0..359691b 100644 --- a/Scripts/DependencyContainer.cs +++ b/Scripts/DependencyContainer.cs @@ -40,8 +40,12 @@ public DependencyContainer() Reset(); } + private static int counter; public void Reset() { + counter++; + if(counter>1) + Debug.LogError(nameof(DependencyContainer)+ " called more than once"); dependencyMap = new DependencyMap(); memberEvaluator = new MemberEvaluator(attributeCache, dependencyMap); From 6d7d9516a37e3c88071c71e81f7e0f9510e3ae7b Mon Sep 17 00:00:00 2001 From: Breno Azevedo Date: Fri, 8 Oct 2021 17:35:16 -0300 Subject: [PATCH 07/12] * Added package.json --- Scripts/package.json | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 Scripts/package.json diff --git a/Scripts/package.json b/Scripts/package.json new file mode 100644 index 0000000..70076f4 --- /dev/null +++ b/Scripts/package.json @@ -0,0 +1,13 @@ +{ + "name": "com.fluidplay.syrinj", + "displayName": "Syrinj", + "version": "1.2.0", + "unity": "2021.1", + "description": "Lightweight dependency injection & convenience attributes for Unity.", + "keywords": [ + "Dependency Injection", + "syrinj" + ], + "license": "MIT", + "category": "DI" +} \ No newline at end of file From 8303ace367ee5981b534ed56a811354d7a47fb39 Mon Sep 17 00:00:00 2001 From: Breno Azevedo Date: Tue, 19 Oct 2021 03:15:57 -0300 Subject: [PATCH 08/12] Reverted 'DependencyContainer called more than once' error message --- Scripts/DependencyContainer.cs | 4 --- .../Resolvers/FindResourceOfTypeResolver.cs | 31 ++++++++---------- Scripts/Resolvers/ResolverGroups.cs | 1 + Tests/TestScene.unity | Bin 5128 -> 3600 bytes 4 files changed, 14 insertions(+), 22 deletions(-) diff --git a/Scripts/DependencyContainer.cs b/Scripts/DependencyContainer.cs index 359691b..6158ef0 100644 --- a/Scripts/DependencyContainer.cs +++ b/Scripts/DependencyContainer.cs @@ -40,12 +40,8 @@ public DependencyContainer() Reset(); } - private static int counter; public void Reset() { - counter++; - if(counter>1) - Debug.LogError(nameof(DependencyContainer)+ " called more than once"); dependencyMap = new DependencyMap(); memberEvaluator = new MemberEvaluator(attributeCache, dependencyMap); diff --git a/Scripts/Resolvers/FindResourceOfTypeResolver.cs b/Scripts/Resolvers/FindResourceOfTypeResolver.cs index 07f8189..e5c4192 100644 --- a/Scripts/Resolvers/FindResourceOfTypeResolver.cs +++ b/Scripts/Resolvers/FindResourceOfTypeResolver.cs @@ -1,6 +1,5 @@ using Syrinj.Attributes; using Syrinj.Injection; -using UnityEditor; using UnityEngine; namespace Syrinj.Resolvers @@ -9,7 +8,6 @@ public class FindResourceOfTypeResolver : IResolver { public object Resolve(Injectable injectable) { - //FindObjectOfTypeAttribute var attribute = (FindResourceOfTypeAttribute)injectable.Attribute; if (attribute.ComponentType == null) { @@ -19,24 +17,21 @@ public object Resolve(Injectable injectable) else { var resources = Resources.FindObjectsOfTypeAll(attribute.ComponentType); + // var resources = Resources.LoadAll("", attribute.ComponentType).ToArray(); return resources?[0]; } } - // public static T[] GetAllInstances() where T : ScriptableObject - // { - // string[] - // guids = AssetDatabase.FindAssets("t:" + - // typeof(T) - // .Name); //FindAssets uses tags check documentation for more info - // T[] a = new T[guids.Length]; - // for (int i = 0; i < guids.Length; i++) //probably could get optimized - // { - // string path = AssetDatabase.GUIDToAssetPath(guids[i]); - // a[i] = AssetDatabase.LoadAssetAtPath(path); - // } - // - // return a; - // } } - + // var attribute = (FindResourceOfTypeAttribute)injectable.Attribute; + // string[] guids; + // + // string path = ""; + // guids = AssetDatabase.FindAssets("t:"+nameof(attribute.ComponentType)); + // foreach (string guid in guids) + // { + // path = AssetDatabase.GUIDToAssetPath(guid); + // Debug.Log("path: "+path); + // } + // + // return AssetDatabase.LoadAssetAtPath(path, attribute.ComponentType); } \ No newline at end of file diff --git a/Scripts/Resolvers/ResolverGroups.cs b/Scripts/Resolvers/ResolverGroups.cs index 2dbbf24..d02f9dd 100644 --- a/Scripts/Resolvers/ResolverGroups.cs +++ b/Scripts/Resolvers/ResolverGroups.cs @@ -10,6 +10,7 @@ public static class ResolverGroups {typeof (AnimatorStringHashAttribute), new AnimatorStringHashResolver()}, {typeof (FindAttribute), new FindResolver()}, {typeof (FindObjectOfTypeAttribute), new FindObjectOfTypeResolver()}, + {typeof (FindResourceOfTypeAttribute), new FindResourceOfTypeResolver()}, {typeof (FindRelativeAttribute), new FindRelativeResolver()}, {typeof (FindWithTagAttribute), new FindWithTagResolver()}, {typeof (GetComponentAttribute), new GetComponentResolver()}, diff --git a/Tests/TestScene.unity b/Tests/TestScene.unity index a362703d2ed7bba684062656fb1861025b19ebc3..915abb440c3745790e8029b87ee6e846a6618d6a 100644 GIT binary patch literal 3600 zcmbUk%TnV;@b0hB9+neOk}N-O#x{l&4law`R8G`bYMTiojU$a%ldb*tbkAt4k%8=1 zTtx}>``xY2e@>QnUT_(7K0izr-lyu5r`T>>8z}&#Uxo&}VafBBCGhZ6K=~v^I`#sebZ3uo0y!+c z+|H2vC%?8)wSzOJ*x38Np=UV^kVHjzR*K%h9l|ACWQz<06 z`yK!M%ig(1IC^gCCmIv{uzX9IVi>yibq0Bf*&|9n(7-#M11nH$tXQEC(T2`*j8wOd z)Fj(*$W{FO+Oi=G!rF>39MpD%z0tYXSWHzo=vgi=_T@>?1^=+=K@5b@kBom;z5~__VSfcm~#7``h-&(pN>t!?;)~fpC zZ=(tWvyq1-Q@Wm=nh5-^PhM6Wqj_3m+Y`XKr(X9|yC#V@OvqRjknhwJ<&EkY>p-vq z8nAIm1Fu;M@g9Kkrb$V_0~}OUpis9=b@A_|no9Z1T^x3XAADpk{I|I?*s@BfHEabo zI`*;~;5W!Mlu}eghD93=wY?4N73Mnu91_O82Jt4D)2dW5YY5(Pv_ci9-rwdaFVIYk zS5jd_-F%z6GKqGR{H267OF2W!>JnNNazpt#_I+>Qopn2ReD|a>w*P;fAD9Waxcx&G z&s!nCnK+tAEN)$)9}ZATu!&)uFdB!%O+f4SeWmu5Izdjv22yz?Wr^d!a?JA=UdTMd z_Sb&lL~jyHBIh~V2%tHgTF2|eHP|&Up?C%-1lgkn%u|lz;itao*pOJad?;Q7BNJSB zM7>Rji4v@gam%1rei&KkJ!P(@xL>lvjF*a%+xR|}*?w|AKkQ|W?ls*R)$pqfNw;A0T~eBtfol8{<}N3|W0$$1K~^ zz0l}Kpb4r*L2W?S%C|fg(L0s}VveK3p>}GxC9%cm5TSp7b2ovN&Nz)6zIW+iq-y!{whiHF{L~fnZ}1A>S3-pihK4elKt1mMQg} z(@M8Fu%7xDGKE<{(>&->f1*98ZZx5#)m$*GS zb^`S&4XJuA)QTo$3D|}0vCxnlM`uG34M)B|?1h72Fc=L7;h>AxOMQv-wmwUfQ5f|{ z(Xb!+Eb0ZL?q;-2w|>yy*h?gAPTEo5JBvEMvzH~F(MN4)=Epbudlx^B>57Zg74V@5 z&tp5BySk)jwlFowlpTWfQB>320PS5{IhrmOk`AiK)SCuP1<&-gX!d}BbO*CS?k#tn zPImaM!r`A3vc&SXi=jsHd<{FSz)1mk1J-rK@`{Nm2w^sjAx)b1%b>4+15*Q<`~g25 zTyk}M4|{!0$C9Kf@UC15{Dz?=Y~zrjg>pkTf?gL!9Zi2IUV!A5xZ_Lw+@gV);zBVL XDQv18eUX_-=6s7~k9Bh2e%Aa81&vxz literal 5128 zcmZ{oZH!$-8OP`D7N{r%O06$QxrHL7K$n6IHqzaD_wKg4u{!QMfxAT!-BLA&sovVn9Iw)syMO*~mg*xR& z@Dv%_Mk+^8VkRFYuaS?6KY-nccc_P%iTnky$IwQ-S7=IZ^nV(4>bWxKgZi(^`JjHz z1QYci!jt+xf#=5vkt(o&_8dc*wp^{5;fG<*B z=ZT5-Jc_5Y2dkyiuszp-nt9$K%Jy8J^NNU3eg>Jg>_*0LXph)H0a=ghh9Q2=@;yWR z=azrc@>WL$s-=>|3sz#$UuvFiP02)>(n9+&)k)%d6v;E9*-WAb7FEzyk&4D4aKiJ| z>=Y$s(ldqAt!5Y{(l5WV(CPST?1h188W%a3l&j^gx94$R`o4-2-HN`212dtoL|b-N zmt{wt>P0H-RH5-1Ym}oSXIf0qPvrjmS)#2L_WLqfGue!kXdJBO?15s$3HWc(Yz3 zTK?ClQhpzDMX&pa4knk3n7BFTrr$rJPWdV_lk=YsP$u6`h~)St%H$k36Zz|~=emlq z=T?J32kkkaWhp;s&uuw3diGg8oF}GXJ-2JNRnNhkn|ZqvdT8ez$V_fN8UxaDQcexR~V4Pl}6}?k%+{KXbT2$p!u+?Ole95v6q}dWzGwfjL_IhWR#S_ zbkIe$-fw#`Y9#wRv|u#v2_&B#)1`N)2Cu1ZL7XqI5MLh+eBtOZ3CqTEi0~P=9=+U%df$FE357EG9Q2&mWph2_3y!~Sxjvz497jd`8SFpE90zx!$gcdiE69_mF9OaXmBF+Lx`o zIiaY3R7djj;G9dY8E)u$yqve6g5yu{gmV3ozhgO1C{Z)=9PfMJoFAT0PM-WD%XvZ> zUJ=*8nQlX-o#uop^f)_tLOFXFshpiWp$s>X`55%D-+jnTdP88#lw#P)*+;@?b=eP} zv>VjP#JYZRc0jgNF&nhik+=``mu7>m7h$6>q{&*EI9m7HsvAy*Va#ZEO7+*mNcxSi zhs!K>cX55}FHHwecu^Si5&yIWxENc5rUTjb6>qKG+%{-4cu`3|@%pN0ai!_5hmct^ z__7TH5s3W^02|*P@wz%D+UksAY=If|g?YI?<;97_fKYGBZWp$r)Cl`)^@Zv6wJ^Y- zN)ZVQ(3FwvD@5X$;mKK6P{6Ix*>+96xOVeyuf+oCpTwsC?&y3euPsWPA}Km9N6_-S zI)>`5VK2Wv>T#@exZDD%1FA63jpoA-$8tr9H{edcAKUfj;mk4|vg zeuxaO)9HTrG{c2X8C`SxaLVw=cX>g%1zEqJ8Mohnj-z07V;xRK!RwZ@4Pww@!r;8+ zCY%<0Fq{^=W93aaEqH9X38#j0n?D1Nool{!YlZxCR$gEDOZL2Exelk6Q_nf8hg;o* zi;DOKiti$mnQ+R!%mwdHU^|c*PT4;>xBuTzri~1z z9g7+yi?ZvbvCw7f;=0`O!!>1a!}t1a;j8Y7nu@|Tw-My}gDL#I6NPb{ZwJ}wq!BJ0 zO&=eN+}fh=1&eA0u3L|k6dmRJE$^GyH!?^O7+h7mrnQ=$$xTwKYDXXZ3g)z!!RrEk z7$X@EZ^Azm$edGFQGN}%r?Y7@jwQrzE$3a~dHbHxjP=3Hei8f)o$bGHoKi3|{kni3 zY|t=`aDf?116=-=+L(KM>@VT66iFv!R?^jcuN}$gjCrBjHTS1#uE>dP|9qhae;OC! zt;wPG3Dj-QCOFQkFWvfpk@AhbYe>Lijzxdp@@oqM8as98nqKw~uWT&q0{#Nby zo7H=c-|>xW!87P#HuGFNXtdzh@>(q?C~#`7=O=_s8J=`br$ZOF`Jqf9=lZn$nueMX t)k(pH(TkH!u&?2yMbSRoX3k(O&9T&k_`>9`E?mHP2U6|q%ZG-U_&={wl92!a From 085930c1bfda816d921f8c462508914aa078017d Mon Sep 17 00:00:00 2001 From: Breno Azevedo Date: Tue, 19 Oct 2021 03:19:12 -0300 Subject: [PATCH 09/12] Removing error message (2) --- Scripts/Attributes.meta | 8 +++ Scripts/Attributes/AnimatorStringHash.cs.meta | 11 ++++ Scripts/Attributes/FindAttribute.cs.meta | 11 ++++ .../FindObjectOfTypeAttribute.cs.meta | 11 ++++ .../Attributes/FindRelativeAttribute.cs.meta | 11 ++++ .../FindResourceOfTypeAttribute.cs.meta | 11 ++++ .../Attributes/FindWithTagAttribute.cs.meta | 11 ++++ .../Attributes/GetComponentAttribute.cs.meta | 11 ++++ .../GetComponentInChildrenAttribute.cs.meta | 11 ++++ Scripts/Attributes/InjectAttribute.cs.meta | 11 ++++ Scripts/Attributes/InstanceAttribute.cs.meta | 11 ++++ Scripts/Attributes/ProvidesAttribute.cs.meta | 11 ++++ Scripts/Attributes/SingletonAttribute.cs.meta | 11 ++++ .../UnityConvenienceAttribute.cs.meta | 11 ++++ .../UnityDependencyAttribute.cs.meta | 11 ++++ .../Attributes/UnityInjectorAttribute.cs.meta | 11 ++++ .../Attributes/UnityProviderAttribute.cs.meta | 11 ++++ Scripts/DependencyContainer.cs.meta | 11 ++++ Scripts/Exceptions.meta | 8 +++ Scripts/Exceptions/InjectionException.cs.meta | 11 ++++ Scripts/GameObjectInjector.cs.meta | 11 ++++ Scripts/Graph.meta | 8 +++ Scripts/Graph/DependencyMap.cs.meta | 11 ++++ Scripts/Injection.meta | 8 +++ Scripts/Injection/Injectable.cs.meta | 11 ++++ Scripts/Injection/InjectableFactory.cs.meta | 11 ++++ Scripts/Injection/InjectableField.cs.meta | 11 ++++ Scripts/Injection/InjectableProperty.cs.meta | 11 ++++ Scripts/InjectorComponent.cs.meta | 11 ++++ Scripts/Provider.cs.meta | 11 ++++ Scripts/Provision.meta | 8 +++ Scripts/Provision/FieldProvider.cs.meta | 11 ++++ Scripts/Provision/IProvider.cs.meta | 11 ++++ Scripts/Provision/InstanceProvider.cs.meta | 11 ++++ Scripts/Provision/PropertyProvider.cs.meta | 11 ++++ Scripts/Provision/ProviderFactory.cs.meta | 11 ++++ Scripts/Provision/SingletonProvider.cs.meta | 11 ++++ Scripts/Reflection.meta | 8 +++ Scripts/Reflection/AttributeCache.cs.meta | 11 ++++ Scripts/Reflection/MemberEvaluator.cs.meta | 11 ++++ Scripts/Resolvers.meta | 8 +++ .../AnimatorStringHashResolver.cs.meta | 11 ++++ .../FindObjectOfTypeResolver.cs.meta | 11 ++++ .../Resolvers/FindRelativeResolver.cs.meta | 11 ++++ Scripts/Resolvers/FindResolver.cs.meta | 11 ++++ .../FindResourceOfTypeResolver.cs.meta | 11 ++++ Scripts/Resolvers/FindWithTagResolver.cs.meta | 11 ++++ .../GetComponentInChildrenResolver.cs.meta | 11 ++++ .../Resolvers/GetComponentResolver.cs.meta | 11 ++++ Scripts/Resolvers/IResolver.cs.meta | 11 ++++ Scripts/Resolvers/ResolverGroups.cs.meta | 11 ++++ .../RuntimeInjectableMonoBehaviour.cs.meta | 11 ++++ Scripts/SceneInjector.cs.meta | 11 ++++ Scripts/TransformExtensions.cs.meta | 11 ++++ Scripts/package.json.meta | 7 +++ Tests/Editor.meta | 8 +++ Tests/TestScene.unity.meta | 7 +++ Tests/TestSceneSettings.lighting | 63 +++++++++++++++++++ Tests/TestSceneSettings.lighting.meta | 8 +++ 59 files changed, 666 insertions(+) create mode 100644 Scripts/Attributes.meta create mode 100644 Scripts/Attributes/AnimatorStringHash.cs.meta create mode 100644 Scripts/Attributes/FindAttribute.cs.meta create mode 100644 Scripts/Attributes/FindObjectOfTypeAttribute.cs.meta create mode 100644 Scripts/Attributes/FindRelativeAttribute.cs.meta create mode 100644 Scripts/Attributes/FindResourceOfTypeAttribute.cs.meta create mode 100644 Scripts/Attributes/FindWithTagAttribute.cs.meta create mode 100644 Scripts/Attributes/GetComponentAttribute.cs.meta create mode 100644 Scripts/Attributes/GetComponentInChildrenAttribute.cs.meta create mode 100644 Scripts/Attributes/InjectAttribute.cs.meta create mode 100644 Scripts/Attributes/InstanceAttribute.cs.meta create mode 100644 Scripts/Attributes/ProvidesAttribute.cs.meta create mode 100644 Scripts/Attributes/SingletonAttribute.cs.meta create mode 100644 Scripts/Attributes/UnityConvenienceAttribute.cs.meta create mode 100644 Scripts/Attributes/UnityDependencyAttribute.cs.meta create mode 100644 Scripts/Attributes/UnityInjectorAttribute.cs.meta create mode 100644 Scripts/Attributes/UnityProviderAttribute.cs.meta create mode 100644 Scripts/DependencyContainer.cs.meta create mode 100644 Scripts/Exceptions.meta create mode 100644 Scripts/Exceptions/InjectionException.cs.meta create mode 100644 Scripts/GameObjectInjector.cs.meta create mode 100644 Scripts/Graph.meta create mode 100644 Scripts/Graph/DependencyMap.cs.meta create mode 100644 Scripts/Injection.meta create mode 100644 Scripts/Injection/Injectable.cs.meta create mode 100644 Scripts/Injection/InjectableFactory.cs.meta create mode 100644 Scripts/Injection/InjectableField.cs.meta create mode 100644 Scripts/Injection/InjectableProperty.cs.meta create mode 100644 Scripts/InjectorComponent.cs.meta create mode 100644 Scripts/Provider.cs.meta create mode 100644 Scripts/Provision.meta create mode 100644 Scripts/Provision/FieldProvider.cs.meta create mode 100644 Scripts/Provision/IProvider.cs.meta create mode 100644 Scripts/Provision/InstanceProvider.cs.meta create mode 100644 Scripts/Provision/PropertyProvider.cs.meta create mode 100644 Scripts/Provision/ProviderFactory.cs.meta create mode 100644 Scripts/Provision/SingletonProvider.cs.meta create mode 100644 Scripts/Reflection.meta create mode 100644 Scripts/Reflection/AttributeCache.cs.meta create mode 100644 Scripts/Reflection/MemberEvaluator.cs.meta create mode 100644 Scripts/Resolvers.meta create mode 100644 Scripts/Resolvers/AnimatorStringHashResolver.cs.meta create mode 100644 Scripts/Resolvers/FindObjectOfTypeResolver.cs.meta create mode 100644 Scripts/Resolvers/FindRelativeResolver.cs.meta create mode 100644 Scripts/Resolvers/FindResolver.cs.meta create mode 100644 Scripts/Resolvers/FindResourceOfTypeResolver.cs.meta create mode 100644 Scripts/Resolvers/FindWithTagResolver.cs.meta create mode 100644 Scripts/Resolvers/GetComponentInChildrenResolver.cs.meta create mode 100644 Scripts/Resolvers/GetComponentResolver.cs.meta create mode 100644 Scripts/Resolvers/IResolver.cs.meta create mode 100644 Scripts/Resolvers/ResolverGroups.cs.meta create mode 100644 Scripts/RuntimeInjectableMonoBehaviour.cs.meta create mode 100644 Scripts/SceneInjector.cs.meta create mode 100644 Scripts/TransformExtensions.cs.meta create mode 100644 Scripts/package.json.meta create mode 100644 Tests/Editor.meta create mode 100644 Tests/TestScene.unity.meta create mode 100644 Tests/TestSceneSettings.lighting create mode 100644 Tests/TestSceneSettings.lighting.meta diff --git a/Scripts/Attributes.meta b/Scripts/Attributes.meta new file mode 100644 index 0000000..af8058e --- /dev/null +++ b/Scripts/Attributes.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a0548255b21720e44ac2c95ffd1a242a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Attributes/AnimatorStringHash.cs.meta b/Scripts/Attributes/AnimatorStringHash.cs.meta new file mode 100644 index 0000000..e05bcb2 --- /dev/null +++ b/Scripts/Attributes/AnimatorStringHash.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 014a2e16a8fdef8409139eec54117fcd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Attributes/FindAttribute.cs.meta b/Scripts/Attributes/FindAttribute.cs.meta new file mode 100644 index 0000000..6efddaf --- /dev/null +++ b/Scripts/Attributes/FindAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a96cc989670eb2c43bfe0b22360b0867 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Attributes/FindObjectOfTypeAttribute.cs.meta b/Scripts/Attributes/FindObjectOfTypeAttribute.cs.meta new file mode 100644 index 0000000..00d7c6a --- /dev/null +++ b/Scripts/Attributes/FindObjectOfTypeAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 315d37b35f467404f801a8f04bfbd0aa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Attributes/FindRelativeAttribute.cs.meta b/Scripts/Attributes/FindRelativeAttribute.cs.meta new file mode 100644 index 0000000..f0a87cd --- /dev/null +++ b/Scripts/Attributes/FindRelativeAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a6812eb1f8d0d62499936b0425e246ff +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Attributes/FindResourceOfTypeAttribute.cs.meta b/Scripts/Attributes/FindResourceOfTypeAttribute.cs.meta new file mode 100644 index 0000000..78b5c7e --- /dev/null +++ b/Scripts/Attributes/FindResourceOfTypeAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2e02008336c667248b870cb4dbf9fb1b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Attributes/FindWithTagAttribute.cs.meta b/Scripts/Attributes/FindWithTagAttribute.cs.meta new file mode 100644 index 0000000..2ed14c8 --- /dev/null +++ b/Scripts/Attributes/FindWithTagAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b2b621793f49ba84bbda8b3c5286b115 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Attributes/GetComponentAttribute.cs.meta b/Scripts/Attributes/GetComponentAttribute.cs.meta new file mode 100644 index 0000000..7d10100 --- /dev/null +++ b/Scripts/Attributes/GetComponentAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 50b83118f289128489b77eaddfbd45ea +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Attributes/GetComponentInChildrenAttribute.cs.meta b/Scripts/Attributes/GetComponentInChildrenAttribute.cs.meta new file mode 100644 index 0000000..10512d8 --- /dev/null +++ b/Scripts/Attributes/GetComponentInChildrenAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9153053b8d41bc9478ed063c403cedd8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Attributes/InjectAttribute.cs.meta b/Scripts/Attributes/InjectAttribute.cs.meta new file mode 100644 index 0000000..ce2515e --- /dev/null +++ b/Scripts/Attributes/InjectAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5009dfa0a0d3de5449299bd4c0d65a07 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Attributes/InstanceAttribute.cs.meta b/Scripts/Attributes/InstanceAttribute.cs.meta new file mode 100644 index 0000000..192b81e --- /dev/null +++ b/Scripts/Attributes/InstanceAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 34eaf50ede415904c8be891ae1cf42b3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Attributes/ProvidesAttribute.cs.meta b/Scripts/Attributes/ProvidesAttribute.cs.meta new file mode 100644 index 0000000..3693806 --- /dev/null +++ b/Scripts/Attributes/ProvidesAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 874de662015e7204db78f04b36aa7879 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Attributes/SingletonAttribute.cs.meta b/Scripts/Attributes/SingletonAttribute.cs.meta new file mode 100644 index 0000000..e68de5c --- /dev/null +++ b/Scripts/Attributes/SingletonAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a965fc93350553146871a6e10928f4f6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Attributes/UnityConvenienceAttribute.cs.meta b/Scripts/Attributes/UnityConvenienceAttribute.cs.meta new file mode 100644 index 0000000..aecd574 --- /dev/null +++ b/Scripts/Attributes/UnityConvenienceAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9dc2ef86bdc6c9948926c2ecd4513396 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Attributes/UnityDependencyAttribute.cs.meta b/Scripts/Attributes/UnityDependencyAttribute.cs.meta new file mode 100644 index 0000000..eb8eaa2 --- /dev/null +++ b/Scripts/Attributes/UnityDependencyAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 983e3970cc37e8d4d94edecdc23ddb47 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Attributes/UnityInjectorAttribute.cs.meta b/Scripts/Attributes/UnityInjectorAttribute.cs.meta new file mode 100644 index 0000000..f32354a --- /dev/null +++ b/Scripts/Attributes/UnityInjectorAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fa1405c74109dda4c90c18fad91a289d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Attributes/UnityProviderAttribute.cs.meta b/Scripts/Attributes/UnityProviderAttribute.cs.meta new file mode 100644 index 0000000..144bc6c --- /dev/null +++ b/Scripts/Attributes/UnityProviderAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6ca1bedc95f07834486a5cff3792ec04 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/DependencyContainer.cs.meta b/Scripts/DependencyContainer.cs.meta new file mode 100644 index 0000000..636aca4 --- /dev/null +++ b/Scripts/DependencyContainer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: feb35e4e7be18e1498b183742f4aa66b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Exceptions.meta b/Scripts/Exceptions.meta new file mode 100644 index 0000000..7e5130b --- /dev/null +++ b/Scripts/Exceptions.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 749620d32153d8542bc77ccec4280797 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Exceptions/InjectionException.cs.meta b/Scripts/Exceptions/InjectionException.cs.meta new file mode 100644 index 0000000..2f02344 --- /dev/null +++ b/Scripts/Exceptions/InjectionException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1ad3251ebff43164fb261ce463ef3bec +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/GameObjectInjector.cs.meta b/Scripts/GameObjectInjector.cs.meta new file mode 100644 index 0000000..f4d0623 --- /dev/null +++ b/Scripts/GameObjectInjector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4b2d1645126f00141a11a45375d1d35e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Graph.meta b/Scripts/Graph.meta new file mode 100644 index 0000000..828ab43 --- /dev/null +++ b/Scripts/Graph.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 48545a69cabf8c942b596878b918a5ed +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Graph/DependencyMap.cs.meta b/Scripts/Graph/DependencyMap.cs.meta new file mode 100644 index 0000000..2dda834 --- /dev/null +++ b/Scripts/Graph/DependencyMap.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6329bd02b1d18f7449cd520edb523ff6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Injection.meta b/Scripts/Injection.meta new file mode 100644 index 0000000..d0f699d --- /dev/null +++ b/Scripts/Injection.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 99b8335a7d2798d4892b37ee220b56d1 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Injection/Injectable.cs.meta b/Scripts/Injection/Injectable.cs.meta new file mode 100644 index 0000000..5a4e1c7 --- /dev/null +++ b/Scripts/Injection/Injectable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dfcd4bbb19d4efd43a45468d8aea0d7a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Injection/InjectableFactory.cs.meta b/Scripts/Injection/InjectableFactory.cs.meta new file mode 100644 index 0000000..2bc34d0 --- /dev/null +++ b/Scripts/Injection/InjectableFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9f57c7841a0c0884ea774ca4e553daa5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Injection/InjectableField.cs.meta b/Scripts/Injection/InjectableField.cs.meta new file mode 100644 index 0000000..9f3e35c --- /dev/null +++ b/Scripts/Injection/InjectableField.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: df4d495dae1a586488c2e8de7d8b51dd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Injection/InjectableProperty.cs.meta b/Scripts/Injection/InjectableProperty.cs.meta new file mode 100644 index 0000000..6a33faf --- /dev/null +++ b/Scripts/Injection/InjectableProperty.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 62e9d0ddf718c274cb1cab2b5f3d4ba3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/InjectorComponent.cs.meta b/Scripts/InjectorComponent.cs.meta new file mode 100644 index 0000000..158e7e4 --- /dev/null +++ b/Scripts/InjectorComponent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f2024519159ec244e8959ef36fb68846 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: -1100 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Provider.cs.meta b/Scripts/Provider.cs.meta new file mode 100644 index 0000000..7def2b1 --- /dev/null +++ b/Scripts/Provider.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f97c4baef5802554f8d176a9418054c3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Provision.meta b/Scripts/Provision.meta new file mode 100644 index 0000000..0d00828 --- /dev/null +++ b/Scripts/Provision.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2bd6dc3b115afc14e897ded81e3c0b94 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Provision/FieldProvider.cs.meta b/Scripts/Provision/FieldProvider.cs.meta new file mode 100644 index 0000000..7e61be0 --- /dev/null +++ b/Scripts/Provision/FieldProvider.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b1f39bd996934404cbc290bfe74700c0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Provision/IProvider.cs.meta b/Scripts/Provision/IProvider.cs.meta new file mode 100644 index 0000000..cdf3e09 --- /dev/null +++ b/Scripts/Provision/IProvider.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ec743d3e5b77b5a48acc97a6729c8a27 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Provision/InstanceProvider.cs.meta b/Scripts/Provision/InstanceProvider.cs.meta new file mode 100644 index 0000000..c170c24 --- /dev/null +++ b/Scripts/Provision/InstanceProvider.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f6b9124418a51c040be96ee46c71f42f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Provision/PropertyProvider.cs.meta b/Scripts/Provision/PropertyProvider.cs.meta new file mode 100644 index 0000000..b3dcee7 --- /dev/null +++ b/Scripts/Provision/PropertyProvider.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7581aad568af1df40a4ca9c7fb790c61 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Provision/ProviderFactory.cs.meta b/Scripts/Provision/ProviderFactory.cs.meta new file mode 100644 index 0000000..e38830d --- /dev/null +++ b/Scripts/Provision/ProviderFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f0fc27a24e626624ea90cdd98c0cdda7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Provision/SingletonProvider.cs.meta b/Scripts/Provision/SingletonProvider.cs.meta new file mode 100644 index 0000000..5db9ebf --- /dev/null +++ b/Scripts/Provision/SingletonProvider.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c2e8e14363a960446ac3e4d134cfe2dc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Reflection.meta b/Scripts/Reflection.meta new file mode 100644 index 0000000..65b52b1 --- /dev/null +++ b/Scripts/Reflection.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7f3e778f8f4b7dd41b42c0633873eb24 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Reflection/AttributeCache.cs.meta b/Scripts/Reflection/AttributeCache.cs.meta new file mode 100644 index 0000000..1b04f8e --- /dev/null +++ b/Scripts/Reflection/AttributeCache.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bad226ffc52495c4bbc01b6b00ab8ce2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Reflection/MemberEvaluator.cs.meta b/Scripts/Reflection/MemberEvaluator.cs.meta new file mode 100644 index 0000000..eaf7310 --- /dev/null +++ b/Scripts/Reflection/MemberEvaluator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6b997a4547e70074da125a9e9c70f856 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Resolvers.meta b/Scripts/Resolvers.meta new file mode 100644 index 0000000..1dfd3d8 --- /dev/null +++ b/Scripts/Resolvers.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d28388f2148b0e04fbf84cfc645977f4 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Resolvers/AnimatorStringHashResolver.cs.meta b/Scripts/Resolvers/AnimatorStringHashResolver.cs.meta new file mode 100644 index 0000000..4b88f70 --- /dev/null +++ b/Scripts/Resolvers/AnimatorStringHashResolver.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7d5f56b1f065aeb4a908a2a920b6c2cf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Resolvers/FindObjectOfTypeResolver.cs.meta b/Scripts/Resolvers/FindObjectOfTypeResolver.cs.meta new file mode 100644 index 0000000..44c474e --- /dev/null +++ b/Scripts/Resolvers/FindObjectOfTypeResolver.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e8da5e536257d4946951c5dce792c5f5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Resolvers/FindRelativeResolver.cs.meta b/Scripts/Resolvers/FindRelativeResolver.cs.meta new file mode 100644 index 0000000..cad493c --- /dev/null +++ b/Scripts/Resolvers/FindRelativeResolver.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 740a5213388d19b49855f4d8a09aa3bf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Resolvers/FindResolver.cs.meta b/Scripts/Resolvers/FindResolver.cs.meta new file mode 100644 index 0000000..ae64e30 --- /dev/null +++ b/Scripts/Resolvers/FindResolver.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f83727cb8853a7644b4df620aadda3cb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Resolvers/FindResourceOfTypeResolver.cs.meta b/Scripts/Resolvers/FindResourceOfTypeResolver.cs.meta new file mode 100644 index 0000000..58b7a14 --- /dev/null +++ b/Scripts/Resolvers/FindResourceOfTypeResolver.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 928083eac9f04a1478bc96c2226d61b6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Resolvers/FindWithTagResolver.cs.meta b/Scripts/Resolvers/FindWithTagResolver.cs.meta new file mode 100644 index 0000000..df3ebe2 --- /dev/null +++ b/Scripts/Resolvers/FindWithTagResolver.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 014187a53a79b0749b8854cfce65fc50 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Resolvers/GetComponentInChildrenResolver.cs.meta b/Scripts/Resolvers/GetComponentInChildrenResolver.cs.meta new file mode 100644 index 0000000..6eac8a2 --- /dev/null +++ b/Scripts/Resolvers/GetComponentInChildrenResolver.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2025d6fd8563e7b47ac074cb60cdf35c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Resolvers/GetComponentResolver.cs.meta b/Scripts/Resolvers/GetComponentResolver.cs.meta new file mode 100644 index 0000000..a00f7f5 --- /dev/null +++ b/Scripts/Resolvers/GetComponentResolver.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2f7ba3879de00784db3b136d340f1d95 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Resolvers/IResolver.cs.meta b/Scripts/Resolvers/IResolver.cs.meta new file mode 100644 index 0000000..86c58aa --- /dev/null +++ b/Scripts/Resolvers/IResolver.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 10393f4df76a26d4fb10d72847c66a6d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Resolvers/ResolverGroups.cs.meta b/Scripts/Resolvers/ResolverGroups.cs.meta new file mode 100644 index 0000000..b0033d9 --- /dev/null +++ b/Scripts/Resolvers/ResolverGroups.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9b2e9ddd0a5e222479161d24e2a614ae +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/RuntimeInjectableMonoBehaviour.cs.meta b/Scripts/RuntimeInjectableMonoBehaviour.cs.meta new file mode 100644 index 0000000..5d221b1 --- /dev/null +++ b/Scripts/RuntimeInjectableMonoBehaviour.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fb5a8729786a7e34a85cc670d6ee9c0b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/SceneInjector.cs.meta b/Scripts/SceneInjector.cs.meta new file mode 100644 index 0000000..8eb6506 --- /dev/null +++ b/Scripts/SceneInjector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bd4ecc5db53680241ac45a4dc6c3c13f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: -1200 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/TransformExtensions.cs.meta b/Scripts/TransformExtensions.cs.meta new file mode 100644 index 0000000..05a7453 --- /dev/null +++ b/Scripts/TransformExtensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f7e018de6222cab418d1059180e82b02 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/package.json.meta b/Scripts/package.json.meta new file mode 100644 index 0000000..0f22341 --- /dev/null +++ b/Scripts/package.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 288cf311b0fe14d4eb70ff9baf5c6aca +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/Editor.meta b/Tests/Editor.meta new file mode 100644 index 0000000..2e2a0ae --- /dev/null +++ b/Tests/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e8591f946c81ecd47bafbe7a9a1e72f3 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/TestScene.unity.meta b/Tests/TestScene.unity.meta new file mode 100644 index 0000000..e3aedfe --- /dev/null +++ b/Tests/TestScene.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 9c3ee56897ed11440af8881d4cdb5904 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/TestSceneSettings.lighting b/Tests/TestSceneSettings.lighting new file mode 100644 index 0000000..40bafca --- /dev/null +++ b/Tests/TestSceneSettings.lighting @@ -0,0 +1,63 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!850595691 &4890085278179872738 +LightingSettings: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: TestSceneSettings + serializedVersion: 3 + m_GIWorkflowMode: 1 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 1 + m_RealtimeEnvironmentLighting: 1 + m_BounceScale: 1 + m_AlbedoBoost: 1 + m_IndirectOutputScale: 1 + m_UsingShadowmask: 0 + m_BakeBackend: 0 + m_LightmapMaxSize: 1024 + m_BakeResolution: 40 + m_Padding: 2 + m_TextureCompression: 1 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 0 + m_CompAOExponentDirect: 0 + m_ExtractAO: 0 + m_MixedBakeMode: 1 + m_LightmapsBakeMode: 1 + m_FilterMode: 1 + m_LightmapParameters: {fileID: 15204, guid: 0000000000000000f000000000000000, type: 0} + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_RealtimeResolution: 2 + m_ForceWhiteAlbedo: 0 + m_ForceUpdates: 0 + m_FinalGather: 0 + m_FinalGatherRayCount: 1024 + m_FinalGatherFiltering: 1 + m_PVRCulling: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 512 + m_PVREnvironmentSampleCount: 512 + m_PVREnvironmentReferencePointCount: 2048 + m_LightProbeSampleCountMultiplier: 4 + m_PVRBounces: 2 + m_PVRMinBounces: 2 + m_PVREnvironmentMIS: 0 + m_PVRFilteringMode: 0 + m_PVRDenoiserTypeDirect: 0 + m_PVRDenoiserTypeIndirect: 0 + m_PVRDenoiserTypeAO: 0 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 diff --git a/Tests/TestSceneSettings.lighting.meta b/Tests/TestSceneSettings.lighting.meta new file mode 100644 index 0000000..b468cd0 --- /dev/null +++ b/Tests/TestSceneSettings.lighting.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 05f0adc9246948640a45193b9fdf016b +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 4890085278179872738 + userData: + assetBundleName: + assetBundleVariant: From bf1f36c6c75767da85adeb4be9eba8421f1770c6 Mon Sep 17 00:00:00 2001 From: Breno Azevedo Date: Tue, 19 Oct 2021 13:03:39 -0300 Subject: [PATCH 10/12] * Fixed issue with FindResourceOfType on first run of the Project --- Scripts/Resolvers/FindResourceOfTypeResolver.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Scripts/Resolvers/FindResourceOfTypeResolver.cs b/Scripts/Resolvers/FindResourceOfTypeResolver.cs index e5c4192..08beb6e 100644 --- a/Scripts/Resolvers/FindResourceOfTypeResolver.cs +++ b/Scripts/Resolvers/FindResourceOfTypeResolver.cs @@ -11,13 +11,14 @@ public object Resolve(Injectable injectable) var attribute = (FindResourceOfTypeAttribute)injectable.Attribute; if (attribute.ComponentType == null) { - var resources = Resources.FindObjectsOfTypeAll(injectable.Type); + //var resources = Resources.FindObjectsOfTypeAll(injectable.Type); + var resources = Resources.LoadAll("", injectable.Type); return resources?[0]; } else { - var resources = Resources.FindObjectsOfTypeAll(attribute.ComponentType); - // var resources = Resources.LoadAll("", attribute.ComponentType).ToArray(); + //var resources = Resources.FindObjectsOfTypeAll(attribute.ComponentType); + var resources = Resources.LoadAll("", attribute.ComponentType); //.ToArray(); return resources?[0]; } } From b2129000da83dc77ab452f31fef577b22516723d Mon Sep 17 00:00:00 2001 From: Breno Azevedo Date: Sun, 8 Sep 2024 14:51:30 -0300 Subject: [PATCH 11/12] * Minor updates to add support for Unity 6 --- Scripts/Resolvers/FindObjectOfTypeResolver.cs | 14 +++++++++++--- Scripts/SceneInjector.cs | 4 ++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Scripts/Resolvers/FindObjectOfTypeResolver.cs b/Scripts/Resolvers/FindObjectOfTypeResolver.cs index 901b496..534249f 100644 --- a/Scripts/Resolvers/FindObjectOfTypeResolver.cs +++ b/Scripts/Resolvers/FindObjectOfTypeResolver.cs @@ -11,12 +11,20 @@ public object Resolve(Injectable injectable) var attribute = (FindObjectOfTypeAttribute)injectable.Attribute; if (attribute.ComponentType == null) { +#if UNITY_5 return Object.FindObjectOfType(injectable.Type); +#else + return Object.FindFirstObjectByType(injectable.Type, FindObjectsInactive.Exclude); +#endif } - else - { + // else + // { +#if UNITY_5 return Object.FindObjectOfType(attribute.ComponentType); - } +#else + return Object.FindFirstObjectByType(attribute.ComponentType, FindObjectsInactive.Exclude); +#endif + // } } } } \ No newline at end of file diff --git a/Scripts/SceneInjector.cs b/Scripts/SceneInjector.cs index 919e9f4..b83ec89 100644 --- a/Scripts/SceneInjector.cs +++ b/Scripts/SceneInjector.cs @@ -34,7 +34,11 @@ public void InjectScene() private MonoBehaviour[] GetAllBehavioursInScene() { +#if UNITY_5 return GameObject.FindObjectsOfType(); +#else + return GameObject.FindObjectsByType(FindObjectsSortMode.None); +#endif } private void InjectBehaviours(MonoBehaviour[] behaviours) From 0e96e6f6f770b0e72bf5e491aacfc5d0d0144b21 Mon Sep 17 00:00:00 2001 From: Breno Azevedo Date: Sun, 6 Apr 2025 23:43:01 -0300 Subject: [PATCH 12/12] * Fixed execution order of InjectorComponent * SceneInjector --- Scripts/InjectorComponent.cs.meta | 2 +- Scripts/SceneInjector.cs.meta | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Scripts/InjectorComponent.cs.meta b/Scripts/InjectorComponent.cs.meta index 158e7e4..6905b54 100644 --- a/Scripts/InjectorComponent.cs.meta +++ b/Scripts/InjectorComponent.cs.meta @@ -4,7 +4,7 @@ MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] - executionOrder: -1100 + executionOrder: -10100 icon: {instanceID: 0} userData: assetBundleName: diff --git a/Scripts/SceneInjector.cs.meta b/Scripts/SceneInjector.cs.meta index 8eb6506..4ed7b01 100644 --- a/Scripts/SceneInjector.cs.meta +++ b/Scripts/SceneInjector.cs.meta @@ -4,7 +4,7 @@ MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] - executionOrder: -1200 + executionOrder: -10200 icon: {instanceID: 0} userData: assetBundleName: