diff --git a/.gitignore b/.gitignore index 48c8a34..dac3cce 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +# Godot 4+ specific ignores +.godot/ + # Godot-specific ignores .import/ export.cfg @@ -7,6 +10,9 @@ export_presets.cfg .mono/ data_*/ +# IntelliJ +.idea/ + # VSCode Settings .vscode/ @@ -21,4 +27,7 @@ obj/ # Tests tests/results.xml -tests/metadata.json \ No newline at end of file +tests/metadata.json + +# MacOS +.DS_Store diff --git a/GDTask.csproj b/GDTask.csproj index a618bdc..c09c73c 100644 --- a/GDTask.csproj +++ b/GDTask.csproj @@ -1,6 +1,7 @@ -<Project Sdk="Godot.NET.Sdk/3.3.0"> +<Project Sdk="Godot.NET.Sdk/4.0.0"> <PropertyGroup> - <TargetFramework>net472</TargetFramework> + <TargetFramework>net6.0</TargetFramework> + <EnableDynamicLoading>true</EnableDynamicLoading> </PropertyGroup> <ItemGroup> <Folder Include="tests\manual\" /> diff --git a/README.md b/README.md index f4497d9..a078339 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ # GDTask ✅ -![Deploy](https://github.com/Fractural/GDTask/actions/workflows/deploy.yml/badge.svg) ![Unit Tests](https://github.com/Fractural/GDTask/actions/workflows/tests.yml/badge.svg) +> **NOTE:** +> +> This branch is for the Godot 4.x version of the addon. +> You can download the Godot 3.x version from the main branch. Adds async/await features in Godot for easier async coding. Based on code from [Cysharp's UniTask library for Unity](https://github.com/Cysharp/UniTask). @@ -10,50 +13,50 @@ using Fractural.Tasks; public Test : Node { - public override _Ready() - { - // Running a task from a non-async method - Run().Forget(); - } - - public async GDTaskVoid Run() - { - await GDTask.DelayFrame(100); - - // waiting some amount of time - await GDTask.Delay(TimeSpan.FromSeconds(10)); - - // Waiting a single frame - await GDTask.Yield(); - await GDTask.NextFrame(); - await GDTask.WaitForEndOfFrame(); - - // Waiting for specific lifetime call - await GDTask.WaitForPhysicsProcess(); - - // Cancellation - var cts = new CancellationTokenSource(); - CancellableReallyLongTask(cts.Token).Forget(); - await GDTask.Delay(TimeSpan.FromSeconds(3)); - cts.Cancel(); - - // Async await with return value - string result = await RunWithResult(); - return result + " with additional text"; - } - - public async GDTask<string> RunWithResult() - { - await GDTask.Delay(TimeSpan.FromSeconds(3)); - return "A result string"; - } - - public async GDTaskVoid ReallyLongTask(CancellationToken cancellationToken) - { - GD.Print("Starting long task."); - await GDTask.Delay(TimeSpan.FromSeconds(1000000), cancellationToken: cancellationToken); - GD.Print("Finished long task."); - } + public override _Ready() + { + // Running a task from a non-async method + Run().Forget(); + } + + public async GDTaskVoid Run() + { + await GDTask.DelayFrame(100); + + // waiting some amount of time + await GDTask.Delay(TimeSpan.FromSeconds(10)); + + // Waiting a single frame + await GDTask.Yield(); + await GDTask.NextFrame(); + await GDTask.WaitForEndOfFrame(); + + // Waiting for specific lifetime call + await GDTask.WaitForPhysicsProcess(); + + // Cancellation + var cts = new CancellationTokenSource(); + CancellableReallyLongTask(cts.Token).Forget(); + await GDTask.Delay(TimeSpan.FromSeconds(3)); + cts.Cancel(); + + // Async await with return value + string result = await RunWithResult(); + return result + " with additional text"; + } + + public async GDTask<string> RunWithResult() + { + await GDTask.Delay(TimeSpan.FromSeconds(3)); + return "A result string"; + } + + public async GDTaskVoid ReallyLongTask(CancellationToken cancellationToken) + { + GD.Print("Starting long task."); + await GDTask.Delay(TimeSpan.FromSeconds(1000000), cancellationToken: cancellationToken); + GD.Print("Finished long task."); + } } ``` @@ -73,4 +76,4 @@ Git Submodules git submodule add -b release https://github.com/fractural/GDTask.git addons/GDTask ``` -3. Add `addons/GDTask/Autoload/GDTaskPlayerLoopAutoload` as an autoload \ No newline at end of file +3. Add `addons/GDTask/Autoload/GDTaskPlayerLoopAutoload` as an autoload diff --git a/addons/GDTask/AsyncLazy.cs b/addons/GDTask/AsyncLazy.cs index b963bff..e072998 100644 --- a/addons/GDTask/AsyncLazy.cs +++ b/addons/GDTask/AsyncLazy.cs @@ -3,7 +3,7 @@ namespace Fractural.Tasks { - public class AsyncLazy + public partial class AsyncLazy { static Action<object> continuation = SetCompletionSource; @@ -122,7 +122,7 @@ static void SetCompletionSource(object state) } } - public class AsyncLazy<T> + public partial class AsyncLazy<T> { static Action<object> continuation = SetCompletionSource; diff --git a/addons/GDTask/Autoload/GDTaskPlayerLoopAutoload.cs b/addons/GDTask/Autoload/GDTaskPlayerLoopAutoload.cs index c5318c1..289308c 100644 --- a/addons/GDTask/Autoload/GDTaskPlayerLoopAutoload.cs +++ b/addons/GDTask/Autoload/GDTaskPlayerLoopAutoload.cs @@ -51,7 +51,7 @@ public interface IPlayerLoopItem /// <summary> /// Singleton that forwards Godot calls and values to GDTasks. /// </summary> - public class GDTaskPlayerLoopAutoload : Node + public partial class GDTaskPlayerLoopAutoload : Node { public static int MainThreadId => Global.mainThreadId; public static bool IsMainThread => System.Threading.Thread.CurrentThread.ManagedThreadId == Global.mainThreadId; @@ -81,8 +81,8 @@ public void LocalAddContinuation(PlayerLoopTiming timing, Action continuation) } public static GDTaskPlayerLoopAutoload Global { get; private set; } - public float DeltaTime => GetProcessDeltaTime(); - public float PhysicsDeltaTime => GetPhysicsProcessDeltaTime(); + public double DeltaTime => GetProcessDeltaTime(); + public double PhysicsDeltaTime => GetPhysicsProcessDeltaTime(); private int mainThreadId; private ContinuationQueue[] yielders; @@ -124,13 +124,13 @@ public override void _Notification(int what) } } - public override void _Process(float delta) + public override void _Process(double delta) { yielders[(int) PlayerLoopTiming.Process].Run(); runners[(int) PlayerLoopTiming.Process].Run(); } - public override void _PhysicsProcess(float delta) + public override void _PhysicsProcess(double delta) { yielders[(int) PlayerLoopTiming.PhysicsProcess].Run(); runners[(int) PlayerLoopTiming.PhysicsProcess].Run(); diff --git a/addons/GDTask/CancellationTokenEqualityComparer.cs b/addons/GDTask/CancellationTokenEqualityComparer.cs index 9db20d6..594b74e 100644 --- a/addons/GDTask/CancellationTokenEqualityComparer.cs +++ b/addons/GDTask/CancellationTokenEqualityComparer.cs @@ -1,9 +1,9 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Threading; namespace Fractural.Tasks { - public class CancellationTokenEqualityComparer : IEqualityComparer<CancellationToken> + public partial class CancellationTokenEqualityComparer : IEqualityComparer<CancellationToken> { public static readonly IEqualityComparer<CancellationToken> Default = new CancellationTokenEqualityComparer(); diff --git a/addons/GDTask/GDTask.Delay.cs b/addons/GDTask/GDTask.Delay.cs index 1d2ac95..f7de42f 100644 --- a/addons/GDTask/GDTask.Delay.cs +++ b/addons/GDTask/GDTask.Delay.cs @@ -133,7 +133,7 @@ public static GDTask WaitForPhysicsProcess(CancellationToken cancellationToken) #if DEBUG // force use Realtime. - if (GDTaskPlayerLoopAutoload.IsMainThread && Engine.EditorHint) + if (GDTaskPlayerLoopAutoload.IsMainThread && Engine.IsEditorHint()) { delayType = DelayType.Realtime; } @@ -431,7 +431,7 @@ public bool MoveNext() { #if DEBUG // force use Realtime. - if (GDTaskPlayerLoopAutoload.IsMainThread && Engine.EditorHint) + if (GDTaskPlayerLoopAutoload.IsMainThread && Engine.IsEditorHint()) { //goto ++currentFrameCount } @@ -477,8 +477,8 @@ static DelayPromise() } int initialFrame; - float delayTimeSpan; - float elapsed; + double delayTimeSpan; + double elapsed; CancellationToken cancellationToken; GDTaskCompletionSourceCore<object> core; diff --git a/addons/GDTask/GDTask.WaitUntil.cs b/addons/GDTask/GDTask.WaitUntil.cs index 90f06f9..ab9a048 100644 --- a/addons/GDTask/GDTask.WaitUntil.cs +++ b/addons/GDTask/GDTask.WaitUntil.cs @@ -25,7 +25,7 @@ public static GDTask WaitUntilCanceled(CancellationToken cancellationToken, Play public static GDTask<U> WaitUntilValueChanged<T, U>(T target, Func<T, U> monitorFunction, PlayerLoopTiming monitorTiming = PlayerLoopTiming.Process, IEqualityComparer<U> equalityComparer = null, CancellationToken cancellationToken = default(CancellationToken)) where T : class { - var isGodotObject = target is Godot.Object; // don't use (unityObject == null) + var isGodotObject = target is Godot.GodotObject; // don't use (unityObject == null) return new GDTask<U>(isGodotObject ? WaitUntilValueChangedGodotObjectPromise<T, U>.Create(target, monitorFunction, equalityComparer, monitorTiming, cancellationToken, out var token) @@ -343,7 +343,7 @@ static WaitUntilValueChangedGodotObjectPromise() } T target; - Godot.Object targetAsGodotObject; + Godot.GodotObject targetAsGodotObject; U currentValue; Func<T, U> monitorFunction; IEqualityComparer<U> equalityComparer; @@ -368,7 +368,7 @@ public static IGDTaskSource<U> Create(T target, Func<T, U> monitorFunction, IEqu } result.target = target; - result.targetAsGodotObject = target as Godot.Object; + result.targetAsGodotObject = target as Godot.GodotObject; result.monitorFunction = monitorFunction; result.currentValue = monitorFunction(target); result.equalityComparer = equalityComparer ?? GodotEqualityComparer.GetDefault<U>(); diff --git a/addons/GDTask/GDTaskCompletionSource.cs b/addons/GDTask/GDTaskCompletionSource.cs index 863dc00..6cd0e1d 100644 --- a/addons/GDTask/GDTaskCompletionSource.cs +++ b/addons/GDTask/GDTaskCompletionSource.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Diagnostics; using System.Runtime.CompilerServices; @@ -314,7 +314,7 @@ private static void CompletionSentinel(object _) // named method to aid debuggin } } - public class AutoResetGDTaskCompletionSource : IGDTaskSource, ITaskPoolNode<AutoResetGDTaskCompletionSource>, IPromise + public partial class AutoResetGDTaskCompletionSource : IGDTaskSource, ITaskPoolNode<AutoResetGDTaskCompletionSource>, IPromise { static TaskPool<AutoResetGDTaskCompletionSource> pool; AutoResetGDTaskCompletionSource nextNode; @@ -437,7 +437,7 @@ bool TryReturn() } } - public class AutoResetGDTaskCompletionSource<T> : IGDTaskSource<T>, ITaskPoolNode<AutoResetGDTaskCompletionSource<T>>, IPromise<T> + public partial class AutoResetGDTaskCompletionSource<T> : IGDTaskSource<T>, ITaskPoolNode<AutoResetGDTaskCompletionSource<T>>, IPromise<T> { static TaskPool<AutoResetGDTaskCompletionSource<T>> pool; AutoResetGDTaskCompletionSource<T> nextNode; @@ -565,7 +565,7 @@ bool TryReturn() } } - public class GDTaskCompletionSource : IGDTaskSource, IPromise + public partial class GDTaskCompletionSource : IGDTaskSource, IPromise { CancellationToken cancellationToken; ExceptionHolder exception; @@ -746,7 +746,7 @@ bool TrySignalCompletion(GDTaskStatus status) } } - public class GDTaskCompletionSource<T> : IGDTaskSource<T>, IPromise<T> + public partial class GDTaskCompletionSource<T> : IGDTaskSource<T>, IPromise<T> { CancellationToken cancellationToken; T result; diff --git a/addons/GDTask/GDTaskSynchronizationContext.cs b/addons/GDTask/GDTaskSynchronizationContext.cs index 3ef3646..16ed2f2 100644 --- a/addons/GDTask/GDTaskSynchronizationContext.cs +++ b/addons/GDTask/GDTaskSynchronizationContext.cs @@ -1,11 +1,11 @@ -using Godot; +using Godot; using System; using System.Runtime.InteropServices; using System.Threading; namespace Fractural.Tasks { - public class GDTaskSynchronizationContext : SynchronizationContext + public partial class GDTaskSynchronizationContext : SynchronizationContext { const int MaxArrayLength = 0X7FEFFFFF; const int InitialSize = 16; diff --git a/addons/GDTask/Internal/GodotEqualityComparer.cs b/addons/GDTask/Internal/GodotEqualityComparer.cs index 16a2560..68ab6ed 100644 --- a/addons/GDTask/Internal/GodotEqualityComparer.cs +++ b/addons/GDTask/Internal/GodotEqualityComparer.cs @@ -10,15 +10,15 @@ internal static class GodotEqualityComparer public static readonly IEqualityComparer<Vector3> Vector3 = new Vector3EqualityComparer(); public static readonly IEqualityComparer<Color> Color = new ColorEqualityComparer(); public static readonly IEqualityComparer<Rect2> Rect2 = new Rect2EqualityComparer(); - public static readonly IEqualityComparer<AABB> AABB = new AABBEqualityComparer(); - public static readonly IEqualityComparer<Quat> Quat = new QuatEqualityComparer(); + public static readonly IEqualityComparer<Aabb> AABB = new AABBEqualityComparer(); + public static readonly IEqualityComparer<Quaternion> Quaternion = new QuatEqualityComparer(); static readonly RuntimeTypeHandle vector2Type = typeof(Vector2).TypeHandle; static readonly RuntimeTypeHandle vector3Type = typeof(Vector3).TypeHandle; static readonly RuntimeTypeHandle colorType = typeof(Color).TypeHandle; static readonly RuntimeTypeHandle rectType = typeof(Rect2).TypeHandle; - static readonly RuntimeTypeHandle AABBType = typeof(AABB).TypeHandle; - static readonly RuntimeTypeHandle quaternionType = typeof(Quat).TypeHandle; + static readonly RuntimeTypeHandle AABBType = typeof(Aabb).TypeHandle; + static readonly RuntimeTypeHandle quaternionType = typeof(Quaternion).TypeHandle; static class Cache<T> { @@ -52,7 +52,7 @@ static object GetDefaultHelper(Type type) if (t.Equals(colorType)) return (object)GodotEqualityComparer.Color; if (t.Equals(rectType)) return (object)GodotEqualityComparer.Rect2; if (t.Equals(AABBType)) return (object)GodotEqualityComparer.AABB; - if (t.Equals(quaternionType)) return (object)GodotEqualityComparer.Quat; + if (t.Equals(quaternionType)) return (object)GodotEqualityComparer.Quaternion; return null; } @@ -61,12 +61,12 @@ sealed class Vector2EqualityComparer : IEqualityComparer<Vector2> { public bool Equals(Vector2 self, Vector2 vector) { - return self.x.Equals(vector.x) && self.y.Equals(vector.y); + return self.X.Equals(vector.X) && self.Y.Equals(vector.Y); } public int GetHashCode(Vector2 obj) { - return obj.x.GetHashCode() ^ obj.y.GetHashCode() << 2; + return obj.X.GetHashCode() ^ obj.Y.GetHashCode() << 2; } } @@ -74,12 +74,12 @@ sealed class Vector3EqualityComparer : IEqualityComparer<Vector3> { public bool Equals(Vector3 self, Vector3 vector) { - return self.x.Equals(vector.x) && self.y.Equals(vector.y) && self.z.Equals(vector.z); + return self.X.Equals(vector.X) && self.Y.Equals(vector.Y) && self.Z.Equals(vector.Z); } public int GetHashCode(Vector3 obj) { - return obj.x.GetHashCode() ^ obj.y.GetHashCode() << 2 ^ obj.z.GetHashCode() >> 2; + return obj.X.GetHashCode() ^ obj.Y.GetHashCode() << 2 ^ obj.Z.GetHashCode() >> 2; } } @@ -87,12 +87,12 @@ sealed class ColorEqualityComparer : IEqualityComparer<Color> { public bool Equals(Color self, Color other) { - return self.r.Equals(other.r) && self.g.Equals(other.g) && self.b.Equals(other.b) && self.a.Equals(other.a); + return self.R.Equals(other.R) && self.G.Equals(other.G) && self.B.Equals(other.B) && self.A.Equals(other.A); } public int GetHashCode(Color obj) { - return obj.r.GetHashCode() ^ obj.g.GetHashCode() << 2 ^ obj.b.GetHashCode() >> 2 ^ obj.a.GetHashCode() >> 1; + return obj.R.GetHashCode() ^ obj.G.GetHashCode() << 2 ^ obj.B.GetHashCode() >> 2 ^ obj.A.GetHashCode() >> 1; } } @@ -109,29 +109,29 @@ public int GetHashCode(Rect2 obj) } } - sealed class AABBEqualityComparer : IEqualityComparer<AABB> + sealed class AABBEqualityComparer : IEqualityComparer<Aabb> { - public bool Equals(AABB self, AABB vector) + public bool Equals(Aabb self, Aabb vector) { return self.Position.Equals(vector.Position) && self.Size.Equals(vector.Size); } - public int GetHashCode(AABB obj) + public int GetHashCode(Aabb obj) { return obj.Position.GetHashCode() ^ obj.Size.GetHashCode() << 2; } } - sealed class QuatEqualityComparer : IEqualityComparer<Quat> + sealed class QuatEqualityComparer : IEqualityComparer<Quaternion> { - public bool Equals(Quat self, Quat vector) + public bool Equals(Quaternion self, Quaternion vector) { - return self.x.Equals(vector.x) && self.y.Equals(vector.y) && self.z.Equals(vector.z) && self.w.Equals(vector.w); + return self.X.Equals(vector.X) && self.Y.Equals(vector.Y) && self.Z.Equals(vector.Z) && self.W.Equals(vector.W); } - public int GetHashCode(Quat obj) + public int GetHashCode(Quaternion obj) { - return obj.x.GetHashCode() ^ obj.y.GetHashCode() << 2 ^ obj.z.GetHashCode() >> 2 ^ obj.w.GetHashCode() >> 1; + return obj.X.GetHashCode() ^ obj.Y.GetHashCode() << 2 ^ obj.Z.GetHashCode() >> 2 ^ obj.W.GetHashCode() >> 1; } } } diff --git a/addons/GDTask/Internal/RuntimeHelpersAbstraction.cs b/addons/GDTask/Internal/RuntimeHelpersAbstraction.cs index 96f3f85..b3ec36c 100644 --- a/addons/GDTask/Internal/RuntimeHelpersAbstraction.cs +++ b/addons/GDTask/Internal/RuntimeHelpersAbstraction.cs @@ -33,8 +33,8 @@ static bool WellKnownNoReferenceContainsTypeInitialize(Type t) if (t == typeof(Vector3)) return true; if (t == typeof(Color)) return true; if (t == typeof(Rect2)) return true; - if (t == typeof(AABB)) return true; - if (t == typeof(Quat)) return true; + if (t == typeof(Aabb)) return true; + if (t == typeof(Quaternion)) return true; return false; } diff --git a/addons/GDTask/PlayerLoopTimer.cs b/addons/GDTask/PlayerLoopTimer.cs index df42c91..e91a424 100644 --- a/addons/GDTask/PlayerLoopTimer.cs +++ b/addons/GDTask/PlayerLoopTimer.cs @@ -30,7 +30,7 @@ public static PlayerLoopTimer Create(TimeSpan interval, bool periodic, DelayType { #if DEBUG // force use Realtime. - if (GDTaskPlayerLoopAutoload.IsMainThread && Engine.EditorHint) + if (GDTaskPlayerLoopAutoload.IsMainThread && Engine.IsEditorHint()) { delayType = DelayType.Realtime; } @@ -143,8 +143,8 @@ bool IPlayerLoopItem.MoveNext() sealed class DeltaTimePlayerLoopTimer : PlayerLoopTimer { int initialFrame; - float elapsed; - float interval; + double elapsed; + double interval; public DeltaTimePlayerLoopTimer(TimeSpan interval, bool periodic, PlayerLoopTiming playerLoopTiming, CancellationToken cancellationToken, Action<object> timerCallback, object state) : base(periodic, playerLoopTiming, cancellationToken, timerCallback, state) @@ -154,7 +154,7 @@ public DeltaTimePlayerLoopTimer(TimeSpan interval, bool periodic, PlayerLoopTimi protected override bool MoveNextCore() { - if (elapsed == 0.0f) + if (elapsed == 0.0) { if (initialFrame == Engine.GetFramesDrawn()) { @@ -173,7 +173,7 @@ protected override bool MoveNextCore() protected override void ResetCore(TimeSpan? interval) { - this.elapsed = 0.0f; + this.elapsed = 0.0; this.initialFrame = GDTaskPlayerLoopAutoload.IsMainThread ? Engine.GetFramesDrawn() : -1; if (interval != null) { diff --git a/addons/GDTask/Triggers/AsyncDestroyTrigger.cs b/addons/GDTask/Triggers/AsyncDestroyTrigger.cs index 7f3c1c0..9973596 100644 --- a/addons/GDTask/Triggers/AsyncDestroyTrigger.cs +++ b/addons/GDTask/Triggers/AsyncDestroyTrigger.cs @@ -11,7 +11,7 @@ public static AsyncDestroyTrigger GetAsyncDestroyTrigger(this Node node) } } - public sealed class AsyncDestroyTrigger : Node + public sealed partial class AsyncDestroyTrigger : Node { bool awakeCalled = false; bool called = false; diff --git a/addons/GDTask/Triggers/AsyncEnterTreeTrigger.cs b/addons/GDTask/Triggers/AsyncEnterTreeTrigger.cs index 1f4feb0..97301a2 100644 --- a/addons/GDTask/Triggers/AsyncEnterTreeTrigger.cs +++ b/addons/GDTask/Triggers/AsyncEnterTreeTrigger.cs @@ -11,7 +11,7 @@ public static AsyncEnterTreeTrigger GetAsyncAwakeTrigger(this Node node) } } - public sealed class AsyncEnterTreeTrigger : AsyncTriggerBase<AsyncUnit> + public sealed partial class AsyncEnterTreeTrigger : AsyncTriggerBase<AsyncUnit> { public GDTask AwakeAsync() { diff --git a/addons/GDTask/Triggers/AsyncReadyTrigger.cs b/addons/GDTask/Triggers/AsyncReadyTrigger.cs index b02ae72..c0a2415 100644 --- a/addons/GDTask/Triggers/AsyncReadyTrigger.cs +++ b/addons/GDTask/Triggers/AsyncReadyTrigger.cs @@ -10,7 +10,7 @@ public static AsyncReadyTrigger GetAsyncStartTrigger(this Node node) } } - public sealed class AsyncReadyTrigger : AsyncTriggerBase<AsyncUnit> + public sealed partial class AsyncReadyTrigger : AsyncTriggerBase<AsyncUnit> { bool called; diff --git a/addons/GDTask/Triggers/AsyncTriggerBase.cs b/addons/GDTask/Triggers/AsyncTriggerBase.cs index 10ce828..4b5af21 100644 --- a/addons/GDTask/Triggers/AsyncTriggerBase.cs +++ b/addons/GDTask/Triggers/AsyncTriggerBase.cs @@ -4,7 +4,7 @@ namespace Fractural.Tasks.Triggers { - public abstract class AsyncTriggerBase<T> : Node + public abstract partial class AsyncTriggerBase<T> : Node { TriggerEvent<T> triggerEvent; diff --git a/addons/GDTask/Triggers/NodeMessagesTriggers.cs b/addons/GDTask/Triggers/NodeMessagesTriggers.cs index 5ff7bcd..76fb34e 100644 --- a/addons/GDTask/Triggers/NodeMessagesTriggers.cs +++ b/addons/GDTask/Triggers/NodeMessagesTriggers.cs @@ -27,9 +27,9 @@ public static AsyncPhysicsProcessTrigger GetAsyncPhysicsProcessTrigger(this Node } } - public sealed class AsyncPhysicsProcessTrigger : AsyncTriggerBase<AsyncUnit> + public sealed partial class AsyncPhysicsProcessTrigger : AsyncTriggerBase<AsyncUnit> { - public override void _PhysicsProcess(float delta) + public override void _PhysicsProcess(double delta) { RaiseEvent(AsyncUnit.Default); } @@ -80,9 +80,9 @@ public static AsyncProcessTrigger GetAsyncProcessTrigger(this Node node) } } - public sealed class AsyncProcessTrigger : AsyncTriggerBase<AsyncUnit> + public sealed partial class AsyncProcessTrigger : AsyncTriggerBase<AsyncUnit> { - public override void _Process(float delta) + public override void _Process(double delta) { RaiseEvent(AsyncUnit.Default); } diff --git a/addons/WAT/LICENSE b/addons/WAT/LICENSE deleted file mode 100644 index 6fadac8..0000000 --- a/addons/WAT/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2021 CodeDarigan - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/addons/WAT/assertions/.idea/.idea.assertions.dir/.idea/encodings.xml b/addons/WAT/assertions/.idea/.idea.assertions.dir/.idea/encodings.xml deleted file mode 100644 index df87cf9..0000000 --- a/addons/WAT/assertions/.idea/.idea.assertions.dir/.idea/encodings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project version="4"> - <component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" /> -</project> \ No newline at end of file diff --git a/addons/WAT/assertions/.idea/.idea.assertions.dir/.idea/indexLayout.xml b/addons/WAT/assertions/.idea/.idea.assertions.dir/.idea/indexLayout.xml deleted file mode 100644 index 5637d53..0000000 --- a/addons/WAT/assertions/.idea/.idea.assertions.dir/.idea/indexLayout.xml +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project version="4"> - <component name="WorkspaceUserModelUpdater"> - <attachedFolders /> - <explicitIncludes /> - <explicitExcludes /> - </component> -</project> \ No newline at end of file diff --git a/addons/WAT/assertions/.idea/.idea.assertions.dir/.idea/projectSettingsUpdater.xml b/addons/WAT/assertions/.idea/.idea.assertions.dir/.idea/projectSettingsUpdater.xml deleted file mode 100644 index 4bb9f4d..0000000 --- a/addons/WAT/assertions/.idea/.idea.assertions.dir/.idea/projectSettingsUpdater.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project version="4"> - <component name="RiderProjectSettingsUpdater"> - <option name="vcsConfiguration" value="2" /> - </component> -</project> \ No newline at end of file diff --git a/addons/WAT/assertions/.idea/.idea.assertions.dir/.idea/vcs.xml b/addons/WAT/assertions/.idea/.idea.assertions.dir/.idea/vcs.xml deleted file mode 100644 index 4fce1d8..0000000 --- a/addons/WAT/assertions/.idea/.idea.assertions.dir/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project version="4"> - <component name="VcsDirectoryMappings"> - <mapping directory="$PROJECT_DIR$/../../../.." vcs="Git" /> - </component> -</project> \ No newline at end of file diff --git a/addons/WAT/assertions/.idea/.idea.assertions.dir/.idea/workspace.xml b/addons/WAT/assertions/.idea/.idea.assertions.dir/.idea/workspace.xml deleted file mode 100644 index 7580d1f..0000000 --- a/addons/WAT/assertions/.idea/.idea.assertions.dir/.idea/workspace.xml +++ /dev/null @@ -1,45 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project version="4"> - <component name="ChangeListManager"> - <list default="true" id="c881f43a-de7c-4c5f-b572-be4420cfa3a0" name="Default Changelist" comment=""> - <change beforePath="$PROJECT_DIR$/../../assets/default_theme.tres" beforeDir="false" afterPath="$PROJECT_DIR$/../../assets/default_theme.tres" afterDir="false" /> - <change beforePath="$PROJECT_DIR$/assertions.gd" beforeDir="false" afterPath="$PROJECT_DIR$/assertions.gd" afterDir="false" /> - <change beforePath="$PROJECT_DIR$/collections.gd" beforeDir="false" afterPath="$PROJECT_DIR$/collections.gd" afterDir="false" /> - <change beforePath="$PROJECT_DIR$/string.gd" beforeDir="false" afterPath="$PROJECT_DIR$/string.gd" afterDir="false" /> - <change beforePath="$PROJECT_DIR$/../../gui.tscn" beforeDir="false" afterPath="$PROJECT_DIR$/../../gui.tscn" afterDir="false" /> - <change beforePath="$PROJECT_DIR$/../../../../tests/test_metadata.json" beforeDir="false" afterPath="$PROJECT_DIR$/../../../../tests/test_metadata.json" afterDir="false" /> - </list> - <option name="SHOW_DIALOG" value="false" /> - <option name="HIGHLIGHT_CONFLICTS" value="true" /> - <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" /> - <option name="LAST_RESOLUTION" value="IGNORE" /> - </component> - <component name="Git.Settings"> - <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/../../../.." /> - </component> - <component name="ProjectId" id="1p5Pntqzb2Cq9uStlVsxiI8GhG3" /> - <component name="ProjectLevelVcsManager" settingsEditedManually="true" /> - <component name="ProjectViewState"> - <option name="hideEmptyMiddlePackages" value="true" /> - <option name="showLibraryContents" value="true" /> - </component> - <component name="PropertiesComponent"> - <property name="RunOnceActivity.OpenProjectViewOnStart" value="true" /> - <property name="RunOnceActivity.ShowReadmeOnStart" value="true" /> - <property name="WebServerToolWindowFactoryState" value="false" /> - </component> - <component name="TaskManager"> - <task active="true" id="Default" summary="Default task"> - <created>1614470179608</created> - <option name="number" value="Default" /> - <option name="presentableId" value="Default" /> - <updated>1614470179608</updated> - <workItem from="1614470214513" duration="5000" /> - </task> - <servers /> - </component> - <component name="UnityUnitTestConfiguration" currentTestLauncher="NUnit" /> - <component name="VcsManagerConfiguration"> - <option name="CLEAR_INITIAL_COMMIT_MESSAGE" value="true" /> - </component> -</project> \ No newline at end of file diff --git a/addons/WAT/assertions/assertion.gd b/addons/WAT/assertions/assertion.gd deleted file mode 100644 index 75feeb4..0000000 --- a/addons/WAT/assertions/assertion.gd +++ /dev/null @@ -1,73 +0,0 @@ -extends Reference - -var success: bool -var expected: String = "NULL" -var result: String -var notes: String = "No Notes" -var context - -static func _result(success: bool, expected: String, actual: String, context: String, notes: String = "No Notes"): - return { - "success": success, - "expected": expected, - "actual": actual, - "context": context - } - -static func type2str(property) -> String: - match typeof(property): - TYPE_NIL: - return "null" - TYPE_BOOL: - return "bool" - TYPE_INT: - return "int" - TYPE_REAL: - return "float" - TYPE_STRING: - return "String" - TYPE_VECTOR2: - return "Vector2" - TYPE_RECT2: - return "Rect2" - TYPE_VECTOR3: - return "Vector3" - TYPE_TRANSFORM2D: - return "Transform2D" - TYPE_PLANE: - return "Plane" - TYPE_QUAT: - return "Quat" - TYPE_AABB: - return "AABB" - TYPE_BASIS: - return "Basis" - TYPE_TRANSFORM: - return "Transform" - TYPE_COLOR: - return "Color" - TYPE_NODE_PATH: - return "NodePath" - TYPE_RID: - return "RID" - TYPE_OBJECT: - return "Object" - TYPE_DICTIONARY: - return "Dictionary" - TYPE_ARRAY: - return "Array" - TYPE_RAW_ARRAY: - return "PoolByteArray" - TYPE_INT_ARRAY: - return "PoolIntArray" - TYPE_REAL_ARRAY: - return "PoolRealArray" - TYPE_STRING_ARRAY: - return "PoolStringArray" - TYPE_VECTOR2_ARRAY: - return "PoolVector2Array" - TYPE_VECTOR3_ARRAY: - return "PoolVector3Array" - TYPE_COLOR_ARRAY: - return "PoolColorArray" - return "OutOfBounds" diff --git a/addons/WAT/assertions/assertions.gd b/addons/WAT/assertions/assertions.gd deleted file mode 100644 index cfbd606..0000000 --- a/addons/WAT/assertions/assertions.gd +++ /dev/null @@ -1,342 +0,0 @@ -extends Object - -const Is: Script = preload("is.gd") -const IsNot: Script = preload("is_not.gd") -const Boolean: Script = preload("boolean.gd") -const Double: Script = preload("double.gd") -const Equality: Script = preload("equality.gd") -const FileX: Script = preload("file.gd") -const Folder: Script = preload("folder.gd") -const Null: Script = preload("null.gd") -const RangeX: Script = preload("range.gd") -const Signal: Script = preload("signal.gd") -const StringX: Script = preload("string.gd") -const Utility: Script = preload("utility.gd") -const Property: Script = preload("property.gd") -const ObjectX: Script = preload("object.gd") -const Collections: Script = preload("collections.gd") -signal asserted - -func output(data: Dictionary) -> void: - emit_signal("asserted", data) - -func is_true(condition: bool, context: String = "") -> void: - output(Boolean.is_true(condition, context)) - -func is_false(condition: bool, context: String = "") -> void: - output(Boolean.is_false(condition, context)) - -func is_equal(a, b, context: String = "") -> void: - output(Equality.is_equal(a, b, context)) - -func is_not_equal(a, b, context: String = "") -> void: - output(Equality.is_not_equal(a, b, context)) - -func is_greater_than(a, b, context: String = "") -> void: - output(Equality.is_greater_than(a, b, context)) - -func is_less_than(a, b, context: String = "") -> void: - output(Equality.is_less_than(a, b, context)) - -func is_equal_or_greater_than(a, b, context: String = "") -> void: - output(Equality.is_equal_or_greater_than(a, b, context)) - -func is_equal_or_less_than(a, b, context: String = "") -> void: - output(Equality.is_equal_or_less_than(a, b, context)) - -func is_equal_approx_(a, b, context: String = "") -> void: - output(Equality.is_equal_approx_(a, b, context)) - -func is_in_range(value, low, high, context: String = "") -> void: - output(RangeX.is_in_range(value, low, high, context)) - -func is_not_in_range(value, low, high, context: String = "") -> void: - output(RangeX.is_not_in_range(value, low, high, context)) - -func has(value, container, context: String = "") -> void: - output(Property.has(value, container, context)) - -func does_not_have(value, container, context: String = "") -> void: - output(Property.does_not_have(value, container, context)) - -func is_class_instance(instance, type, context: String = "") -> void: - output(Is.is_class_instance(instance, type, context)) - -func is_not_class_instance(instance, type, context: String = "") -> void: - output(Is.is_not_class_instance(instance, type, context)) - -func is_null(value, context: String = "") -> void: - output(Null.is_null(value, context)) - -func is_not_null(value, context: String = "") -> void: - output(Null.is_not_null(value, context)) - -func string_contains(value, string: String, context: String = "") -> void: - output(StringX.contains(value, string, context)) - -func string_does_not_contain(value, string: String, context: String = "") -> void: - output(StringX.does_not_contain(value, string, context)) - -func string_begins_with(value, string: String, context: String = "") -> void: - output(StringX.begins_with(value, string, context)) - -func string_does_not_begin_with(value, string: String, context: String = "") -> void: - output(StringX.does_not_begin_with(value, string, context)) - -func string_ends_with(value, string: String, context: String = "") -> void: - output(StringX.ends_with(value, string, context)) - -func string_does_not_end_with(value, string: String, context: String = "") -> void: - output(StringX.does_not_end_with(value, string, context)) - -func was_called(double, method: String, context: String = "") -> void: - output(Double.was_called(double, method, context)) - -func was_not_called(double, method: String, context: String = "") -> void: - output(Double.was_not_called(double, method, context)) - -func was_called_with_arguments(double, method: String, arguments: Array, context: String = "") -> void: - output(Double.called_with_arguments(double, method, arguments, context)) - -func signal_was_emitted(emitter, _signal, context: String = "") -> void: - output(Signal.was_emitted(emitter, _signal, context)) - -func signal_was_emitted_x_times(emitter, _signal, times: int, context: String = "") -> void: - output(Signal.was_emitted_x_times(emitter, _signal, times, context)) - -func signal_was_not_emitted(emitter, _signal: String, context: String = "") -> void: - output(Signal.was_not_emitted(emitter, _signal, context)) - -func signal_was_emitted_with_arguments(emitter, _signal, arguments: Array, context: String = "") -> void: - output(Signal.was_emitted_with_args(emitter, _signal, arguments, context)) - -func file_exists(path: String, context: String = "") -> void: - output(FileX.exists(path, context)) - -func file_does_not_exist(path: String, context: String = "") -> void: - output(FileX.does_not_exist(path, context)) - -func folder_exists(path: String, context: String = "") -> void: - output(Folder.exists(path, context)) - -func folder_does_not_exist(path: String, context: String = "") -> void: - output(Folder.does_not_exist(path, context)) - -func that(obj: Object, method: String, arguments: Array = [], context: String = "", passed: String = "", failed: String = "") -> void: - output(Utility.that(obj, method, arguments, context, passed, failed)) - -func is_valid_instance(obj: Object, context: String = "") -> void: - output(ObjectX.o_is_valid_instance(obj, context)) - -func is_not_valid_instance(obj: Object, context: String = "") -> void: - output(ObjectX.o_is_not_valid_instance(obj, context)) - -func object_has_meta(obj: Object, meta: String, context: String = "") -> void: - output(ObjectX.o_has_meta(obj, meta, context)) - -func object_does_not_have_meta(obj: Object, meta: String, context: String = "") -> void: - output(ObjectX.does_not_have_meta(obj, meta, context)) - -func object_has_method(obj: Object, method: String, context: String = "") -> void: - output(ObjectX.o_has_method(obj, method, context)) - -func object_does_not_have_method(obj: Object, method: String, context: String = "") -> void: - output(ObjectX.does_not_have_method(obj, method, context)) - -func object_is_queued_for_deletion(obj: Object, context: String = "") -> void: - output(ObjectX.o_is_queued_for_deletion(obj, context)) - -func object_is_not_queued_for_deletion(obj: Object, context: String = "") -> void: - output(ObjectX.o_is_not_queued_for_deletion(obj, context)) - -func object_is_connected(sender: Object, _signal: String, receiver: Object, method: String, context: String = "") -> void: - output(ObjectX.o_is_connected(sender, _signal, receiver, method, context)) - -func object_is_not_connected(sender: Object, _signal: String, receiver: Object, method: String, context: String = "") -> void: - output(ObjectX.o_is_not_connected(sender, _signal, receiver, method, context)) - -func object_is_blocking_signals(obj: Object, context: String = "") -> void: - output(ObjectX.o_is_blocking_signals(obj, context)) - -func object_is_not_blocking_signals(obj: Object, context: String = "") -> void: - output(ObjectX.o_is_not_blocking_signals(obj, context)) - -func object_has_user_signal(obj: Object, _signal: String, context: String = "") -> void: - output(ObjectX.o_has_user_signal(obj, _signal, context)) - -func object_does_not_have_user_signal(obj: Object, _signal: String, context: String = "") -> void: - output(ObjectX.does_not_have_user_signal(obj, _signal, context)) - -func is_freed(obj: Object, context: String = "") -> void: - output(ObjectX.o_is_freed(obj, context)) - -func is_not_freed(obj: Object, context: String = "") -> void: - output(ObjectX.o_is_not_freed(obj, context)) - -func is_empty(value, context: String = "") -> void: - if value is String: - output(StringX.is_empty(value, context)) - else: - output(Collections.is_empty(value, context)) - -func is_bool(value, context: String = "") -> void: - output(Is.is_bool(value, context)) - -func is_not_bool(value, context: String = "") -> void: - output(IsNot.is_not_bool(value, context)) - -func is_int(value, context: String = "") -> void: - output(Is.is_int(value, context)) - -func is_not_int(value, context: String = "") -> void: - output(IsNot.is_not_int(value, context)) - -func is_float(value, context: String = "") -> void: - output(Is.is_float(value, context)) - -func is_not_float(value, context: String = "") -> void: - output(IsNot.is_not_float(value, context)) - -func is_String(value, context: String = "") -> void: - output(Is.is_String(value, context)) - -func is_not_String(value, context: String = "") -> void: - output(IsNot.is_not_String(value, context)) - -func is_Vector2(value, context: String = "") -> void: - output(Is.is_Vector2(value, context)) - -func is_not_Vector2(value, context: String = "") -> void: - output(IsNot.is_not_Vector2(value, context)) - -func is_Rect2(value, context: String = "") -> void: - output(Is.is_Rect2(value, context)) - -func is_not_Rect2(value, context: String = "") -> void: - output(IsNot.is_not_Rect2(value, context)) - -func is_Vector3(value, context: String = "") -> void: - output(Is.is_Vector3(value, context)) - -func is_not_Vector3(value, context: String = "") -> void: - output(IsNot.is_not_Vector3(value, context)) - -func is_Transform2D(value, context: String = "") -> void: - output(Is.is_Transform2D(value, context)) - -func is_not_Transform2D(value, context: String = "") -> void: - output(IsNot.is_not_Transform2D(value, context)) - -func is_Plane(value, context: String = "") -> void: - output(Is.is_Plane(value, context)) - -func is_not_Plane(value, context: String = "") -> void: - output(IsNot.is_not_Plane(value, context)) - -func is_Quat(value, context: String = "") -> void: - output(Is.is_Quat(value, context)) - -func is_not_Quat(value, context: String = "") -> void: - output(IsNot.is_not_Quat(value, context)) - -func is_AABB(value, context: String = "") -> void: - output(Is.is_AABB(value, context)) - -func is_not_AABB(value, context: String = "") -> void: - output(IsNot.is_not_AABB(value, context)) - -func is_Basis(value, context: String = "") -> void: - output(Is.is_Basis(value, context)) - -func is_not_Basis(value, context: String = "") -> void: - output(IsNot.is_not_Basis(value, context)) - -func is_Transform(value, context: String = "") -> void: - output(Is.is_Transform(value, context)) - -func is_not_Transform(value, context: String = "") -> void: - output(IsNot.is_not_Transform(value, context)) - -func is_Color(value, context: String = "") -> void: - output(Is.is_Color(value, context)) - -func is_not_Color(value, context: String = "") -> void: - output(IsNot.is_not_Color(value, context)) - -func is_NodePath(value, context: String = "") -> void: - output(Is.is_NodePath(value, context)) - -func is_not_NodePath(value, context: String = "") -> void: - output(IsNot.is_not_NodePath(value, context)) - -func is_RID(value, context: String = "") -> void: - output(Is.is_RID(value, context)) - -func is_not_RID(value, context: String = "") -> void: - output(IsNot.is_not_RID(value, context)) - -func is_Object(value, context: String = "") -> void: - output(Is.is_Object(value, context)) - -func is_not_Object(value, context: String = "") -> void: - output(IsNot.is_not_Object(value, context)) - -func is_Dictionary(value, context: String = "") -> void: - output(Is.is_Dictionary(value, context)) - -func is_not_Dictionary(value, context: String = "") -> void: - output(IsNot.is_not_Dictionary(value, context)) - -func is_Array(value, context: String = "") -> void: - output(Is.is_Array(value, context)) - -func is_not_Array(value, context: String = "") -> void: - output(IsNot.is_not_Array(value, context)) - -func is_PoolByteArray(value, context: String = "") -> void: - output(Is.is_PoolByteArray(value, context)) - -func is_not_PoolByteArray(value, context: String = "") -> void: - output(IsNot.is_not_PoolByteArray(value, context)) - -func is_PoolIntArray(value, context: String = "") -> void: - output(Is.is_PoolIntArray(value, context)) - -func is_not_PoolIntArray(value, context: String = "") -> void: - output(IsNot.is_not_PoolIntArray(value, context)) - -func is_PoolRealArray(value, context: String = "") -> void: - output(Is.is_PoolRealArray(value, context)) - -func is_not_PoolRealArray(value, context: String = "") -> void: - output(IsNot.is_not_PoolRealArray(value, context)) - -func is_PoolStringArray(value, context: String = "") -> void: - output(Is.is_PoolStringArray(value, context)) - -func is_not_PoolStringArray(value, context: String = "") -> void: - output(IsNot.is_not_PoolStringArray(value, context)) - -func is_PoolVector2Array(value, context: String = "") -> void: - output(Is.is_PoolVector2Array(value, context)) - -func is_not_PoolVector2Array(value, context: String = "") -> void: - output(IsNot.is_not_PoolVector2Array(value, context)) - -func is_PoolVector3Array(value, context: String = "") -> void: - output(Is.is_PoolVector3Array(value, context)) - -func is_not_PoolVector3Array(value, context: String = "") -> void: - output(IsNot.is_not_PoolVector3Array(value, context)) - -func is_PoolColorArray(value, context: String = "") -> void: - output(Is.is_PoolColorArray(value, context)) - -func is_not_PoolColorArray(value, context: String = "") -> void: - output(IsNot.is_not_PoolColorArray(value, context)) - -func fail(context: String = "Unimplemented Test") -> void: - output(Utility.fail(context)) - -func auto_pass(context: String = "") -> void: - output(Utility.auto_pass(context)) diff --git a/addons/WAT/assertions/boolean.gd b/addons/WAT/assertions/boolean.gd deleted file mode 100644 index 4aa3e8a..0000000 --- a/addons/WAT/assertions/boolean.gd +++ /dev/null @@ -1,18 +0,0 @@ -extends "assertion.gd" - -static func is_true(value, context: String) -> Dictionary: - var type = type2str(value) - var passed: String = "|%s| %s == true" % [type, value] - var failed: String = "|%s| %s != true" % [type, value] - var success: bool = (value == true) - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_false(value, context: String) -> Dictionary: - var type = type2str(value) - var passed: String = "|%s| %s == false" % [type, value] - var failed: String = "|%s| %s != false" % [type, value] - var success = (value == false) - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) diff --git a/addons/WAT/assertions/collections.gd b/addons/WAT/assertions/collections.gd deleted file mode 100644 index 3c8127e..0000000 --- a/addons/WAT/assertions/collections.gd +++ /dev/null @@ -1,9 +0,0 @@ -extends "assertion.gd" - -static func is_empty(value, context: String) -> Dictionary: - var passed: String = "Array is empty" - var failed: String = "Collection is not empty (%s)" % str(value) - var success = value.empty() - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) diff --git a/addons/WAT/assertions/double.gd b/addons/WAT/assertions/double.gd deleted file mode 100644 index 28517d8..0000000 --- a/addons/WAT/assertions/double.gd +++ /dev/null @@ -1,36 +0,0 @@ -extends "assertion.gd" - -static func called_with_arguments(double, method: String, args: Array, context: String) -> Dictionary: - var passed: String = "method: %s was called with arguments: %s" % [method, args] - var failed: String = "method: %s was not called with arguments: %s" % [method, args] - var alt_failed: String = "method: %s was not called at all" % method - var expected = passed - - var success: bool - var result: String - if double.call_count(method) == 0: - success = false - result = alt_failed - elif double.found_matching_call(method, args): - success = true - result = passed - else: - success = false - result = failed - return _result(success, expected, result, context) - -static func was_called(double, method: String, context: String) -> Dictionary: - var passed: String = "%s was called" % method - var failed: String = "%s was not called" % method - var success = double.call_count(method) > 0 - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) - -static func was_not_called(double, method: String, context: String) -> Dictionary: - var passed: String = "%s was not called" % method - var failed: String = "%s was called" % method - var success = double.call_count(method) <= 0 - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) diff --git a/addons/WAT/assertions/equality.gd b/addons/WAT/assertions/equality.gd deleted file mode 100644 index 0f64b7a..0000000 --- a/addons/WAT/assertions/equality.gd +++ /dev/null @@ -1,72 +0,0 @@ -extends "assertion.gd" - -static func is_equal(a, b, context: String) -> Dictionary: - var typeofa = type2str(a) - var typeofb = type2str(b) - var passed: String = "|%s| %s is equal to |%s| %s" % [typeofa, a, typeofb, b] - var failed: String = "|%s| %s is not equal to |%s| %s" % [typeofa, a, typeofb, b] - var success = (a == b) - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) - -static func is_not_equal(a, b, context: String) -> Dictionary: - var success = (a != b) - var expected = "|%s| %s != |%s| %s" % [type2str(a), a, type2str(b), b] - var result = "|%s| %s %s |%s| %s" % [type2str(a), a, ("is not equal to" if success else "is equal to"), type2str(b),b] - return _result(success, expected, result, context) - -static func is_less_than(a, b, context: String) -> Dictionary: - var typeofa = type2str(a) - var typeofb = type2str(b) - var passed: String = "|%s| %s is less than |%s| %s" % [typeofa, a, typeofb, b] - var failed: String = "|%s| %s is equal or greater than |%s| %s" % [typeofa, a, typeofb, b] - var success = (a < b) - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) - -static func is_greater_than(a, b, context: String) -> Dictionary: - var typeofa = type2str(a) - var typeofb = type2str(b) - var passed: String = "|%s| %s is greater than |%s| %s" % [typeofa, a, typeofb, b] - var failed: String = "|%s| %s if equal or less than |%s| %s" % [typeofa, a, typeofb, b] - var success = (a > b) - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) - -static func is_equal_or_less_than(a, b, context: String) -> Dictionary: - var typeofa = type2str(a) - var typeofb = type2str(b) - var passed: String = "|%s| %s is equal or less than |%s| %s" % [typeofa, a, typeofb, b] - var failed: String = "|%s| %s is greater than |%s| %s" % [typeofa, a, typeofb, b] - var success = (a <= b) - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) - -static func is_equal_or_greater_than(a, b, context: String) -> Dictionary: - var typeofa = type2str(a) - var typeofb = type2str(b) - var passed: String = "|%s| %s is equal or greater |%s| %s" % [typeofa, a, typeofb, b] - var failed: String = "|%s| %s is less than |%s| %s" % [typeofa, a, typeofb, b] - var success = (a >= b) - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) - -static func is_equal_approx_(a, b, context: String) -> Dictionary: - var typeofa = type2str(a) - var typeofb = type2str(b) - var passed: String = "|%s| %s is approx. equal to |%s| %s" % [typeofa, a, typeofb, b] - var failed: String = "|%s| %s is not approx. equal to |%s| %s" % [typeofa, a, typeofb, b] - var success - if a is int or a is float: - success = is_equal_approx(a, b) - else: - success = a.is_equal_approx(b) - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) - diff --git a/addons/WAT/assertions/file.gd b/addons/WAT/assertions/file.gd deleted file mode 100644 index fac8f91..0000000 --- a/addons/WAT/assertions/file.gd +++ /dev/null @@ -1,17 +0,0 @@ -extends "assertion.gd" - -static func exists(path: String, context: String) -> Dictionary: - var passed: String = "%s exists" % path - var failed: String = "%s does not exist" % path - var success = File.new().file_exists(path) - var expected = "%s exists" % path - var result = passed if success else failed - return _result(success, expected, result, context) - -static func does_not_exist(path: String, context: String) -> Dictionary: - var passed: String = "%s does not exist" % path - var failed: String = "%s exists" % path - var success = not File.new().file_exists(path) - var expected = "%s does not exist" % path - var result = passed if success else failed - return _result(success, expected, result, context) diff --git a/addons/WAT/assertions/folder.gd b/addons/WAT/assertions/folder.gd deleted file mode 100644 index b0c203b..0000000 --- a/addons/WAT/assertions/folder.gd +++ /dev/null @@ -1,17 +0,0 @@ -extends "assertion.gd" - -static func exists(path: String, context: String) -> Dictionary: - var passed: String = "%s exists" % path - var failed: String = "%s does not exist" % path - var success = not path.empty() and Directory.new().dir_exists(path) - var expected = "%s exists" % path - var result = passed if success else failed - return _result(success, expected, result, context) - -static func does_not_exist(path: String, context: String) -> Dictionary: - var passed: String = "%s does not exist" % path - var failed: String = "%s exists" % path - var success = path.empty() or not Directory.new().dir_exists(path) - var expected = "%s does not exist" % path - var result = passed if success else failed - return _result(success, expected, result, context) diff --git a/addons/WAT/assertions/is.gd b/addons/WAT/assertions/is.gd deleted file mode 100644 index 27b6055..0000000 --- a/addons/WAT/assertions/is.gd +++ /dev/null @@ -1,217 +0,0 @@ -extends "assertion.gd" - -static func is_AABB(value, context: String) -> Dictionary: - var passed: String = "%s is builtin: AABB" % value - var failed: String = "%s is not builtin: AABB" % value - var success = value is AABB - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_Array(value, context: String) -> Dictionary: - var passed: String = "%s is builtin: Array" % value as String - var failed: String = "%s is not builtin: Array" % value as String - var success = value is Array - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_Basis(value, context: String) -> Dictionary: - var passed: String = "%s is builtin: Basis" % value - var failed: String = "%s is not builtin: Basis" % value - var success = value is Basis - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_bool(value, context: String) -> Dictionary: - var passed: String = "%s is builtin: bool" % value - var failed: String = "%s is not builtin: bool" % value - var success = value is bool - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_class_instance(instance, klass: Script, context: String) -> Dictionary: - var passed: String = "%s is instance of class: %s" % [instance, klass] - var failed: String = "%s is not instance of class: %s" % [instance, klass] - var success = instance is klass - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_Color(value, context: String) -> Dictionary: - var passed: String = "%s is builtin: Color" % value - var failed: String = "%s is not builtin: Color" % value - var success = value is Color - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_Dictionary(value, context: String) -> Dictionary: - var passed: String = "%s is builtin: Dictionary" % value - var failed: String = "%s is not builtin: Dictionary" % value - var success = value is Dictionary - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_float(value, context: String) -> Dictionary: - var passed: String = "%s is builtin: float" % value - var failed: String = "%s is not builtin: float" % value - var success = value is float - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_int(value, context: String) -> Dictionary: - var passed: String = "%s is builtin: int" % value - var failed: String = "%s is not builtin: int" % value - var success = value is int - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_NodePath(value, context: String) -> Dictionary: - var passed: String = "%s is builtin: NodePath" % value - var failed: String = "%s is not builtin: NodePath" % value - var success = value is NodePath - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_Object(value, context: String) -> Dictionary: - var passed: String = "%s is builtin: Object" % value - var failed: String = "%s is not builtin: Object" % value - var success = value is Object - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_Plane(value, context: String) -> Dictionary: - var passed: String = "%s is builtin: Plane" % value - var failed: String = "%s is not builtin: Plane" % value - var success = value is Plane - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_PoolByteArray(value, context: String) -> Dictionary: - var passed: String = "%s is builtin: PoolByteArray" % value - var failed: String = "%s is not builtin: PoolByteArray" % value - var success = value is PoolByteArray - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_PoolColorArray(value, context: String) -> Dictionary: - var passed: String = "%s is builtin: PoolColorArray" % value - var failed: String = "%s is not builtin: PoolColorArray" % value - var success = value is PoolColorArray - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_PoolIntArray(value, context: String) -> Dictionary: - var passed: String = "%s is builtin: PoolIntArray" % value - var failed: String = "%s is not builtin: PoolIntArray" % value - var success = value is PoolIntArray - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_PoolRealArray(value, context: String) -> Dictionary: - var passed: String = "%s is builtin: PoolRealArray" % value - var failed: String = "%s is not builtin: PoolRealArray" % value - var success = value is PoolRealArray - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_PoolStringArray(value, context: String) -> Dictionary: - var passed: String = "%s is builtin: PoolStringArray" % value - var failed: String = "%s is not builtin: PoolStringArray" % value - var success = value is PoolStringArray - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_PoolVector2Array(value, context: String) -> Dictionary: - var passed: String = "%s is builtin: PoolVector2Array" % value - var failed: String = "%s is not builtin: PoolVector2Array" % value - var success = value is PoolVector2Array - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_PoolVector3Array(value, context: String) -> Dictionary: - var passed: String = "%s is builtin: PoolVector3Array" % value - var failed: String = "%s is not builtin: PoolVector3Array" % value - var success = value is PoolVector3Array - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_Quat(value, context: String) -> Dictionary: - var passed: String = "%s is builtin: Quat" % value - var failed: String = "%s is not builtin: Quat" % value - var success = value is Quat - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_Rect2(value, context: String) -> Dictionary: - var passed: String = "%s is builtin: Rect2" % value - var failed: String = "%s is not builtin: Rect2" % value - var success = value is Rect2 - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_RID(value, context: String) -> Dictionary: - var passed: String = "%s is builtin: RID" % value - var failed: String = "%s is not builtin: RID" % value - var success = value is RID - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_String(value, context: String) -> Dictionary: - var passed: String = "%s is builtin: String" % value - var failed: String = "%s is not builtin: String" % value - var success = value is String - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_Transform(value, context: String) -> Dictionary: - var passed: String = "%s is builtin: Transform" % value - var failed: String = "%s is not builtin: Transform" % value - var success = value is Transform - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_Transform2D(value, context: String) -> Dictionary: - var passed: String = "%s is builtin: Transform2D" % value - var failed: String = "%s is not builtin: Transform2D" % value - var success = value is Transform2D - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_Vector2(value, context: String) -> Dictionary: - var passed: String = "%s is builtin: Vector2" % value - var failed: String = "%s is not builtin: Vector2" % value - var success = value is Vector2 - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_Vector3(value, context: String) -> Dictionary: - var passed: String = "%s is builtin: Vector3" % value - var failed: String = "%s is not builtin: Vector3" % value - var success = value is Vector3 - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) diff --git a/addons/WAT/assertions/is_not.gd b/addons/WAT/assertions/is_not.gd deleted file mode 100644 index 978eb1c..0000000 --- a/addons/WAT/assertions/is_not.gd +++ /dev/null @@ -1,218 +0,0 @@ -extends "assertion.gd" - -static func is_not_AABB(value, context: String) -> Dictionary: - var passed: String = "%s is not builtin: AABB" % value - var failed: String = "%s is builtin: AABB" % value - var success = not value is AABB - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_not_Array(value, context: String) -> Dictionary: - var passed: String = "%s is not builtin: Array" % value - var failed: String = "%s is builtin: Array" % value - var success = not value is Array - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_not_Basis(value, context: String) -> Dictionary: - var passed: String = "%s is not builtin: Basis" % value - var failed: String = "%s is builtin: Basis" % value - var success = not value is Basis - var expected = passed - var result = passed if success else failed - - return _result(success, passed, result, context) - -static func is_not_bool(value, context: String) -> Dictionary: - var passed: String = "%s is not builtin: bool" % value - var failed: String = "%s is builtin: bool" % value - var success = not value is bool - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_not_class_instance(instance, klass: Script, context: String) -> Dictionary: - var passed: String = "%s is not instance of class: %s" % [instance, klass] - var failed: String = "%s is instance of class: %s" % [instance, klass] - var success = not instance is klass - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_not_Color(value, context: String) -> Dictionary: - var passed: String = "%s is not builtin: Color" % value - var failed: String = "%s is builtin: Color" % value - var success = not value is Color - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_not_Dictionary(value, context: String) -> Dictionary: - var passed: String = "%s is not builtin: Dictionary" % value - var failed: String = "%s is builtin: Dictionary" % value - var success = not value is Dictionary - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_not_float(value, context: String) -> Dictionary: - var passed: String = "%s is not builtin: float" % value - var failed: String = "%s is builtin: float" % value - var success = not value is float - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_not_int(value, context: String) -> Dictionary: - var passed: String = "%s is not builtin: int" % value - var failed: String = "%s is builtin: int" % value - var success = not value is int - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_not_NodePath(value, context: String) -> Dictionary: - var passed: String = "%s is not builtin: NodePath" % value - var failed: String = "%s is builtin: NodePath" % value - var success = not value is NodePath - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_not_Object(value, context: String) -> Dictionary: - var passed: String = "%s is not builtin: Object" % value - var failed: String = "%s is builtin: Object" % value - var success = not value is Object - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_not_Plane(value, context: String) -> Dictionary: - var passed: String = "%s is not builtin: Plane" % value - var failed: String = "%s is builtin: Plane" % value - var success = not value is Plane - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_not_PoolByteArray(value, context: String) -> Dictionary: - var passed: String = "%s is not builtin: PoolByteArray" % value - var failed: String = "%s is builtin: PoolByteArray" % value - var success = not value is PoolByteArray - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_not_PoolColorArray(value, context: String) -> Dictionary: - var passed: String = "%s is not builtin: PoolColorArray" % value - var failed: String = "%s is builtin: PoolColorArray" % value - var success = not value is PoolColorArray - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_not_PoolIntArray(value, context: String) -> Dictionary: - var passed: String = "%s is not builtin: PoolIntArray" % value - var failed: String = "%s is builtin: PoolIntArray" % value - var success = not value is PoolIntArray - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_not_PoolRealArray(value, context: String) -> Dictionary: - var passed: String = "%s is not builtin: PoolRealArray" % value - var failed: String = "%s is builtin: PoolRealArray" % value - var success = not value is PoolRealArray - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_not_PoolStringArray(value, context: String) -> Dictionary: - var passed: String = "%s is not builtin: PoolStringArray" % value - var failed: String = "%s is builtin: PoolStringArray" % value - var success = not value is PoolStringArray - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_not_PoolVector2Array(value, context: String) -> Dictionary: - var passed: String = "%s is not builtin: PoolVector2Array" % value - var failed: String = "%s is builtin: PoolVector2Array" % value - var success = not value is PoolVector2Array - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_not_PoolVector3Array(value, context: String) -> Dictionary: - var passed: String = "%s is not builtin: PoolVector3Array" % value - var failed: String = "%s is builtin: PoolVector3Array" % value - var success = not value is PoolVector3Array - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_not_Quat(value, context: String) -> Dictionary: - var passed: String = "%s is not builtin: Quat" % value - var failed: String = "%s is builtin: Quat" % value - var success = not value is Quat - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_not_Rect2(value, context: String) -> Dictionary: - var passed: String = "%s is not builtin: Rect2" % value - var failed: String = "%s is builtin: Rect2" % value - var success = not value is Rect2 - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_not_RID(value, context: String) -> Dictionary: - var passed: String = "%s is not builtin: RID" % value - var failed: String = "%s is builtin: RID" % value - var success = not value is RID - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_not_String(value, context: String) -> Dictionary: - var passed: String = "%s is not builtin: String" % value - var failed: String = "%s is builtin: String" % value - var success = not value is String - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_not_Transform(value, context: String) -> Dictionary: - var passed: String = "%s is not builtin: Transform" % value - var failed: String = "%s is builtin: Transform" % value - var success = not value is Transform - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_not_Transform2D(value, context: String) -> Dictionary: - var passed: String = "%s is not builtin: Transform2D" % value - var failed: String = "%s is builtin: Transform2D" % value - var success = not value is Transform2D - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_not_Vector2(value, context: String) -> Dictionary: - var passed: String = "%s is not builtin: Vector2" % value - var failed: String = "%s is builtin: Vector2" % value - var success = not value is Vector2 - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) - -static func is_not_Vector3(value, context: String) -> Dictionary: - var passed: String = "%s is not builtin: Vector3" % value - var failed: String = "%s is builtin: Vector3" % value - var success = not value is Vector3 - var expected = passed - var result = passed if success else failed - return _result(success, passed, result, context) diff --git a/addons/WAT/assertions/null.gd b/addons/WAT/assertions/null.gd deleted file mode 100644 index 1dcb286..0000000 --- a/addons/WAT/assertions/null.gd +++ /dev/null @@ -1,20 +0,0 @@ -extends "assertion.gd" - - -static func is_null(value, context: String) -> Dictionary: - var type = type2str(value) - var passed: String = "|%s| %s == null" % [type, value] - var failed: String = "|%s| %s != null" % [type, value] - var success = (value == null) - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) - -static func is_not_null(value, context: String) -> Dictionary: - var type = type2str(value) - var passed: String = "|%s| %s != null" % [type, value] - var failed: String = "|%s| %s == null" % [type, value] - var success = (value != null) - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) diff --git a/addons/WAT/assertions/object.gd b/addons/WAT/assertions/object.gd deleted file mode 100644 index 2ae8860..0000000 --- a/addons/WAT/assertions/object.gd +++ /dev/null @@ -1,129 +0,0 @@ -extends "assertion.gd" - -static func does_not_have_meta(object: Object, meta: String, context: String) -> Dictionary: - var passed: String = "%s does not have meta: %s" % [object, meta] - var failed: String = "%s has meta: %s" % [object, meta] - var success = not object.has_meta(meta) - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) - -static func does_not_have_method(obj: Object, method: String, context: String) -> Dictionary: - var passed: String = "%s does not have method: %s" % [obj, method] - var failed: String = "%s has method: %s" % [obj, method] - var success = not obj.has_method(method) - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) - -static func does_not_have_user_signal(obj: Object, _signal: String, context: String) -> Dictionary: - var passed: String = "%s does not have user signal: %s" % [obj, _signal] - var failed: String = "%s has user signal: %s" % [obj, _signal] - var success = not obj.has_user_signal(_signal) - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) - -static func o_has_meta(object: Object, meta: String, context: String) -> Dictionary: - var passed: String = "%s has meta: %s" % [object, meta] - var failed: String = "%s does not have meta: %s" % [object, meta] - var success = object.has_meta(meta) - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) - -static func o_has_method(obj: Object, method: String, context: String) -> Dictionary: - var passed: String = "%s has method: %s" % [obj, method] - var failed: String = "%s does not have method: %s" % [obj, method] - var success = obj.has_method(method) - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) - -static func o_has_user_signal(obj: Object, _signal: String, context: String) -> Dictionary: - var passed: String = "%s has user signal: %s" % [obj, _signal] - var failed: String = "%s does not have user signal: %s" % [obj, _signal] - var success = obj.has_user_signal(_signal) - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) - -static func o_is_blocking_signals(obj, context: String) -> Dictionary: - var passed: String = "%s is blocking signals" % obj - var failed: String = "%s is not blocking signals" % obj - var success = obj.is_blocking_signals() - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) - -static func o_is_connected(sender: Object, _signal: String, receiver: Object, method: String, context: String) -> Dictionary: - var passed: String = "%s.%s is connected to %s.%s" % [sender, _signal, receiver, method] - var failed: String = "%s.%s is not connected to %s.%s" % [sender, _signal, receiver, method] - var success = sender.is_connected(_signal, receiver, method) - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) - -static func o_is_freed(object: Object, context: String) -> Dictionary: - var passed: String = "%s is freed from memory" % object - var failed: String = "%s is not freed from memory" % object - var success = not is_instance_valid(object) - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) - -static func o_is_not_blocking_signals(obj, context: String) -> Dictionary: - var passed: String = "%s is not blocking signals" % obj - var failed: String = "%s is blocking signals" % obj - var success = not obj.is_blocking_signals() - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) - -static func o_is_not_connected(sender: Object, _signal: String, receiver: Object, method: String, context: String) -> Dictionary: - var passed: String = "%s.%s is not connected to %s.%s" % [sender, _signal, receiver, method] - var failed: String = "%s.%s is connected to %s.%s" % [sender, _signal, receiver, method] - var success = not sender.is_connected(_signal, receiver, method) - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) - -static func o_is_not_freed(obj: Object, context: String) -> Dictionary: - var success = is_instance_valid(obj) - var passed = "%s is not freed" % obj - var expected = passed - var failed = "%s is freed" % obj - var result = passed if success else failed - return _result(success, expected, result, context) - -static func o_is_not_queued_for_deletion(obj: Object, context: String) -> Dictionary: - var passed: String = "%s is not queued for deletion" % obj - var failed: String = "%s is queued for deletion" % obj - var expected = passed - var success = not obj.is_queued_for_deletion() - var result = passed if success else failed - return _result(success, expected, result, context) - -static func o_is_queued_for_deletion(obj: Object, context: String) -> Dictionary: - var passed: String = "%s is queued for deletion" % obj - var failed: String = "%s is not queued for deletion" % obj - var expected = passed - var success = obj.is_queued_for_deletion() - var result = passed if success else failed - return _result(success, expected, result, context) - -static func o_is_valid_instance(obj: Object, context: String) -> Dictionary: - var passed: String = "%s is a valid instance" % obj - var failed: String = "%s is not a valid instance" % obj - var expected = passed - var success = is_instance_valid(obj) - var result = passed if success else failed - return _result(success, expected, result, context) - -static func o_is_not_valid_instance(obj: Object, context: String) -> Dictionary: - var passed: String = "%s is not a valid instance" % obj - var failed: String = "%s is a valid instance" % obj - var expected = passed - var success = !is_instance_valid(obj) - var result = passed if success else failed - return _result(success, expected, result, context) diff --git a/addons/WAT/assertions/property.gd b/addons/WAT/assertions/property.gd deleted file mode 100644 index c552c31..0000000 --- a/addons/WAT/assertions/property.gd +++ /dev/null @@ -1,18 +0,0 @@ -extends "assertion.gd" - -# ONLY FOR CONTAINER CLASSES. NOT FOR OBJECTS -static func has(value, container, context: String) -> Dictionary: - var passed: String = "%s has %s" % [container, value] - var failed: String = "%s has %s" % [container, value] - var success = container.has(value) - var expected = "%s has %s" % [container, value] - var result = passed if success else failed - return _result(success, expected, result, context) - -static func does_not_have(value, container, context: String) -> Dictionary: - var passed: String = "%s does not have %s" % [container, value] - var failed: String = "%s has %s" % [container, value] - var success = not container.has(value) - var expected = "%s does not have %s" % [container, value] - var result = passed if success else failed - return _result(success, expected, result, context) diff --git a/addons/WAT/assertions/range.gd b/addons/WAT/assertions/range.gd deleted file mode 100644 index 8ccc6f6..0000000 --- a/addons/WAT/assertions/range.gd +++ /dev/null @@ -1,17 +0,0 @@ -extends "assertion.gd" - -static func is_in_range(value, low, high, context: String) -> Dictionary: - var passed: String = "%s is in range(%s, %s)" % [value, low, high] - var failed: String = "%s is not in range(%s, %s)" % [value, low, high] - var success = low <= value and value < high - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) - -static func is_not_in_range(value, low, high, context: String) -> Dictionary: - var passed: String = "%s is not in range(%s, %s)" % [value, low, high] - var failed: String = "%s is in range(%s, %s)" % [value, low, high] - var success = low > value or value >= high - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) diff --git a/addons/WAT/assertions/signal.gd b/addons/WAT/assertions/signal.gd deleted file mode 100644 index 842dddf..0000000 --- a/addons/WAT/assertions/signal.gd +++ /dev/null @@ -1,60 +0,0 @@ -extends "assertion.gd" - -static func was_emitted(emitter, event: String, context: String) -> Dictionary: - var passed: String = "signal: %s was emitted from %s" % [event, emitter] - var failed: String = "signal: %s was not emitted from %s" % [event, emitter] - var success = emitter.get_meta("watcher").watching[event].emit_count > 0 - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) - -static func was_not_emitted(emitter, _signal: String, context: String) -> Dictionary: - var success = emitter.get_meta("watcher").watching[_signal].emit_count <= 0 - var passed = "Signal: %s was not emitted from %s" % [_signal, emitter] - var failed = "Signal: %s was emitted from %s" % [_signal, emitter] - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) - -static func was_emitted_x_times(emitter, event: String, times: int, context: String) -> Dictionary: - var passed: String = "signal: %s was emitted from %s %s" % [event, emitter, times as String] - var failed: String = "signal: %s was not emitted from %s %s" % [event, emitter, times as String] - var success = emitter.get_meta("watcher").watching[event].emit_count == times - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) - -static func was_emitted_with_args(emitter: Object, event: String, arguments: Array, context: String) -> Dictionary: - var passed: String = "Signal: %s was emitted from %s with arguments: %s" % [event, emitter, arguments] - var failed: String = "Signal: %s was not emitted from %s with arguments: %s" % [event, emitter, arguments] - var alt_failure: String = "Signal: %s was not emitted from %s" % [event, emitter] - var expected = passed - - var success: bool - var result: String - var data = emitter.get_meta("watcher").watching[event] - if data.emit_count <= 0: - success = false - result = alt_failure - - elif _found_matching_call(arguments, data.calls): - success = true - result = passed - - else: - success = false - result = failed - - return _result(success, expected, result, context) - -static func _found_matching_call(args, calls) -> bool: - for call in calls: - if _match(args, call.args): - return true - return false - -static func _match(args, call_args) -> bool: - for i in args.size(): - if args[i] != call_args[i]: - return false - return true diff --git a/addons/WAT/assertions/string.gd b/addons/WAT/assertions/string.gd deleted file mode 100644 index 6958ca9..0000000 --- a/addons/WAT/assertions/string.gd +++ /dev/null @@ -1,58 +0,0 @@ -extends "assertion.gd" - -static func begins_with(value: String, string: String, context: String) -> Dictionary: - var passed: String = "%s begins with %s" % [string, value] - var failed: String = "%s does not begins with %s" % [string, value] - var success = string.begins_with(value) - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) - -static func contains(value: String, string: String, context: String) -> Dictionary: - var passed: String = "%s contains %s" % [string, value] - var failed: String = "%s does not contain %s" % [string, value] - var success = value in string - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) - -static func does_not_begin_with(value: String, string: String, context: String) -> Dictionary: - var passed: String = "%s does not begin with %s" % [string, value] - var failed: String = "%s begins with %s" % [string, value] - var success = not string.begins_with(value) - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) - -static func does_not_contain(value: String, string: String, context: String) -> Dictionary: - var passed: String = "%s does not contain %s" % [string, value] - var failed: String = "%s contains %s" % [string, value] - var success = not value in string - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) - -static func does_not_end_with(value: String, string: String, context: String) -> Dictionary: - var passed: String = "%s does not end with %s" % [string, value] - var failed: String = "%s ends with %s" % [string, value] - var success = not string.ends_with(value) - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) - -static func ends_with(value: String, string: String, context: String) -> Dictionary: - var passed: String = "%s ends with %s" % [string, value] - var failed: String = "%s does not end with %s" % [string, value] - var success = string.ends_with(value) - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) - -static func is_empty(value: String, context: String) -> Dictionary: - var passed: String = "String is empty" - var failed: String = "String %s is not empty" % [value] - var success = value.empty() - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) - diff --git a/addons/WAT/assertions/utility.gd b/addons/WAT/assertions/utility.gd deleted file mode 100644 index a326593..0000000 --- a/addons/WAT/assertions/utility.gd +++ /dev/null @@ -1,17 +0,0 @@ -extends "assertion.gd" - -static func fail(context: String = "Test Not Implemented") -> Dictionary: - # Intentionally Fails Test - return _result(false, "N/A", "N/A", context) - -static func auto_pass(context: String = "Auto Pass") -> Dictionary: - return _result(true, "N/A", "N/A", context) - -# Callv does not work on virtual classes (Array etc) -static func that(obj, method: String, arguments: Array = [], context: String = "", passed: String = "", failed: String = "") -> Dictionary: - var success = obj.callv(method, arguments) - var expected = passed - var result = passed if success else failed - return _result(success, expected, result, context) - -# asserts.that(array, "empty", [], "Array is empty", "Empty", "Found %s items" % array.size()) diff --git a/addons/WAT/assets/debug_failed.png b/addons/WAT/assets/debug_failed.png deleted file mode 100644 index c40b57c..0000000 Binary files a/addons/WAT/assets/debug_failed.png and /dev/null differ diff --git a/addons/WAT/assets/debug_failed.png.import b/addons/WAT/assets/debug_failed.png.import deleted file mode 100644 index c490920..0000000 --- a/addons/WAT/assets/debug_failed.png.import +++ /dev/null @@ -1,35 +0,0 @@ -[remap] - -importer="texture" -type="StreamTexture" -path="res://.import/debug_failed.png-0deb1d1782c19daaffc5af47aba4eafc.stex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://addons/WAT/assets/debug_failed.png" -dest_files=[ "res://.import/debug_failed.png-0deb1d1782c19daaffc5af47aba4eafc.stex" ] - -[params] - -compress/mode=0 -compress/lossy_quality=0.7 -compress/hdr_mode=0 -compress/bptc_ldr=0 -compress/normal_map=0 -flags/repeat=0 -flags/filter=true -flags/mipmaps=true -flags/anisotropic=false -flags/srgb=1 -process/fix_alpha_border=true -process/premult_alpha=false -process/HDR_as_SRGB=false -process/invert_color=false -process/normal_map_invert_y=false -stream=false -size_limit=0 -detect_3d=true -svg/scale=1.0 diff --git a/addons/WAT/assets/docs.svg b/addons/WAT/assets/docs.svg deleted file mode 100644 index 2c4d3bc..0000000 --- a/addons/WAT/assets/docs.svg +++ /dev/null @@ -1,38 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<svg - height="16" - viewBox="0 0 16 16" - width="16" - version="1.1" - id="svg4" - sodipodi:docname="docs.svg" - inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns="http://www.w3.org/2000/svg" - xmlns:svg="http://www.w3.org/2000/svg"> - <defs - id="defs8" /> - <sodipodi:namedview - id="namedview6" - pagecolor="#505050" - bordercolor="#ffffff" - borderopacity="1" - inkscape:pageshadow="0" - inkscape:pageopacity="0" - inkscape:pagecheckerboard="1" - showgrid="false" - inkscape:zoom="23.53125" - inkscape:cx="0.91367862" - inkscape:cy="5.9282868" - inkscape:window-width="1920" - inkscape:window-height="1149" - inkscape:window-x="0" - inkscape:window-y="0" - inkscape:window-maximized="1" - inkscape:current-layer="svg4" /> - <path - d="m5.0293 1c-.99969-.010925-2.0096.31165-3.0293 1v7c2.0172-1.3529 4.0167-1.3136 6 0 1.9833-1.3136 3.9828-1.3529 6 0v-7c-1.0197-.68835-2.0296-1.0109-3.0293-1-.6613.007227-1.3175.1735-1.9707.46289v4.5371h-1v-4c-.98156-.64465-1.971-.98908-2.9707-1zm-5.0293 9v6h2a3 3 0 0 0 3-3 3 3 0 0 0 -3-3zm5 3a3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0 -3-3 3 3 0 0 0 -3 3zm6 0a3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1 1 1 0 0 1 1-1h1v-2h-1a3 3 0 0 0 -3 3zm-9-1a1 1 0 0 1 1 1 1 1 0 0 1 -1 1zm6 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" - style="fill:#e0e0e0;fill-opacity:1;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:0.32549;stroke-width:2" - id="path2" /> -</svg> diff --git a/addons/WAT/assets/docs.svg.import b/addons/WAT/assets/docs.svg.import deleted file mode 100644 index 89bb0fc..0000000 --- a/addons/WAT/assets/docs.svg.import +++ /dev/null @@ -1,35 +0,0 @@ -[remap] - -importer="texture" -type="StreamTexture" -path="res://.import/docs.svg-a649391eeb4006a0bb13c9007d30760f.stex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://addons/WAT/assets/docs.svg" -dest_files=[ "res://.import/docs.svg-a649391eeb4006a0bb13c9007d30760f.stex" ] - -[params] - -compress/mode=0 -compress/lossy_quality=0.7 -compress/hdr_mode=0 -compress/bptc_ldr=0 -compress/normal_map=0 -flags/repeat=0 -flags/filter=true -flags/mipmaps=false -flags/anisotropic=false -flags/srgb=2 -process/fix_alpha_border=true -process/premult_alpha=false -process/HDR_as_SRGB=false -process/invert_color=false -process/normal_map_invert_y=false -stream=false -size_limit=0 -detect_3d=true -svg/scale=1.0 diff --git a/addons/WAT/assets/failed.png b/addons/WAT/assets/failed.png deleted file mode 100644 index 28bddf7..0000000 Binary files a/addons/WAT/assets/failed.png and /dev/null differ diff --git a/addons/WAT/assets/failed.png.import b/addons/WAT/assets/failed.png.import deleted file mode 100644 index e7e8884..0000000 --- a/addons/WAT/assets/failed.png.import +++ /dev/null @@ -1,35 +0,0 @@ -[remap] - -importer="texture" -type="StreamTexture" -path="res://.import/failed.png-18188bee7d18ad72bc7cbc6222c355b1.stex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://addons/WAT/assets/failed.png" -dest_files=[ "res://.import/failed.png-18188bee7d18ad72bc7cbc6222c355b1.stex" ] - -[params] - -compress/mode=0 -compress/lossy_quality=0.7 -compress/hdr_mode=0 -compress/bptc_ldr=0 -compress/normal_map=0 -flags/repeat=0 -flags/filter=true -flags/mipmaps=true -flags/anisotropic=true -flags/srgb=2 -process/fix_alpha_border=true -process/premult_alpha=false -process/HDR_as_SRGB=false -process/invert_color=false -process/normal_map_invert_y=false -stream=false -size_limit=0 -detect_3d=true -svg/scale=1.0 diff --git a/addons/WAT/assets/folder.png b/addons/WAT/assets/folder.png deleted file mode 100644 index 188c45b..0000000 Binary files a/addons/WAT/assets/folder.png and /dev/null differ diff --git a/addons/WAT/assets/folder.png.import b/addons/WAT/assets/folder.png.import deleted file mode 100644 index a09af20..0000000 --- a/addons/WAT/assets/folder.png.import +++ /dev/null @@ -1,35 +0,0 @@ -[remap] - -importer="texture" -type="StreamTexture" -path="res://.import/folder.png-f6fa55e0795097315a7c899b7b15ee27.stex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://addons/WAT/assets/folder.png" -dest_files=[ "res://.import/folder.png-f6fa55e0795097315a7c899b7b15ee27.stex" ] - -[params] - -compress/mode=0 -compress/lossy_quality=0.7 -compress/hdr_mode=0 -compress/bptc_ldr=0 -compress/normal_map=0 -flags/repeat=0 -flags/filter=true -flags/mipmaps=false -flags/anisotropic=false -flags/srgb=2 -process/fix_alpha_border=true -process/premult_alpha=false -process/HDR_as_SRGB=false -process/invert_color=false -process/normal_map_invert_y=false -stream=false -size_limit=0 -detect_3d=true -svg/scale=1.0 diff --git a/addons/WAT/assets/function.png b/addons/WAT/assets/function.png deleted file mode 100644 index 8c19f70..0000000 Binary files a/addons/WAT/assets/function.png and /dev/null differ diff --git a/addons/WAT/assets/function.png.import b/addons/WAT/assets/function.png.import deleted file mode 100644 index 2133137..0000000 --- a/addons/WAT/assets/function.png.import +++ /dev/null @@ -1,35 +0,0 @@ -[remap] - -importer="texture" -type="StreamTexture" -path="res://.import/function.png-b5f751bc93a3ee5a29c4d32864c250fc.stex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://addons/WAT/assets/function.png" -dest_files=[ "res://.import/function.png-b5f751bc93a3ee5a29c4d32864c250fc.stex" ] - -[params] - -compress/mode=0 -compress/lossy_quality=0.7 -compress/hdr_mode=0 -compress/bptc_ldr=0 -compress/normal_map=0 -flags/repeat=0 -flags/filter=true -flags/mipmaps=false -flags/anisotropic=false -flags/srgb=2 -process/fix_alpha_border=true -process/premult_alpha=false -process/HDR_as_SRGB=false -process/invert_color=false -process/normal_map_invert_y=false -stream=false -size_limit=0 -detect_3d=true -svg/scale=1.0 diff --git a/addons/WAT/assets/issue.svg b/addons/WAT/assets/issue.svg deleted file mode 100644 index 457d070..0000000 --- a/addons/WAT/assets/issue.svg +++ /dev/null @@ -1 +0,0 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="m5.2902433 14.98657h1.9512087v2.441414h-1.9512087zm0-11.909101h1.9512087v6.2957719l-.1922373 3.4314361h-1.5571222l-.2018492-3.4314361z" transform="matrix(1.2172834 0 0 .60107067 .478728 1.839214)"/><path d="m8.0503291 1.1522775a6.8983747 6.8983747 0 0 0 -6.8980516 6.8980516 6.8983747 6.8983747 0 0 0 6.8980516 6.8997839 6.8983747 6.8983747 0 0 0 6.8997839-6.8997839 6.8983747 6.8983747 0 0 0 -6.8997839-6.8980516zm-.0294418 1.1430364a5.6659852 5.6659852 0 0 1 5.6666897 5.6649578 5.6659852 5.6659852 0 0 1 -5.6666897 5.6666893 5.6659852 5.6659852 0 0 1 -5.6666896-5.6666893 5.6659852 5.6659852 0 0 1 5.6666896-5.6649578z" stroke-width=".886719"/></g></svg> diff --git a/addons/WAT/assets/issue.svg.import b/addons/WAT/assets/issue.svg.import deleted file mode 100644 index d70ed80..0000000 --- a/addons/WAT/assets/issue.svg.import +++ /dev/null @@ -1,35 +0,0 @@ -[remap] - -importer="texture" -type="StreamTexture" -path="res://.import/issue.svg-0e50d01edf27a6e481699d3b4373a6f9.stex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://addons/WAT/assets/issue.svg" -dest_files=[ "res://.import/issue.svg-0e50d01edf27a6e481699d3b4373a6f9.stex" ] - -[params] - -compress/mode=0 -compress/lossy_quality=0.7 -compress/hdr_mode=0 -compress/bptc_ldr=0 -compress/normal_map=0 -flags/repeat=0 -flags/filter=true -flags/mipmaps=false -flags/anisotropic=false -flags/srgb=2 -process/fix_alpha_border=true -process/premult_alpha=false -process/HDR_as_SRGB=false -process/invert_color=false -process/normal_map_invert_y=false -stream=false -size_limit=0 -detect_3d=true -svg/scale=1.0 diff --git a/addons/WAT/assets/kofi.png b/addons/WAT/assets/kofi.png deleted file mode 100644 index a797ceb..0000000 Binary files a/addons/WAT/assets/kofi.png and /dev/null differ diff --git a/addons/WAT/assets/kofi.png.import b/addons/WAT/assets/kofi.png.import deleted file mode 100644 index 2994289..0000000 --- a/addons/WAT/assets/kofi.png.import +++ /dev/null @@ -1,35 +0,0 @@ -[remap] - -importer="texture" -type="StreamTexture" -path="res://.import/kofi.png-25130db51d1b80d6426df72322b3f642.stex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://addons/WAT/assets/kofi.png" -dest_files=[ "res://.import/kofi.png-25130db51d1b80d6426df72322b3f642.stex" ] - -[params] - -compress/mode=0 -compress/lossy_quality=0.7 -compress/hdr_mode=0 -compress/bptc_ldr=0 -compress/normal_map=0 -flags/repeat=0 -flags/filter=true -flags/mipmaps=false -flags/anisotropic=false -flags/srgb=2 -process/fix_alpha_border=true -process/premult_alpha=false -process/HDR_as_SRGB=false -process/invert_color=false -process/normal_map_invert_y=false -stream=false -size_limit=0 -detect_3d=true -svg/scale=1.0 diff --git a/addons/WAT/assets/label.png b/addons/WAT/assets/label.png deleted file mode 100644 index 033c689..0000000 Binary files a/addons/WAT/assets/label.png and /dev/null differ diff --git a/addons/WAT/assets/label.png.import b/addons/WAT/assets/label.png.import deleted file mode 100644 index e6f5f8c..0000000 --- a/addons/WAT/assets/label.png.import +++ /dev/null @@ -1,35 +0,0 @@ -[remap] - -importer="texture" -type="StreamTexture" -path="res://.import/label.png-6b04b72410cd91559f10027900e1c444.stex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://addons/WAT/assets/label.png" -dest_files=[ "res://.import/label.png-6b04b72410cd91559f10027900e1c444.stex" ] - -[params] - -compress/mode=0 -compress/lossy_quality=0.7 -compress/hdr_mode=0 -compress/bptc_ldr=0 -compress/normal_map=0 -flags/repeat=0 -flags/filter=true -flags/mipmaps=false -flags/anisotropic=false -flags/srgb=2 -process/fix_alpha_border=true -process/premult_alpha=false -process/HDR_as_SRGB=false -process/invert_color=false -process/normal_map_invert_y=false -stream=false -size_limit=0 -detect_3d=true -svg/scale=1.0 diff --git a/addons/WAT/assets/passed.png b/addons/WAT/assets/passed.png deleted file mode 100644 index 3a70738..0000000 Binary files a/addons/WAT/assets/passed.png and /dev/null differ diff --git a/addons/WAT/assets/passed.png.import b/addons/WAT/assets/passed.png.import deleted file mode 100644 index 1abd8ca..0000000 --- a/addons/WAT/assets/passed.png.import +++ /dev/null @@ -1,35 +0,0 @@ -[remap] - -importer="texture" -type="StreamTexture" -path="res://.import/passed.png-1606da9dc4505c2bac72d61e0f5f988c.stex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://addons/WAT/assets/passed.png" -dest_files=[ "res://.import/passed.png-1606da9dc4505c2bac72d61e0f5f988c.stex" ] - -[params] - -compress/mode=0 -compress/lossy_quality=0.7 -compress/hdr_mode=0 -compress/bptc_ldr=0 -compress/normal_map=0 -flags/repeat=0 -flags/filter=true -flags/mipmaps=false -flags/anisotropic=false -flags/srgb=2 -process/fix_alpha_border=true -process/premult_alpha=false -process/HDR_as_SRGB=false -process/invert_color=false -process/normal_map_invert_y=false -stream=false -size_limit=0 -detect_3d=true -svg/scale=1.0 diff --git a/addons/WAT/assets/play.png b/addons/WAT/assets/play.png deleted file mode 100644 index a446ecd..0000000 Binary files a/addons/WAT/assets/play.png and /dev/null differ diff --git a/addons/WAT/assets/play.png.import b/addons/WAT/assets/play.png.import deleted file mode 100644 index 4a65ea6..0000000 --- a/addons/WAT/assets/play.png.import +++ /dev/null @@ -1,35 +0,0 @@ -[remap] - -importer="texture" -type="StreamTexture" -path="res://.import/play.png-2962300029223d688c79411a6cda4a6d.stex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://addons/WAT/assets/play.png" -dest_files=[ "res://.import/play.png-2962300029223d688c79411a6cda4a6d.stex" ] - -[params] - -compress/mode=0 -compress/lossy_quality=0.7 -compress/hdr_mode=0 -compress/bptc_ldr=0 -compress/normal_map=0 -flags/repeat=0 -flags/filter=true -flags/mipmaps=true -flags/anisotropic=false -flags/srgb=0 -process/fix_alpha_border=true -process/premult_alpha=false -process/HDR_as_SRGB=false -process/invert_color=false -process/normal_map_invert_y=false -stream=false -size_limit=0 -detect_3d=true -svg/scale=1.0 diff --git a/addons/WAT/assets/play_debug.png b/addons/WAT/assets/play_debug.png deleted file mode 100644 index 42b8b60..0000000 Binary files a/addons/WAT/assets/play_debug.png and /dev/null differ diff --git a/addons/WAT/assets/play_debug.png.import b/addons/WAT/assets/play_debug.png.import deleted file mode 100644 index 376b0c0..0000000 --- a/addons/WAT/assets/play_debug.png.import +++ /dev/null @@ -1,35 +0,0 @@ -[remap] - -importer="texture" -type="StreamTexture" -path="res://.import/play_debug.png-b9aaa3991495e16a0dfe9e46268ae0a2.stex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://addons/WAT/assets/play_debug.png" -dest_files=[ "res://.import/play_debug.png-b9aaa3991495e16a0dfe9e46268ae0a2.stex" ] - -[params] - -compress/mode=0 -compress/lossy_quality=0.7 -compress/hdr_mode=0 -compress/bptc_ldr=0 -compress/normal_map=0 -flags/repeat=0 -flags/filter=true -flags/mipmaps=false -flags/anisotropic=false -flags/srgb=2 -process/fix_alpha_border=true -process/premult_alpha=false -process/HDR_as_SRGB=false -process/invert_color=false -process/normal_map_invert_y=false -stream=false -size_limit=0 -detect_3d=true -svg/scale=1.0 diff --git a/addons/WAT/assets/play_failed.png b/addons/WAT/assets/play_failed.png deleted file mode 100644 index e540eb3..0000000 Binary files a/addons/WAT/assets/play_failed.png and /dev/null differ diff --git a/addons/WAT/assets/play_failed.png.import b/addons/WAT/assets/play_failed.png.import deleted file mode 100644 index 2d2279e..0000000 --- a/addons/WAT/assets/play_failed.png.import +++ /dev/null @@ -1,35 +0,0 @@ -[remap] - -importer="texture" -type="StreamTexture" -path="res://.import/play_failed.png-206503f73ae232b267852de2008ff514.stex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://addons/WAT/assets/play_failed.png" -dest_files=[ "res://.import/play_failed.png-206503f73ae232b267852de2008ff514.stex" ] - -[params] - -compress/mode=0 -compress/lossy_quality=0.7 -compress/hdr_mode=0 -compress/bptc_ldr=0 -compress/normal_map=0 -flags/repeat=0 -flags/filter=true -flags/mipmaps=false -flags/anisotropic=false -flags/srgb=2 -process/fix_alpha_border=true -process/premult_alpha=false -process/HDR_as_SRGB=false -process/invert_color=false -process/normal_map_invert_y=false -stream=false -size_limit=0 -detect_3d=true -svg/scale=1.0 diff --git a/addons/WAT/assets/request_docs.svg b/addons/WAT/assets/request_docs.svg deleted file mode 100644 index 89c8735..0000000 --- a/addons/WAT/assets/request_docs.svg +++ /dev/null @@ -1 +0,0 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m9 0a4 4 0 0 0 -4 4 4 4 0 0 0 .55859 2.0273l-2.2656 2.2656 1.4141 1.4141 2.2656-2.2656a4 4 0 0 0 2.0273.55859 4 4 0 0 0 4-4 4 4 0 0 0 -4-4zm0 2a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2-2 2 2 0 0 1 2-2zm-9 8v6h2c1.6569 0 3-1.3431 3-3s-1.3431-3-3-3zm5 3c0 1.6569 1.3431 3 3 3s3-1.3431 3-3-1.3431-3-3-3-3 1.3431-3 3zm6 0c0 1.6569 1.3431 3 3 3h1v-2h-1c-.55228-.00001-.99999-.44772-1-1 .00001-.55228.44772-.99999 1-1h1v-2h-1c-1.6569 0-3 1.3431-3 3zm-9-1c.55228 0 1 .44772 1 1s-.44772 1-1 1zm6 0c.55228.00001.99999.44772 1 1-.0000096.55228-.44772.99999-1 1-.55228-.00001-.99999-.44772-1-1 .0000096-.55228.44772-.99999 1-1z" fill="#e0e0e0" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".32549" stroke-width="2"/></svg> diff --git a/addons/WAT/assets/request_docs.svg.import b/addons/WAT/assets/request_docs.svg.import deleted file mode 100644 index d4c8505..0000000 --- a/addons/WAT/assets/request_docs.svg.import +++ /dev/null @@ -1,35 +0,0 @@ -[remap] - -importer="texture" -type="StreamTexture" -path="res://.import/request_docs.svg-66a60c4eba54402104d46cbe772a490e.stex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://addons/WAT/assets/request_docs.svg" -dest_files=[ "res://.import/request_docs.svg-66a60c4eba54402104d46cbe772a490e.stex" ] - -[params] - -compress/mode=0 -compress/lossy_quality=0.7 -compress/hdr_mode=0 -compress/bptc_ldr=0 -compress/normal_map=0 -flags/repeat=0 -flags/filter=true -flags/mipmaps=false -flags/anisotropic=false -flags/srgb=2 -process/fix_alpha_border=true -process/premult_alpha=false -process/HDR_as_SRGB=false -process/invert_color=false -process/normal_map_invert_y=false -stream=false -size_limit=0 -detect_3d=true -svg/scale=1.0 diff --git a/addons/WAT/assets/script.png b/addons/WAT/assets/script.png deleted file mode 100644 index 78399c7..0000000 Binary files a/addons/WAT/assets/script.png and /dev/null differ diff --git a/addons/WAT/assets/script.png.import b/addons/WAT/assets/script.png.import deleted file mode 100644 index 926520b..0000000 --- a/addons/WAT/assets/script.png.import +++ /dev/null @@ -1,35 +0,0 @@ -[remap] - -importer="texture" -type="StreamTexture" -path="res://.import/script.png-6590c0f9543eaeb2a6b5b8ca50aae436.stex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://addons/WAT/assets/script.png" -dest_files=[ "res://.import/script.png-6590c0f9543eaeb2a6b5b8ca50aae436.stex" ] - -[params] - -compress/mode=0 -compress/lossy_quality=0.7 -compress/hdr_mode=0 -compress/bptc_ldr=0 -compress/normal_map=0 -flags/repeat=0 -flags/filter=true -flags/mipmaps=false -flags/anisotropic=false -flags/srgb=2 -process/fix_alpha_border=true -process/premult_alpha=false -process/HDR_as_SRGB=false -process/invert_color=false -process/normal_map_invert_y=false -stream=false -size_limit=0 -detect_3d=true -svg/scale=1.0 diff --git a/addons/WAT/assets/timer.png b/addons/WAT/assets/timer.png deleted file mode 100644 index 6cc5524..0000000 Binary files a/addons/WAT/assets/timer.png and /dev/null differ diff --git a/addons/WAT/assets/timer.png.import b/addons/WAT/assets/timer.png.import deleted file mode 100644 index f7e95b3..0000000 --- a/addons/WAT/assets/timer.png.import +++ /dev/null @@ -1,35 +0,0 @@ -[remap] - -importer="texture" -type="StreamTexture" -path="res://.import/timer.png-16c233793d4e507805f02aeac7ec3915.stex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://addons/WAT/assets/timer.png" -dest_files=[ "res://.import/timer.png-16c233793d4e507805f02aeac7ec3915.stex" ] - -[params] - -compress/mode=0 -compress/lossy_quality=0.7 -compress/hdr_mode=0 -compress/bptc_ldr=0 -compress/normal_map=0 -flags/repeat=0 -flags/filter=true -flags/mipmaps=false -flags/anisotropic=false -flags/srgb=2 -process/fix_alpha_border=true -process/premult_alpha=false -process/HDR_as_SRGB=false -process/invert_color=false -process/normal_map_invert_y=false -stream=false -size_limit=0 -detect_3d=true -svg/scale=1.0 diff --git a/addons/WAT/cli.tscn b/addons/WAT/cli.tscn deleted file mode 100644 index 37f2841..0000000 --- a/addons/WAT/cli.tscn +++ /dev/null @@ -1,6 +0,0 @@ -[gd_scene load_steps=2 format=2] - -[ext_resource path="res://addons/WAT/ui/cli.gd" type="Script" id=1] - -[node name="Commandline" type="Node"] -script = ExtResource( 1 ) diff --git a/addons/WAT/double/factory.gd b/addons/WAT/double/factory.gd deleted file mode 100644 index 6dd38bf..0000000 --- a/addons/WAT/double/factory.gd +++ /dev/null @@ -1,66 +0,0 @@ -extends Node - -const ScriptDirector = preload("script_director.gd") -const SceneDirector = preload("scene_director.gd") -var registry - -func clear() -> void: - # Allow users to clear registry in the post hook if they want fresh values between runs - registry.clear() - for director in registry.test_directors.values() : - director.free() - registry.test_directors.clear() - -func script(path, inner: String = "", deps: Array = []) -> ScriptDirector: - if path is GDScript: path = path.resource_path - return ScriptDirector.new(registry, path, inner, deps) - -func scene(tscn) -> SceneDirector: - # Must be String.tscn or PackedScene - var scene: PackedScene = load(tscn) if tscn is String else tscn - var instance: Node = scene.instance() - var nodes: Dictionary = {} - var frontier: Array = [] - frontier.append(instance) - while not frontier.empty(): - var next: Node = frontier.pop_front() - if next.name.begins_with("@@"): - # Don't double engine-generated classes (usually begin with @@) - continue - frontier += next.get_children() - var path: String = instance.get_path_to(next) - if next.get_script() != null: - nodes[path] = script(next.get_script().resource_path) - elif ClassDB.class_exists(next.get_class()): - nodes[path] = script(next.get_class()) - _set_nodepath_variables(instance, nodes) - var export_values = _get_exported_variable_values(instance) - instance.queue_free() - return SceneDirector.new(nodes, export_values) - -func _set_nodepath_variables(instance, nodes: Dictionary): - # Nodepath Variables Are Exported - # Which means they are typically not shared by instances - # Therefore we got to do it manually - for path in nodes: - var source = instance.get_node(path) - var copy = nodes[path] - for prop in source.get_property_list(): - if(prop.type == TYPE_NODE_PATH and prop.name != "_import_path"): - var exported_value = source.get(prop.name) as NodePath - copy.nodepaths[prop.name] = exported_value as NodePath - -# We need this script to be inside the tree to prevent some errors... -# ..everything should be fine if the instance isn't a tool script I think.. -# ..at least in editor -func _get_exported_variable_values(instance) -> Dictionary: - var exported: Dictionary = {} - add_child(instance) - for prop in instance.get_property_list(): - if _is_exported_variable(prop.usage): - exported[prop.name] = instance.get(prop.name) - remove_child(instance) - return exported - -func _is_exported_variable(usage: int) -> bool: - return usage == PROPERTY_USAGE_DEFAULT + PROPERTY_USAGE_SCRIPT_VARIABLE diff --git a/addons/WAT/double/method.gd b/addons/WAT/double/method.gd deleted file mode 100644 index c618b6e..0000000 --- a/addons/WAT/double/method.gd +++ /dev/null @@ -1,97 +0,0 @@ -extends Reference - -var name: String = "" -var spying: bool = false -var stubbed: bool = false -var calls_super: bool = false -var args: String = "" -var args_with_defaults: String = "" -var keyword: String = "" -var calls: Array = [] -var stubs: Array = [] -var supers: Array = [] -var callables: Array = [] -var default -var double - -func _init(name: String, keyword: String, args: String, defaults: String) -> void: - self.name = name - self.keyword = keyword - self.args = args - self.args_with_defaults = defaults - -func dummy() -> Reference: - stubbed = true - default = null - return self - -func spy() -> Reference: - push_warning("Deprecated. Spying on Methods is now Automatic. Please Remove") - spying = true - return self - -func stub(return_value, arguments: Array = []): - stubbed = true - if arguments.empty(): - default = return_value - else: - stubs.append({args = arguments, "return_value": return_value}) - return self - -func primary(args: Array): - if stubbed: - return get_stub(args) - elif calls.size() > 0: - for call in callables: - return call.call_func(double, args) - else: - return null - -func add_call(args: Array = []) -> void: - calls.append(args) - -func subcall(function: Object, deprecated_var = null) -> void: - if deprecated_var != null: - push_warning("Users no longer need to pass in the return boolean") - callables.append(function) - -func get_stub(args: Array = []): - for stub in stubs: - if _pattern_matched(stub.args, args): - return stub.return_value - return default - -func executes(args: Array) -> bool: - for s in supers: - if _pattern_matched(s, args): - return true - for s in stubs: - if _pattern_matched(s.args, args): - return false - if supers.has([]): - return true - return false - -func call_super(args: Array = []) -> void: - supers.append(args) - calls_super = true - -func found_matching_call(expected_args: Array = []) -> bool: - for call in calls: - if _pattern_matched(expected_args, call): - return true - return false - -func _pattern_matched(pattern: Array = [], args: Array = []) -> bool: - var indices: Array = [] - if pattern.size() != args.size(): - return false - for index in pattern.size(): - if pattern[index] is Object and pattern[index].get_class() == "Any": - continue - indices.append(index) - for i in indices: - # We check based on type first otherwise some errors occur (ie object can't be compared to int) - if typeof(pattern[i]) != typeof(args[i]) or pattern[i] != args[i]: - return false - return true diff --git a/addons/WAT/double/methods.gd b/addons/WAT/double/methods.gd deleted file mode 100644 index b9e5bc7..0000000 --- a/addons/WAT/double/methods.gd +++ /dev/null @@ -1,9 +0,0 @@ -extends Reference - -var base: Array = [] - -func set_base_methods(director: Reference) -> void: - pass - -func call_count(): - pass diff --git a/addons/WAT/double/registry.gd b/addons/WAT/double/registry.gd deleted file mode 100644 index 400cebc..0000000 --- a/addons/WAT/double/registry.gd +++ /dev/null @@ -1,26 +0,0 @@ -extends Object - -var test_directors: Dictionary = {} - -func register(director) -> void: - # This probably doesn't need to exist as a singleton? - # We could likely store a cache within each test - # This way we can isolate it from other caches - # (We could even probably store it directly within the factory) - if director.get_instance_id() in test_directors: - push_warning("Director Object is already registered") - return - test_directors[director.get_instance_id()] = director - -func method(instance_id: int, method: String) -> Object: - return test_directors[instance_id].methods[method] - -func clear() -> void: - var directors = test_directors.values() - while not directors.empty(): - var director = directors.pop_back() - director.clear() - -func _notification(what): - if what == NOTIFICATION_PREDELETE: - clear() diff --git a/addons/WAT/double/scene_director.gd b/addons/WAT/double/scene_director.gd deleted file mode 100644 index de92da0..0000000 --- a/addons/WAT/double/scene_director.gd +++ /dev/null @@ -1,54 +0,0 @@ -extends Reference -tool -# We don't seem to need tool here yet but I'm keeping this comment JIC - -var nodes: Dictionary = {} -var _created: bool = false -var cache: Array = [] -var _export_vars = {} - -func _init(nodes: Dictionary = {}, export_vars = {}) -> void: - self.nodes = nodes - _export_vars = export_vars - -func get_node(path: String) -> Node: - return nodes[path] - -func double() -> Node: - if _created: - push_error("WAT: You can only create one instance of a double" - + "Create a new doubler Object for new Test Doubles") - return nodes["."] - _created = true - var root: Node = nodes["."].double() - for nodepath in nodes: - var path: PoolStringArray = nodepath.split("/") - if nodepath == ".": - # Skip if root node since already defined - continue - elif path.size() == 1: - _add_child(path, nodepath, root) - elif path.size() > 1: - _add_grandchild(path, nodepath, root) - for prop_name in _export_vars: - root.set(prop_name, _export_vars[prop_name]) - return root - -func _add_child(path: PoolStringArray, nodepath: String, root: Node) -> void: - var node: Node = nodes[nodepath].double() - node.name = path[0] - root.add_child(node) - -func _add_grandchild(path: PoolStringArray, nodepath: String, root: Node) -> void: - var node: Node = nodes[nodepath].double() - var p = Array(path) - node.name = p.pop_back() - var parent = "" - for element in p: - parent += "%s/" % element - parent = parent.rstrip("/") - var grandparent = root.get_node(parent) - grandparent.add_child(node) - -func clear() -> void: - nodes = {} diff --git a/addons/WAT/double/script_director.gd b/addons/WAT/double/script_director.gd deleted file mode 100644 index 200d278..0000000 --- a/addons/WAT/double/script_director.gd +++ /dev/null @@ -1,151 +0,0 @@ -extends Reference - -const STATIC: String = "static " -const REMOTE: String = "remote " -const REMOTESYNC: String = "remotesync " -const MASTER: String = "master " -const PUPPET: String = "puppet " -const SCRIPT_WRITER = preload("script_writer.gd") -const Method = preload("method.gd") -var klass: String -var inner_klass: String = "" -var methods: Dictionary = {} -var _created: bool = false -var is_scene: bool = false -var klasses: Array = [] -var base_methods: Dictionary = {} -var dependecies: Array = [] -var is_built_in: bool = false -var object -var registry - -# Used to handle exported nodepaths -# <var name> <var value> -var nodepaths: Dictionary = {} - -func _init(_registry, _klass: String, _inner_klass: String, deps: Array = []) -> void: - klass = _klass - inner_klass = _inner_klass - dependecies = deps - is_built_in = ClassDB.class_exists(_klass) - registry = _registry - registry.register(self) - set_methods() - -func method(name: String, keyword: String = "") -> Method: - if not methods.has(name): - methods[name] = Method.new(name, keyword, base_methods[name].arguments, base_methods[name].default_arguments) - return methods[name] - -func clear(): - if is_instance_valid(object) and object is Object and not object is Reference: - object.free() - object = null - -## BEGIN METHOD CLASS -func call_count(method: String) -> int: - return methods[method].calls.size() - -func get_stub(method: String, args: Array): - # We might be able to write this into source? - # However reducing how much we write might be best - return methods[method].get_stub(args) - -func found_matching_call(method, expected_args: Array): - # Requires changing an expectation method - return methods[method].found_matching_call(expected_args) - -func add_call(method: String, args: Array = []) -> void: - methods[method].add_call(args) - -func set_methods() -> void: - var params: String = "abcdefghij" - for m in method_list(): - var arguments: String = "" - # m.args.size() causes crashes in release exports - var idx = 0 - for i in m.args: - arguments = arguments + params[idx] + ", " - idx += 1 - var sanitized = arguments.replace(", ", "") - arguments = arguments.rstrip(", ") - var default_args = arguments - var def_idx = 0 - # m.default_args.size() causes crashes in release exports - for def in m.default_args: - def_idx += 1 - if def_idx > 0: - default_args = get_args_with_default(sanitized, m.default_args) - base_methods[m.name] = {"arguments": arguments, "default_arguments": default_args} - -func get_args_with_default(args: String, base_default_args: Array) -> String: - var retval_args: String - var substr_start = args.length() - base_default_args.size() - var length = args.length() # We're transforming in loop so we capture first - var arg_index = 0 - for i in length: - if i < substr_start: - retval_args += "%s, " % args[i] - continue - var letter = args[i] - var arg = base_default_args[arg_index] - if arg is String: - retval_args += '%s = "%s", ' % [letter, str(arg)] - else: - retval_args += '%s = %s, ' % [letter, arg] - arg_index += 1 - retval_args = retval_args.rstrip(", ") - return retval_args - -func method_list() -> Array: - var list: Array = [] - if is_built_in: - return ClassDB.class_get_method_list(klass) - var script = load(klass) if inner_klass == "" else _load_nested_class() -# # We get our script methods first in case there is a custom constructor -# # This way we don't end up reading the empty base constructors of Object - list += script.get_script_method_list() - list += ClassDB.class_get_method_list(script.get_instance_base_type()) - var filtered = {} - for m in list: - if m.name in filtered: - continue - filtered[m.name] = m - return filtered.values() -## END METHOD CLASS - -func add_inner_class(klass: Object, name: String) -> void: - klasses.append({"director": klass, "name": name}) - -func script(): - var script = GDScript.new() - for klass in klasses: - klass.director.script() - script.source_code = SCRIPT_WRITER.new().write(self) - script.reload() # Necessary to load source code into memory - return script - -func double(deps: Array = [], show_error = true) -> Object: - if _created: - # Can only create unique instances - if show_error: - push_error("WAT: You can only create one instance of a double. Create a new doubler Object for new Test Doubles") - return object - _created = true - if not deps.empty() and dependecies.empty(): - dependecies = deps - object = script().callv("new", dependecies) - object.WATRegistry.append(registry) - for m in methods.values(): - m.double = object - for prop_name in nodepaths: - object.set(prop_name, nodepaths[prop_name]) - return object - - - -func _load_nested_class() -> Script: - var expression = Expression.new() - var script = load(klass) - expression.parse("%s" % [inner_klass]) - return expression.execute([], script, true) diff --git a/addons/WAT/double/script_writer.gd b/addons/WAT/double/script_writer.gd deleted file mode 100644 index 22ea199..0000000 --- a/addons/WAT/double/script_writer.gd +++ /dev/null @@ -1,47 +0,0 @@ -extends Reference - - -func write(double) -> String: - var source: String = "" - source += _extension_to_string(double) - source += "\nconst WATRegistry = []\n" - if double.base_methods.has("_init"): - source += _constructor_to_string(double.base_methods["_init"].arguments) - - for name in double.methods: - var m = double.methods[name] - source += _method_to_string(double.get_instance_id(), m) - for klass in double.klasses: - source += _inner_class(klass) - source = source.replace(",)", ")") - return source - -func _extension_to_string(double) -> String: - if double.is_built_in: - return 'extends %s' % double.klass - if double.inner_klass != "": - return 'extends "%s".%s\n' % [double.klass, double.inner_klass] - return 'extends "%s"\n' % double.klass - -func _constructor_to_string(parameters: String) -> String: - var constructor: String = "" - constructor += "\nfunc _init(%s).(%s):" % [parameters, parameters] - constructor += "\n\tpass\n" - return constructor - -func _method_to_string(id: int, method: Object) -> String: - var text: String - text += "{keyword}func {name}({args_with_defaults}):" - text += "\n\tvar args = [{args}]" - text += "\n\tvar method = WATRegistry[0].method({id}, '{name}')" - text += "\n\tmethod.add_call(args)" - text += "\n\tif method.executes(args):" - text += "\n\t\treturn .{name}({args})" # We may want to add a retval check here - text += "\n\treturn method.primary(args)\n\n" - text = text.format({"id": id, "keyword": method.keyword, - "name": method.name, "args_with_defaults": method.args_with_defaults, - "args": method.args}) - return text - -func _inner_class(klass: Dictionary) -> String: - return "\nclass %s extends '%s'.%s:\n\tconst PLACEHOLDER = 0" % [klass.name, klass.director.klass, klass.name] diff --git a/addons/WAT/filesystem/directory.gd b/addons/WAT/filesystem/directory.gd deleted file mode 100644 index a05c18c..0000000 --- a/addons/WAT/filesystem/directory.gd +++ /dev/null @@ -1,28 +0,0 @@ -extends Reference - -var is_root: bool = false -var name: String setget ,_get_sanitized_name -var path: String setget ,_get_path -var relative_subdirs: Array -var nested_subdirs: Array -var tests: Array = [] - -func _get_sanitized_name() -> String: - # Required for interface compability - return path - -func _get_path() -> String: - # res:/// should be res://f - return path.replace("///", "//") # - -func get_tests() -> Array: - var requested: Array = [] - if is_root: - for subdir in nested_subdirs: - requested += subdir.get_tests() - for script in tests: - requested += script.get_tests() - return requested - -func is_empty() -> bool: - return tests.empty() diff --git a/addons/WAT/filesystem/failed.gd b/addons/WAT/filesystem/failed.gd deleted file mode 100644 index 700d1d1..0000000 --- a/addons/WAT/filesystem/failed.gd +++ /dev/null @@ -1,19 +0,0 @@ -extends Reference - -var paths: Array = [] -var _tests: Array = [] - -func update(results: Array) -> void: - paths.clear() - for result in results: - if not result["success"]: - paths.append(result["path"]) - -func set_tests(root: Reference) -> void: - _tests.clear() - for test in root.get_tests(): - if paths.has(test["path"]): - _tests.append(test) - -func get_tests() -> Array: - return _tests diff --git a/addons/WAT/filesystem/filesystem.gd b/addons/WAT/filesystem/filesystem.gd deleted file mode 100644 index 3e26617..0000000 --- a/addons/WAT/filesystem/filesystem.gd +++ /dev/null @@ -1,111 +0,0 @@ -extends Reference - -const TestDirectory: GDScript = preload("directory.gd") -const TestScript: GDScript = preload("script.gd") -const TestMethod: GDScript = preload("method.gd") -const FailedTests: GDScript = preload("failed.gd") -const TaggedTests: GDScript = preload("tagged.gd") -const Settings: GDScript = preload("res://addons/WAT/settings.gd") -const YieldCalculator: GDScript = preload("yield_calculator.gd") -const Validator: GDScript = preload("validator.gd") -const DO_NOT_SEARCH_PARENT_DIRECTORIES: bool = true -var root: TestDirectory -var tagged: TaggedTests -var failed: FailedTests -var changed: bool = false setget _set_filesystem_changed -var built: bool = false setget ,_get_filesystem_built # CSharpScript -var build_function: FuncRef -var index = {} # Path / Object -var test_validator: Reference - -# Initialize/Save meta -func _init(_build_function = null) -> void: - build_function = _build_function - tagged = TaggedTests.new(Settings) - failed = FailedTests.new() - test_validator = Validator.new() - -func _set_filesystem_changed(has_changed: bool) -> void: - changed = has_changed - if has_changed or ClassDB.class_exists("CSharpScript"): - built = false - -func _get_filesystem_built() -> bool: - # If not Mono, return true because it is irrelevant to GDScript. - return built or not Engine.is_editor_hint() or not ClassDB.class_exists("CSharpScript") - -func _recursive_update(testdir: TestDirectory) -> void: - var dir: Directory = Directory.new() - var err: int = dir.open(testdir.path) - if err != OK: - push_warning("WAT: Could not update filesystem") - return - - var subdirs: Array = [] - dir.list_dir_begin(DO_NOT_SEARCH_PARENT_DIRECTORIES) - var absolute: String = "" - var relative: String = dir.get_next() - while relative != "": - absolute = "%s/%s" % [testdir.path, relative] - - # /. deals with most things like .git, .import, .mono etc - if dir.current_is_dir() and not "/." in absolute and not "/addons" in absolute: - var sub_testdir: TestDirectory = TestDirectory.new() - sub_testdir.path = absolute - subdirs.append(sub_testdir) - index[sub_testdir.path] = sub_testdir - pass - - elif dir.file_exists(absolute): - var test_script: TestScript = _get_test_script(absolute) - if test_script: - testdir.tests.append(test_script) - test_script.dir = testdir.path - index[test_script.path] = test_script - - relative = dir.get_next() - - dir.list_dir_end() - - testdir.relative_subdirs += subdirs - testdir.nested_subdirs += subdirs - for subdir in subdirs: - _recursive_update(subdir) - testdir.nested_subdirs += subdir.nested_subdirs - -func update(testdir: TestDirectory = _get_root()) -> void: - _recursive_update(testdir) - # Set "changed" to false after the update, otherwise it is redundant. - changed = false - -func _get_root() -> TestDirectory: - index = {} - root = TestDirectory.new() - root.path = Settings.test_directory() - root.is_root = true - return root - -func _get_test_script(p: String) -> TestScript: - test_validator.load_path(p, changed) - var test_script: TestScript = null - if test_validator.is_valid_test(): - test_script = TestScript.new(p, test_validator.get_load_error()) - var script_instance = test_validator.script_instance - if script_instance: - test_script.names = script_instance.get_test_methods() - # Skip scripts with 0 defined test methods if validator allows. - if test_validator.skip_empty and test_script.names.empty(): - return null - for m in test_script.names: - var test_method: TestMethod = TestMethod.new() - test_method.path = p - test_method.name = m - test_script.methods.append(test_method) - index[test_script.path+m] = test_method - if p.ends_with(".gd") or p.ends_with(".gdc"): - test_script.time = YieldCalculator.calculate_yield_time( - test_validator.script_resource, test_script.names.size()) - return test_script - -func clear() -> void: - index.clear() diff --git a/addons/WAT/filesystem/method.gd b/addons/WAT/filesystem/method.gd deleted file mode 100644 index d451ed6..0000000 --- a/addons/WAT/filesystem/method.gd +++ /dev/null @@ -1,21 +0,0 @@ -extends Reference - -var path: String -var dir: String setget ,_get_path -var name: String setget ,_get_sanitized_name - -func _init(method_path: String = "", method_name: String = ""): - path = method_path - name = method_name - -# Method Name != test name -func get_tests() -> Array: - return [{"dir": dir, "name": name, "path": self.path, "methods": [name], "time": 0.0}] - -func _get_sanitized_name() -> String: - var n: String = name.replace("test_", "").replace("_", " ") - return n - -func _get_path() -> String: - # res:/// should be res:// - return path.replace("///", "//") # diff --git a/addons/WAT/filesystem/script.gd b/addons/WAT/filesystem/script.gd deleted file mode 100644 index 6b48760..0000000 --- a/addons/WAT/filesystem/script.gd +++ /dev/null @@ -1,30 +0,0 @@ -extends Reference - -var name: String setget ,_get_sanitized_name -var dir: String -var path: String setget ,_get_path -var methods: Array # TestMethods -var names: Array # MethodNames -var time: float = 0.0 # YieldTime -var parse: int # stores error code (int) of last load() - -# Constructor for script.gd reference. -# script_path: Resource path of the script. -# load_result: Error code when resource path is reloaded. -func _init(script_path: String = "", load_result: int = OK): - path = script_path - parse = load_result - -func _get_sanitized_name() -> String: - var n: String = path.substr(path.find_last("/") + 1) - n = n.replace(".gd", "").replace(".gdc", "").replace(".cs", "") - n = n.replace(".test", "").replace("test", "").replace("_", " ") - n[0] = n[0].to_upper() - return n - -func _get_path() -> String: - # res:/// should be res:// - return path.replace("///", "//") # - -func get_tests() -> Array: - return [{"dir": dir, "name": self.name, "path": self.path, "methods": names, "time": time, "parse": parse}] diff --git a/addons/WAT/filesystem/tagged.gd b/addons/WAT/filesystem/tagged.gd deleted file mode 100644 index 14d4552..0000000 --- a/addons/WAT/filesystem/tagged.gd +++ /dev/null @@ -1,45 +0,0 @@ -extends Reference -# Tag / Resource Path -var tagged: Dictionary = {} -var _settings: GDScript -var _tests: Array = [] - -func _init(settings: GDScript) -> void: - _settings = settings - update() - -func tag(tag: String, path: String) -> void: - update() - if not tagged[tag].has(path): - tagged[tag].append(path) - -func untag(tag: String, path: String) -> void: - update() - if tagged[tagged].has(path): - tagged[tag].erase(path) - -func is_tagged(tag: String, path: String) -> bool: - update() - return tagged[tag].has(path) - -func swap(old: String, new: String) -> void: - for tag in tagged: - if tagged[tag].has(old): - tagged[tag].erase(old) - tagged[tag].append(new) - -func update() -> void: - for tag in _settings.tags(): - if not tagged.has(tag): - tagged[tag] = [] - -func set_tests(tag: String, root: Reference) -> void: - _tests.clear() - for test in root.get_tests(): - if tagged[tag].has(test["path"]): - _tests.append(test) - -func get_tests() -> Array: - return _tests - - diff --git a/addons/WAT/filesystem/tracker.gd b/addons/WAT/filesystem/tracker.gd deleted file mode 100644 index 61ae218..0000000 --- a/addons/WAT/filesystem/tracker.gd +++ /dev/null @@ -1,56 +0,0 @@ -tool -extends Reference - -### This only works in the Editor Context. There are no similair methods.. -### ..available for the Scene Context. - -const Settings: GDScript = preload("res://addons/WAT/settings.gd") -var _file_system - -func _init(filesystem) -> void: - _file_system = filesystem - -func start_tracking_files(plugin: EditorPlugin) -> void: - var dock: FileSystemDock = plugin.get_editor_interface().get_file_system_dock() - for event in ["file_removed", "files_moved", "folder_moved", "folder_removed"]: - var callback: String = "_on_%s" % event - if not dock.is_connected(event, self, callback): - dock.connect(event, self, callback) - if not plugin.is_connected("resource_saved", self, "_on_resource_saved"): - plugin.connect("resource_saved", self, "_on_resource_saved") - -func _stop_tracking_files(plugin: EditorPlugin) -> void: - var dock: FileSystemDock = plugin.get_editor_interface().get_file_system_dock() - for event in ["file_removed", "files_moved", "folder_moved", "folder_removed"]: - var callback: String = "_on_%s" % event - if dock.is_connected(event, self, callback): - dock.disconnect(event, self, callback) - if plugin.is_connected("resource_saved", self, "_on_resource_saved"): - plugin.disconnect("resource_saved", self, "_on_resource_saved") - -func _on_filesystem_changed(has_changed: bool) -> void: - if has_changed: - _file_system.changed = true - -func _on_file_removed(file: String) -> void: - _on_filesystem_changed(file.begins_with(Settings.test_directory())) - -func _on_files_moved(old: String, new: String) -> void: - if old.begins_with(Settings.test_directory()) and new.begins_with(Settings.test_directory()): - _file_system.tagged.swap(old, new) - _on_filesystem_changed( - old.begins_with(Settings.test_directory()) - or new.begins_with(Settings.test_directory())) - - -func _on_folder_moved(old: String, new: String) -> void: - _on_filesystem_changed( - old.begins_with(Settings.test_directory()) - or new.begins_with(Settings.test_directory())) - -func _on_folder_removed(old: String) -> void: - _on_filesystem_changed(old.begins_with(Settings.test_directory())) - -func _on_resource_saved(resource: Resource) -> void: - _on_filesystem_changed( - resource.resource_path.begins_with(Settings.test_directory())) diff --git a/addons/WAT/filesystem/validator.gd b/addons/WAT/filesystem/validator.gd deleted file mode 100644 index 00970ab..0000000 --- a/addons/WAT/filesystem/validator.gd +++ /dev/null @@ -1,82 +0,0 @@ -extends Reference - -# To search broken script source for WAT.Test usage. -const WAT_TEST_PATTERN = "(\\bextends\\s+WAT.Test\\b)" + \ - "|(\\bextends\\b\\s+\\\"res:\\/\\/addons\\/WAT\\/test\\/test.gd\\\")" + \ - "|(class\\s\\w[\\w<>]+\\s*:\\s*WAT.Test[\\s\\{])" - -var path: String setget load_path -var regex: RegEx -var script_resource: Script setget ,get_script_resource -var script_instance setget ,get_script_instance -# If true, test scripts with 0 defined test methods should be skipped. -var skip_empty: bool = true - -func _init(regex_pattern = WAT_TEST_PATTERN): - regex = RegEx.new() - regex.compile(regex_pattern) - -# Frees the script_instance on destroy. -func _notification(what: int) -> void: - if what == NOTIFICATION_PREDELETE and is_instance_valid(script_instance): - # Cannot call _clear_resource() at predelete stage. - script_instance.free() - -# Clears the script resource and frees the script instance. -func _clear_resource() -> void: - if is_instance_valid(script_instance): - script_instance.free() - script_instance = null - script_resource = null - -# Checks if the Script's source code is matching the compiled regex pattern. -func _is_matching_regex_pattern() -> bool: - return true if script_resource and \ - regex.search(script_resource.source_code) else false - -func _is_valid_gdscript() -> bool: - return path.ends_with(".gd") and path != "res://addons/WAT/test/test.gd" - -func _is_valid_compiled_gdscript() -> bool: - return path.ends_with(".gdc") and path != "res://addons/WAT/test/test.gdc" - -func _is_valid_csharp() -> bool: - return path.ends_with(".cs") and not "addons/WAT" in path - -func _is_valid_file() -> bool: - return _is_valid_gdscript() or _is_valid_compiled_gdscript() or \ - (ClassDB.class_exists("CSharpScript") and _is_valid_csharp()) - -func is_valid_test() -> bool: - return get_script_resource() and get_script_instance() or \ - get_load_error() == ERR_PARSE_ERROR and _is_matching_regex_pattern() - -# Returns error code during resource load. -func get_load_error() -> int: - var error = ERR_SKIP - if script_resource: - # Script resource with 0 methods signify parse error / uncompiled. - # Loaded scripts always have at least one method from its base class. - error = OK if not script_resource.get_script_method_list().empty() \ - else ERR_PARSE_ERROR - return error - -func get_script_instance(): - # Create script_instance if no errors are found. Performed once and stored. - if not script_instance and get_load_error() == OK and \ - (script_resource.get("IS_WAT_TEST") if not _is_valid_csharp() \ - else _is_matching_regex_pattern()): - script_instance = script_resource.new() - return script_instance - -func get_script_resource() -> Script: - return script_resource - -func load_path(resource_path: String, refresh: bool = true) -> void: - _clear_resource() - path = resource_path - if _is_valid_file(): - # .cs scripts should load from cache due to how it is compiled. - # .gd scripts need to be reloaded on filesystem update. - script_resource = ResourceLoader.load(path, "Script", - refresh and not _is_valid_csharp()) diff --git a/addons/WAT/filesystem/yield_calculator.gd b/addons/WAT/filesystem/yield_calculator.gd deleted file mode 100644 index 318c7a3..0000000 --- a/addons/WAT/filesystem/yield_calculator.gd +++ /dev/null @@ -1,35 +0,0 @@ -extends Reference - -const COMMENT: String = "#" -const PRE_HOOK: String = "func pre()" -const POST_HOOK: String = "func post()" -const FUNCTION: String = "func" -const OPENING_STRING_QUOTE: String = '"' - -static func calculate_yield_time(gdscript: Script, test_method_count: int) -> float: - var time: float = 0.0 - var floats: PoolRealArray = PoolRealArray() - var in_hook: bool = false - for line in gdscript.source_code.split("\n"): - if line.begins_with(PRE_HOOK) or line.begins_with(POST_HOOK): - # Yielding pre or post requires counting for each test method - in_hook = true - elif line.begins_with(FUNCTION): - in_hook = false - if "YIELD" in line and not line.begins_with(COMMENT) and not line.begins_with(OPENING_STRING_QUOTE): - var f: PoolRealArray = PoolRealArray() - f += line.split_floats("(") - f += line.split_floats(",") - if in_hook: - f = duplicate(f, test_method_count) - floats += f - for real in floats: - time += real - return time - -static func duplicate(source: PoolRealArray, count: int) -> PoolRealArray: - var floats: PoolRealArray = PoolRealArray() - for real in source: - for i in count: - floats.append(real) - return floats diff --git a/addons/WAT/gui.tscn b/addons/WAT/gui.tscn deleted file mode 100644 index 22d8ed6..0000000 --- a/addons/WAT/gui.tscn +++ /dev/null @@ -1,258 +0,0 @@ -[gd_scene load_steps=23 format=2] - -[ext_resource path="res://addons/WAT/ui/gui.gd" type="Script" id=1] -[ext_resource path="res://addons/WAT/assets/play.png" type="Texture" id=2] -[ext_resource path="res://addons/WAT/ui/summary.gd" type="Script" id=3] -[ext_resource path="res://addons/WAT/ui/links.gd" type="Script" id=4] -[ext_resource path="res://addons/WAT/ui/scaling/dynamic_size_spinbox.gd" type="Script" id=5] -[ext_resource path="res://addons/WAT/ui/results/tab_container.gd" type="Script" id=6] -[ext_resource path="res://addons/WAT/ui/test_menu.gd" type="Script" id=9] -[ext_resource path="res://addons/WAT/assets/play_debug.png" type="Texture" id=10] -[ext_resource path="res://addons/WAT/assets/timer.png" type="Texture" id=11] -[ext_resource path="res://addons/WAT/assets/kofi.png" type="Texture" id=13] -[ext_resource path="res://addons/WAT/assets/script.png" type="Texture" id=14] -[ext_resource path="res://addons/WAT/assets/issue.svg" type="Texture" id=16] -[ext_resource path="res://addons/WAT/assets/failed.png" type="Texture" id=17] -[ext_resource path="res://addons/WAT/assets/passed.png" type="Texture" id=18] -[ext_resource path="res://addons/WAT/network/test_server.gd" type="Script" id=19] - -[sub_resource type="StyleBoxEmpty" id=1] - -[sub_resource type="StyleBoxEmpty" id=2] - -[sub_resource type="StyleBoxEmpty" id=3] - -[sub_resource type="StyleBoxEmpty" id=4] - -[sub_resource type="StyleBoxEmpty" id=5] - -[sub_resource type="InputEventKey" id=6] - -[sub_resource type="ShortCut" id=7] -shortcut = SubResource( 6 ) - -[node name="Tests" type="PanelContainer"] -anchor_right = 1.0 -anchor_bottom = 1.0 -size_flags_horizontal = 3 -size_flags_vertical = 3 -script = ExtResource( 1 ) - -[node name="Core" type="VBoxContainer" parent="."] -margin_left = 7.0 -margin_top = 7.0 -margin_right = 1017.0 -margin_bottom = 593.0 -size_flags_horizontal = 3 -size_flags_vertical = 3 -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="Menu" type="HBoxContainer" parent="Core"] -margin_right = 617.0 -margin_bottom = 24.0 -focus_mode = 2 -size_flags_horizontal = 0 -size_flags_vertical = 0 -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="RunAll" type="Button" parent="Core/Menu"] -margin_top = 4.0 -margin_right = 16.0 -margin_bottom = 20.0 -hint_tooltip = "Run All (Non Debug)" -size_flags_horizontal = 0 -size_flags_vertical = 4 -custom_styles/hover = SubResource( 1 ) -custom_styles/pressed = SubResource( 2 ) -custom_styles/focus = SubResource( 3 ) -custom_styles/disabled = SubResource( 4 ) -custom_styles/normal = SubResource( 5 ) -shortcut = SubResource( 7 ) -icon = ExtResource( 2 ) -flat = true - -[node name="Space1" type="Control" parent="Core/Menu"] -margin_left = 20.0 -margin_right = 23.0 -margin_bottom = 24.0 -rect_min_size = Vector2( 3, 0 ) - -[node name="DebugAll" type="Button" parent="Core/Menu"] -margin_left = 27.0 -margin_top = 4.0 -margin_right = 43.0 -margin_bottom = 20.0 -hint_tooltip = "Run All (With Debugger)" -size_flags_horizontal = 0 -size_flags_vertical = 4 -custom_styles/hover = SubResource( 1 ) -custom_styles/pressed = SubResource( 2 ) -custom_styles/focus = SubResource( 3 ) -custom_styles/disabled = SubResource( 4 ) -custom_styles/normal = SubResource( 5 ) -shortcut = SubResource( 7 ) -icon = ExtResource( 10 ) -flat = true - -[node name="Space2" type="Control" parent="Core/Menu"] -margin_left = 47.0 -margin_right = 50.0 -margin_bottom = 24.0 -rect_min_size = Vector2( 3, 0 ) - -[node name="Space4" type="Control" parent="Core/Menu"] -margin_left = 54.0 -margin_right = 57.0 -margin_bottom = 24.0 -rect_min_size = Vector2( 3, 0 ) - -[node name="TestMenu" type="Button" parent="Core/Menu"] -margin_left = 61.0 -margin_right = 150.0 -margin_bottom = 24.0 -size_flags_horizontal = 0 -size_flags_vertical = 5 -text = "Select Tests" -flat = true -script = ExtResource( 9 ) - -[node name="ResultsMenu" type="MenuButton" parent="Core/Menu"] -margin_left = 154.0 -margin_right = 250.0 -margin_bottom = 24.0 -focus_mode = 2 -size_flags_horizontal = 0 -size_flags_vertical = 5 -text = "Filter Results" -items = [ "Expand All", null, 0, false, false, 0, 0, null, "", false, "Collapse All", null, 0, false, false, 1, 0, null, "", false, "Expand All Failures", null, 0, false, false, 2, 0, null, "", false ] - -[node name="RunSettings" type="HBoxContainer" parent="Core/Menu"] -margin_left = 254.0 -margin_right = 568.0 -margin_bottom = 24.0 -size_flags_horizontal = 0 -size_flags_vertical = 4 -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="Repeats" type="SpinBox" parent="Core/Menu/RunSettings"] -margin_right = 150.0 -margin_bottom = 24.0 -rect_min_size = Vector2( 150, 0 ) -size_flags_horizontal = 0 -size_flags_vertical = 0 -align = 1 -prefix = "Repeat" -suffix = "Time(s)" -script = ExtResource( 5 ) - -[node name="Threads" type="SpinBox" parent="Core/Menu/RunSettings"] -margin_left = 154.0 -margin_right = 314.0 -margin_bottom = 24.0 -rect_min_size = Vector2( 160, 0 ) -size_flags_horizontal = 0 -size_flags_vertical = 0 -min_value = 1.0 -max_value = 15.0 -value = 1.0 -align = 1 -prefix = "Run on" -suffix = "Thread(s)" -script = ExtResource( 5 ) - -[node name="Links" type="MenuButton" parent="Core/Menu"] -margin_left = 572.0 -margin_right = 617.0 -margin_bottom = 24.0 -focus_mode = 2 -size_flags_horizontal = 0 -size_flags_vertical = 5 -text = "Links" -items = [ "Support WAT", ExtResource( 13 ), 0, false, false, 0, 0, "https://ko-fi.com/alexanddraw", "", false, "Report an Issue", ExtResource( 16 ), 0, false, false, 1, 0, "https://github.com/AlexDarigan/WAT/issues/new", "", false ] -script = ExtResource( 4 ) - -[node name="Results" type="TabContainer" parent="Core"] -margin_top = 28.0 -margin_right = 1010.0 -margin_bottom = 560.0 -rect_min_size = Vector2( 0, 300 ) -size_flags_horizontal = 3 -size_flags_vertical = 3 -tab_align = 0 -script = ExtResource( 6 ) -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="Summary" type="HBoxContainer" parent="Core"] -margin_top = 564.0 -margin_right = 1010.0 -margin_bottom = 586.0 -size_flags_horizontal = 3 -script = ExtResource( 3 ) -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="Runs" type="Button" parent="Core/Summary"] -margin_right = 50.0 -margin_bottom = 22.0 -rect_min_size = Vector2( 50, 0 ) -focus_mode = 0 -button_mask = 0 -text = "0" -icon = ExtResource( 2 ) -flat = true - -[node name="Tests" type="Button" parent="Core/Summary"] -margin_left = 54.0 -margin_right = 104.0 -margin_bottom = 22.0 -rect_min_size = Vector2( 50, 0 ) -focus_mode = 0 -button_mask = 0 -text = "0" -icon = ExtResource( 14 ) -flat = true - -[node name="Passing" type="Button" parent="Core/Summary"] -margin_left = 108.0 -margin_right = 158.0 -margin_bottom = 22.0 -rect_min_size = Vector2( 50, 0 ) -focus_mode = 0 -button_mask = 0 -text = "0" -icon = ExtResource( 18 ) -flat = true - -[node name="Failing" type="Button" parent="Core/Summary"] -margin_left = 162.0 -margin_right = 212.0 -margin_bottom = 22.0 -rect_min_size = Vector2( 50, 0 ) -focus_mode = 0 -button_mask = 0 -text = "0" -icon = ExtResource( 17 ) -flat = true - -[node name="Time" type="Button" parent="Core/Summary"] -margin_left = 216.0 -margin_right = 266.0 -margin_bottom = 22.0 -rect_min_size = Vector2( 50, 0 ) -focus_mode = 0 -button_mask = 0 -text = "0" -icon = ExtResource( 11 ) -flat = true - -[node name="Server" type="Node" parent="."] -script = ExtResource( 19 ) diff --git a/addons/WAT/io/junit_xml.gd b/addons/WAT/io/junit_xml.gd deleted file mode 100644 index b2350ba..0000000 --- a/addons/WAT/io/junit_xml.gd +++ /dev/null @@ -1,41 +0,0 @@ -extends Script - -static func write(results, settings: Reference, time: float = 0.0) -> void: - var path: String - if not settings.results_directory(): - push_warning("WAT: Cannot find results directory. Defaulting to root to write Junit XML") - path = "res://" - else: - path = settings.results_directory() - if not Directory.new().dir_exists(path): - Directory.new().make_dir_recursive(path) - var tests: int = results.size() - var failures: int = 0 - for i in results: - if not i.success: - failures += 1 - var output: String = "" - output += '<?xml version="1.0" ?>' - output += '\n<testsuites failures="%s" name="TestXML" tests="%s" time="%s">' % [failures, tests, time] - for result in results: - output += '\n\t<testsuite name="%s" failures="%s" tests="%s" time="%s">' % [result.context, result.total - result.passed, result.total, result.time_taken] - if result.methods.empty(): - output += '\n\t\t<testcase name="Not Found" time="0">' - output += '<failure message="No Tests Found On Suite %s"></failure>' % result.path - output += "</testcase>" - for case in result.methods: - output += '\n\t\t<testcase name="%s" time="%s">' % [case.context, case.time] - for assertion in case.assertions: - if not assertion.success: - output += '\n\t\t\t<failure message="EXPECTED: %s but GOT %s"></failure>' % [assertion.expected, assertion.actual] - # I think these are unnecessary. Will revisit on CLI creation. - output += '</testcase>' - output += "\n\t</testsuite>\n" - output += '\n</testsuites>' - var XML = File.new() - var xml_file: String = "%s/results.xml" % path - var err = XML.open(xml_file, File.WRITE) - if err: - push_warning("Error saving result xml to %s : %s" % [xml_file, err as String]) - XML.store_string(output) - XML.close() diff --git a/addons/WAT/io/metadata.gd b/addons/WAT/io/metadata.gd deleted file mode 100644 index 855f3fb..0000000 --- a/addons/WAT/io/metadata.gd +++ /dev/null @@ -1,44 +0,0 @@ -extends Reference - -static func load_metadata(filesystem: Reference) -> void: - var path: String - if not filesystem.Settings.metadata_directory(): - path = filesystem.Settings.test_directory() - else: - path = filesystem.Settings.metadata_directory() - path += "/metadata.json" - if not Directory.new().file_exists(path): - return - - var file = File.new() - file.open(path, File.READ) - var content: Dictionary = JSON.parse(file.get_as_text()).result - file.close() - - for key in content: - if key == "failed": - filesystem.failed.paths = content[key] - else: - filesystem.tagged.tagged[key] = content[key] - -static func save_metadata(filesystem: Reference) -> void: - var path: String - if not filesystem.Settings.metadata_directory(): - push_warning("WAT: Cannot find metadata directory. Defaulting to test directory to save metadata") - path = filesystem.Settings.test_directory() - else: - path = filesystem.Settings.metadata_directory() - if not Directory.new().dir_exists(path): - Directory.new().make_dir_recursive(path) - - path += "/metadata.json" - var data = {"failed": filesystem.failed.paths} - for tag in filesystem.tagged.tagged: - var paths: Array = filesystem.tagged.tagged[tag] - if not paths.empty(): - data[tag] = paths - - var file = File.new() - file.open(path, File.WRITE) - file.store_string(JSON.print(data, "\t", true)) - file.close() diff --git a/addons/WAT/mono/Attributes.cs b/addons/WAT/mono/Attributes.cs deleted file mode 100644 index 5591336..0000000 --- a/addons/WAT/mono/Attributes.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using Godot; - -namespace WAT -{ - public partial class Test: Node - { - [AttributeUsage(AttributeTargets.Class)] - protected class TitleAttribute : Attribute - { - public readonly string Title; - - public TitleAttribute(string title) - { - Title = title; - } - } - - [AttributeUsage(AttributeTargets.Class)] - protected class HookAttribute : Attribute - { - public readonly string Method; - protected HookAttribute(string method) => Method = method; - } - - [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] - protected class TestAttribute : Attribute - { - public readonly object[] Arguments; - public TestAttribute(params object[] args) { Arguments = args; } - } - - protected class StartAttribute : HookAttribute { public StartAttribute(string method) : base(method) { } } - protected class PreAttribute : HookAttribute { public PreAttribute(string method) : base(method) { } } - protected class PostAttribute : HookAttribute { public PostAttribute(string method) : base(method) { } } - protected class EndAttribute : HookAttribute { public EndAttribute(string method) : base(method) { } } - } -} diff --git a/addons/WAT/mono/BuildScene.cs b/addons/WAT/mono/BuildScene.cs deleted file mode 100644 index d8021c7..0000000 --- a/addons/WAT/mono/BuildScene.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Godot; -using System; - -public class BuildScene : Node -{ - public override void _Ready() - { - GetTree().Quit(); - } -} diff --git a/addons/WAT/mono/BuildScene.tscn b/addons/WAT/mono/BuildScene.tscn deleted file mode 100644 index f758b81..0000000 --- a/addons/WAT/mono/BuildScene.tscn +++ /dev/null @@ -1,6 +0,0 @@ -[gd_scene load_steps=2 format=2] - -[ext_resource path="res://addons/WAT/mono/BuildScene.cs" type="Script" id=1] - -[node name="BuildScene" type="Node"] -script = ExtResource( 1 ) diff --git a/addons/WAT/mono/GDScriptWrapper.cs b/addons/WAT/mono/GDScriptWrapper.cs deleted file mode 100644 index f0db55d..0000000 --- a/addons/WAT/mono/GDScriptWrapper.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using Godot; -using Array = Godot.Collections.Array; -using Object = Godot.Object; -// ReSharper disable InconsistentNaming - - -namespace WAT -{ - - public partial class Test: Node - { - [Signal] public delegate void test_method_started(); - [Signal] public delegate void asserted(); - [Signal] public delegate void test_method_finished(); - [Signal] public delegate void test_script_finished(); - - private const bool IS_WAT_TEST = true; - - private void OnAssertion(Godot.Collections.Dictionary assertion) - { - EmitSignal(nameof(asserted), assertion); - } - - public String title() { return Title(); } - - public Array get_test_methods() - { - return new Array - (GetType().GetMethods(). - Where(m => m.IsDefined(typeof(TestAttribute))). - Select(m => (string) m.Name).ToList()); - } - - public Test setup(string directory, string filepath, IEnumerable<string> methods) - { - _methods = GenerateTestMethods(methods); - _case = (Object) GD.Load<GDScript>("res://addons/WAT/test/case.gd").New(directory, filepath, Title(), this); - return this; - } - - } -} diff --git a/addons/WAT/mono/Test.cs b/addons/WAT/mono/Test.cs deleted file mode 100644 index 62dc61a..0000000 --- a/addons/WAT/mono/Test.cs +++ /dev/null @@ -1,183 +0,0 @@ -using Godot; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Threading.Tasks; -using Godot.Collections; -using Object = Godot.Object; - -namespace WAT -{ - [Start(nameof(Blank))] - [Pre(nameof(Blank))] - [Post(nameof(Blank))] - [End(nameof(Blank))] - public partial class Test : Node - { - [Signal] private delegate void EventRaised(); - [Signal] public delegate void described(); - private const int Recorder = 0; // Apparently we require the C# Version - private IEnumerable<Executable> _methods = null; - private Object _case = null; - private static GDScript TestCase { get; } = GD.Load<GDScript>("res://addons/WAT/test/case.gd"); - private Reference _watcher { get; set; } - protected Timer Yielder { get; private set; } - protected Assertions Assert { get; private set; } - protected Type _type; - - protected Test() { _type = GetType(); } - public void Blank() { } - - public override void _Ready() - { - - _watcher = (Reference) GD.Load<GDScript>("res://addons/WAT/test/watcher.gd").New(); - Yielder = (Timer) GD.Load<GDScript>("res://addons/WAT/test/yielder.gd").New(); - Assert = new Assertions(); - Assert.Connect(nameof(Assertions.asserted), _case, "_on_asserted"); - Assert.Connect(nameof(Assertions.asserted), this, nameof(OnAssertion)); - Connect(nameof(described), _case, "_on_test_method_described"); - AddChild(Yielder); - CallDeferred(nameof(Run)); - } - - private async void Run() - { - // Can we do this in _Ready - MethodInfo start = GetTestHook(typeof(StartAttribute)); - MethodInfo pre = GetTestHook(typeof(PreAttribute)); - MethodInfo post = GetTestHook(typeof(PostAttribute)); - MethodInfo end = GetTestHook(typeof(EndAttribute)); - await CallTestHook(start); - foreach (Executable test in _methods) - { - _case.Call("add_method", test.Method.Name); - EmitSignal(nameof(test_method_started), test.Method.Name); - await CallTestHook(pre); - await Execute(test); - EmitSignal(nameof(test_method_finished)); - await CallTestHook(post); - } - - await CallTestHook(end); - EmitSignal(nameof(test_script_finished), GetResults()); - } - - private string Title() - { - if (!Attribute.IsDefined(_type, typeof(TitleAttribute))) return _type.Name; - TitleAttribute title = (TitleAttribute) Attribute.GetCustomAttribute(_type, typeof(TitleAttribute)); - return title.Title; - } - - private MethodInfo GetTestHook(Type attributeType) - { - HookAttribute hook = (HookAttribute) Attribute.GetCustomAttribute(_type, attributeType); - return _type.GetMethod(hook.Method); - } - - private async Task CallTestHook(MethodInfo hook) - { - try { - if (hook.Invoke(this, null) is Task task) { await task; } else { await Task.Run((() => { })); } - } catch (Exception e) { - GD.PushError($"WAT: {e}"); - } - } - - private async Task Execute(Executable test) - { - try { - if (test.Method.Invoke(this, test.Arguments) is Task task) { await task; } - else { await Task.Run((() => { })); } - } catch (Exception e) { - GD.PushError($"WAT: {e}"); - } - } - - protected void Describe(string description) - { - EmitSignal(nameof(described), description); - } - - protected SignalAwaiter UntilTimeout(double time) { return ToSignal((Timer) Yielder.Call("until_timeout", time), "finished"); } - - protected SignalAwaiter UntilSignal(Godot.Object emitter, string signal, double time) - { - _watcher.Call("watch", emitter, signal); - return ToSignal((Timer) Yielder.Call("until_signal", time, emitter, signal), "finished"); - } - - protected async Task<TestEventData> UntilEvent(object sender, string handle, double time) - { - EventInfo eventInfo = sender.GetType().GetEvent(handle); - MethodInfo methodInfo = GetType().GetMethod("OnEventRaised"); - Delegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, this, methodInfo); - eventInfo.AddEventHandler(sender, handler); - object[] results = await UntilSignal(this, nameof(EventRaised), time); - eventInfo.RemoveEventHandler(sender, handler); - Godot.Collections.Array ourResults = (Godot.Collections.Array) results[0]; - return (TestEventData) ourResults[0] ?? new TestEventData(null, null); - } - - public void OnEventRaised(object sender = null, EventArgs args = null) - { - EmitSignal(nameof(EventRaised), new TestEventData(sender, args)); - } - - protected class TestEventData: Godot.Object - { - public object Sender { get; } - public EventArgs Arguments { get; } - - public TestEventData(object sender, EventArgs arguments) - { - Sender = sender; - Arguments = arguments; - } - } - - protected void Watch(Godot.Object emitter, string signal) { _watcher.Call("watch", emitter, signal); } - protected void UnWatch(Godot.Object emitter, string signal) { _watcher.Call("unwatch", emitter, signal); } - - public void Simulate(Node obj, int times, float delta) - { - for (int i = 0; i < times; i++) - { - if (obj.HasMethod("_Process")) { obj._Process(delta); } - if (obj.HasMethod("_PhysicsProcess")) { obj._PhysicsProcess(delta); } - foreach (Node kid in obj.GetChildren()) { Simulate(kid, 1, delta); } - } - } - - private IEnumerable<Executable> GenerateTestMethods(IEnumerable<string> names) - { - return (from methodInfo in _type.GetMethods().Where(info => names.Contains(info.Name)) - let tests = Attribute.GetCustomAttributes(methodInfo) - .OfType<TestAttribute>() - from attribute in tests - select new Executable(methodInfo, attribute.Arguments)).ToList(); - } - - private Dictionary GetResults() - { - _case.Call("calculate"); // #") - Dictionary results = (Dictionary) _case.Call("to_dictionary"); - _case.Free(); - return results; - } - - private class Executable - { - public readonly MethodInfo Method; - public readonly object[] Arguments; - - public Executable(MethodInfo method, object[] arguments) - { - Method = method; - Arguments = arguments; - } - } - } -} diff --git a/addons/WAT/mono/assertions/Assertion.cs b/addons/WAT/mono/assertions/Assertion.cs deleted file mode 100644 index 13f6fb0..0000000 --- a/addons/WAT/mono/assertions/Assertion.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Diagnostics; -using System.Dynamic; -using Godot; -using Godot.Collections; - -namespace WAT -{ - public class Assertion - { - - protected static Dictionary Result(bool success, string expected, string actual, string context, string notes = "") - { - return new Dictionary - { - {"success", success}, - {"expected", expected}, - {"actual", actual}, - {"context", context} - }; - } - } -} diff --git a/addons/WAT/mono/assertions/Assertions.cs b/addons/WAT/mono/assertions/Assertions.cs deleted file mode 100644 index 760d357..0000000 --- a/addons/WAT/mono/assertions/Assertions.cs +++ /dev/null @@ -1,260 +0,0 @@ -using System; -using Godot; -using GDArray = Godot.Collections.Array; -using Object = Godot.Object; - -namespace WAT { - - public class Assertions : Reference - { - // ReSharper disable once InconsistentNaming - [Signal] public delegate void asserted(); - - public Assertions(){} - - private void Output(Godot.Collections.Dictionary result) - { - EmitSignal(nameof(asserted), result); - } - - public void IsTrue(bool a, string context = "") - { - Output(Boolean.IsTrue(a, context)); - } - - public void IsFalse(bool a, string context = "") - { - Output(Boolean.IsFalse(a, context)); - } - - public void IsEqual(object a, object b, string context = "") - { - Output(Equality.IsEqual(a, b, context)); - } - - public void IsNotEqual(object a, object b, string context = "") - { - Output(Equality.IsNotEqual(a, b, context)); - } - - public void IsGreaterThan(float a, float b, string context = "") - { - Output(Equality.IsGreaterThan(a, b, context)); - } - - public void IsLessThan(float a, float b, string context = "") - { - Output(Equality.IsLessThan(a, b, context)); - } - - public void IsEqualOrGreaterThan(float a, float b, string context = "") - { - Output(Equality.IsEqualOrGreaterThan(a, b, context)); - } - - public void IsEqualOrLessThan(float a, float b, string context = "") - { - Output(Equality.IsEqualOrLessThan(a, b, context)); - } - - public void SignalWasEmitted(Godot.Object emitter, string signal, string context = "") - { - Output(Signal.WasEmitted(emitter, signal, context)); - } - - public void SignalWasEmittedXTimes(Godot.Object emitter, string signal, int times, string context = "") - { - Output(Signal.WasEmittedXTimes(emitter, signal, times, context)); - } - - public void SignalWasNotEmitted(Godot.Object emitter, string signal, string context = "") - { - Output(Signal.WasNotEmitted(emitter, signal, context)); - } - - public void SignalWasEmittedWithArguments(Godot.Object emitter, string signal, GDArray args, string context = "") - { - Output(Signal.WasEmittedWithArgs(emitter, signal, args, context)); - } - - public void IsInRange(double a, double b, double c, string context = "") - { - Output(Range.IsInRange(a, b, c, context)); - } - - public void IsNotInRange(double a, double b, double c, string context = "") - { - Output(Range.IsNotInRange(a, b, c, context)); - } - - public void Contains<T>(object value, T container, string context = "") - { - Output(Property.Contains(value, container, context)); - } - - public void DoesNotContain<T>(object value, T container, string context = "") - { - Output(Property.DoesNotContain(value, container, context)); - } - - public void StringContains(string value, string str, string context = "") - { - Output(StringX.Contains(value, str, context)); - } - - public void StringDoesNotContain(string value, string str, string context = "") - { - Output(StringX.DoesNotContain(value, str, context)); - } - - public void StringBeginsWith(string value, string str, string context = "") - { - Output(StringX.BeginsWith(value, str, context)); - } - - public void StringDoesNotBeginWith(string value, string str, string context = "") - { - Output(StringX.DoesNotBeginWith(value, str, context)); - } - - public void StringEndsWith(string value, string str, string context = "") - { - Output(StringX.EndsWith(value, str, context)); - } - - public void StringDoesNotEndWith(string value, string str, string context = "") - { - Output(StringX.DoesNotEndWith(value, str, context)); - } - - public void FileExists(string path, string context = "") - { - Output(File.Exists(path, context)); - } - - public void FileDoesNotExist(string path, string context = "") - { - Output(File.DoesNotExist(path, context)); - } - - public void IsValidInstance(Object obj = null, string context = "") - { - Output(ObjectX.IsValidInstance(obj, context)); - } - - public void IsNotValidInstance(Object obj = null, string context = "") - { - Output(ObjectX.IsNotValidInstance(obj, context)); - } - - public void ObjectHasMeta(Godot.Object obj, string meta, string context = "") - { - Output(ObjectX.HasMeta(obj, meta, context)); - } - - public void ObjectDoesNotHaveMeta(Godot.Object obj, string meta, string context = "") - { - Output(ObjectX.DoesNotHaveMeta(obj, meta, context)); - } - - public void ObjectHasMethod(Godot.Object obj, string method, string context = "") - { - Output(ObjectX.HasMethod(obj, method, context)); - } - - public void ObjectDoesNotHaveMethod(Godot.Object obj, string method, string context = "") - { - Output(ObjectX.DoesNotHaveMethod(obj, method, context)); - } - - public void ObjectIsQueuedForDeletion(Godot.Object obj, string context = "") - { - Output(ObjectX.IsQueuedForDeletion(obj, context)); - } - - public void ObjectIsNotQueuedForDeletion(Godot.Object obj, string context = "") - { - Output(ObjectX.IsNotQueuedForDeletion(obj, context)); - } - - public void ObjectIsConnected(Object sender, string signal, Object receiver, string method, string context = "") - { - Output(ObjectX.IsConnected(sender, signal, receiver, method, context)); - } - - public void ObjectIsNotConnected(Object sender, string signal, Object receiver, string method, string context = "") - { - Output(ObjectX.IsNotConnected(sender, signal, receiver, method, context)); - } - - public void ObjectIsBlockingSignals(Object obj, string context = "") - { - Output(ObjectX.IsBlockingSignals(obj, context)); - } - - public void ObjectIsNotBlockingSignals(Object obj, string context = "") - { - Output(ObjectX.IsNotBlockingSignals(obj, context)); - } - - public void ObjectHasUserSignal(Object obj, string signal, string context = "") - { - Output(ObjectX.HasUserSignal(obj, signal, context)); - } - - public void ObjectDoesNotHaveUserSignal(Object obj, string signal, string context = "") - { - Output(ObjectX.DoesNotHaveUserSignal(obj, signal, context)); - } - - public void IsNull(object obj, string context = "") - { - Output(Null.IsNull(obj, context)); - } - - public void IsNotNull(object obj, string context = "") - { - Output(Null.IsNotNull(obj, context)); - } - - public void IsType<T>(object value, string context = "") - { - Output(Is.IsType<T>(value, context)); - } - - public void IsNotType<T>(object value, string context = "") - { - Output(Is.IsNotType<T>(value, context)); - } - - public void Fail(string context = "") - { - Output(Utility.Fail(context)); - } - - public void AutoPass(string context = "") - { - Output(Utility.AutoPass(context)); - } - - public void Throws(Action function, string context = "") - { - Output(Utility.Throws(function, context)); - } - - public void DoesNotThrow(Action function, string context = "") - { - Output(Utility.DoesNotThrow(function, context)); - } - - public void Throws<T>(Action function, string context = "") - { - Output(Utility.Throws<T>(function, context)); - } - - public void DoesNotThrow<T>(Action function, string context = "") - { - Output(Utility.DoesNotThrow<T>(function, context)); - } - } -} diff --git a/addons/WAT/mono/assertions/Boolean.cs b/addons/WAT/mono/assertions/Boolean.cs deleted file mode 100644 index 4d5a0f0..0000000 --- a/addons/WAT/mono/assertions/Boolean.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Godot.Collections; - -namespace WAT -{ - public class Boolean: Assertion - { - public static Dictionary IsTrue(bool value, string context) - { - string passed = $"|boolean| {value.ToString()} == true"; - string failed = $"|boolean| {value.ToString()} == false"; - string result = value ? passed : failed; - return Result(value, passed, result, context); - } - - public static Dictionary IsFalse(bool value, string context) - { - string passed = $"|boolean| {value.ToString()} == false"; - string failed = $"|boolean| {value.ToString()} == true"; - bool success = !value; - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - } -} - diff --git a/addons/WAT/mono/assertions/Equality.cs b/addons/WAT/mono/assertions/Equality.cs deleted file mode 100644 index d0aef59..0000000 --- a/addons/WAT/mono/assertions/Equality.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System; -using System.Collections; -using System.Globalization; -using System.Reflection; -using Godot.Collections; - -namespace WAT -{ - public class Equality: Assertion - { - public static Dictionary IsEqual(object a, object b, string context) - { - string passed = $"|{a?.GetType()}| {a} is equal to |{b?.GetType()}|{b}"; - string failed = $"|{a?.GetType()}| {a} is not equal to |{b?.GetType()}|{b}"; - bool success = a != null && b!= null && a.Equals(b); - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - - public static Dictionary IsNotEqual(object a, object b, string context) - { - string passed = $"|{a?.GetType()}| {a} is not equal to |{b?.GetType()}|{b}"; - string failed = $"|{a?.GetType()}| {a} is equal to |{b?.GetType()}|{b}"; - bool success = a != null && b!= null && !(a.Equals(b)); - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - - public static Dictionary IsEqualOrGreaterThan(float a, float b, string context) - { - string passed = $"|{a.GetType()}| {a} is equal to or greater than |{b.GetType()}|{b}"; - string failed = $"|{a.GetType()}| {a} is less than |{b.GetType()}|{b}"; - bool success = a >= b; - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - - public static Dictionary IsEqualOrLessThan(float a, float b, string context) - { - string passed = $"|{a.GetType()}| {a} is equal to or less than |{b.GetType()}|{b}"; - string failed = $"|{a.GetType()}| {a} is greater than |{b.GetType()}|{b}"; - bool success = a <= b; - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - - public static Dictionary IsGreaterThan(float a, float b, string context) - { - string passed = $"|{a.GetType()}| {a} is greater than |{b.GetType()}|{b}"; - string failed = $"|{a.GetType()}| {a} is equal to or less than |{b.GetType()}|{b}"; - bool success = a > b; - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - - public static Dictionary IsLessThan(float a, float b, string context) - { - string passed = $"|{a.GetType()}| {a} is less than |{b.GetType()}|{b}"; - string failed = $"|{a.GetType()}| {a} is equal to or greater than |{b.GetType()}|{b}"; - bool success = a < b; - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - } -} \ No newline at end of file diff --git a/addons/WAT/mono/assertions/File.cs b/addons/WAT/mono/assertions/File.cs deleted file mode 100644 index 853ab09..0000000 --- a/addons/WAT/mono/assertions/File.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using Godot; -using Godot.Collections; - -namespace WAT -{ - public class File: Assertion - { - public static Dictionary Exists(string path, string context) - { - string passed = $"{path} exists"; - string failed = $"{path} does not exist"; - bool success = new Godot.File().FileExists(path); - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - - public static Dictionary DoesNotExist(string path, string context) - { - string passed = $"{path} does not exist"; - string failed = $"{path} exists"; - bool success = !new Godot.File().FileExists(path); - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - } -} \ No newline at end of file diff --git a/addons/WAT/mono/assertions/Is.cs b/addons/WAT/mono/assertions/Is.cs deleted file mode 100644 index 63ecfb9..0000000 --- a/addons/WAT/mono/assertions/Is.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Godot; -using System; -using Godot.Collections; - -namespace WAT { - - public class Is : Assertion - { - public static Dictionary IsType<T>(object value, string context) - { - string passed = $"{value} is builtin {typeof(T)}"; - string failed = $"{value} is not builtin {typeof(T)}"; - bool success = value is T; - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - - public static Dictionary IsNotType<T>(object value, string context) - { - string passed = $"{value} is builtin {typeof(T)}"; - string failed = $"{value} is not builtin {typeof(T)}"; - bool success = !(value is T); - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - } -} diff --git a/addons/WAT/mono/assertions/Null.cs b/addons/WAT/mono/assertions/Null.cs deleted file mode 100644 index 8a584f3..0000000 --- a/addons/WAT/mono/assertions/Null.cs +++ /dev/null @@ -1,40 +0,0 @@ -using Godot; -using System; -using Godot.Collections; - - -namespace WAT -{ - public class Null : Assertion - { - // Godot Objects that are freed don't become null immediatly - // so they may still be valid instances - public static Dictionary IsNull(object obj, string context) - { - const string passed = "object is null"; - const string failed = "object is not null"; - bool success = obj is null; - if (!success) - { - //failed = $"{obj} is not null"; - } - - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - - public static Dictionary IsNotNull(object obj, string context) - { - string passed = "object is not null"; - const string failed = "object is null"; - bool success = !(obj is null); - if (success) - { - passed = $"{obj} is not null"; - } - - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - } -} diff --git a/addons/WAT/mono/assertions/ObjectX.cs b/addons/WAT/mono/assertions/ObjectX.cs deleted file mode 100644 index 719ddf3..0000000 --- a/addons/WAT/mono/assertions/ObjectX.cs +++ /dev/null @@ -1,137 +0,0 @@ -using System.Runtime.Remoting; -using Godot; -using Godot.Collections; - -namespace WAT -{ - public class ObjectX: Assertion - { - public static Dictionary DoesNotHaveMeta(Object obj, string meta, string context) - { - string passed = $"{obj} does not have meta {meta}"; - string failed = $"{obj} has meta {meta}"; - bool success = !obj.HasMeta(meta); - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - - public static Dictionary DoesNotHaveMethod(Object obj, string method, string context) - { - string passed = $"{obj} does not have method {method}"; - string failed = $"{obj} has method {method}"; - bool success = !obj.HasMethod(method); - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - - public static Dictionary DoesNotHaveUserSignal(Object obj, string signal, string context) - { - string passed = $"{obj} does not have user signal {signal}"; - string failed = $"{obj} does have user signal {signal}"; - bool success = !obj.HasUserSignal(signal); - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - - public static Dictionary HasMeta(Object obj, string meta, string context) - { - string passed = $"{obj} has meta {meta}"; - string failed = $"{obj} does not have meta {meta}"; - bool success = obj.HasMeta(meta); - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - - public static Dictionary HasMethod(Object obj, string method, string context) - { - string passed = $"{obj} has method {method}"; - string failed = $"{obj} does not have method {method}"; - bool success = obj.HasMethod(method); - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - - public static Dictionary HasUserSignal(Object obj, string signal, string context) - { - string passed = $"{obj} does has signal {signal}"; - string failed = $"{obj} does not have user signal {signal}"; - bool success = obj.HasUserSignal(signal); - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - - public static Dictionary IsBlockingSignals(Object obj, string context) - { - string passed = $"{obj} is blocking signals"; - string failed = $"{obj} is not blocking signals"; - bool success = obj.IsBlockingSignals(); - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - - public static Dictionary IsConnected(Object sender, string signal, Object receiver, string method, string context) - { - string passed = $"{sender}.{signal} is connected to {receiver}.{method}"; - string failed = $"{sender}.{signal} is not connected to {receiver}.{method}"; - bool success = sender.IsConnected(signal, receiver, method); - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - - public static Dictionary IsNotBlockingSignals(Object obj, string context) - { - string passed = $"{obj} is not blocking signals"; - string failed = $"{obj} is blocking signals"; - bool success = !obj.IsBlockingSignals(); - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - - public static Dictionary IsNotConnected(Object sender, string signal, Object receiver, string method, string context) - { - string passed = $"{sender}.{signal} is not connected to {receiver}.{method}"; - string failed = $"{sender}.{signal} is connected to {receiver}.{method}"; - bool success = !sender.IsConnected(signal, receiver, method); - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - - public static Dictionary IsNotQueuedForDeletion(Object obj, string context) - { - string passed = $"{obj} is not queued for deletion"; - string failed = $"{obj} is queued for deletion"; - bool success = !obj.IsQueuedForDeletion(); - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - - public static Dictionary IsQueuedForDeletion(Object obj, string context) - { - string passed = $"{obj} is queued for deletion"; - string failed = $"{obj} is not queued for deletion"; - bool success = obj.IsQueuedForDeletion(); - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - - public static Dictionary IsValidInstance(Object obj = null, string context = "") - { - bool success = Object.IsInstanceValid(obj); - string text = success ? obj?.ToString() : ""; - string passed = $"{text} is a valid instance"; - string failed = $"{text} is not a valid instance"; - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - - public static Dictionary IsNotValidInstance(Object obj = null, string context = "") - { - bool success = !Object.IsInstanceValid(obj); - string text = success ? "" : obj?.ToString(); - string passed = $"{text} is not a valid instance"; - string failed = $"{text} is a valid instance"; - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - } -} diff --git a/addons/WAT/mono/assertions/Property.cs b/addons/WAT/mono/assertions/Property.cs deleted file mode 100644 index 22197b3..0000000 --- a/addons/WAT/mono/assertions/Property.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System.Reflection; -using Godot.Collections; - -namespace WAT -{ - public class Property: Assertion - { - public static Dictionary Contains<T>(object value, T container, string context) - { - string passed = $"{container.GetType()} contains |{value.GetType()}|{value}"; - string failed = $"{container.GetType()} does not contain |{value.GetType()}|{value}"; - MethodInfo method = container.GetType().GetMethod("Contains"); - bool success = false; - if (method != null) - { - success = (bool) method.Invoke(container, new object[] {value}); - } - - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - - public static Dictionary DoesNotContain<T>(object value, T container, string context) - { - string passed = $"{container.GetType()} does not contain |{value.GetType()}|{value}"; - string failed = $"{container.GetType()} contains |{value.GetType()}|{value}"; - MethodInfo method = container.GetType().GetMethod("Contains"); - bool success = false; - if (method != null) - { - success = !(bool) method.Invoke(container, new object[] {value}); - } - - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - } -} diff --git a/addons/WAT/mono/assertions/Range.cs b/addons/WAT/mono/assertions/Range.cs deleted file mode 100644 index 97a9878..0000000 --- a/addons/WAT/mono/assertions/Range.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using Godot.Collections; - -namespace WAT -{ - public class Range: Assertion - { - public static Dictionary IsInRange(double val, double low, double high, string context) - { - string passed = $"{val} is in range {low}-{high}"; - string failed = $"{val} is not in range {low}-{high}"; - bool success = val >= low && val < high; - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - - public static Dictionary IsNotInRange(double val, double low, double high, string context) - { - string passed = $"{val} is not in range {low}-{high}"; - string failed = $"{val} is in range {low}-{high}"; - bool success = val < low || val >= high; - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - - } -} diff --git a/addons/WAT/mono/assertions/Signal.cs b/addons/WAT/mono/assertions/Signal.cs deleted file mode 100644 index cbceafa..0000000 --- a/addons/WAT/mono/assertions/Signal.cs +++ /dev/null @@ -1,104 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; -using Godot; -using Godot.Collections; -using Array = Godot.Collections.Array; -using Object = Godot.Object; - -namespace WAT -{ - public class Signal: Assertion - { - public static Dictionary WasEmitted(Object emitter, string signal, string context) - { - string passed = $"Signal {signal} was emitted from {emitter}"; - string failed = $"Signal {signal} was not emitted from {emitter}"; - - Reference watcher = (Reference) emitter.Call("get_meta", "watcher"); - bool success = (int) watcher.Call("get_emit_count", signal) > 0; - string result = success ? passed : failed; - - return Result(success, passed, result, context); - } - - public static Dictionary WasNotEmitted(Object emitter, string signal, string context) - { - string passed = $"Signal {signal} was not emitted from {emitter}"; - string failed = $"Signal {signal} was emitted from {emitter}"; - - Reference watcher = (Reference) emitter.GetMeta("watcher"); - bool success = (int) watcher.Call("get_emit_count", signal) <= 0; - string result = success ? passed : failed; - - return Result(success, passed, result, context); - } - - public static Dictionary WasEmittedXTimes(Object emitter, string signal, int times, string context) - { - string passed = $"Signal {signal} was emitted {times} times from {emitter}"; - string failed = $"Signal {signal} was not emitted {times} times from {emitter}"; - - Reference watcher = (Reference) emitter.GetMeta("watcher"); - bool success = (int) watcher.Call("get_emit_count", signal) == times; - string result = success ? passed : failed; - - return Result(success, passed, result, context); - } - - public static Dictionary WasEmittedWithArgs(Object emitter, string signal, Array arguments, string context) - { - string passed = $"Signal {signal} was emitted from {emitter} with arguments {arguments}"; - string failed = $"Signal {signal} was not emitted from {emitter} with arguments {arguments}"; - string altFailure = $"Signal {signal} was not emitted from {emitter}"; - - bool success = false; - string result = ""; - Reference watcher = (Reference) emitter.GetMeta("watcher"); - IDictionary data = (IDictionary) watcher.Call("get_data", signal); - if ((int) data["emit_count"] <= 0) - { - success = false; - result = altFailure; - } - else if (FoundMatchingCall(arguments, (IEnumerable) data["calls"])) - { - success = true; - result = passed; - } - else - { - success = false; - result = failed; - } - - return Result(success, passed, result, context); - } - - private static bool FoundMatchingCall(IList args, IEnumerable calls) - { - foreach (IDictionary call in calls) - { - if (Match(args, (Array) call["args"])) - { - return true; - } - } - - return false; - } - - private static bool Match(IList arguments, IList callArguments) - { - for (int i = 0; i < arguments.Count; i++) - { - if (!Equals(arguments[i], callArguments[i])) - { - return false; - } - } - return true; - } - } -} diff --git a/addons/WAT/mono/assertions/StringX.cs b/addons/WAT/mono/assertions/StringX.cs deleted file mode 100644 index d3225b1..0000000 --- a/addons/WAT/mono/assertions/StringX.cs +++ /dev/null @@ -1,62 +0,0 @@ -using Godot; -using Godot.Collections; - -namespace WAT -{ - public class StringX: Assertion - { - public static Dictionary BeginsWith(string value, string str, string context) - { - string passed = $"{str} begins with {value}"; - string failed = $"{str} does not begin with {value}"; - bool success = str.BeginsWith(value); - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - - public static Dictionary DoesNotBeginWith(string value, string str, string context) - { - string passed = $"{str} does not begin with {value}"; - string failed = $"{str} begins with {value}"; - bool success = !str.BeginsWith(value); - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - - public static Dictionary Contains(string value, string str, string context) - { - string passed = $"{str} contains {value}"; - string failed = $"{str} does not contain {value}"; - bool success = str.Contains(value); - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - - public static Dictionary DoesNotContain(string value, string str, string context) - { - string passed = $"{str} does not contain {value}"; - string failed = $"{str} contains {value}"; - bool success = !str.Contains(value); - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - - public static Dictionary EndsWith(string value, string str, string context) - { - string passed = $"{str} ends with {value}"; - string failed = $"{str} does not end with {value}"; - bool success = str.EndsWith(value); - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - - public static Dictionary DoesNotEndWith(string value, string str, string context) - { - string passed = $"{str} does not end with {value}"; - string failed = $"{str} end with {value}"; - bool success = !str.EndsWith(value); - string result = success ? passed : failed; - return Result(success, passed, result, context); - } - } -} \ No newline at end of file diff --git a/addons/WAT/mono/assertions/Utility.cs b/addons/WAT/mono/assertions/Utility.cs deleted file mode 100644 index 02e4ec6..0000000 --- a/addons/WAT/mono/assertions/Utility.cs +++ /dev/null @@ -1,96 +0,0 @@ -using System; -using System.Collections.Generic; -using Godot; -using Godot.Collections; -using Object = Godot.Object; - -namespace WAT -{ - public class Utility: Assertion - { - public static Dictionary Fail(string context) - { - return Result(false, "N/A", "N/A", context); - } - - public static Dictionary AutoPass(string context) - { - return Result(true, "N/A", "N/A", context); - } - - public static Dictionary Throws(Action function, string context) - { - try - { - function(); - const string fail = "No exception was thrown"; - return Result(false, "Exception was thrown", fail, context); - } - catch (Exception e) - { - string pass = $"Threw Exception {e} with Message: {e.Message}"; - return Result(true, "Exception was thrown", pass, context); - } - } - - public static Dictionary DoesNotThrow(Action function, string context) - { - try - { - function(); - string pass = $"No exception was thrown"; - return Result(true, "No Exception was thrown", pass, context); - } - catch (Exception e) - { - string fail = $"Threw {e} with Message: {e.Message}"; - return Result(true, "No Exception was thrown", fail, context); - } - } - - public static Dictionary Throws<T>(Action function, string context) - { - string expected = $"{typeof(T)} was thrown"; - try - { - function(); - const string fail = "No Exception was thrown"; - return Result(false, expected, fail, context); - } - catch (Exception e) - { - if (e is T) - { - string pass = $"Threw {e} with Message: {e.Message}"; - return Result(true, expected, pass, context); - } - - string fail = $"Threw {e} with Message: {e.Message}"; - return Result(false, expected, fail, context); - } - } - - public static Dictionary DoesNotThrow<T>(Action function, string context) - { - string expected = $"{typeof(T)} was not thrown"; - try - { - function(); - string pass = $"Did not throw {typeof(T)}"; - return Result(true, expected, pass, context); - } - catch (Exception e) - { - string pass = ""; - if (e is T) - { - string fail = $"Threw {e} with Message: {e.Message}"; - return Result(false, expected, fail, context); - } - - pass = $"Threw {e} with Message: {e.Message}"; - return Result(true, expected, pass, context); - } - } - } -} diff --git a/addons/WAT/namespace.gd b/addons/WAT/namespace.gd deleted file mode 100644 index a786d56..0000000 --- a/addons/WAT/namespace.gd +++ /dev/null @@ -1,8 +0,0 @@ -tool -extends Reference -class_name WAT - - -const COMPLETED: String = "completed" -const Test: Script = preload("res://addons/WAT/test/test.gd") -const TestRunnerScene: PackedScene = preload("res://addons/WAT/runner/TestRunner.tscn") diff --git a/addons/WAT/network/test_client.gd b/addons/WAT/network/test_client.gd deleted file mode 100644 index 8771460..0000000 --- a/addons/WAT/network/test_client.gd +++ /dev/null @@ -1,32 +0,0 @@ -extends "res://addons/WAT/network/test_network.gd" - -func _ready() -> void: - custom_multiplayer.connect("connection_failed", self, "_on_connection_failed") - if _error(_peer.create_client(IPAddress, PORT)) == OK: - custom_multiplayer.network_peer = _peer - -func _on_connection_failed() -> void: - push_warning("TestClient could not connect to TestServer") - -puppet func _on_tests_received_from_server(tests: Array, repeat: int, thread_count: int) -> void: - var results: Array = yield(get_parent().run(tests, repeat, thread_count, self), "completed") - rpc_id(MASTER, "_on_results_received_from_client", results) - -# LiveWire Functions -func on_test_script_started(data: Dictionary) -> void: - rpc_id(MASTER, "_on_test_script_started", data) - -func on_test_script_finished(data: Dictionary) -> void: - rpc_id(MASTER, "_on_test_script_finished", data) - -func on_test_method_started(data: Dictionary) -> void: - rpc_id(MASTER, "_on_test_method_started", data) - -func on_test_method_finished(data: Dictionary) -> void: - rpc_id(MASTER, "_on_test_method_finished", data) - -func on_asserted(data: Dictionary) -> void: - rpc_id(MASTER, "_on_asserted", data) - -func on_test_method_described(data: Dictionary) -> void: - rpc_id(MASTER, "_on_test_method_described", data) diff --git a/addons/WAT/network/test_network.gd b/addons/WAT/network/test_network.gd deleted file mode 100644 index 683b70a..0000000 --- a/addons/WAT/network/test_network.gd +++ /dev/null @@ -1,43 +0,0 @@ -tool -extends Node - -const IPAddress: String = "127.0.0.1" -const PORT: int = 6019 -const MAXCLIENTS: int = 1 -const MASTER: int = 1 -var _peer: NetworkedMultiplayerENet -var _id: int - -func _init() -> void: - _close() - custom_multiplayer = MultiplayerAPI.new() - custom_multiplayer.root_node = self - custom_multiplayer.allow_object_decoding = true - _peer = NetworkedMultiplayerENet.new() - -func _process(delta: float) -> void: - if custom_multiplayer.has_network_peer(): - custom_multiplayer.poll() - -func _close() -> void: - if is_instance_valid(_peer): - if _is_connected(): - _peer.close_connection() - _peer = null - -func _error(err: int) -> int: - if err != OK: - match err: - ERR_ALREADY_IN_USE: - push_warning("Network Peer is already in use") - ERR_CANT_CREATE: - push_warning("Network Peer cannot be created") - _: - push_warning(err as String) - return err - -func _is_connected() -> bool: - return _peer.get_connection_status() == NetworkedMultiplayerENet.CONNECTION_CONNECTED - -func _exit_tree() -> void: - _close() diff --git a/addons/WAT/network/test_server.gd b/addons/WAT/network/test_server.gd deleted file mode 100644 index 6cb5940..0000000 --- a/addons/WAT/network/test_server.gd +++ /dev/null @@ -1,60 +0,0 @@ -tool -extends "res://addons/WAT/network/test_network.gd" - -signal network_peer_connected -signal results_received - -enum STATE { SENDING, RECEIVING, DISCONNECTED } - -var _peer_id: int -# Store incoming cases from client in case of abrupt termination. -var caselist: Array = [] -var results_view: TabContainer -var status: int = STATE.DISCONNECTED - -func _ready() -> void: - if not Engine.is_editor_hint(): - return - custom_multiplayer.connect("network_peer_connected", self, "_on_network_peer_connected") - custom_multiplayer.connect("network_peer_disconnected", self, "_on_network_peer_disconnected") - if _error(_peer.create_server(PORT, MAXCLIENTS)) == OK: - custom_multiplayer.network_peer = _peer - -func _on_network_peer_connected(id: int) -> void: - _peer_id = id - _peer.set_peer_timeout(id, 1000, 2000, 3000) - emit_signal("network_peer_connected") - -func _on_network_peer_disconnected(_id: int) -> void: - if status == STATE.SENDING: - emit_signal("results_received", caselist) - caselist.clear() - status = STATE.DISCONNECTED - -func send_tests(testdir: Array, repeat: int, thread_count: int) -> void: - status = STATE.SENDING - rpc_id(_peer_id, "_on_tests_received_from_server", testdir, repeat, thread_count) - -master func _on_results_received_from_client(results: Array = []) -> void: - status = STATE.RECEIVING - emit_signal("results_received", results) - _peer.disconnect_peer(_peer_id, true) - -master func _on_test_script_started(data: Dictionary) -> void: - results_view.on_test_script_started(data) - -master func _on_test_script_finished(data: Dictionary) -> void: - results_view.on_test_script_finished(data) - caselist.append(data) - -master func _on_test_method_started(data: Dictionary) -> void: - results_view.on_test_method_started(data) - -master func _on_test_method_finished(data: Dictionary) -> void: - results_view.on_test_method_finished(data) - -master func _on_asserted(data: Dictionary) -> void: - results_view.on_asserted(data) - -master func _on_test_method_described(data: Dictionary) -> void: - results_view.on_test_method_described(data) diff --git a/addons/WAT/plugin.cfg b/addons/WAT/plugin.cfg deleted file mode 100644 index 2a6308c..0000000 --- a/addons/WAT/plugin.cfg +++ /dev/null @@ -1,7 +0,0 @@ -[plugin] - -name="WAT" -description="Unit Testing Plugin" -author="github/AlexDarigan" -version="6" -script="plugin.gd" diff --git a/addons/WAT/plugin.gd b/addons/WAT/plugin.gd deleted file mode 100644 index de67766..0000000 --- a/addons/WAT/plugin.gd +++ /dev/null @@ -1,63 +0,0 @@ -tool -extends EditorPlugin - -const Title: String = "Tests" -const GUI: PackedScene = preload("res://addons/WAT/gui.tscn") -const TestPanel: GDScript = preload("res://addons/WAT/ui/gui.gd") -const TestPanelDocker: GDScript = preload("res://addons/WAT/ui/docker.gd") -const FileSystem: GDScript = preload("res://addons/WAT/filesystem/filesystem.gd") -const FileTracker: GDScript = preload("res://addons/WAT/filesystem/tracker.gd") -const Settings: GDScript = preload("res://addons/WAT/settings.gd") -const Metadata: GDScript = preload("res://addons/WAT/io/metadata.gd") -const PluginAssetsRegistry: GDScript = preload("res://addons/WAT/ui/scaling/plugin_assets_registry.gd") -var _test_panel: TestPanel -var _file_system: FileSystem -var _file_tracker: FileTracker -var _assets_registiry: PluginAssetsRegistry -var _panel_docker: TestPanelDocker - -func _enter_tree() -> void: - Settings.initialize() - var build: FuncRef = funcref(self, "_build_function") - _file_system = FileSystem.new(build) - _file_tracker = FileTracker.new(_file_system) - Metadata.load_metadata(_file_system) - _assets_registiry = PluginAssetsRegistry.new(self) - _file_tracker.start_tracking_files(self) - _test_panel = GUI.instance() - _test_panel.setup_editor_context(self, build, funcref(self, "goto_function"), _file_system) - _panel_docker = TestPanelDocker.new(self, _test_panel) - add_child(_panel_docker) - -func _exit_tree() -> void: - Metadata.save_metadata(_file_system) - _panel_docker.queue_free() - if(is_instance_valid(_test_panel)): - _test_panel.queue_free() - -func _build_function() -> bool: - _test_panel.Results.clear() - var text: String = "FileSystem has been changed since last build." - text += "\nTriggering a Build by launching an Empty Scene." - text += "\nPlease select your option again after the scene quits." - OS.alert(text, "Build Required") - var editor: EditorInterface = get_editor_interface() - editor.play_custom_scene("res://addons/WAT/mono/BuildScene.tscn") - while editor.is_playing_scene(): - yield(get_tree(), "idle_frame") - yield(get_tree(), "idle_frame") - _file_system.update() - _file_system.changed = false - make_bottom_panel_item_visible(_test_panel) - return true - -func goto_function(path: String, function: String) -> void: - var script: Script = load(path) - var script_editor: ScriptEditor = get_editor_interface().get_script_editor() - get_editor_interface().edit_resource(script) - var idx: int = 0 - for line in script.source_code.split("\n"): - idx += 1 - if function in line and line.begins_with("func"): - script_editor.goto_line(idx) - return diff --git a/addons/WAT/runner/TestRunner.gd b/addons/WAT/runner/TestRunner.gd deleted file mode 100644 index 51593d4..0000000 --- a/addons/WAT/runner/TestRunner.gd +++ /dev/null @@ -1,43 +0,0 @@ -tool -extends Node - -const Settings: GDScript = preload("res://addons/WAT/settings.gd") -const Splitter: GDScript = preload("splitter.gd") -const COMPLETED: String = "completed" -signal completed - -func _ready() -> void: - name = "TestRunner" - if not Engine.is_editor_hint(): - OS.window_size = Settings.window_size() - if Settings.minimize_window_when_running_tests(): - OS.window_minimized = true - -func run(tests: Array, repeat: int, threads: int, results_view: Node = null) -> Array: - var results: Array = [] - tests = _repeat(tests, repeat) - var testthreads = Splitter.split(tests, threads) - for thread in testthreads: - thread.controller.results = results_view - add_child(thread.controller) - thread.start(self, "_run", thread) - thread.wait_to_finish() - for count in testthreads: - results += yield(self, COMPLETED) - return results - -func _run(thread: Thread) -> void: - var results: Array = [] - for test in thread.tests: - results.append(yield(thread.controller.run(test), COMPLETED)) - thread.controller.queue_free() - emit_signal(COMPLETED, results) - -func _repeat(tests: Array, repeat: int) -> Array: - var duplicates: Array = [] - for idx in repeat: - for test in tests: - duplicates.append(test) - duplicates += tests - return duplicates - diff --git a/addons/WAT/runner/TestRunner.tscn b/addons/WAT/runner/TestRunner.tscn deleted file mode 100644 index a823ce5..0000000 --- a/addons/WAT/runner/TestRunner.tscn +++ /dev/null @@ -1,10 +0,0 @@ -[gd_scene load_steps=3 format=2] - -[ext_resource path="res://addons/WAT/runner/TestRunner.gd" type="Script" id=1] -[ext_resource path="res://addons/WAT/network/test_client.gd" type="Script" id=2] - -[node name="TestRunner" type="Node"] -script = ExtResource( 1 ) - -[node name="TestClient" type="Node" parent="."] -script = ExtResource( 2 ) diff --git a/addons/WAT/runner/splitter.gd b/addons/WAT/runner/splitter.gd deleted file mode 100644 index a870c01..0000000 --- a/addons/WAT/runner/splitter.gd +++ /dev/null @@ -1,47 +0,0 @@ -extends Node - -static func split(tests: Array, threads: int = 1) -> Array: - tests.sort_custom(YieldTimeSorter, "sort_ascending") - threads = calibrate_threads(tests.size(), threads) - return _testthreads(_distribute(_testpools(threads), tests, threads)) - -static func calibrate_threads(tests: int, threads: int) -> int: - if tests < threads: - push_warning("Readjusting thread count to match low test size") - threads = tests - return threads - -static func _testpools(count: int) -> Array: - var pools: Array = [] - for pool in count: - pools.append([]) - return pools - -static func _distribute(pools: Array, tests: Array, count: int) -> Array: - var idx: int = 0 - for test in tests: - pools[idx].append(test) - idx = 0 if idx == count - 1 else idx + 1 - return pools - -static func _testthreads(pools: Array) -> Array: - # Our tests are sorted from slowest to quickest.. - # ..so we loop through each pool in order to disaparate time - var threads: Array = [] - for pool in pools: - threads.append(TestThread.new(pool)) - return threads - -class TestThread extends Thread: - var tests: Array - var controller: Node = load("res://addons/WAT/runner/test_controller.gd").new() - - func _init(_tests): - tests = _tests - -class YieldTimeSorter: - - static func sort_ascending(a: Dictionary, b: Dictionary) -> bool: - return a["time"] < b["time"] - - diff --git a/addons/WAT/runner/test_controller.gd b/addons/WAT/runner/test_controller.gd deleted file mode 100644 index 1e8b03f..0000000 --- a/addons/WAT/runner/test_controller.gd +++ /dev/null @@ -1,91 +0,0 @@ -extends Node - - -var _current_method: String = "" -var _dir: String = "" -var _path: String -var _test: Node -var results: Node # either server or results tree - -signal results_received - -func run(metadata: Dictionary) -> void: - _dir = metadata["dir"] - _path = metadata["path"] - var _methods = metadata["methods"] - - # Default test results to -1 if there is a parse error, so the CLI or GUI will.. - # ..know that an error had occurred. - var test_results = { - total = -1, - passed = -1, - context = metadata["name"], - methods = _methods, - success = false, - path = _path, - time_taken = metadata["time"], - dir = _dir - } - - # If there was a parsing error, skip the test case. - if metadata.get("parse", OK) == OK: - # Signals leak in C# so we're just using a direct connection and GetParent Calls - _test = load(_path).new().setup(_dir, _path, _methods) - _test.connect("test_method_started", self, "_on_test_method_started") - _test.connect("described", self, "_on_test_method_described") - _test.connect("asserted", self, "_on_asserted") - _test.connect("test_method_finished", self, "_on_test_method_finished") - _test.connect("test_script_finished", self, "_on_test_script_finished") - _on_test_script_started(metadata) # Needs to be after _test is loaded. - - # We need to wait for the object itself to emit the signal (since we.. - # ..cannot yield for C# so we defer the call to run so we have time to.. - # ..to setup our yielding rather than deal with a race condition) - call_deferred("add_child", _test) - test_results = yield(self, "results_received") # test_script_finished - _test.queue_free() - # Reset for the next case. - _test = null - else: - _on_test_script_started(metadata) - # Nothing to call_deferred here, so just yield for next idle_frame. - yield(get_tree(), "idle_frame") - _on_test_script_finished(test_results) - return test_results - -func _on_test_script_started(data: Dictionary) -> void: - data["title"] = _test.title() if is_instance_valid(_test) else data["name"] - if results != null: - results.on_test_script_started(data) - -# Results broker doesn't make any sense -func _on_test_script_finished(data: Dictionary) -> void: - if results != null: - results.on_test_script_finished(data) - emit_signal("results_received", data) - -func _on_test_method_started(method) -> void: - var x = {"dir" : _dir, "path": _path, "method": method} - #emit_signal("method_started", x) # What about "described" methods? - if results != null: - results.on_test_method_started(x) - _current_method = method - -func _on_test_method_finished() -> void: - var method = _test._case._methods.back() - var count = method["total"] - var passed = method["passed"] - var success = count > 0 and count == passed - var x = {"dir": _dir, "path": _path, "method": _current_method, "success": success, "total": count, "passed": passed} - if results != null: - results.on_test_method_finished(x) - -func _on_asserted(assertion) -> void: - var x = {"dir" : _dir, "path": _path, "method": _current_method, "assertion": assertion} - if results != null: - results.on_asserted(x) #emit_signal("asserted", x) - -func _on_test_method_described(desc: String) -> void: - var x = {"dir": _dir, "path": _path, "method": _current_method, "description": desc} - if results != null: - results.on_test_method_described(x) diff --git a/addons/WAT/settings.gd b/addons/WAT/settings.gd deleted file mode 100644 index bef64d5..0000000 --- a/addons/WAT/settings.gd +++ /dev/null @@ -1,59 +0,0 @@ -tool -extends Reference - - -static func initialize() -> void: - if not ProjectSettings.has_setting("WAT/Test_Directory"): - push_warning("Test Directory was set to project root.\nYou may change any setting for WAT in Project -> ProjectSettings -> General -> WAT") - _add_setting("Test_Directory", TYPE_STRING, "res://") - _add_setting("Results_Directory", TYPE_STRING, "res://") - _add_setting("Test_Metadata_Directory", TYPE_STRING, "res://") - _add_setting("Tags", TYPE_STRING_ARRAY, PoolStringArray()) - _add_setting("Cache_Tests", TYPE_BOOL, true) - _add_setting("Window_Size", TYPE_VECTOR2, Vector2(1280, 720)) - _add_setting("Minimize_Window_When_Running_Tests", TYPE_BOOL, false) - _add_setting("Port", TYPE_INT, 6008) - _add_setting("Tags", TYPE_STRING_ARRAY, PoolStringArray()) - - # Set this to true if using external editors - ProjectSettings.save() - -static func _add_setting(title: String, type: int, value, hint_type: int = -1, hint_string = "") -> void: - title = title.insert(0, "WAT/") - if ProjectSettings.has_setting(title): - return - ProjectSettings.set(title, value) - var prop: Dictionary = {} - prop["name"] = title - prop["type"] = type - if hint_type > -1: - prop["hint"] = hint_type - prop["hint_string"] = hint_string - ProjectSettings.add_property_info(prop) - -static func test_directory() -> String: - return ProjectSettings.get_setting("WAT/Test_Directory") - -static func results_directory() -> String: - return ProjectSettings.get_setting("WAT/Results_Directory") - -static func metadata_directory() -> String: - return ProjectSettings.get_setting("WAT/Test_Metadata_Directory") - -static func window_size() -> Vector2: - return ProjectSettings.get_setting("WAT/Window_Size") - -static func tags() -> PoolStringArray: - return ProjectSettings.get_setting("WAT/Tags") - -static func cache_tests() -> bool: - return ProjectSettings.get_setting("WAT/Cache_Tests") - -static func minimize_window_when_running_tests() -> bool: - return ProjectSettings.get_setting("WAT/Minimize_Window_When_Running_Tests") - -static func port() -> int: - return ProjectSettings.get_setting("WAT/Port") - -static func is_bottom_panel() -> int: - return ProjectSettings.get_setting("WAT/Display") == 8 diff --git a/addons/WAT/test/any.gd b/addons/WAT/test/any.gd deleted file mode 100644 index a29ac7e..0000000 --- a/addons/WAT/test/any.gd +++ /dev/null @@ -1,8 +0,0 @@ -extends Reference - -# I hate this -# Used for do not care values in stubs -# Probably a better way to handle it - -func get_class() -> String: - return "Any" diff --git a/addons/WAT/test/case.gd b/addons/WAT/test/case.gd deleted file mode 100644 index 7c45551..0000000 --- a/addons/WAT/test/case.gd +++ /dev/null @@ -1,56 +0,0 @@ -extends Node - -var _total: int = 0 -var _passed: int = 0 -var _directory: String -var _title: String -var _path: String -var _methods: Array = [] -var _success: bool = false -var _time_taken: float = 0.0 -var _test: Node -var _names: Array = [] - -func _init(directory, filepath, title, test) -> void: - _test = test - _title = title - _path = filepath - _directory = directory - -func add_method(name: String) -> void: - if name in _names: - # We're running a test with multiple arguments - return - _names.append(name) - var contxt = name.replace("_", " ").lstrip("test") - _methods.append({fullname = name, context = contxt, assertions = [], total = 0, passed = 0, success = false, time = 0.0}) - -func _on_test_method_described(description: String) -> void: - _methods.back().context = description - - # We pass this to the controller who passes it to the runner who passes -func _on_asserted(assertion: Dictionary) -> void: - assertion["method"] = _methods.back()["fullname"] - assertion["script"] = _path - # Handle on demand so we can pass it on to live updaters - _methods.back().assertions.append(assertion) - _methods.back()["total"] += 1 - _methods.back()["passed"] += assertion["success"] as int # false = 0, true = 1 - -func calculate() -> void: - for method in _methods: - method.success = method.total > 0 and method.total == method.passed - _passed += method.success as int - _total = _methods.size() - _success = _total > 0 and _total == _passed - -func to_dictionary() -> Dictionary: - return { total = _total, - passed = _passed, - context = _title, - methods = _methods, - success = _success, - path = _path, - time_taken = _time_taken, - dir = _directory, - } diff --git a/addons/WAT/test/parameters.gd b/addons/WAT/test/parameters.gd deleted file mode 100644 index aa9748d..0000000 --- a/addons/WAT/test/parameters.gd +++ /dev/null @@ -1,20 +0,0 @@ -extends Reference - -var _keys: Array = [] -var _values: Array = [] - -var parameters: Dictionary = {} -#parameters([["a", "b", "expected"], [2, 2, 4], [5, 5, 10], [7, 7, 14]]) -func parameters(list: Array) -> bool: - if _keys.empty() or _values.empty(): - # Keys aren't empty, so we'll be updating this implicilty every time a call is made instead - _keys = list.pop_front() - _values = list - return _update() - -func _update() -> bool: - parameters.clear() - var values = _values.pop_front() - for i in _keys.size(): - parameters[_keys[i]] = values[i] - return not _values.empty() diff --git a/addons/WAT/test/recorder.gd b/addons/WAT/test/recorder.gd deleted file mode 100644 index 5c4423e..0000000 --- a/addons/WAT/test/recorder.gd +++ /dev/null @@ -1,32 +0,0 @@ -extends Node - -var _recording: Object -var _properties: Dictionary -var _is_recording: bool = false - -func record(what: Object, properties: Array) -> void: - _recording = what - for property in properties: - _properties[property] = [] - -func start() -> void: - _is_recording = true - -func stop() -> void: - _is_recording = false - -func _process(delta: float) -> void: - if _is_recording: - _capture() - -func _capture() -> void: - if not is_instance_valid(_recording): - return - for property in _properties: - _properties[property].append(_recording.get(property)) - -func get_property_timeline(property: String): - return _properties[property] - -func get_property_map() -> Dictionary: - return _properties diff --git a/addons/WAT/test/test.gd b/addons/WAT/test/test.gd deleted file mode 100644 index 77bf7d6..0000000 --- a/addons/WAT/test/test.gd +++ /dev/null @@ -1,163 +0,0 @@ -extends Node -class_name WATTest - -const Assertions: GDScript = preload("res://addons/WAT/assertions/assertions.gd") -const COMPLETED: String = "completed" -const IS_WAT_TEST: bool = true -const YIELD: String = "finished" -const Executed: String = "executed" -signal described -signal completed - -var rerun_method: bool -var p: Dictionary -var _last_assertion_passed: bool = false - -var recorder: Script = preload("res://addons/WAT/test/recorder.gd") -var any: Script = preload("res://addons/WAT/test/any.gd") -var asserts: Assertions -var direct -var _parameters -var _watcher -var _registry -var _yielder: Timer -var _case -var _methods = [] - -signal test_method_started -signal asserted -signal test_method_finished -signal test_script_finished -signal results_received - -func setup(directory = "", filepath = "", methods = []): - _methods = methods - _case = preload("res://addons/WAT/test/case.gd").new(directory, filepath, title(), self) - return self - -func run(): - var cursor = -1 - yield(call_function("start"), COMPLETED) - while cursor < _methods.size() - 1 or rerun_method: - if not rerun_method: - cursor += 1 - for hook in ["pre", "execute", "post"]: - yield(call_function(hook, cursor), COMPLETED) - # Post-yield so this should be correct - # What about repeated methods? - if hook == "execute" and not rerun_method: - emit_signal("test_method_finished") - yield(call_function("end"), COMPLETED) - emit_signal("test_script_finished", get_results()) - -func call_function(function, cursor = 0): - var s = call(function) if function != "execute" else execute(cursor) - call_deferred("emit_signal", COMPLETED) - yield(s, COMPLETED) if s is GDScriptFunctionState else yield(self, COMPLETED) - -func execute(cursor: int): - var _current_method: String = _methods[cursor] - if not rerun_method: - emit_signal("test_method_started", _current_method) - _case.add_method(_current_method) - return call(_current_method) - -func _on_assertion(assertion: Dictionary) -> void: - _last_assertion_passed = assertion["success"] - emit_signal("asserted", assertion) - -func previous_assertion_failed() -> bool: - return not _last_assertion_passed - -func _ready() -> void: - asserts = preload("res://addons/WAT/assertions/assertions.gd").new() - direct = preload("res://addons/WAT/double/factory.gd").new() - _parameters = preload("res://addons/WAT/test/parameters.gd").new() - _watcher = preload("res://addons/WAT/test/watcher.gd").new() - _registry = preload("res://addons/WAT/double/registry.gd").new() - _yielder = preload("res://addons/WAT/test/yielder.gd").new() - - p = _parameters.parameters - direct.registry = _registry - # May be better just as a property on asserts itself - asserts.connect("asserted", self, "_on_assertion") - add_child(direct) - add_child(_yielder) - connect("described", _case, "_on_test_method_described") - asserts.connect("asserted", _case, "_on_asserted") - run() - -func start(): - pass - -func pre(): - pass - -func post(): - pass - -func end(): - pass - -func any(): - return any.new() - -func watch(emitter, event: String) -> void: - _watcher.watch(emitter, event) - -func unwatch(emitter, event: String) -> void: - _watcher.unwatch(emitter, event) - -func record(who: Object, properties: Array) -> Node: - var record = recorder.new() - record.record(who, properties) - add_child(record) - return record - -## Thanks to bitwes @ https://github.com/bitwes/Gut/ -func simulate(obj, times, delta): - for i in range(times): - if(obj.has_method("_process")): - obj._process(delta) - if(obj.has_method("_physics_process")): - obj._physics_process(delta) - - for kid in obj.get_children(): - simulate(kid, 1, delta) - -func describe(message: String) -> void: - #get_parent().on_method_described(message) - emit_signal("described", message) - -func title() -> String: - var path: String = get_script().get_path() - var substr: String = path.substr(path.find_last("/") + 1, - path.find(".gd")).replace(".gd", "").replace("test", "").replace(".", " ").capitalize() - return substr - -func path() -> String: - # Expand for suites - return get_script().get_path() - -func parameters(list: Array) -> void: - rerun_method = _parameters.parameters(list) - -func until_signal(emitter: Object, event: String, time_limit: float) -> Node: - watch(emitter, event) - return _yielder.until_signal(time_limit, emitter, event) - -func until_timeout(time_limit: float) -> Node: - return _yielder.until_timeout(time_limit) - -func get_results() -> Dictionary: - _case.calculate() - var results: Dictionary = _case.to_dictionary() - _case.free() - return results - -func get_test_methods() -> Array: - var methods: Array = [] - for method in get_script().get_script_method_list(): - if method.name.begins_with("test"): - methods.append(method.name) - return methods diff --git a/addons/WAT/test/watcher.gd b/addons/WAT/test/watcher.gd deleted file mode 100644 index fd828e7..0000000 --- a/addons/WAT/test/watcher.gd +++ /dev/null @@ -1,43 +0,0 @@ -extends Reference - -var watching: Dictionary = {} -var _objects: Array = [] - -func watch(emitter, event: String) -> void: - _objects.append(emitter) - if emitter.is_connected(event, self, "_add_emit"): - return - emitter.set_meta("watcher", self) - emitter.connect(event, self, "_add_emit", [emitter, event]) - watching[event] = {emit_count = 0, calls = []} - - -func _add_emit(a = null, b = null, c = null, d = null, e = null, f = null, g = null, h = null, i = null, j = null, k = null): - var arguments: Array = [a, b, c, d, e, f, g, h, i, j, k] - var event - while not event: - event = arguments.pop_back() - var obj = arguments.pop_back() - watching[event].emit_count += 1 - watching[event].calls.append({emitter = obj, args = arguments}) - -func unwatch(emitter, event: String) -> void: - if emitter.is_connected(event, self, "_add_emit"): - emitter.disconnect(event, self, "_add_emit") - watching.erase(event) - emitter.set_meta("watcher", null) - -func get_emit_count(event: String) -> int: - return watching[event]["emit_count"] - -func get_data(event: String) -> Dictionary: - return watching[event] - -func clear() -> void: - for object in _objects: - if is_instance_valid(object): - object.set_meta("watcher", null) - -#func _notification(what): -# if what == NOTIFICATION_PREDELETE: -# clear() diff --git a/addons/WAT/test/yielder.gd b/addons/WAT/test/yielder.gd deleted file mode 100644 index 4d95cde..0000000 --- a/addons/WAT/test/yielder.gd +++ /dev/null @@ -1,33 +0,0 @@ -extends Timer - -signal finished -var _emitter: Object -var _event: String - -func _init() -> void: - one_shot = true - connect("timeout", self, "_on_resume", [], CONNECT_DEFERRED) - -func until_timeout(time: float) -> Timer: - start(time) - return self - -func until_signal(time: float, emitter: Object, event: String) -> Timer: - _emitter = emitter - _event = event - _emitter.connect(event, self, "_on_resume", [], CONNECT_DEFERRED) - start(time) - return self - -func _on_resume(a = null, b = null, c = null, d = null, e = null, f = null) -> void: - stop() - if is_instance_valid(_emitter) and _emitter.is_connected(_event, self, "_on_resume"): - _emitter.disconnect(_event, self, "_on_resume") - # Our adapter is connected to this. When this is emitted our adapter - # ..will call "_next" which call defers _change_state. Since it is a deferred - # ..call the test will resume first. Therefore if a new yield gets constructed - # ..in the interim we will be able to check if we have restarted the yield clock - emit_signal("finished", [a, b, c, d, e, f]) - -func is_active() -> bool: - return not is_stopped() and time_left > 0 diff --git a/addons/WAT/ui/cli.gd b/addons/WAT/ui/cli.gd deleted file mode 100644 index 20cdde5..0000000 --- a/addons/WAT/ui/cli.gd +++ /dev/null @@ -1,142 +0,0 @@ -extends Node - -const JUnitXML: GDScript = preload("res://addons/WAT/io/junit_xml.gd") -const Metadata: GDScript = preload("res://addons/WAT/io/metadata.gd") -const FileSystem: GDScript = preload("res://addons/WAT/filesystem/filesystem.gd") -const TestRunner: GDScript = preload("res://addons/WAT/runner/TestRunner.gd") -var _filesystem: FileSystem -var _run: Dictionary = {} -var _time_taken: float = 0.0 -var _runner - -func _ready() -> void: - _load_tests() - _run = {} - var arguments: Array = Array(OS.get_cmdline_args()) - arguments = arguments.slice(1, arguments.size()) - var run: Dictionary = {} - for arg in arguments: - var split = arg.split("=") - _run[split[0]] = split[1] - _parse() - -func _load_tests() -> void: - _filesystem = FileSystem.new() - Metadata.load_metadata(_filesystem) - _filesystem.update() - -func _parse() -> void: - var split: Array = _run["run"].split("+") - match split[0]: - "all": - # run=all - run(_filesystem.root) - "dir": - # run=dir+dirpath - run(_filesystem.index[split[1]]) - "script": - # run=script+scriptpath - run(_filesystem.index[split[1]]) - "method": - # run=method+scriptpath+methodname - run(_filesystem.index[split[1] + split[2]]) - "failed": - # run=failed - run(_filesystem.failed) - "tag": - # run=tag+tagname - _filesystem.tagged.set_tests(split[1], _filesystem.root) - run(_filesystem.tagged) - _: - _quit() - -func run(data: Reference) -> void: - var repeats: int = _repeats() - var threads: int = _threads() - - var tests: Array = data.get_tests() - if tests.empty(): - push_warning("WAT: No tests found") - OS.exit_code = 1 - _quit() - - _runner = TestRunner.new() - add_child(_runner) - var x = load("res://addons/WAT/ui/results/tab_container.gd").new() - var results: Array = yield(_runner.run(tests, _repeats(), _threads()), "completed") - _runner.queue_free() - - var cases = {passed = 0, total = 0, crashed = 0} - for case in results: - cases.total += 1 - if case.success: - cases.passed += 1 - else: - _display_failures(case) - - _display(cases) - _filesystem.failed.update(results) - OS.exit_code = not int(cases.total > 0 and cases.total == cases.passed) - - Metadata.save_metadata(_filesystem) - JUnitXML.write(results, _filesystem.Settings, _time_taken) - #cases.clear() - #results.clear() - _quit() - -func _repeats() -> int: - # r=X where X is a number - if _run.has("r"): - return _run["r"] as int - # r=X where X is a number - elif _run.has("repeat"): - return _run.has("repeat") as int - else: - return 0 - -func _threads() -> int: - var threads: int = 0 - # t=X where X is a number - if _run.has("t"): - threads = _run["t"] as int - # thread=X where X is a number - elif _run.has("thread"): - threads = _run.has("thread") as int - else: - return 1 - if threads > OS.get_processor_count(): - threads = OS.get_processor_count() - 1 - return threads - - -func _display(cases: Dictionary) -> void: - cases.seconds = stepify(OS.get_ticks_msec() / 1000.0, 0.001) - _time_taken = cases.seconds - print(""" - -------RESULTS------- - Took {seconds} second(s) - {passed} / {total} Test Scripts Passed - -------RESULTS------- - """.format(cases).dedent()) - -func _display_failures(case) -> void: - # We could create this somewhere else? - print("%s (%s)" % [case.context, case.path]) - match case.total: - -1: - print("\n Parse Error (check syntax or broken dependencies)") - 0: - print("\n No Test Methods Defined") - _: - for method in case.methods: - if not method.success: - print("\n %s" % method.context) - for assertion in method.assertions: - if not assertion.success: - print("\t%s" % assertion.context, - "\n\t (EXPECTED: %s) | (RESULTED: %s)" % \ - [assertion.expected, assertion.actual]) - -func _quit() -> void: - _filesystem.clear() - get_tree().quit() diff --git a/addons/WAT/ui/docker.gd b/addons/WAT/ui/docker.gd deleted file mode 100644 index 67f01f2..0000000 --- a/addons/WAT/ui/docker.gd +++ /dev/null @@ -1,56 +0,0 @@ -extends Node - -const BOTTOM_PANEL: int = 8 -const displays: Dictionary = { - 0: "Left.UL Dock", 1: "Left.BL Dock", 2: "Left.UR Dock", - 3: "Left.BR Dock", 4: "Right.UL Dock", 5: "Right.BL Dock", - 6: "Right.UR Dock", 7: "Right.BR Dock", 8: "Bottom Panel", -} - -var _plugin: EditorPlugin -var _scene: Control -var _state: int - -func _init(plugin: EditorPlugin, scene: Control) -> void: - _plugin = plugin - _scene = scene - add_setting() - _state = ProjectSettings.get_setting("WAT/Display") - construct() - -func _process(delta: float) -> void: - var state = ProjectSettings.get_setting("WAT/Display") - if state != _state: - deconstruct() - _state = state - construct() - -func construct() -> void: - if _state == BOTTOM_PANEL: - _plugin.add_control_to_bottom_panel(_scene, "Tests") - else: - _plugin.add_control_to_dock(_state, _scene) - -func deconstruct() -> void: - if _state == BOTTOM_PANEL and is_instance_valid(_scene): - _plugin.remove_control_from_bottom_panel(_scene) - elif is_instance_valid(_scene): - _plugin.remove_control_from_docks(_scene) - -func _notification(what) -> void: - if what == NOTIFICATION_PREDELETE: - ProjectSettings.set_setting("WAT/Display", _state) - ProjectSettings.save() - deconstruct() - -func add_setting() -> void: - if not ProjectSettings.has_setting("WAT/Display"): - ProjectSettings.set_setting("WAT/Display", BOTTOM_PANEL) - ProjectSettings.save() - var property = {} - property.name = "WAT/Display" - property.type = TYPE_INT - property.hint = PROPERTY_HINT_ENUM - property.hint_string = PoolStringArray(displays.values()).join(",") - ProjectSettings.add_property_info(property) - ProjectSettings.save() diff --git a/addons/WAT/ui/gui.gd b/addons/WAT/ui/gui.gd deleted file mode 100644 index 2d0f145..0000000 --- a/addons/WAT/ui/gui.gd +++ /dev/null @@ -1,129 +0,0 @@ -tool -extends PanelContainer - -const FileSystem: GDScript = preload("res://addons/WAT/filesystem/filesystem.gd") -const SceneTreeAdjuster: GDScript = preload("res://addons/WAT/ui/scaling/scene_tree_adjuster.gd") -const Settings: GDScript = preload("res://addons/WAT/settings.gd") -const JUnitXML: GDScript = preload("res://addons/WAT/io/junit_xml.gd") -onready var RunAll: Button = $Core/Menu/RunAll -onready var DebugAll: Button = $Core/Menu/DebugAll -onready var TestMenu: Button = $Core/Menu/TestMenu -onready var Results: TabContainer = $Core/Results -onready var Summary: HBoxContainer = $Core/Summary -onready var Threads: SpinBox = $Core/Menu/RunSettings/Threads -onready var Repeats: SpinBox = $Core/Menu/RunSettings/Repeats -onready var Server: Node = $Server - -var _icons: Reference -var _filesystem: FileSystem -var _plugin = null -var _build: FuncRef - -func _ready() -> void: - _icons = preload("res://addons/WAT/ui/scaling/icons.gd").new() - TestMenu.icons = _icons - Results.icons = _icons - RunAll.set_focus_mode(FOCUS_ALL) - DebugAll.set_focus_mode(FOCUS_ALL) - TestMenu.set_focus_mode(FOCUS_ALL) - $Core/Menu.set_focus_mode(FOCUS_ALL) - - if not Engine.is_editor_hint(): - _setup_scene_context() - Threads.max_value = OS.get_processor_count() - 1 - RunAll.connect("pressed", self, "_on_run_pressed") - DebugAll.connect("pressed", self, "_on_debug_pressed") - TestMenu.connect("run_pressed", self, "_on_run_pressed") - TestMenu.connect("debug_pressed", self, "_on_debug_pressed") - $Core/Menu/ResultsMenu.get_popup().connect("index_pressed", Results, "_on_view_pressed") - -func _setup_scene_context() -> void: - OS.window_size = ProjectSettings.get_setting("WAT/Window_Size") - SceneTreeAdjuster.adjust(self, _icons) - _filesystem = load("res://addons/WAT/filesystem/filesystem.gd").new() - TestMenu.filesystem = _filesystem - _filesystem.update() - TestMenu.update_menus() - DebugAll.disabled = true - -func setup_editor_context(plugin, build: FuncRef, goto_func: FuncRef, filesystem: Reference) -> void: - yield(self, "ready") - SceneTreeAdjuster.adjust(self, _icons, plugin) - _plugin = plugin - _filesystem = filesystem - _build = build - Results.goto_function = goto_func - TestMenu.filesystem = _filesystem - _filesystem.update() - TestMenu.update_menus() - Server.results_view = Results - - -# Setup tests for display. Returns false if run should be terminated. -func _setup_display(tests: Array) -> bool: - if tests.empty(): - push_warning("WAT: No tests found. Terminating run") - return false - Summary.time() - Results.display(tests, Repeats.value) - return true - - -func _on_run_pressed(data = _filesystem.root) -> void: - Results.clear() - var current_build = true - if _filesystem.changed or not Settings.cache_tests(): - if not _filesystem.built: - current_build = false - _filesystem.built = yield(_filesystem.build_function.call_func(), "completed") - if data == _filesystem.root: - _filesystem.update() - data = _filesystem.root # New Root - TestMenu.update_menus() # Also update the "Select Tests" dropdown - # Only run if the build is current and up to date. - if current_build: - var tests: Array = data.get_tests() - if _setup_display(tests): - var instance = preload("res://addons/WAT/runner/TestRunner.gd").new() - add_child(instance) - var results: Array = yield(instance.run(tests, Repeats.value, - Threads.value, Results), "completed") - instance.queue_free() - _on_test_run_finished(results) - -func _on_debug_pressed(data = _filesystem.root) -> void: - Results.clear() - var current_build = true - if _filesystem.changed or not Settings.cache_tests(): - if not _filesystem.built: - current_build = false - _filesystem.built = yield(_filesystem.build_function.call_func(), "completed") - if data == _filesystem.root: - _filesystem.update() - data = _filesystem.root # New Root - TestMenu.update_menus() - - if current_build: - var tests: Array = data.get_tests() - if _setup_display(tests): - _plugin.get_editor_interface().play_custom_scene( - "res://addons/WAT/runner/TestRunner.tscn") - if Settings.is_bottom_panel(): - _plugin.make_bottom_panel_item_visible(self) - yield(Server, "network_peer_connected") - Server.send_tests(tests, Repeats.value, Threads.value) - var results: Array = yield(Server, "results_received") - _plugin.get_editor_interface().stop_playing_scene() # Check if this works exported - _on_test_run_finished(results) - - -func _on_test_run_finished(results: Array) -> void: - if _plugin: - _plugin.get_editor_interface().stop_playing_scene() # Check if this works exported - Summary.summarize(results) - JUnitXML.write(results, Settings, Summary.time_taken) - _filesystem.failed.update(results) - -func _notification(what): - if what == NOTIFICATION_WM_QUIT_REQUEST: - queue_free() diff --git a/addons/WAT/ui/links.gd b/addons/WAT/ui/links.gd deleted file mode 100644 index 80de650..0000000 --- a/addons/WAT/ui/links.gd +++ /dev/null @@ -1,12 +0,0 @@ -extends MenuButton -tool - -func _ready() -> void: - set_focus_mode(FOCUS_ALL) - var p: PopupMenu = get_popup() - p.set_item_metadata(0, "https://ko-fi.com/alexanddraw") - p.set_item_metadata(1, "https://github.com/AlexDarigan/WAT/issues/new") - p.connect("index_pressed", self, "_on_idx_pressed") - -func _on_idx_pressed(idx: int) -> void: - OS.shell_open(get_popup().get_item_metadata(idx)) diff --git a/addons/WAT/ui/results/assertion.gd b/addons/WAT/ui/results/assertion.gd deleted file mode 100644 index 80e6755..0000000 --- a/addons/WAT/ui/results/assertion.gd +++ /dev/null @@ -1,12 +0,0 @@ -extends Reference - -var component: TreeItem -var context: String = "" -var success: bool = false - -func _init(_component: TreeItem, data: Dictionary) -> void: - component = _component - context = data["context"] - success = data["success"] - if context != "": - component.set_text(0, context) diff --git a/addons/WAT/ui/results/counter.gd b/addons/WAT/ui/results/counter.gd deleted file mode 100644 index 0fdfea4..0000000 --- a/addons/WAT/ui/results/counter.gd +++ /dev/null @@ -1,32 +0,0 @@ -extends Reference -# Counter TreeItem component for tests passed over total executed. - -signal counter_changed - -var component: TreeItem -var path: String -var title: String setget set_title -var passed: int = 0 setget set_passed -var total: int = 0 setget set_total -var show: bool = true - -func _init(_component: TreeItem) -> void: - component = _component - connect("counter_changed", self, "display") - -func set_passed(_passed: int) -> void: - passed = _passed - emit_signal("counter_changed") - -func set_total(_total: int) -> void: - total = _total - emit_signal("counter_changed") - -func set_title(_title: String) -> void: - title = _title - component.set_text(0, _title) - -# Displays (total / passed) in the component text. -func display() -> void: - if show: - component.set_text(0, "(%s/%s) %s" % [passed, total, title]) diff --git a/addons/WAT/ui/results/method.gd b/addons/WAT/ui/results/method.gd deleted file mode 100644 index 3dfe8b5..0000000 --- a/addons/WAT/ui/results/method.gd +++ /dev/null @@ -1,37 +0,0 @@ -extends "res://addons/WAT/ui/results/counter.gd" - -const AssertionTreeItem: GDScript = preload("res://addons/WAT/ui/results/assertion.gd") - -var scriptpath: String -var name: String -var assertions: Array = [] - -func _init(_component: TreeItem, _title: String, _script: String).(_component) -> void: - scriptpath = _script - path = _title - name = _title # func name - set_title(_title.replace("test_", "").replace("_", " ")) - show = false # Modify if test method results should display number of assertions passed. - -func add_assertion(tree: Tree, data: Dictionary): - set_total(total + 1) - if data["assertion"]["success"]: - set_passed(passed + 1) - if data["assertion"]["context"] == "": - component.collapsed = true - var expected: TreeItem = tree.create_item(component) - var actual: TreeItem = tree.create_item(component) - expected.set_text(0, "EXPECTED: %s" % data["assertion"]["expected"]) - actual.set_text(0, "RESULTED: %s" % data["assertion"]["actual"]) - else: - var assertion: AssertionTreeItem = AssertionTreeItem.new(tree.create_item(component), data["assertion"]) - assertion.component.collapsed = true - var expected: TreeItem = tree.create_item(assertion.component) - var actual: TreeItem = tree.create_item(assertion.component) - expected.set_text(0, "EXPECTED: %s" % data["assertion"]["expected"]) - actual.set_text(0, "RESULTED: %s" % data["assertion"]["actual"]) - assertion.component.set_custom_color(0, tree.PASSED if assertion.success else tree.FAILED) - assertion.component.set_icon(0, tree.icons.passed if assertion.success else tree.icons.failed) - tree.scroll_to_item(assertion.component) - assertions.append(assertion) - return assertion diff --git a/addons/WAT/ui/results/script.gd b/addons/WAT/ui/results/script.gd deleted file mode 100644 index 38a3231..0000000 --- a/addons/WAT/ui/results/script.gd +++ /dev/null @@ -1,21 +0,0 @@ -extends "res://addons/WAT/ui/results/counter.gd" - -const MethodTreeItem: GDScript = preload("res://addons/WAT/ui/results/method.gd") - -var methods: Dictionary = {} -var method_names: PoolStringArray - -func _init(_component: TreeItem, data: Dictionary).(_component) -> void: - set_title(data["name"] if data["title"] == "" else data["title"]) - path = data["path"] - method_names = data["methods"] - -func add_method(tree: Tree, data: Dictionary) -> void: - var method = MethodTreeItem.new(tree.create_item(component), data["method"], path) - methods[method.path] = method - set_total(total + 1) - tree.scroll_to_item(method.component) - -func on_method_finished(data: Dictionary) -> void: - if data["success"]: - set_passed(passed + 1) diff --git a/addons/WAT/ui/results/tab.gd b/addons/WAT/ui/results/tab.gd deleted file mode 100644 index 7ce03bc..0000000 --- a/addons/WAT/ui/results/tab.gd +++ /dev/null @@ -1,30 +0,0 @@ -extends Reference - -var tree: Tree -var title: String -var idx: int = 0 -var count: int = 0 -var passed: int = 0 -var _multiplier: int = 0 -var _expected_total: int = 0 -var success: bool = false -var expected setget ,_get_expected - -func _init(_tree: Tree, _title: String, multiplier: int) -> void: - tree = _tree - title = _title - _multiplier = multiplier + 1 - -func increment_expected_total() -> void: - # Multiplier tracks how many times we repeat tests - # count should always be 1 - _expected_total += 1 * _multiplier - -func on_test_script_finished(successful: bool) -> void: - if successful: - passed += 1 - if count == _expected_total and passed == count: - success = true - -func _get_expected() -> int: - return _expected_total diff --git a/addons/WAT/ui/results/tab_container.gd b/addons/WAT/ui/results/tab_container.gd deleted file mode 100644 index d0bfe56..0000000 --- a/addons/WAT/ui/results/tab_container.gd +++ /dev/null @@ -1,92 +0,0 @@ -tool -extends TabContainer - -const Tab: GDScript = preload("res://addons/WAT/ui/results/tab.gd") -const ResultTree: GDScript = preload("res://addons/WAT/ui/results/tree.gd") -var tabs: Dictionary = {} # of Tabs -var idx: int = 0 -var icons: Reference -var goto_function: FuncRef - -func clear() -> void: - tabs = {} - idx = 0 - for child in get_children(): - child.free() - -func display(tests: Array, multiplier: int) -> void: - clear() - for test in tests: - - if not tabs.has(test["dir"]): - var tree: ResultTree = ResultTree.new(icons) - var tab: Tab = Tab.new(tree, test.dir, multiplier) - tabs[test.dir] = tab - tree.goto_function = goto_function - tabs[test.dir].increment_expected_total() - update() - -func on_test_script_started(data: Dictionary) -> void: - var tab: Tab = tabs[data["dir"]] - tab.count += 1 - if not tab.tree.is_inside_tree(): - tab.idx = idx - add_child(tab.tree, true) - set_tab_title(tab.idx, "( %s / %s ) %s" % [tab.passed, tab.expected, tab.title]) - idx += 1 - else: - set_tab_title(tab.idx, "( %s / %s ) %s" % [tab.passed, tab.expected, tab.title]) - current_tab = tab.idx - tab.tree.add_test(data) - -func on_test_method_started(data: Dictionary) -> void: - tabs[data["dir"]].tree.add_method(data) - -func on_test_method_described(data: Dictionary) -> void: - tabs[data["dir"]].tree.on_test_method_described(data) - -func on_test_method_finished(data: Dictionary) -> void: - var tab: Tab = tabs[data["dir"]] - tab.tree.on_test_method_finished(data) - if tab.tree.failed: - set_tab_icon(tab.idx, icons.failed) - -func on_test_script_finished(data: Dictionary) -> void: - var tab: Tab = tabs[data["dir"]] - tab.tree.on_test_script_finished(data) - tab.on_test_script_finished(data["success"]) - if data["success"]: - set_tab_title(tab.idx, "( %s / %s ) %s" % [tab.passed, tab.expected, tab.title]) - else: - set_tab_icon(tab.idx, icons.failed) - if tab.success: - set_tab_icon(tab.idx, icons.passed) - -func on_asserted(data: Dictionary): - var tab: Tab = tabs[data["dir"]] - tab.tree.add_assertion(data) - if tab.tree.failed: - set_tab_icon(tab.idx, icons.failed) - -func _collapse_all() -> void: - for child in get_children(): - child.collapse_all() - -func _expand_all() -> void: - for child in get_children(): - child.expand_all() - -func _expand_failures() -> void: - for child in get_children(): - child.expand_failures() - -enum { EXPAND_ALL, COLLAPSE_ALL, EXPAND_FAILURES } -func _on_view_pressed(option: int) -> void: - match option: - EXPAND_ALL: - _expand_all() - COLLAPSE_ALL: - _collapse_all() - EXPAND_FAILURES: - _expand_failures() - diff --git a/addons/WAT/ui/results/tree.gd b/addons/WAT/ui/results/tree.gd deleted file mode 100644 index 9cb91fa..0000000 --- a/addons/WAT/ui/results/tree.gd +++ /dev/null @@ -1,121 +0,0 @@ -tool -extends Tree - -const ScriptTreeItem: GDScript = preload("res://addons/WAT/ui/results/script.gd") -const MethodTreeItem: GDScript = preload("res://addons/WAT/ui/results/method.gd") -const AssertionTreeItem: GDScript = preload("res://addons/WAT/ui/results/assertion.gd") - -var tests = [] -var root: TreeItem -var scripts: Dictionary = {} -var current_method: MethodTreeItem -var icons: Reference -var failed: bool = false -var goto_function: FuncRef - -func _init(_icons: Reference) -> void: - icons = _icons - if Engine.is_editor_hint(): - connect("button_pressed", self, "_on_button_pressed") - -func _on_button_pressed(item: TreeItem, col: int = 0, id: int = 0) -> void: - var data: MethodTreeItem = item.get_meta("data") - goto_function.call_func(data.scriptpath, data.name) - -func _ready() -> void: - visible = false - hide_root = true - root = create_item() - add_constant_override("Scroll Speed", 24) - -const PASSED: Color = Color(0.34375, 1, 0.34375) -const FAILED: Color = Color(1, 0.425781, 0.425781) - -func add_result(result) -> void: - var script: ScriptTreeItem = scripts[result["path"]] - var success: bool = result["success"] - script.component.set_custom_color(0, PASSED if success else FAILED) - script.component.set_icon(0, icons.passed if success else icons.failed) - failed = not success - scroll_to_item(root) - -# TODO: All of these dict values should be serialized and unserialized at server points -# ..or sent directly if run in the editor but point is objects > dicts -func add_test(test) -> void: - var script: ScriptTreeItem = ScriptTreeItem.new(create_item(root), test) - scripts[script.path] = script - # Scrolling to a Script Component hides the scroll bar so don't - -func add_method(data: Dictionary) -> void: - var script: ScriptTreeItem = scripts[data["path"]] - script.add_method(self, data) - var method: MethodTreeItem = script.methods.values().back() - if Engine.is_editor_hint(): - method.component.add_button(0, icons.function) - method.component.set_tooltip(0, "Click function icon to show test method in editor") - method.component.set_meta("data", method) - -func add_assertion(data: Dictionary) -> void: - var script: ScriptTreeItem = scripts[data["path"]] - var method: MethodTreeItem = script.methods[data["method"]] - var assertion_maybe = method.add_assertion(self, data) - if not data["assertion"]["success"]: - script.component.set_custom_color(0, FAILED) - script.component.set_icon(0, icons.failed) - method.component.set_custom_color(0, FAILED) - method.component.set_icon(0, icons.failed) - if assertion_maybe != null: - _failures.append(assertion_maybe.component) - failed = true - -func on_test_method_described(data: Dictionary) -> void: - scripts[data["path"]].methods[data["method"]].component.set_text(0, data["description"]) - -func on_test_script_finished(data: Dictionary) -> void: - # On a finished test, change its color - var script: ScriptTreeItem = scripts[data["path"]] - var success: bool = data["success"] - script.component.set_custom_color(0, PASSED if success else FAILED) - script.component.set_icon(0, icons.passed if success else icons.failed) - _results.append(script.component) - if not success: - _failures.append(script.component) - - if data["total"] < 0: - var message: TreeItem = create_item(script.component) - message.set_text(0, "Error parsing test script, check for syntax errors or broken dependencies") - elif data["total"] == 0: - var message: TreeItem = create_item(script.component) - message.set_text(0, "No test methods implemented") - -func on_test_method_finished(data: Dictionary) -> void: - # On a finished method, change its color - var script: ScriptTreeItem = scripts[data["path"]] - var method: MethodTreeItem = script.methods[data["method"]] - script.on_method_finished(data) - _results.append(method.component) - if not data["success"]: - script.component.set_custom_color(0, FAILED) - script.component.set_icon(0, icons.failed) - failed = true - _failures.append(method.component) - method.component.set_custom_color(0, PASSED if data["success"] else FAILED) - method.component.set_icon(0, icons.passed if data["success"] else icons.failed) - method.component.collapsed = true - scroll_to_item(method.component) - -var _results: Array = [] -var _failures: Array = [] - -func expand_all() -> void: - for item in _results: - item.collapsed = false - -func collapse_all() -> void: - for item in _results: - item.collapsed = true - -func expand_failures() -> void: - collapse_all() - for item in _failures: - item.collapsed = false diff --git a/addons/WAT/ui/scaling/dynamic_size_spinbox.gd b/addons/WAT/ui/scaling/dynamic_size_spinbox.gd deleted file mode 100644 index dc072ec..0000000 --- a/addons/WAT/ui/scaling/dynamic_size_spinbox.gd +++ /dev/null @@ -1,60 +0,0 @@ -extends SpinBox -tool - -var oldText - -func _ready(): - get_line_edit().expand_to_text_length = true - get_line_edit().connect("text_changed", self, "_on_text_edit_changed") - get_line_edit().connect("focus_exited", self, "_on_focus_exited") - connect("value_changed", self, "_on_value_changed") - oldText = get_line_edit().text - - # Set's the text to itself in order to shoot an update to the line edit - # This is needed or else the line edit starts off off-centered at startup - get_line_edit().text = oldText - -func _on_focus_exited(): - # Disgusting frame waiting workaround because there is currently no way to - # listen for when a spinbox is changed and the change is rejected. - # (ie. inputting 20 in the spinbox when the spinbox already has a value of 20) - yield(get_tree(),"idle_frame") - yield(get_tree(),"idle_frame") - set_size(get_minimum_size()) - pass - -func _on_value_changed(newValue): - set_size(get_minimum_size()) - -func _on_text_edit_changed(newText): - # Using regex since you cannot reliably detect if a string is not an int - # (ie. String(invalid text) = 0, when 0 might be a value we want) - var regex = RegEx.new() - regex.compile("^(0|[1-9][0-9]*)$") - - # Remove prefix and suffixes - newText = newText.trim_prefix(prefix + " ").trim_suffix(" " + suffix) - - # Try and parse the inputted text in the middle - var result = regex.search(newText) - var invalidInput = false - - # If input is not an integer (excluding empty input), then revert the input back - if not newText.empty() and not result: - get_line_edit().text = oldText - invalidInput = true - # If input is out of bounds, bring it back to the nearest bound - elif result: - if int(result.get_string()) > max_value: - get_line_edit().text = str(max_value) - get_line_edit().caret_position = get_line_edit().text.length() - invalidInput = true - elif int(result.get_string()) < min_value: - get_line_edit().text = str(min_value) - get_line_edit().caret_position = get_line_edit().text.length() - invalidInput = true - - if not invalidInput: - oldText = prefix + " " + newText + " " + suffix - - set_size(get_minimum_size()) diff --git a/addons/WAT/ui/scaling/icons.gd b/addons/WAT/ui/scaling/icons.gd deleted file mode 100644 index b4fabc6..0000000 --- a/addons/WAT/ui/scaling/icons.gd +++ /dev/null @@ -1,17 +0,0 @@ -extends Reference - -var debug_failed = preload("res://addons/WAT/assets/debug_failed.png") -var docs = preload("res://addons/WAT/assets/docs.svg") -var failed = preload("res://addons/WAT/assets/failed.png") -var folder = preload("res://addons/WAT/assets/folder.png") -var function = preload("res://addons/WAT/assets/function.png") -var issue = preload("res://addons/WAT/assets/issue.svg") -var kofi = preload("res://addons/WAT/assets/kofi.png") -var label = preload("res://addons/WAT/assets/label.png") -var passed = preload("res://addons/WAT/assets/passed.png") -var play = preload("res://addons/WAT/assets/play.png") -var play_debug = preload("res://addons/WAT/assets/play_debug.png") -var play_failed = preload("res://addons/WAT/assets/play_failed.png") -var request_docs = preload("res://addons/WAT/assets/request_docs.svg") -var scriptx = preload("res://addons/WAT/assets/script.png") -var timer = preload("res://addons/WAT/assets/timer.png") diff --git a/addons/WAT/ui/scaling/plugin_assets_registry.gd b/addons/WAT/ui/scaling/plugin_assets_registry.gd deleted file mode 100644 index f0f3a76..0000000 --- a/addons/WAT/ui/scaling/plugin_assets_registry.gd +++ /dev/null @@ -1,122 +0,0 @@ -extends Reference -# Stores and scales editor related UI assets according to the user's editor scale. -# Repo: https://github.com/Atlinx/Godot-PluginAssetsRegistry - -# Replace 'demo_plugin' with your plugin's name -const PLUGIN_ABSOLUTE_PATH_PREFIX = "res://addons/WAT/" - -var plugin - -# Stores already loaded assets so multiple loads of the same asset -# do not duplicate the same asset multiple times. -var loaded_editor_assets: Dictionary - -# Only used by pre 3.3 Godot editors -var _cached_editor_scale = -1 - -func _init(plugin_ = null): - plugin = plugin_ - -# Returns an asset scaled to fit the current editor's UI scale -# Can load scaled asset with a string using the plugin folder as the root older -# Can load scaled asset using an already loaded asset -func load_asset(asset): - if asset is String: - return load_asset(load(PLUGIN_ABSOLUTE_PATH_PREFIX + asset)) - else: - # Godot compares by reference by default for dictionaries that use objects as keys - if loaded_editor_assets.has(asset): - return loaded_editor_assets[asset] - else: - if asset is Font: - loaded_editor_assets[asset] = _load_scaled_font(asset) - return loaded_editor_assets[asset] - elif asset is Texture: - loaded_editor_assets[asset] = _load_scaled_texture(asset) - return loaded_editor_assets[asset] - assert(false, "Cannot scale asset of type " + asset.get_class()) - -func _load_scaled_texture(texture: Texture) -> Texture: - # get_data already returns a copy, therefore no need to duplicate - var image = texture.get_data() - image.resize(image.get_width() * get_editor_scale(), image.get_height() * get_editor_scale()) - - var scaled_texture = ImageTexture.new() - scaled_texture.create_from_image(image) - - return scaled_texture - -func _load_scaled_font(font: Font) -> DynamicFont: - var duplicate = font.duplicate() - duplicate.size *= get_editor_scale() - return duplicate - -func get_editor_scale() -> float: - if plugin == null: - return 1.0 - if Engine.get_version_info().major > 3 or (Engine.get_version_info().major == 3 and Engine.get_version_info().minor >= 3): - return plugin.get_editor_interface().get_editor_scale() - elif Engine.get_version_info().major == 3: - if _cached_editor_scale == -1: - if Engine.get_version_info().minor >= 1: - _cached_editor_scale = _calculate_current_editor_scale_3_1() - else: - _cached_editor_scale = _calculate_current_editor_scale_3_0() - return _cached_editor_scale - else: - push_error("PluginAssetsRegistry is not supported for version: " % Engine.get_version_info().string) - return 1.0 - -func _calculate_current_editor_scale_3_1() -> float: - var editor_settings = plugin.get_editor_interface().get_editor_settings() - - var display_scale: int = editor_settings.get_setting("interface/editor/display_scale") - var custom_display_scale: float = editor_settings.get_setting("interface/editor/custom_display_scale") - - match display_scale: - 0: - if OS.get_name() == "OSX": - return OS.get_screen_max_scale() - else: - var screen: int = OS.get_current_screen() - if OS.get_screen_dpi(screen) >= 192 and OS.get_screen_size(screen).x > 2000: - return 2.0 - else: - return 1.0 - 1: - return 0.75 - 2: - return 1.0 - 3: - return 1.25 - 4: - return 1.5 - 5: - return 1.75 - 6: - return 2.0 - _: - return custom_display_scale - -func _calculate_current_editor_scale_3_0() -> float: - var editor_settings = plugin.get_editor_interface().get_editor_settings() - - var dpi_mode = editor_settings.get_settings("interface/editor/hidpi_mode") - - match dpi_mode: - 0: - var screen: int = OS.get_current_screen() - if OS.get_screen_dpi(screen) >= 192 and OS.get_screen_size(screen).x > 2000: - return 2.0 - else: - return 1.0 - 1: - return 0.75 - 2: - return 1.0 - 3: - return 1.5 - 4: - return 2.0 - _: - return 1.0 diff --git a/addons/WAT/ui/scaling/scene_tree_adjuster.gd b/addons/WAT/ui/scaling/scene_tree_adjuster.gd deleted file mode 100644 index 0c0e028..0000000 --- a/addons/WAT/ui/scaling/scene_tree_adjuster.gd +++ /dev/null @@ -1,35 +0,0 @@ -tool -extends Reference - -const PluginAssetsRegistry: GDScript = preload("res://addons/WAT/ui/scaling/plugin_assets_registry.gd") - -static func adjust(runner: PanelContainer, icons: Reference, plugin = null) -> void: - var registry: PluginAssetsRegistry = PluginAssetsRegistry.new(plugin) - - # Scale Icons - icons.debug_failed = registry.load_asset("assets/debug_failed.png") - icons.docs = registry.load_asset("assets/docs.svg") - icons.failed = registry.load_asset("assets/failed.png") - icons.folder = registry.load_asset("assets/folder.png") - icons.function = registry.load_asset("assets/function.png") - icons.issue = registry.load_asset("assets/issue.svg") - icons.kofi = registry.load_asset("assets/kofi.png") - icons.label = registry.load_asset("assets/label.png") - icons.passed = registry.load_asset("assets/passed.png") - icons.play = registry.load_asset("assets/play.png") - icons.play_debug = registry.load_asset("assets/play_debug.png") - icons.play_failed = registry.load_asset("assets/play_failed.png") - icons.request_docs = registry.load_asset("assets/request_docs.svg") - icons.scriptx = registry.load_asset("assets/script.png") - icons.timer = registry.load_asset("assets/timer.png") - - # Scale Icons already in the editor - runner.RunAll.icon = registry.load_asset(runner.RunAll.icon) - runner.DebugAll.icon = registry.load_asset(runner.DebugAll.icon) - - # Scale summary icons - runner.Summary.Time.icon = registry.load_asset(runner.Summary.Time.icon) - runner.Summary.Tests.icon = registry.load_asset(runner.Summary.Tests.icon) - runner.Summary.Passing.icon = registry.load_asset(runner.Summary.Passing.icon) - runner.Summary.Failing.icon = registry.load_asset(runner.Summary.Failing.icon) - runner.Summary.Runs.icon = registry.load_asset(runner.Summary.Runs.icon) diff --git a/addons/WAT/ui/summary.gd b/addons/WAT/ui/summary.gd deleted file mode 100644 index 62d06c4..0000000 --- a/addons/WAT/ui/summary.gd +++ /dev/null @@ -1,52 +0,0 @@ -extends HBoxContainer -tool - -var time: float = 0 -var runcount: int = 0 -var running = false -var time_taken: float = 0.0 - -onready var Time: Button = $Time -onready var Tests: Button = $Tests -onready var Passing: Button = $Passing -onready var Failing: Button = $Failing -onready var Runs: Button = $Runs - -func _ready() -> void: - for child in get_children(): - child.set_focus_mode(FOCUS_NONE) - -func time() -> void: - time_taken = 0.0 - runcount += 1 - time = OS.get_ticks_msec() - running = true - -func _process(delta): - if running: - Time.text = str((OS.get_ticks_msec() - time) / 1000) - -func summarize(caselist: Array) -> void: - running = false - time_taken = (OS.get_ticks_msec() - time) / 1000 - var passed = 0 - var failed = 0 - var total = 0 - for case in caselist: - total += 1 - if case.success: - passed += 1 - else: - failed += 1 - Time.text = time_taken as String - Tests.text = total as String - Passing.text = passed as String - Failing.text = failed as String - Runs.text = runcount as String - -func _setup_editor_assets(assets_registry): - Time.icon = assets_registry.load_asset(Time.icon) - Tests.icon = assets_registry.load_asset(Tests.icon) - Passing.icon = assets_registry.load_asset(Passing.icon) - Failing.icon = assets_registry.load_asset(Failing.icon) - Runs.icon = assets_registry.load_asset(Runs.icon) diff --git a/addons/WAT/ui/test_menu.gd b/addons/WAT/ui/test_menu.gd deleted file mode 100644 index 58b9b4c..0000000 --- a/addons/WAT/ui/test_menu.gd +++ /dev/null @@ -1,164 +0,0 @@ -tool -extends Button - -# TODO -# Add RunTag -# Add RunFailures - -const Settings: GDScript = preload("res://addons/WAT/settings.gd") -var _menu: PopupMenu -var filesystem -var icons -signal run_pressed -signal debug_pressed - -func _init() -> void: - _menu = PopupMenu.new() - add_child(_menu) - -func _pressed(): - var current_build = true - if filesystem.changed: - if not filesystem.built: - current_build = false - filesystem.built = yield(filesystem.build_function.call_func(), "completed") - filesystem.update() - update_menus() - if current_build: - var position: Vector2 = rect_global_position - position.y += rect_size.y - _menu.rect_global_position = position - _menu.rect_size = Vector2(rect_size.x, 0) - _menu.grab_focus() - _menu.popup() - -func clear() -> void: - _menu.queue_free() - -func update_menus() -> void: - _menu.queue_free() - _menu = PopupMenu.new() - add_child(_menu) - - _add_failed_run_menu() - _add_tag_run_menu() - - for dir in [filesystem.root] + filesystem.root.nested_subdirs: - if dir.tests.empty(): - continue - var dir_menu = _add_menu(_menu, dir, icons.folder, -1) - _add_run_callback(dir_menu, dir) - - for script in dir.tests: - var script_menu = _add_menu(dir_menu, script, icons.scriptx) - _add_run_callback(script_menu, script) - _add_tag_editor(script_menu, script) - - for method in script.methods: - var method_menu = _add_menu(script_menu, method, icons.function) - _add_run_callback(method_menu, method) - -func _add_menu(parent: PopupMenu, data: Object, icon, offset: int = 1) -> PopupMenu: - var child: PopupMenu = PopupMenu.new() - parent.add_child(child) - child.name = child.get_index() as String - parent.add_submenu_item(data.name, child.name, child.get_index()) - parent.set_item_icon(child.get_index() + offset, icon) - parent.hide_on_item_selection = true - child.hide_on_item_selection = true - return child - -func _add_run_callback(menu: PopupMenu, data: Object) -> void: - menu.add_item("Run") - menu.add_item("Debug") - menu.set_item_metadata(0, data) - menu.set_item_metadata(1, data) - menu.set_item_icon(0, icons.play) - menu.set_item_icon(1, icons.play_debug) - menu.set_item_disabled(1, not Engine.is_editor_hint()) - menu.connect("index_pressed", self, "_on_idx_pressed", [menu]) - -func _add_failed_run_menu() -> void: - var failed_menu: PopupMenu = PopupMenu.new() - _menu.add_child(failed_menu) - _menu.add_submenu_item("Failed", failed_menu.name) - _menu.set_item_icon(failed_menu.get_index() - 1, icons.failed) - failed_menu.add_item("Run") - failed_menu.add_item("Debug") - failed_menu.set_item_icon(0, icons.play) - failed_menu.set_item_icon(1, icons.play_debug) - failed_menu.set_item_metadata(0, filesystem.failed) - failed_menu.set_item_metadata(1, filesystem.failed) - failed_menu.set_item_disabled(1, not Engine.is_editor_hint()) - failed_menu.connect("index_pressed", self, "_on_failed_menu_pressed") - -func _add_tag_run_menu() -> void: - var tag_menu: PopupMenu = PopupMenu.new() - _menu.add_child(tag_menu) - _menu.add_submenu_item("Tagged", tag_menu.name) - _menu.set_item_icon(tag_menu.get_index() - 1, icons.label) - for tag in Settings.tags(): - var options: PopupMenu = PopupMenu.new() - tag_menu.add_child(options) - tag_menu.add_submenu_item(tag, options.name) - tag_menu.set_item_icon(options.get_index() - 1, icons.label) - options.add_item("Run") - options.add_item("Debug") - options.set_item_icon(0, icons.play) - options.set_item_icon(1, icons.play_debug) - options.set_item_disabled(1, not Engine.is_editor_hint()) - options.connect("index_pressed", self, "_on_tag_pressed", [tag]) - -func _add_tag_editor(script_menu: PopupMenu, script: Object) -> void: - var tagger: PopupMenu = PopupMenu.new() - tagger.hide_on_checkable_item_selection = false - tagger.connect("about_to_show", self, "_on_tag_editor_about_to_show", [tagger, script]) - tagger.connect("index_pressed", self, "_on_tagged", [tagger, script]) - # Unnecessary since we change per access - for tag in Settings.tags(): - tagger.add_check_item(tag) - script_menu.add_child(tagger) - script_menu.add_submenu_item("Edit Tags", tagger.name) - script_menu.set_item_icon(2, icons.label) - -func _on_tag_editor_about_to_show(tagger: PopupMenu, script: Object) -> void: - tagger.clear() - tagger.set_as_minsize() - var idx: int = 0 - for tag in Settings.tags(): - tagger.add_check_item(tag) - if filesystem.tagged.is_tagged(tag, script.path): - tagger.set_item_checked(idx, true) - idx += 1 - -func _on_tagged(index: int, tagger: PopupMenu, script: Object) -> void: - var tag: String = tagger.get_item_text(index) - if tagger.is_item_checked(index): - filesystem.tagged.untag(tag, script.path) - tagger.set_item_checked(index, false) - else: - filesystem.tagged.tag(tag, script.path) - tagger.set_item_checked(index, true) - -func _on_idx_pressed(idx: int, menu: PopupMenu) -> void: - match idx: - 0: - emit_signal("run_pressed", menu.get_item_metadata(idx)) - 1: - emit_signal("debug_pressed", menu.get_item_metadata(idx)) - -func _on_failed_menu_pressed(idx: int) -> void: - filesystem.failed.set_tests(filesystem.root) - match idx: - 0: - emit_signal("run_pressed", filesystem.failed) - 1: - emit_signal("debug_pressed", filesystem.failed) - -func _on_tag_pressed(idx: int, tag: String) -> void: - filesystem.tagged.set_tests(tag, filesystem.root) - match idx: - 0: - emit_signal("run_pressed", filesystem.tagged) - 1: - emit_signal("debug_pressed", filesystem.tagged) diff --git a/bootsplash.png.import b/bootsplash.png.import index be24c87..5fedd22 100644 --- a/bootsplash.png.import +++ b/bootsplash.png.import @@ -1,8 +1,9 @@ [remap] importer="texture" -type="StreamTexture" -path="res://.import/bootsplash.png-30e2c9990faa42442c2d12c3b0f7ed9a.stex" +type="CompressedTexture2D" +uid="uid://xs4tet3rfluv" +path="res://.godot/imported/bootsplash.png-30e2c9990faa42442c2d12c3b0f7ed9a.ctex" metadata={ "vram_texture": false } @@ -10,26 +11,24 @@ metadata={ [deps] source_file="res://bootsplash.png" -dest_files=[ "res://.import/bootsplash.png-30e2c9990faa42442c2d12c3b0f7ed9a.stex" ] +dest_files=["res://.godot/imported/bootsplash.png-30e2c9990faa42442c2d12c3b0f7ed9a.ctex"] [params] compress/mode=0 +compress/high_quality=false compress/lossy_quality=0.7 -compress/hdr_mode=0 -compress/bptc_ldr=0 +compress/hdr_compression=1 compress/normal_map=0 -flags/repeat=0 -flags/filter=true -flags/mipmaps=false -flags/anisotropic=false -flags/srgb=2 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" process/fix_alpha_border=true process/premult_alpha=false -process/HDR_as_SRGB=false -process/invert_color=false process/normal_map_invert_y=false -stream=false -size_limit=0 -detect_3d=true -svg/scale=1.0 +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/default_env.tres b/default_env.tres index 20207a4..75cee1f 100644 --- a/default_env.tres +++ b/default_env.tres @@ -1,7 +1,7 @@ -[gd_resource type="Environment" load_steps=2 format=2] +[gd_resource type="Environment" load_steps=2 format=3 uid="uid://d1jylo21mpcqw"] -[sub_resource type="ProceduralSky" id=1] +[sub_resource type="Sky" id="1"] [resource] background_mode = 2 -background_sky = SubResource( 1 ) +sky = SubResource("1") diff --git a/icon.png.import b/icon.png.import index a4c02e6..48170e1 100644 --- a/icon.png.import +++ b/icon.png.import @@ -1,8 +1,9 @@ [remap] importer="texture" -type="StreamTexture" -path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" +type="CompressedTexture2D" +uid="uid://cw01ge0bgos8m" +path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex" metadata={ "vram_texture": false } @@ -10,26 +11,24 @@ metadata={ [deps] source_file="res://icon.png" -dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ] +dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"] [params] compress/mode=0 +compress/high_quality=false compress/lossy_quality=0.7 -compress/hdr_mode=0 -compress/bptc_ldr=0 +compress/hdr_compression=1 compress/normal_map=0 -flags/repeat=0 -flags/filter=true -flags/mipmaps=false -flags/anisotropic=false -flags/srgb=2 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" process/fix_alpha_border=true process/premult_alpha=false -process/HDR_as_SRGB=false -process/invert_color=false process/normal_map_invert_y=false -stream=false -size_limit=0 -detect_3d=true -svg/scale=1.0 +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/project.godot b/project.godot index 8d832bb..a050174 100644 --- a/project.godot +++ b/project.godot @@ -6,32 +6,16 @@ ; [section] ; section goes between [] ; param=value ; assign values to parameters -config_version=4 - -_global_script_classes=[ { -"base": "Reference", -"class": "WAT", -"language": "GDScript", -"path": "res://addons/WAT/namespace.gd" -}, { -"base": "Node", -"class": "WATTest", -"language": "GDScript", -"path": "res://addons/WAT/test/test.gd" -} ] -_global_script_class_icons={ -"WAT": "", -"WATTest": "" -} +config_version=5 [WAT] Test_Directory="res://" Results_Directory="res://" Test_Metadata_Directory="res://" -Tags=PoolStringArray( ) +Tags=PackedStringArray() Cache_Tests=true -Window_Size=Vector2( 1280, 720 ) +Window_Size=Vector2(1280, 720) Minimize_Window_When_Running_Tests=false Port=6008 Display=8 @@ -40,17 +24,22 @@ Display=8 config/name="GDTask" run/main_scene="res://tests/manual/Test.tscn" +config/features=PackedStringArray("4.0", "C#") +boot_splash/bg_color=Color(0, 0, 0, 1) boot_splash/image="res://bootsplash.png" -boot_splash/bg_color=Color( 0, 0, 0, 1 ) config/icon="res://icon.png" [autoload] GdTaskPlayerLoopAutoload="*res://addons/GDTask/Autoload/GDTaskPlayerLoopAutoload.cs" +[dotnet] + +project/assembly_name="GDTask" + [editor_plugins] -enabled=PoolStringArray( "res://addons/WAT/plugin.cfg" ) +enabled=PackedStringArray() [gui] @@ -66,4 +55,4 @@ common/enable_pause_aware_picking=true [rendering] -environment/default_environment="res://default_env.tres" +environment/defaults/default_environment="res://default_env.tres" diff --git a/tests/GDTaskTests.cs b/tests/GDTaskTests.cs deleted file mode 100644 index 723d76b..0000000 --- a/tests/GDTaskTests.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Godot; -using Fractural.Tasks; - -namespace Tests -{ - public class GDTaskTests : WAT.Test - { - [Test] - public void TODO_Make_Tests() - { - Assert.IsTrue(true); - } - } -} \ No newline at end of file diff --git a/tests/manual/Test.cs b/tests/manual/Test.cs index 13dd5ab..923c24d 100644 --- a/tests/manual/Test.cs +++ b/tests/manual/Test.cs @@ -5,15 +5,15 @@ namespace Tests.Manual { - public class Test : Node2D + public partial class Test : Node2D { [Export] private NodePath spritePath; - public Sprite sprite; + public Sprite2D sprite; public override void _Ready() { - sprite = GetNode<Sprite>(spritePath); + sprite = GetNode<Sprite2D>(spritePath); } diff --git a/tests/manual/Test.tscn b/tests/manual/Test.tscn index bc24fe6..ea67b9e 100644 --- a/tests/manual/Test.tscn +++ b/tests/manual/Test.tscn @@ -1,14 +1,13 @@ -[gd_scene load_steps=3 format=2] +[gd_scene load_steps=3 format=3 uid="uid://cfm0u7eao06ff"] -[ext_resource path="res://tests/manual/Test.cs" type="Script" id=1] -[ext_resource path="res://icon.png" type="Texture" id=2] +[ext_resource type="Script" path="res://tests/manual/Test.cs" id="1"] +[ext_resource type="Texture2D" uid="uid://cw01ge0bgos8m" path="res://icon.png" id="2"] [node name="Test" type="Node2D"] -script = ExtResource( 1 ) -spritePath = NodePath("Sprite") +script = ExtResource("1") +spritePath = NodePath("Sprite2D") -[node name="Sprite" type="Sprite" parent="."] -texture = ExtResource( 2 ) +[node name="Sprite2D" type="Sprite2D" parent="."] +texture = ExtResource("2") [node name="Camera2D" type="Camera2D" parent="."] -current = true