├── Analyzers
├── AnalyzerReleases.Unshipped.md
├── nupkg
│ └── .gitignore
├── src
│ └── AssemblyInfo.cs
├── ReleaseNotes.txt
├── AnalyzerReleases.Shipped.md
└── documentation
│ ├── index.md
│ ├── GdUnit0201.md
│ ├── GdUnit0501.md
│ └── GdUnit0500.md
├── Api
├── nupkg
│ └── .gitignore
├── buildTransitive
│ └── gdUnit4.api.props
├── build
│ └── gdUnit4.api.props
├── src
│ ├── asserts
│ │ ├── IBoolAssert.cs
│ │ ├── ISignalAssert.cs
│ │ ├── CompareExtensions.cs
│ │ ├── IObjectAssert.cs
│ │ ├── IEnumerableAssert.cs
│ │ ├── IDictionaryAssert.cs
│ │ ├── IVectorAssert.cs
│ │ ├── BoolAssert.cs
│ │ ├── INumberAssert.cs
│ │ ├── ITuple.cs
│ │ ├── IValueExtractor.cs
│ │ ├── IStringAssert.cs
│ │ ├── Comparable.cs
│ │ ├── Tuple.cs
│ │ ├── ObjectAssert.cs
│ │ └── IExceptionAssert.cs
│ ├── AssemblyInfo.cs
│ ├── core
│ │ ├── runners
│ │ │ ├── GdUnit4TestRunnerSceneTemplate.cs
│ │ │ ├── GodotLogger.cs
│ │ │ ├── DefaultTestRunner.cs
│ │ │ └── GdUnit4TestRunnerSceneCore.cs
│ │ ├── hooks
│ │ │ ├── StdOutHookFactory.cs
│ │ │ └── StdOutConsoleHook.cs
│ │ ├── commands
│ │ │ ├── Response.cs
│ │ │ ├── IsAlive.cs
│ │ │ ├── BaseCommand.cs
│ │ │ └── TerminateGodotInstanceCommand.cs
│ │ ├── execution
│ │ │ ├── BeforeExecutionStage.cs
│ │ │ ├── monitoring
│ │ │ │ ├── OrphanNodesMonitor.cs
│ │ │ │ ├── GodotExceptionPattern.cs
│ │ │ │ ├── GodotPushErrorPattern.cs
│ │ │ │ └── MemoryPool.cs
│ │ │ ├── BeforeTestExecutionStage.cs
│ │ │ ├── DirectCommandExecutor.cs
│ │ │ ├── exceptions
│ │ │ │ └── ExecutionTimeoutException.cs
│ │ │ └── TestCaseExecutionStage.cs
│ │ ├── reporting
│ │ │ └── TestReportCollector.cs
│ │ ├── DebuggerUtils.cs
│ │ ├── attributes
│ │ │ ├── TestCategoryAttribute.cs
│ │ │ ├── RequireGodotRuntimeAttribute.cs
│ │ │ ├── TestSuiteAttribute.cs
│ │ │ ├── AfterAttribute.cs
│ │ │ ├── BeforeAttribute.cs
│ │ │ ├── BeforeTestAttribute.cs
│ │ │ ├── AfterTestAttribute.cs
│ │ │ ├── TraitAttribute.cs
│ │ │ ├── GodotExceptionMonitorAttribute.cs
│ │ │ ├── TestStageAttribute.cs
│ │ │ └── FuzzerAttribute.cs
│ │ ├── extensions
│ │ │ └── SystemVectorExtension.cs
│ │ ├── discovery
│ │ │ └── CodeNavigation.cs
│ │ ├── data
│ │ │ └── IValueProvider.cs
│ │ └── MouseMoveTask.cs
│ ├── api
│ │ ├── LogLevel.cs
│ │ ├── TestNode.cs
│ │ ├── ITestRunner.cs
│ │ ├── ITestEventListener.cs
│ │ ├── TestAssemblyNode.cs
│ │ ├── IGdUnitAwaitable.cs
│ │ ├── TestSuiteNode.cs
│ │ ├── IDebuggerFramework.cs
│ │ ├── TestCaseNode.cs
│ │ ├── ITestEngineLogger.cs
│ │ ├── ReportType.cs
│ │ ├── ICommandExecutor.cs
│ │ ├── ITestReport.cs
│ │ ├── TestRunnerConfig.cs
│ │ └── ITestEvent.cs
│ └── constraints
│ │ ├── IBoolConstraint.cs
│ │ └── IObjectConstraint.cs
└── nuget.config
├── TestAdapter
├── nupkg
│ └── .gitignore
├── src
│ ├── AssemblyInfo.cs
│ ├── extensions
│ │ ├── TestEventExtensions.cs
│ │ └── StringExtensions.cs
│ ├── discovery
│ │ └── TestCaseDiscoverySink.cs
│ ├── DefaultDebuggerFramework.cs
│ ├── RiderDebuggerFramework.cs
│ ├── utilities
│ │ ├── IdeDetector.cs
│ │ ├── Utils.cs
│ │ └── Logger.cs
│ ├── settings
│ │ └── GdUnit4SettingsProvider.cs
│ └── execution
│ │ └── TestCaseFilter.cs
└── ReleaseNotes.txt
├── Api.Test
├── .gitignore
├── .gitattributes
├── src
│ ├── core
│ │ ├── resources
│ │ │ ├── testsuites
│ │ │ │ └── mono
│ │ │ │ │ ├── spaceA
│ │ │ │ │ └── TestSuite.cs
│ │ │ │ │ ├── spaceB
│ │ │ │ │ └── TestSuite.cs
│ │ │ │ │ ├── noSpace
│ │ │ │ │ └── TestSuiteWithoutNamespace.cs
│ │ │ │ │ ├── NotATestSuite.cs
│ │ │ │ │ ├── ExampleTestSuiteA.cs
│ │ │ │ │ ├── TestSuiteAllStagesSuccess.cs
│ │ │ │ │ ├── TestSuiteWithFileScopedNamespace.cs
│ │ │ │ │ ├── TestSuiteFailOnTestCase1.cs
│ │ │ │ │ ├── TestSuiteFailOnStageBeforeTest.cs
│ │ │ │ │ ├── TestSuiteFailOnStageAfter.cs
│ │ │ │ │ ├── TestSuiteFailOnStageBefore.cs
│ │ │ │ │ ├── TestSuiteFailOnStageAfterTest.cs
│ │ │ │ │ ├── TestSuiteFailOnMultiStages.cs
│ │ │ │ │ ├── TestSuiteParameterizedTests.cs
│ │ │ │ │ ├── TestSuiteAllTestsFailWithExceptions.cs
│ │ │ │ │ ├── TestSuiteFailAndOrphansDetected.cs
│ │ │ │ │ └── TestSuiteAbortOnTestTimeout.cs
│ │ │ ├── scenes
│ │ │ │ ├── SimpleScene.scn
│ │ │ │ ├── DragAndDrop
│ │ │ │ │ ├── icon.png
│ │ │ │ │ ├── DragAndDropControl.tscn
│ │ │ │ │ ├── DragAndDropTestScene.gd
│ │ │ │ │ ├── DragAndDropTestScene.tscn
│ │ │ │ │ └── DragAndDropControl.gd
│ │ │ │ ├── TestSceneWithInitialization.tscn
│ │ │ │ ├── SimpleScene.gd
│ │ │ │ ├── TestSceneWithExceptionTest.tscn
│ │ │ │ ├── SimpleScene.tscn
│ │ │ │ ├── TestSceneWithInitialization.cs
│ │ │ │ ├── Spell.gd
│ │ │ │ ├── TestSceneWithButton.tscn
│ │ │ │ ├── TestSceneWithExceptionTest.cs
│ │ │ │ └── Spell.cs
│ │ │ └── sources
│ │ │ │ ├── TestPerson.cs
│ │ │ │ └── TestPerson2.cs
│ │ ├── UtilsX2.cs
│ │ ├── execution
│ │ │ └── monitoring
│ │ │ │ ├── ExampleEventBus.cs
│ │ │ │ └── ExampleWithWithEventBus.cs
│ │ ├── ExternalDataPoints.cs
│ │ ├── hooks
│ │ │ └── StdOutConsoleHookTest.cs
│ │ ├── GodotRuntimeAnalyzerExampleTestSuite.cs
│ │ ├── discovery
│ │ │ ├── DiscoverTestUtils.cs
│ │ │ └── TestCaseDescriptorTest.cs
│ │ └── TestSuiteWithExpectedExceptions.cs
│ ├── GdUnit4NetApiGodotBridgeTest.cs
│ ├── asserts
│ │ ├── ValueFormatter.cs
│ │ ├── CSharpTypes
│ │ │ └── Player.cs
│ │ └── Example.cs
│ ├── extensions
│ │ ├── GodotVariantExtensionsTest.cs
│ │ └── GodotObjectExtensionsTest.cs
│ └── UtilsTest.cs
├── .editorconfig
├── run_tests.sh
├── nuget.config
├── Directory.Build.props
├── project.godot
├── icon.svg
└── GdUnit4ApiTest.csproj
├── Example
├── .gitignore
├── assets
│ └── TestExplorerRun.png
├── .editorconfig
├── Directory.Build.props
├── src
│ └── Menu.tscn
├── nuget.config
├── project.godot
├── test
│ ├── api
│ │ ├── CSharpTypes
│ │ │ └── Player.cs
│ │ └── AssertionsTest.cs
│ └── ExampleTest.cs
├── icon.svg
├── .runsettings
├── ExampleProject.csproj
└── .runsettings-ci
├── global.json
├── Analyzers.Test
├── src
│ ├── UtilsX1.cs
│ ├── UtilsX2.cs
│ ├── ModuleInitializer.cs
│ ├── TestSourceBuilder.cs
│ └── ExampleTest.cs
├── GdUnit4Analyzers.Tests.csproj
├── .runsettings
└── test.ruleset
├── TestAdapter.Test
├── test
│ ├── NoOpLogger.cs
│ ├── TestUtils.cs
│ ├── resources
│ │ ├── project.godot
│ │ └── project.godot2
│ └── utilities
│ │ └── UtilsTest.cs
├── GdUnit4TestAdapter.Tests.csproj
├── .runsettings
└── test.ruleset
├── .vscode
├── extensions.json
├── tasks.json
└── settings.json
├── GdUnit4Net.sln.DotSettings
├── stylecop.json
├── clean.sh
├── ProjectVersions.props
└── LICENSE
/Analyzers/AnalyzerReleases.Unshipped.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Api/nupkg/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/Analyzers/nupkg/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/TestAdapter/nupkg/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/Api.Test/.gitignore:
--------------------------------------------------------------------------------
1 | # Godot 4+ specific ignores
2 | .godot/
3 |
--------------------------------------------------------------------------------
/Example/.gitignore:
--------------------------------------------------------------------------------
1 | # Godot 4+ specific ignores
2 | .godot/
3 | gdunit4_testadapter/
4 |
5 |
--------------------------------------------------------------------------------
/Api.Test/.gitattributes:
--------------------------------------------------------------------------------
1 | # Normalize EOL for all files that Git considers text files.
2 | * text=auto eol=lf
3 |
--------------------------------------------------------------------------------
/Example/assets/TestExplorerRun.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/godot-gdunit-labs/gdUnit4Net/HEAD/Example/assets/TestExplorerRun.png
--------------------------------------------------------------------------------
/Api.Test/src/core/resources/testsuites/mono/spaceA/TestSuite.cs:
--------------------------------------------------------------------------------
1 | namespace GdUnit4.Tests.SpaceA;
2 |
3 | public class TestSuite
4 | {
5 | }
6 |
--------------------------------------------------------------------------------
/Api.Test/src/core/resources/testsuites/mono/spaceB/TestSuite.cs:
--------------------------------------------------------------------------------
1 | namespace GdUnit4.Tests.SpaceB;
2 |
3 | public class TestSuite
4 | {
5 | }
6 |
--------------------------------------------------------------------------------
/Api.Test/src/core/resources/scenes/SimpleScene.scn:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/godot-gdunit-labs/gdUnit4Net/HEAD/Api.Test/src/core/resources/scenes/SimpleScene.scn
--------------------------------------------------------------------------------
/Api.Test/src/core/resources/scenes/DragAndDrop/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/godot-gdunit-labs/gdUnit4Net/HEAD/Api.Test/src/core/resources/scenes/DragAndDrop/icon.png
--------------------------------------------------------------------------------
/Api.Test/.editorconfig:
--------------------------------------------------------------------------------
1 | # Temporary ignore the global editor config for this sub project
2 | root = true
3 |
4 | # Apply to all files in this directory and subdirectories
5 | [*]
6 |
--------------------------------------------------------------------------------
/Example/.editorconfig:
--------------------------------------------------------------------------------
1 | # Temporary ignore the global editor config for this sub project
2 | root = true
3 |
4 | # Apply to all files in this directory and subdirectories
5 | [*]
6 |
--------------------------------------------------------------------------------
/Api/buildTransitive/gdUnit4.api.props:
--------------------------------------------------------------------------------
1 |
2 |
3 | $(DefineConstants);GDUNIT4NET_API_V5
4 |
5 |
6 |
--------------------------------------------------------------------------------
/global.json:
--------------------------------------------------------------------------------
1 | {
2 | "sdk": {
3 | "version": "9.0.308",
4 | "rollForward": "latestPatch",
5 | "allowPrerelease": false
6 | },
7 | "msbuild-sdks": {
8 | "Godot.NET.Sdk": "4.4"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/Api/build/gdUnit4.api.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $(DefineConstants);GDUNIT4NET_API_V5
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Analyzers.Test/src/UtilsX1.cs:
--------------------------------------------------------------------------------
1 | namespace GdUnit4.Analyzers.Test;
2 |
3 | public static class UtilsX1
4 | {
5 | // [MethodImpl(MethodImplOptions.AggressiveInlining)]
6 | public static string Foo() => string.Empty;
7 | }
8 |
--------------------------------------------------------------------------------
/Analyzers/src/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2025 Mike Schulze
2 | // MIT License - See LICENSE file in the repository root for full license text
3 |
4 | using System.Runtime.CompilerServices;
5 |
6 | [assembly: InternalsVisibleTo("gdUnit4Analyzers.Tests")]
7 |
--------------------------------------------------------------------------------
/TestAdapter.Test/test/NoOpLogger.cs:
--------------------------------------------------------------------------------
1 | namespace GdUnit4.TestAdapter.Test;
2 |
3 | using Api;
4 |
5 | internal sealed class NoOpLogger : ITestEngineLogger
6 | {
7 | public void SendMessage(LogLevel logLevel, string message)
8 | {
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/Api.Test/src/core/resources/testsuites/mono/noSpace/TestSuiteWithoutNamespace.cs:
--------------------------------------------------------------------------------
1 | #pragma warning disable CA1050 // Declare types in namespaces
2 | public class TestSuiteWithoutNamespace
3 | #pragma warning restore CA1050 // Declare types in namespaces
4 | {
5 |
6 | }
7 |
--------------------------------------------------------------------------------
/TestAdapter/src/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2025 Mike Schulze
2 | // MIT License - See LICENSE file in the repository root for full license text
3 |
4 | using System.Runtime.CompilerServices;
5 |
6 | [assembly: InternalsVisibleTo("gdUnit4.TestAdapter.Test")]
7 |
--------------------------------------------------------------------------------
/Api.Test/src/core/UtilsX2.cs:
--------------------------------------------------------------------------------
1 | namespace GdUnit4.Tests.Core;
2 |
3 | using Godot;
4 |
5 | public static class UtilsX2
6 | {
7 | public static string Foo() => "";
8 |
9 | public static string Bar() => ProjectSettings.GlobalizePath("res://src/core/resources/sources/TestPerson.cs");
10 | }
11 |
--------------------------------------------------------------------------------
/Api.Test/run_tests.sh:
--------------------------------------------------------------------------------
1 | # !/usr/bin/env bash
2 |
3 | rm -rf ./reports
4 | $GODOT_BIN . --headless --build-solutions --quit-after 100 --verbose
5 | echo "Compile exit: $?"
6 |
7 |
8 | echo "Run tests"
9 |
10 | dotnet test --settings .runsettings --results-directory ./reports
11 | echo "Exit Code: $?"
12 |
--------------------------------------------------------------------------------
/Analyzers.Test/src/UtilsX2.cs:
--------------------------------------------------------------------------------
1 | namespace GdUnit4.Analyzers.Test;
2 |
3 | using Godot;
4 |
5 | public static class UtilsX2
6 | {
7 | public static string Foo() => string.Empty;
8 |
9 | public static string Bar() => ProjectSettings.GlobalizePath("res://src/core/resources/sources/TestPerson.cs");
10 | }
11 |
--------------------------------------------------------------------------------
/Api.Test/src/GdUnit4NetApiGodotBridgeTest.cs:
--------------------------------------------------------------------------------
1 | namespace GdUnit4.Tests;
2 |
3 | using static Assertions;
4 |
5 | [TestSuite]
6 | public class GdUnit4NetApiGodotBridgeTest
7 | {
8 | [TestCase]
9 | public void Version()
10 | => AssertThat(GdUnit4NetApiGodotBridge.Version()).StartsWith("5.1.");
11 | }
12 |
--------------------------------------------------------------------------------
/Api.Test/src/core/resources/scenes/TestSceneWithInitialization.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=2 format=3 uid="uid://b4d0favbx8ckg"]
2 |
3 | [ext_resource type="Script" path="res://src/core/resources/scenes/TestSceneWithInitialization.cs" id="1"]
4 |
5 | [node name="SceneWithInitialization" type="Node2D"]
6 | script = ExtResource("1")
7 |
--------------------------------------------------------------------------------
/Api.Test/src/core/resources/scenes/SimpleScene.gd:
--------------------------------------------------------------------------------
1 | extends Node2D
2 |
3 | class Player extends Node:
4 | var position :Vector3 = Vector3.ZERO
5 |
6 |
7 | func _init():
8 | set_name("Player")
9 |
10 |
11 | func is_on_floor() -> bool:
12 | return true
13 |
14 |
15 | func _ready():
16 | add_child(Player.new(), true)
17 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "ms-dotnettools.csharp",
4 | "EditorConfig.EditorConfig",
5 | "selcukermaya.se-csproj-extensions",
6 | "josefpihrt-vscode.roslynator",
7 | "streetsidesoftware.code-spell-checker",
8 | "DavidAnson.vscode-markdownlint",
9 | "Gruntfuggly.todo-tree"
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------
/Api.Test/src/core/resources/testsuites/mono/NotATestSuite.cs:
--------------------------------------------------------------------------------
1 | namespace GdUnit4.Tests.Resources;
2 |
3 | using static GdUnit4.Assertions;
4 |
5 | // will be ignored because of missing `[TestSuite]` annotation
6 | public partial class NotATestSuite
7 | {
8 | [TestCase]
9 | public void TestFoo()
10 | => AssertBool(true).IsEqual(false);
11 | }
12 |
--------------------------------------------------------------------------------
/Api.Test/nuget.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
13 |
--------------------------------------------------------------------------------
/Example/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | false
5 | false
6 | false
7 | false
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Api/src/asserts/IBoolAssert.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2025 Mike Schulze
2 | // MIT License - See LICENSE file in the repository root for full license text
3 | namespace GdUnit4.Asserts;
4 |
5 | using Constraints;
6 |
7 | ///
8 | /// An Assertion to verify boolean values.
9 | ///
10 | public interface IBoolAssert : IBoolConstraint, IAssertMessage
11 | {
12 | }
13 |
--------------------------------------------------------------------------------
/Api/src/asserts/ISignalAssert.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2025 Mike Schulze
2 | // MIT License - See LICENSE file in the repository root for full license text
3 | namespace GdUnit4.Asserts;
4 |
5 | using Constraints;
6 |
7 | ///
8 | /// An Assertion Tool to verify Godot signals.
9 | ///
10 | public interface ISignalAssert : ISignalConstraint, IAssertMessage
11 | {
12 | }
13 |
--------------------------------------------------------------------------------
/Api.Test/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | false
5 | false
6 | false
7 | false
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Api/src/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2025 Mike Schulze
2 | // MIT License - See LICENSE file in the repository root for full license text
3 |
4 | using System.Runtime.CompilerServices;
5 |
6 | [assembly: InternalsVisibleTo("GdUnit4ApiTest")]
7 | [assembly: InternalsVisibleTo("GdUnit4.TestAdapter")]
8 | [assembly: InternalsVisibleTo("GdUnit4.Analyzers")]
9 | [assembly: InternalsVisibleTo("GdUnit4Analyzers.Tests")]
10 |
--------------------------------------------------------------------------------
/GdUnit4Net.sln.DotSettings:
--------------------------------------------------------------------------------
1 |
2 | False
--------------------------------------------------------------------------------
/Api.Test/src/core/execution/monitoring/ExampleEventBus.cs:
--------------------------------------------------------------------------------
1 | namespace GdUnit4.Tests.Core.Execution.Monitoring;
2 |
3 | using Godot;
4 |
5 | public partial class ExampleEventBus : Node
6 | {
7 | [Signal]
8 | public delegate void OnMyEventEventHandler();
9 |
10 | public void Emit() => EmitSignal(SignalName.OnMyEvent);
11 |
12 | public void Connect(Callable callback) => Connect(SignalName.OnMyEvent, callback);
13 | }
14 |
--------------------------------------------------------------------------------
/Example/src/Menu.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene format=3 uid="uid://5hobjg6fgrwy"]
2 |
3 | [node name="Menu" type="Control"]
4 | layout_mode = 3
5 | anchors_preset = 15
6 | anchor_right = 1.0
7 | anchor_bottom = 1.0
8 | grow_horizontal = 2
9 | grow_vertical = 2
10 |
11 | [node name="Button" type="Button" parent="."]
12 | layout_mode = 0
13 | offset_left = 308.0
14 | offset_top = 188.0
15 | offset_right = 465.0
16 | offset_bottom = 228.0
17 | text = "Click me"
18 |
--------------------------------------------------------------------------------
/TestAdapter.Test/test/TestUtils.cs:
--------------------------------------------------------------------------------
1 | namespace GdUnit4.TestAdapter.Test;
2 |
3 | internal static class TestUtils
4 | {
5 | public static string GetResourcePath(string resourcePath)
6 | {
7 | var baseDir = AppDomain.CurrentDomain.BaseDirectory;
8 | var projectRoot = Path.GetFullPath(Path.Combine(baseDir, "..", "..", ".."));
9 | return Path.Combine(projectRoot, "test", "resources", resourcePath);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Api/src/core/runners/GdUnit4TestRunnerSceneTemplate.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2025 Mike Schulze
2 | // MIT License - See LICENSE file in the repository root for full license text
3 |
4 | // ReSharper disable once CheckNamespace
5 | namespace GdUnit4.TestRunner;
6 |
7 | using Core.Runners;
8 |
9 | ///
10 | /// The GdUnit4Net test runner scene.
11 | ///
12 | public partial class GdUnit4TestRunnerSceneTemplate : GdUnit4TestRunnerSceneCore
13 | {
14 | }
15 |
--------------------------------------------------------------------------------
/Api.Test/src/core/resources/scenes/TestSceneWithExceptionTest.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=2 format=3 uid="uid://cjd3v7it80k0u"]
2 |
3 | [ext_resource type="Script" path="res://src/core/resources/scenes/TestSceneWithExceptionTest.cs" id="1_m8etn"]
4 |
5 | [node name="TestSceneWithExceptionTest" type="Control"]
6 | layout_mode = 3
7 | anchors_preset = 15
8 | anchor_right = 1.0
9 | anchor_bottom = 1.0
10 | grow_horizontal = 2
11 | grow_vertical = 2
12 | script = ExtResource("1_m8etn")
13 |
--------------------------------------------------------------------------------
/Api.Test/src/core/resources/scenes/SimpleScene.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=3 format=3 uid="uid://cn8ucy2rheu0f"]
2 |
3 | [ext_resource type="Texture2D" uid="uid://c8au0x20kepw0" path="res://icon.svg" id="1"]
4 | [ext_resource type="Script" path="res://src/core/resources/scenes/SimpleScene.gd" id="2"]
5 |
6 | [node name="Node2D" type="Node2D"]
7 | script = ExtResource("2")
8 |
9 | [node name="Sprite2D" type="Sprite2D" parent="."]
10 | position = Vector2(504, 252)
11 | texture = ExtResource("1")
12 |
--------------------------------------------------------------------------------
/Api/nuget.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
14 |
--------------------------------------------------------------------------------
/Api.Test/src/core/resources/testsuites/mono/ExampleTestSuiteA.cs:
--------------------------------------------------------------------------------
1 | namespace GdUnit4.Tests.Resources;
2 |
3 | using static Assertions;
4 | // will be ignored because of missing `[TestSuite]` annotation
5 | // used by executor integration test
6 | public class ExampleTestSuiteA
7 | {
8 |
9 | [TestCase]
10 | public void TestCase1()
11 | => AssertBool(true).IsEqual(false);
12 |
13 | [TestCase]
14 | public void TestCase2()
15 | => AssertBool(true).IsEqual(false);
16 | }
17 |
--------------------------------------------------------------------------------
/Api/src/asserts/CompareExtensions.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2025 Mike Schulze
2 | // MIT License - See LICENSE file in the repository root for full license text
3 |
4 | namespace GdUnit4.Asserts;
5 |
6 | internal static class CompareExtensions
7 | {
8 | internal static bool IsEquals(this T? c, T? e) => Comparable.IsEqual(c, e).Valid;
9 |
10 | internal static bool IsSame(this T? c, T? e)
11 | where TAssert : IAssert
12 | => AssertBase.IsSame(c, e);
13 | }
14 |
--------------------------------------------------------------------------------
/Api.Test/src/core/execution/monitoring/ExampleWithWithEventBus.cs:
--------------------------------------------------------------------------------
1 | namespace GdUnit4.Tests.Core.Execution.Monitoring;
2 |
3 | using System;
4 |
5 | using Godot;
6 |
7 | public partial class ExampleWithWithEventBus : Node
8 | {
9 | public void Register(ExampleEventBus bus)
10 | => bus.Connect(new Callable(this, nameof(MyCallback)));
11 |
12 | #pragma warning disable CA2201
13 | private void MyCallback() => throw new NullReferenceException("Nope");
14 | #pragma warning restore CA2201
15 | }
16 |
--------------------------------------------------------------------------------
/Api.Test/src/core/resources/scenes/TestSceneWithInitialization.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 |
3 | namespace GdUnit4.Tests.core.resources.scenes;
4 |
5 | using System.Collections.Generic;
6 |
7 | public partial class TestSceneWithInitialization : Node2D
8 | {
9 | private readonly List methodCalls = new();
10 | public List MethodCalls => methodCalls;
11 | public void Initialize() => methodCalls.Add("Initialize");
12 |
13 | public override void _Ready() => methodCalls.Add("_Ready");
14 | }
15 |
16 |
--------------------------------------------------------------------------------
/Api.Test/src/core/resources/testsuites/mono/TestSuiteAllStagesSuccess.cs:
--------------------------------------------------------------------------------
1 | namespace GdUnit4.Tests.Resources;
2 |
3 | using static Assertions;
4 |
5 | // will be ignored because of missing `[TestSuite]` annotation
6 | // used by executor integration test
7 | public class TestSuiteAllStagesSuccess
8 | {
9 |
10 | [TestCase]
11 | public void TestCase1()
12 | => AssertBool(true).IsEqual(true);
13 |
14 | [TestCase]
15 | public void TestCase2()
16 | => AssertBool(true).IsEqual(true);
17 | }
18 |
--------------------------------------------------------------------------------
/Api.Test/src/asserts/ValueFormatter.cs:
--------------------------------------------------------------------------------
1 | namespace GdUnit4.Tests.asserts;
2 |
3 | using GdUnit4.Asserts;
4 |
5 | public static class ValueFormatter
6 | {
7 | internal static string AsString(object? value)
8 | {
9 | if (value == null)
10 | return "NULL";
11 | if (value is string s)
12 | return $"\"{s}\"";
13 | if (value.GetType().IsPrimitive)
14 | return value.ToString() ?? "NULL";
15 |
16 | return AssertFailures.AsObjectId(value);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Api.Test/src/core/resources/testsuites/mono/TestSuiteWithFileScopedNamespace.cs:
--------------------------------------------------------------------------------
1 | namespace GdUnit4.Tests.Resources;
2 |
3 | using static Assertions;
4 | // will be ignored because of missing `[TestSuite]` annotation
5 | // used by executor integration test
6 | public class TestSuiteWithFileScopedNamespace
7 | {
8 |
9 | [TestCase]
10 | public void TestCase1()
11 | => AssertBool(true).IsEqual(false);
12 |
13 | [TestCase]
14 | public void TestCase2()
15 | => AssertBool(true).IsEqual(false);
16 | }
17 |
--------------------------------------------------------------------------------
/Api/src/asserts/IObjectAssert.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2025 Mike Schulze
2 | // MIT License - See LICENSE file in the repository root for full license text
3 | namespace GdUnit4.Asserts;
4 |
5 | using Constraints;
6 |
7 | ///
8 | /// An Assertion Tool to verify object values.
9 | ///
10 | ///
11 | /// The object type being tested.
12 | ///
13 | public interface IObjectAssert : IObjectConstraint, IAssertMessage>
14 | {
15 | }
16 |
--------------------------------------------------------------------------------
/Api.Test/project.godot:
--------------------------------------------------------------------------------
1 | ; Engine configuration file.
2 | ; It's best edited using the editor UI and not directly,
3 | ; since the parameters that go here are not all obvious.
4 | ;
5 | ; Format:
6 | ; [section] ; section goes between []
7 | ; param=value ; assign values to parameters
8 |
9 | config_version=5
10 |
11 | [application]
12 |
13 | config/name="GdUnit4ApiTest"
14 | config/features=PackedStringArray("4.3", "C#", "Forward Plus")
15 | config/icon="res://icon.svg"
16 |
17 | [dotnet]
18 |
19 | project/assembly_name="GdUnit4ApiTest"
20 |
--------------------------------------------------------------------------------
/Api/src/asserts/IEnumerableAssert.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2025 Mike Schulze
2 | // MIT License - See LICENSE file in the repository root for full license text
3 | namespace GdUnit4.Asserts;
4 |
5 | using Constraints;
6 |
7 | ///
8 | /// An Assertion tool to verify enumerating.
9 | ///
10 | /// The type of elements in the enumerable being asserted.
11 | public interface IEnumerableAssert : IEnumerableConstraint, IAssertMessage>
12 | {
13 | }
14 |
--------------------------------------------------------------------------------
/Example/nuget.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
15 |
16 |
--------------------------------------------------------------------------------
/TestAdapter.Test/test/resources/project.godot:
--------------------------------------------------------------------------------
1 | ; Engine configuration file.
2 | ; It's best edited using the editor UI and not directly,
3 | ; since the parameters that go here are not all obvious.
4 | ;
5 | ; Format:
6 | ; [section] ; section goes between []
7 | ; param=value ; assign values to parameters
8 |
9 | config_version=5
10 |
11 | [application]
12 |
13 | config/name="gdUnit4Test"
14 | config/features=PackedStringArray("4.3", "C#", "Forward Plus")
15 | config/icon="res://icon.svg"
16 |
17 | [dotnet]
18 |
19 | project/assembly_name="gdUnit4Test"
20 |
--------------------------------------------------------------------------------
/Example/project.godot:
--------------------------------------------------------------------------------
1 | ; Engine configuration file.
2 | ; It's best edited using the editor UI and not directly,
3 | ; since the parameters that go here are not all obvious.
4 | ;
5 | ; Format:
6 | ; [section] ; section goes between []
7 | ; param=value ; assign values to parameters
8 |
9 | config_version=5
10 |
11 | [application]
12 |
13 | config/name="ExampleProject"
14 | config/features=PackedStringArray("4.2.2", "C#", "Forward Plus")
15 | config/icon="res://icon.svg"
16 | run/main_scene="res://src/Menu.tscn"
17 |
18 | [dotnet]
19 |
20 | project/assembly_name="ExampleProject"
21 |
--------------------------------------------------------------------------------
/Api.Test/src/core/resources/scenes/DragAndDrop/DragAndDropControl.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=2 format=3 uid="uid://ca2rr3dan4vvw"]
2 |
3 | [ext_resource type="Script" path="res://src/core/resources/scenes/DragAndDrop/DragAndDropControl.gd" id="1"]
4 |
5 | [node name="Panel" type="PanelContainer"]
6 | offset_left = 245.0
7 | offset_top = 232.0
8 | offset_right = 350.0
9 | offset_bottom = 337.0
10 | size_flags_horizontal = 3
11 | size_flags_vertical = 3
12 | script = ExtResource("1")
13 |
14 | [node name="TextureRect" type="TextureRect" parent="."]
15 | layout_mode = 2
16 | expand_mode = 1
17 |
--------------------------------------------------------------------------------
/Api.Test/src/core/resources/scenes/DragAndDrop/DragAndDropTestScene.gd:
--------------------------------------------------------------------------------
1 | extends Control
2 |
3 | @onready var texture = preload("res://src/core/resources/scenes/DragAndDrop/icon.png")
4 |
5 | func _ready():
6 | # set initial drag texture
7 | $left/TextureRect.texture = texture
8 |
9 |
10 | # Virtual method to be implemented by the user. Use this method to process and accept inputs on UI elements. See accept_event().
11 | func _gui_input(_event):
12 | #prints("Game _gui_input", _event.as_text())
13 | pass
14 |
15 |
16 | func _on_Button_button_down():
17 | # print("BUTTON DOWN")
18 | pass
19 |
--------------------------------------------------------------------------------
/Api/src/api/LogLevel.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2025 Mike Schulze
2 | // MIT License - See LICENSE file in the repository root for full license text
3 | namespace GdUnit4.Api;
4 |
5 | ///
6 | /// Defines the available logging severity levels.
7 | ///
8 | public enum LogLevel
9 | {
10 | ///
11 | /// Informational message.
12 | ///
13 | Informational = 0,
14 |
15 | ///
16 | /// Warning message.
17 | ///
18 | Warning = 1,
19 |
20 | ///
21 | /// Error message.
22 | ///
23 | Error = 2
24 | }
25 |
--------------------------------------------------------------------------------
/Api/src/core/hooks/StdOutHookFactory.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2025 Mike Schulze
2 | // MIT License - See LICENSE file in the repository root for full license text
3 |
4 | namespace GdUnit4.Core.Hooks;
5 |
6 | using System;
7 |
8 | internal static class StdOutHookFactory
9 | {
10 | public static IStdOutHook CreateStdOutHook()
11 | {
12 | if (OperatingSystem.IsWindows())
13 | return new WindowsStdOutHook();
14 | if (OperatingSystem.IsMacOS() || OperatingSystem.IsLinux())
15 | return new UnixStdOutHook();
16 | throw new PlatformNotSupportedException("Unsupported operating system");
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Api.Test/src/core/resources/sources/TestPerson.cs:
--------------------------------------------------------------------------------
1 | namespace GdUnit4.Example.Test.Resources;
2 |
3 | public class TestPerson
4 | {
5 |
6 | public TestPerson(string firstName, string lastName)
7 | {
8 | FirstName = firstName;
9 | LastName = lastName;
10 | }
11 |
12 | public string FirstName { get; }
13 |
14 | public string LastName { get; }
15 |
16 | public string FullName => FirstName + " " + LastName;
17 |
18 | public string FullName2() => FirstName + " " + LastName;
19 |
20 | public string FullName3()
21 | {
22 | var fullName = $"{FirstName} {LastName}";
23 | return fullName;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/Api.Test/src/core/resources/sources/TestPerson2.cs:
--------------------------------------------------------------------------------
1 | #pragma warning disable CA1050 // Declare types in namespaces
2 | public class TestPerson2
3 | #pragma warning restore CA1050 // Declare types in namespaces
4 | {
5 |
6 | public TestPerson2(string firstName, string lastName)
7 | {
8 | FirstName = firstName;
9 | LastName = lastName;
10 | }
11 |
12 | public string FirstName { get; }
13 |
14 | public string LastName { get; }
15 |
16 | public string FullName => FirstName + " " + LastName;
17 |
18 | public string FullName2() => FirstName + " " + LastName;
19 |
20 | public string FullName3() => FirstName + " " + LastName;
21 | }
22 |
--------------------------------------------------------------------------------
/stylecop.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
3 | "settings": {
4 | "documentationRules": {
5 | "companyName": "Mike Schulze",
6 | "copyrightText": "Copyright (c) 2025 Mike Schulze\nMIT License - See LICENSE file in the repository root for full license text",
7 | "xmlHeader": false,
8 | "headerDecoration": "",
9 | "documentInternalElements": false,
10 | "documentPrivateElements": false,
11 | "documentPrivateFields": false,
12 | "fileNamingConvention": "stylecop"
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Example/test/api/CSharpTypes/Player.cs:
--------------------------------------------------------------------------------
1 | namespace Examples.Test.Api.CSharpTypes;
2 |
3 | // Original Player class (without IEquatable for comparison)
4 | public class Player
5 | {
6 | public Player(string name, int level, float health, bool isAlive)
7 | {
8 | Name = name;
9 | Level = level;
10 | Health = health;
11 | IsAlive = isAlive;
12 | }
13 |
14 | public string Name { get; }
15 |
16 | public int Level { get; }
17 | public float Health { get; }
18 | public bool IsAlive { get; }
19 |
20 | public override string ToString()
21 | => $"Player(Name: {Name}, Level: {Level}, Health: {Health}, IsAlive: {IsAlive})";
22 | }
23 |
--------------------------------------------------------------------------------
/Api.Test/src/core/ExternalDataPoints.cs:
--------------------------------------------------------------------------------
1 | namespace GdUnit4.Tests.Core;
2 |
3 | using System.Collections.Generic;
4 |
5 | public static class ExternalDataPoints
6 | {
7 | public static IEnumerable